File indexing completed on 2025-01-19 03:55:48
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2012-01-18 0007 * Description : database worker interface 0008 * 0009 * SPDX-FileCopyrightText: 2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "databaseworkeriface.h" 0016 0017 // KDE includes 0018 0019 #include <klocalizedstring.h> 0020 0021 // Local includes 0022 0023 #include "digikam_debug.h" 0024 #include "collectionscanner.h" 0025 #include "coredboperationgroup.h" 0026 #include "iteminfotasksplitter.h" 0027 #include "fileactionmngr_p.h" 0028 #include "scancontroller.h" 0029 #include "disjointmetadata.h" 0030 #include "faceutils.h" 0031 0032 namespace Digikam 0033 { 0034 0035 void FileActionMngrDatabaseWorker::assignTags(const FileActionItemInfoList& infos, const QList<int>& tagIDs) 0036 { 0037 changeTags(infos, tagIDs, true); 0038 } 0039 0040 void FileActionMngrDatabaseWorker::removeTags(const FileActionItemInfoList& infos, const QList<int>& tagIDs) 0041 { 0042 changeTags(infos, tagIDs, false); 0043 } 0044 0045 void FileActionMngrDatabaseWorker::changeTags(const FileActionItemInfoList& infos, 0046 const QList<int>& tagIDs, bool addOrRemove) 0047 { 0048 DisjointMetadata hub; 0049 QList<ItemInfo> forWriting; 0050 0051 { 0052 CoreDbOperationGroup group; 0053 group.setMaximumTime(200); 0054 0055 Q_FOREACH (const ItemInfo& info, infos) 0056 { 0057 if (state() == WorkerObject::Deactivating) 0058 { 0059 break; 0060 } 0061 0062 hub.load(info); 0063 0064 for (QList<int>::const_iterator tagIt = tagIDs.constBegin() ; tagIt != tagIDs.constEnd() ; ++tagIt) 0065 { 0066 if (addOrRemove) 0067 { 0068 hub.setTag(*tagIt, DisjointMetadataDataFields::MetadataAvailable); 0069 } 0070 else 0071 { 0072 hub.setTag(*tagIt, DisjointMetadataDataFields::MetadataInvalid); 0073 } 0074 } 0075 0076 hub.write(info, DisjointMetadata::PartialWrite); 0077 0078 if (hub.willWriteMetadata(DisjointMetadata::FullWriteIfChanged) && 0079 d->shallSendForWriting(info.id())) 0080 { 0081 forWriting << info; 0082 } 0083 0084 infos.dbProcessedOne(); 0085 group.allowLift(); 0086 } 0087 } 0088 0089 // send for writing file metadata 0090 0091 if (!forWriting.isEmpty()) 0092 { 0093 FileActionItemInfoList forWritingTaskList = FileActionItemInfoList::continueTask(forWriting, infos.progress()); 0094 forWritingTaskList.schedulingForWrite(i18n("Writing metadata to files"), d->fileProgressCreator()); 0095 0096 qCDebug(DIGIKAM_GENERAL_LOG) << "Scheduled to write"; 0097 0098 for (ItemInfoTaskSplitter splitter(forWritingTaskList) ; splitter.hasNext() ; ) 0099 { 0100 Q_EMIT writeMetadata(FileActionItemInfoList(splitter.next()), MetadataHub::WRITE_TAGS); 0101 } 0102 } 0103 0104 infos.dbFinished(); 0105 } 0106 0107 void FileActionMngrDatabaseWorker::assignPickLabel(const FileActionItemInfoList& infos, int pickId) 0108 { 0109 DisjointMetadata hub; 0110 QList<ItemInfo> forWriting; 0111 0112 { 0113 CoreDbOperationGroup group; 0114 group.setMaximumTime(200); 0115 0116 Q_FOREACH (const ItemInfo& info, infos) 0117 { 0118 if (state() == WorkerObject::Deactivating) 0119 { 0120 break; 0121 } 0122 0123 hub.load(info); 0124 hub.setPickLabel(pickId); 0125 hub.write(info, DisjointMetadata::PartialWrite); 0126 0127 if (hub.willWriteMetadata(DisjointMetadata::FullWriteIfChanged) && 0128 d->shallSendForWriting(info.id())) 0129 { 0130 forWriting << info; 0131 } 0132 0133 infos.dbProcessedOne(); 0134 group.allowLift(); 0135 } 0136 } 0137 0138 // send for writing file metadata 0139 0140 if (!forWriting.isEmpty()) 0141 { 0142 FileActionItemInfoList forWritingTaskList = FileActionItemInfoList::continueTask(forWriting, infos.progress()); 0143 forWritingTaskList.schedulingForWrite(i18n("Writing metadata to files"), d->fileProgressCreator()); 0144 0145 for (ItemInfoTaskSplitter splitter(forWritingTaskList) ; splitter.hasNext() ; ) 0146 { 0147 Q_EMIT writeMetadata(FileActionItemInfoList(splitter.next()), MetadataHub::WRITE_PICKLABEL); 0148 } 0149 } 0150 0151 infos.dbFinished(); 0152 } 0153 0154 void FileActionMngrDatabaseWorker::assignColorLabel(const FileActionItemInfoList& infos, int colorId) 0155 { 0156 DisjointMetadata hub; 0157 QList<ItemInfo> forWriting; 0158 0159 { 0160 CoreDbOperationGroup group; 0161 group.setMaximumTime(200); 0162 0163 Q_FOREACH (const ItemInfo& info, infos) 0164 { 0165 if (state() == WorkerObject::Deactivating) 0166 { 0167 break; 0168 } 0169 0170 hub.load(info); 0171 hub.setColorLabel(colorId); 0172 hub.write(info, DisjointMetadata::PartialWrite); 0173 0174 if (hub.willWriteMetadata(DisjointMetadata::FullWriteIfChanged) && 0175 d->shallSendForWriting(info.id())) 0176 { 0177 forWriting << info; 0178 } 0179 0180 infos.dbProcessedOne(); 0181 group.allowLift(); 0182 } 0183 } 0184 0185 // send for writing file metadata 0186 0187 if (!forWriting.isEmpty()) 0188 { 0189 FileActionItemInfoList forWritingTaskList = FileActionItemInfoList::continueTask(forWriting, infos.progress()); 0190 forWritingTaskList.schedulingForWrite(i18n("Writing metadata to files"), d->fileProgressCreator()); 0191 0192 for (ItemInfoTaskSplitter splitter(forWritingTaskList) ; splitter.hasNext() ; ) 0193 { 0194 Q_EMIT writeMetadata(FileActionItemInfoList(splitter.next()), MetadataHub::WRITE_COLORLABEL); 0195 } 0196 } 0197 0198 infos.dbFinished(); 0199 } 0200 0201 void FileActionMngrDatabaseWorker::assignRating(const FileActionItemInfoList& infos, int rating) 0202 { 0203 DisjointMetadata hub; 0204 QList<ItemInfo> forWriting; 0205 rating = qMin(RatingMax, qMax(RatingMin, rating)); 0206 0207 { 0208 CoreDbOperationGroup group; 0209 group.setMaximumTime(200); 0210 0211 Q_FOREACH (const ItemInfo& info, infos) 0212 { 0213 if (state() == WorkerObject::Deactivating) 0214 { 0215 break; 0216 } 0217 0218 hub.load(info); 0219 hub.setRating(rating); 0220 hub.write(info, DisjointMetadata::PartialWrite); 0221 0222 if (hub.willWriteMetadata(DisjointMetadata::FullWriteIfChanged) && 0223 d->shallSendForWriting(info.id())) 0224 { 0225 forWriting << info; 0226 } 0227 0228 infos.dbProcessedOne(); 0229 group.allowLift(); 0230 } 0231 } 0232 0233 // send for writing file metadata 0234 0235 if (!forWriting.isEmpty()) 0236 { 0237 FileActionItemInfoList forWritingTaskList = FileActionItemInfoList::continueTask(forWriting, infos.progress()); 0238 forWritingTaskList.schedulingForWrite(i18n("Writing metadata to files"), d->fileProgressCreator()); 0239 0240 for (ItemInfoTaskSplitter splitter(forWritingTaskList) ; splitter.hasNext() ; ) 0241 { 0242 Q_EMIT writeMetadata(FileActionItemInfoList(splitter.next()), MetadataHub::WRITE_RATING); 0243 } 0244 } 0245 0246 infos.dbFinished(); 0247 } 0248 0249 void FileActionMngrDatabaseWorker::editGroup(int groupAction, const ItemInfo& pick, const FileActionItemInfoList& infos) 0250 { 0251 { 0252 CoreDbOperationGroup group; 0253 group.setMaximumTime(200); 0254 0255 Q_FOREACH (const ItemInfo& constInfo, infos) 0256 { 0257 if (state() == WorkerObject::Deactivating) 0258 { 0259 break; 0260 } 0261 0262 ItemInfo info(constInfo); 0263 0264 switch (groupAction) 0265 { 0266 case AddToGroup: 0267 { 0268 info.addToGroup(pick); 0269 break; 0270 } 0271 0272 case RemoveFromGroup: 0273 { 0274 info.removeFromGroup(); 0275 break; 0276 } 0277 0278 case Ungroup: 0279 { 0280 info.clearGroup(); 0281 break; 0282 } 0283 } 0284 0285 infos.dbProcessedOne(); 0286 group.allowLift(); 0287 } 0288 } 0289 0290 infos.dbFinished(); 0291 } 0292 0293 void FileActionMngrDatabaseWorker::setExifOrientation(const FileActionItemInfoList& infos, int orientation) 0294 { 0295 { 0296 CoreDbOperationGroup group; 0297 group.setMaximumTime(200); 0298 0299 Q_FOREACH (ItemInfo info, infos) 0300 { 0301 if (state() == WorkerObject::Deactivating) 0302 { 0303 break; 0304 } 0305 0306 // Adjust Faces 0307 0308 FaceUtils().rotateFaces(info.id(), info.dimensions(), 0309 info.orientation(), orientation); 0310 0311 info.setOrientation(orientation); 0312 } 0313 } 0314 0315 infos.dbProcessed(infos.count()); 0316 infos.schedulingForWrite(infos.count(), i18n("Revising Exif Orientation tags"), d->fileProgressCreator()); 0317 0318 for (ItemInfoTaskSplitter splitter(infos) ; splitter.hasNext() ; ) 0319 { 0320 Q_EMIT writeOrientationToFiles(FileActionItemInfoList(splitter.next()), orientation); 0321 } 0322 0323 infos.dbFinished(); 0324 } 0325 0326 void FileActionMngrDatabaseWorker::applyMetadata(const FileActionItemInfoList& infos, 0327 DisjointMetadata* hub) 0328 { 0329 { 0330 CoreDbOperationGroup group; 0331 group.setMaximumTime(200); 0332 0333 Q_FOREACH (const ItemInfo& info, infos) 0334 { 0335 if (state() == WorkerObject::Deactivating) 0336 { 0337 break; 0338 } 0339 0340 // apply to database 0341 0342 hub->write(info); 0343 infos.dbProcessedOne(); 0344 group.allowLift(); 0345 } 0346 } 0347 0348 if (hub->willWriteMetadata(DisjointMetadata::FullWriteIfChanged)) 0349 { 0350 int flags = hub->changedFlags(); 0351 0352 // don't filter by shallSendForWriting here; we write from the hub, not from freshly loaded data 0353 0354 infos.schedulingForWrite(infos.size(), i18n("Writing metadata to files"), d->fileProgressCreator()); 0355 0356 for (ItemInfoTaskSplitter splitter(infos) ; splitter.hasNext() ; ) 0357 { 0358 Q_EMIT writeMetadata(FileActionItemInfoList(splitter.next()), flags); 0359 } 0360 } 0361 0362 delete hub; 0363 infos.dbFinished(); 0364 } 0365 0366 void FileActionMngrDatabaseWorker::copyAttributes(const FileActionItemInfoList& infos, const QStringList& derivedPaths) 0367 { 0368 if (infos.size() == 1) 0369 { 0370 Q_FOREACH (const QString& path, derivedPaths) 0371 { 0372 if (state() == WorkerObject::Deactivating) 0373 { 0374 break; 0375 } 0376 0377 ItemInfo dest = ScanController::instance()->scannedInfo(path); 0378 CollectionScanner::copyFileProperties(infos.first(), dest); 0379 } 0380 0381 infos.dbProcessedOne(); 0382 } 0383 0384 infos.dbFinished(); 0385 } 0386 0387 } // namespace Digikam 0388 0389 #include "moc_databaseworkeriface.cpp"