1 /* Copyright (C) 2003-2006 Jesper K. Pedersen <blackie@kde.org>
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "XMLDB/Database.h"
21 #include <qfileinfo.h>
23 #include "Browser/BrowserWidget.h"
24 #include "DB/CategoryCollection.h"
25 #include "DB/ResultId.h"
26 #include <QProgressBar>
27 #include <qapplication.h>
28 #include "NewImageFinder.h"
29 #include <DB/MediaCount.h>
30 #include <config-kpa-sqldb.h>
32 #include "SQLDB/Database.h"
33 #include "SQLDB/DatabaseAddress.h"
35 #include <QProgressDialog>
39 ImageDB
* ImageDB::_instance
= 0;
41 ImageDB
* DB::ImageDB::instance()
44 qFatal("ImageDB::instance must not be called before ImageDB::setup");
48 void ImageDB::setupXMLDB( const QString
& configFile
)
51 qFatal("ImageDB::setupXMLDB: Setup must be called only once.");
52 _instance
= new XMLDB::Database( configFile
);
57 void ImageDB::setupSQLDB( const SQLDB::DatabaseAddress
& address
)
60 qFatal("ImageDB::setupSQLDB: Setup must be called only once.");
61 _instance
= new SQLDB::Database(address
);
65 #endif /* SQLDB_SUPPORT */
67 void ImageDB::deleteInstance()
73 void ImageDB::connectSlots()
75 connect( Settings::SettingsData::instance(), SIGNAL( locked( bool, bool ) ), _instance
, SLOT( lockDB( bool, bool ) ) );
76 connect( &_instance
->memberMap(), SIGNAL( dirty() ), _instance
, SLOT( markDirty() ));
79 QString
ImageDB::NONE()
81 return QString::fromLatin1("**NONE**");
84 DB::Result
ImageDB::currentScope(bool requireOnDisk
) const
86 // TODO: DEPENDENCY: DB:: should not depend on other directories.
87 return search( Browser::BrowserWidget::instance()->currentContext(), requireOnDisk
);
90 void ImageDB::markDirty()
95 void ImageDB::setDateRange( const ImageDate
& range
, bool includeFuzzyCounts
)
97 _selectionRange
= range
;
98 _includeFuzzyCounts
= includeFuzzyCounts
;
101 void ImageDB::clearDateRange()
103 _selectionRange
= ImageDate();
106 void ImageDB::slotRescan()
108 bool newImages
= NewImageFinder().findImages();
112 emit
totalChanged( totalCount() );
115 void ImageDB::slotRecalcCheckSums(const DB::Result
& inputList
)
117 DB::Result list
= inputList
;
118 if (list
.isEmpty()) {
123 bool d
= NewImageFinder().calculateMD5sums( list
, md5Map() );
127 emit
totalChanged( totalCount() );
130 StringSet
DB::ImageDB::imagesWithMD5Changed()
134 NewImageFinder().calculateMD5sums(images(), &map
, &wasCanceled
);
138 StringSet changes
= md5Map()->diff( map
);
140 for ( StringSet::const_iterator it
= changes
.begin(); it
!= changes
.end(); ++it
)
141 res
.insert( Settings::SettingsData::instance()->imageDirectory() + *it
);
151 DB::MediaCount
ImageDB::count( const ImageSearchInfo
& searchInfo
)
155 Q_FOREACH(const DB::ImageInfoPtr inf
, search(searchInfo
).fetchInfos()) {
156 if ( inf
->mediaType() == Image
)
161 return MediaCount( images
, videos
);
164 void ImageDB::convertBackend(ImageDB
* newBackend
, QProgressBar
* progressBar
)
166 const DB::Result allImages
= images();
168 CategoryCollection
* origCategories
= categoryCollection();
169 CategoryCollection
* newCategories
= newBackend
->categoryCollection();
171 QList
<CategoryPtr
> categories
= origCategories
->categories();
174 progressBar
->setMaximum(categories
.count() + allImages
.size());
175 progressBar
->setValue(0);
180 // Convert the Category info
181 for( QList
<CategoryPtr
>::ConstIterator it
= categories
.constBegin(); it
!= categories
.constEnd(); ++it
) {
182 newCategories
->addCategory( (*it
)->name(), (*it
)->iconName(), (*it
)->viewType(),
183 (*it
)->thumbnailSize(), (*it
)->doShow() );
184 newCategories
->categoryForName( (*it
)->name() )->addOrReorderItems( (*it
)->items() );
187 progressBar
->setValue(n
++);
188 qApp
->processEvents();
192 // Convert member map
193 newBackend
->memberMap() = memberMap();
195 // Convert all images to the new back end
198 Q_FOREACH(const DB::ImageInfoPtr info
, allImages
.fetchInfos()) {
200 if (++count
% 100 == 0) {
201 newBackend
->addImages( list
);
205 progressBar
->setValue(n
++);
206 qApp
->processEvents();
209 newBackend
->addImages(list
);
211 progressBar
->setValue(n
);
214 void ImageDB::slotReread( const QStringList
& list
, DB::ExifMode mode
)
216 // Do here a reread of the exif info and change the info correctly in the database without loss of previous added data
217 QProgressDialog
dialog( i18n("Loading information from images"),
218 i18n("Cancel"), 0, list
.count() );
221 for( QStringList::ConstIterator it
= list
.begin(); it
!= list
.end(); ++it
, ++count
) {
222 if ( count
% 10 == 0 ) {
223 dialog
.setValue( count
); // ensure to call setProgress(0)
224 qApp
->processEvents( QEventLoop::AllEvents
);
226 if ( dialog
.wasCanceled() )
233 info(*it
, DB::AbsolutePath
)->readExif(*it
, mode
);
238 DB::ResultId
ImageDB::findFirstItemInRange(const DB::Result
& images
,
239 const ImageDate
& range
,
240 bool includeRanges
) const
242 DB::ResultId candidate
;
243 QDateTime candidateDateStart
;
244 Q_FOREACH(DB::ResultId id
, images
) {
245 ImageInfoPtr iInfo
= id
.fetchInfo();
247 ImageDate::MatchType match
= iInfo
->date().isIncludedIn(range
);
248 if (match
== DB::ImageDate::ExactMatch
||
249 (includeRanges
&& match
== DB::ImageDate::RangeMatch
)) {
250 if (candidate
.isNull() ||
251 iInfo
->date().start() < candidateDateStart
) {
253 // Looking at this, can't this just be iInfo->date().start()?
254 // Just in the middle of refactoring other stuff, so leaving
255 // this alone now. TODO(hzeller): revisit.
256 candidateDateStart
= info(candidate
)->date().start();
263 /** \fn void ImageDB::renameCategory( const QString& oldName, const QString newName )
264 * \brief Rename category in media items stored in database.
267 #include "ImageDB.moc"