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 : 2009-05-05 0007 * Description : file action manager 0008 * 0009 * SPDX-FileCopyrightText: 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "fileactionmngr_p.h" 0017 0018 // KDE includes 0019 0020 #include <klocalizedstring.h> 0021 0022 // Local includes 0023 0024 #include "digikam_debug.h" 0025 #include "thumbnailloadthread.h" 0026 #include "loadingcacheinterface.h" 0027 0028 namespace Digikam 0029 { 0030 0031 FileActionMngr::Private::Private(FileActionMngr* const qq) 0032 : q(qq) 0033 { 0034 qRegisterMetaType<MetadataHub*>("MetadataHub*"); 0035 qRegisterMetaType<FileActionItemInfoList>("FileActionItemInfoList"); 0036 qRegisterMetaType<FileActionItemInfoList*>("FileActionItemInfoList*"); 0037 qRegisterMetaType<QList<ItemInfo> >("QList<ItemInfo>"); 0038 0039 dbWorker = new FileActionMngrDatabaseWorker(this); 0040 fileWorker = new ParallelAdapter<FileWorkerInterface>(); 0041 0042 while (!fileWorker->optimalWorkerCountReached()) 0043 { 0044 fileWorker->add(new FileActionMngrFileWorker(this)); 0045 } 0046 0047 sleepTimer = new QTimer(this); 0048 sleepTimer->setSingleShot(true); 0049 sleepTimer->setInterval(1000); 0050 0051 connectToDatabaseWorker(); 0052 0053 connectDatabaseToFileWorker(); 0054 0055 connect(this, SIGNAL(signalTransform(FileActionItemInfoList,int)), 0056 fileWorker, SLOT(transform(FileActionItemInfoList,int)), 0057 Qt::DirectConnection); 0058 0059 fileWorker->connect(SIGNAL(imageDataChanged(QString,bool,bool)), 0060 this, SLOT(slotImageDataChanged(QString,bool,bool))); 0061 0062 connect(&dbProgress, SIGNAL(lastItemCompleted()), 0063 this, SLOT(slotLastProgressItemCompleted())); 0064 0065 connect(&fileProgress, SIGNAL(lastItemCompleted()), 0066 this, SLOT(slotLastProgressItemCompleted())); 0067 0068 connect(sleepTimer, SIGNAL(timeout()), 0069 this, SLOT(slotSleepTimer())); 0070 } 0071 0072 void FileActionMngr::Private::connectToDatabaseWorker() 0073 { 0074 WorkerObject::connectAndSchedule(this, SIGNAL(signalAddTags(FileActionItemInfoList,QList<int>)), 0075 dbWorker, SLOT(assignTags(FileActionItemInfoList,QList<int>))); 0076 0077 WorkerObject::connectAndSchedule(this, SIGNAL(signalRemoveTags(FileActionItemInfoList,QList<int>)), 0078 dbWorker, SLOT(removeTags(FileActionItemInfoList,QList<int>))); 0079 0080 WorkerObject::connectAndSchedule(this, SIGNAL(signalAssignPickLabel(FileActionItemInfoList,int)), 0081 dbWorker, SLOT(assignPickLabel(FileActionItemInfoList,int))); 0082 0083 WorkerObject::connectAndSchedule(this, SIGNAL(signalAssignColorLabel(FileActionItemInfoList,int)), 0084 dbWorker, SLOT(assignColorLabel(FileActionItemInfoList,int))); 0085 0086 WorkerObject::connectAndSchedule(this, SIGNAL(signalAssignRating(FileActionItemInfoList,int)), 0087 dbWorker, SLOT(assignRating(FileActionItemInfoList,int))); 0088 0089 WorkerObject::connectAndSchedule(this, SIGNAL(signalEditGroup(int,ItemInfo,FileActionItemInfoList)), 0090 dbWorker, SLOT(editGroup(int,ItemInfo,FileActionItemInfoList))); 0091 0092 WorkerObject::connectAndSchedule(this, SIGNAL(signalSetExifOrientation(FileActionItemInfoList,int)), 0093 dbWorker, SLOT(setExifOrientation(FileActionItemInfoList,int))); 0094 0095 WorkerObject::connectAndSchedule(this, SIGNAL(signalApplyMetadata(FileActionItemInfoList,DisjointMetadata*)), 0096 dbWorker, SLOT(applyMetadata(FileActionItemInfoList,DisjointMetadata*))); 0097 0098 WorkerObject::connectAndSchedule(this, SIGNAL(signalCopyAttributes(FileActionItemInfoList,QStringList)), 0099 dbWorker, SLOT(copyAttributes(FileActionItemInfoList,QStringList))); 0100 } 0101 0102 void FileActionMngr::Private::connectDatabaseToFileWorker() 0103 { 0104 connect(dbWorker, SIGNAL(writeMetadataToFiles(FileActionItemInfoList)), 0105 fileWorker, SLOT(writeMetadataToFiles(FileActionItemInfoList)), 0106 Qt::DirectConnection); 0107 0108 connect(dbWorker, SIGNAL(writeMetadata(FileActionItemInfoList,int)), 0109 fileWorker, SLOT(writeMetadata(FileActionItemInfoList,int)), 0110 Qt::DirectConnection); 0111 0112 connect(dbWorker, SIGNAL(writeOrientationToFiles(FileActionItemInfoList,int)), 0113 fileWorker, SLOT(writeOrientationToFiles(FileActionItemInfoList,int)), 0114 Qt::DirectConnection); 0115 } 0116 0117 FileActionMngr::Private::~Private() 0118 { 0119 delete dbWorker; 0120 delete fileWorker; 0121 } 0122 0123 bool FileActionMngr::Private::isActive() const 0124 { 0125 return dbProgress.activeProgressItems || fileProgress.activeProgressItems; 0126 } 0127 0128 bool FileActionMngr::Private::shallSendForWriting(qlonglong id) 0129 { 0130 QMutexLocker lock(&mutex); 0131 0132 if (scheduledToWrite.contains(id)) 0133 { 0134 return false; 0135 } 0136 0137 scheduledToWrite << id; 0138 0139 return true; 0140 } 0141 0142 void FileActionMngr::Private::startingToWrite(const QList<ItemInfo>& infos) 0143 { 0144 QMutexLocker lock(&mutex); 0145 0146 Q_FOREACH (const ItemInfo& info, infos) 0147 { 0148 scheduledToWrite.remove(info.id()); 0149 } 0150 } 0151 0152 void FileActionMngr::Private::slotSleepTimer() 0153 { 0154 if (!dbProgress.activeProgressItems) 0155 { 0156 dbWorker->deactivate(); 0157 } 0158 0159 if (!fileProgress.activeProgressItems) 0160 { 0161 fileWorker->deactivate(); 0162 } 0163 } 0164 0165 void FileActionMngr::Private::slotLastProgressItemCompleted() 0166 { 0167 if (!isActive()) 0168 { 0169 Q_EMIT signalTasksFinished(); 0170 } 0171 0172 sleepTimer->start(); 0173 } 0174 0175 void FileActionMngr::Private::slotImageDataChanged(const QString& path, bool removeThumbnails, bool notifyCache) 0176 { 0177 // must be done from the UI thread, touches pixmaps 0178 0179 if (removeThumbnails) 0180 { 0181 ThumbnailLoadThread::deleteThumbnail(path); 0182 } 0183 0184 if (notifyCache) 0185 { 0186 LoadingCacheInterface::fileChanged(path); 0187 } 0188 } 0189 0190 PrivateProgressItemCreator* FileActionMngr::Private::dbProgressCreator() 0191 { 0192 return &dbProgress; 0193 } 0194 0195 PrivateProgressItemCreator* FileActionMngr::Private::fileProgressCreator() 0196 { 0197 return &fileProgress; 0198 } 0199 0200 ProgressItem* PrivateProgressItemCreator::createProgressItem(const QString& action) const 0201 { 0202 return new ProgressItem(nullptr, ProgressManager::instance()->getUniqueID(), action, QString(), true, true); 0203 } 0204 0205 void PrivateProgressItemCreator::addProgressItem(ProgressItem* const item) 0206 { 0207 activeProgressItems.ref(); 0208 0209 connect(item, SIGNAL(progressItemCompleted(ProgressItem*)), 0210 this, SLOT(slotProgressItemCompleted()), 0211 Qt::DirectConnection); 0212 0213 connect(item, SIGNAL(progressItemCanceled(ProgressItem*)), 0214 this, SLOT(slotProgressItemCanceled(ProgressItem*)), 0215 Qt::DirectConnection); 0216 0217 ProgressManager::addProgressItem(item); 0218 } 0219 0220 void PrivateProgressItemCreator::slotProgressItemCompleted() 0221 { 0222 if (!activeProgressItems.deref()) 0223 { 0224 Q_EMIT lastItemCompleted(); 0225 } 0226 } 0227 0228 void PrivateProgressItemCreator::slotProgressItemCanceled(ProgressItem* item) 0229 { 0230 FileActionMngr::instance()->shutDown(); 0231 item->setComplete(); 0232 } 0233 0234 } // namespace Digikam 0235 0236 #include "moc_fileactionmngr_p.cpp"