File indexing completed on 2025-03-09 03:58:50

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-02-06
0007  * Description : Thread actions manager.
0008  *
0009  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2012      by Pankaj Kumar <me at panks dot me>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "actionthread.h"
0017 
0018 // Local includes
0019 
0020 #include "digikam_debug.h"
0021 #include "digikam_config.h"
0022 #include "collectionscanner.h"
0023 #include "scancontroller.h"
0024 #include "metadatahub.h"
0025 #include "task.h"
0026 
0027 namespace Digikam
0028 {
0029 
0030 class Q_DECL_HIDDEN ActionThread::Private
0031 {
0032 public:
0033 
0034     explicit Private()
0035     {
0036     }
0037 
0038     QueueSettings settings;
0039 };
0040 
0041 // --------------------------------------------------------------------------------------
0042 
0043 ActionThread::ActionThread(QObject* const parent)
0044     : ActionThreadBase(parent),
0045       d               (new Private)
0046 {
0047     setObjectName(QLatin1String("QueueMngrThread"));
0048     qRegisterMetaType<ActionData>("ActionData");
0049 
0050     connect(this, SIGNAL(finished()),
0051             this, SLOT(slotThreadFinished()));
0052 }
0053 
0054 ActionThread::~ActionThread()
0055 {
0056     cancel();
0057 
0058     wait();
0059 
0060     delete d;
0061 }
0062 
0063 void ActionThread::setSettings(const QueueSettings& settings)
0064 {
0065     d->settings = settings;
0066 
0067     if (!d->settings.useMultiCoreCPU)
0068     {
0069         setMaximumNumberOfThreads(1);
0070     }
0071     else
0072     {
0073         setDefaultMaximumNumberOfThreads();
0074     }
0075 }
0076 
0077 void ActionThread::processQueueItems(const QList<AssignedBatchTools>& items)
0078 {
0079     ActionJobCollection collection;
0080 
0081     for (int i = 0 ; i < items.size() ; ++i)
0082     {
0083         Task* const t = new Task();
0084         t->setSettings(d->settings);
0085         t->setItem(items.at(i));
0086 
0087         connect(t, SIGNAL(signalStarting(Digikam::ActionData)),
0088                 this, SIGNAL(signalStarting(Digikam::ActionData)));
0089 
0090         connect(t, SIGNAL(signalFinished(Digikam::ActionData)),
0091                 this, SLOT(slotUpdateItemInfo(Digikam::ActionData)),
0092                 Qt::BlockingQueuedConnection);
0093 
0094         connect(this, SIGNAL(signalCancelTask()),
0095                 t, SLOT(slotCancel()),
0096                 Qt::QueuedConnection);
0097 
0098         collection.insert(t, 0);
0099     }
0100 
0101     appendJobs(collection);
0102 }
0103 
0104 void ActionThread::cancel()
0105 {
0106     if (isRunning())
0107     {
0108         Q_EMIT signalCancelTask();
0109     }
0110 
0111     ActionThreadBase::cancel();
0112 }
0113 
0114 void ActionThread::slotUpdateItemInfo(const Digikam::ActionData& ad)
0115 {
0116     if (ad.status == ActionData::BatchDone)
0117     {
0118         ItemInfo info;
0119         CollectionScanner scanner;
0120         ItemInfo source = ItemInfo::fromUrl(ad.fileUrl);
0121 
0122         if (ad.fileUrl == ad.destUrl)
0123         {
0124             info = ItemInfo(scanner.scanFile(ad.destUrl.toLocalFile(),
0125                                              CollectionScanner::Rescan));
0126         }
0127         else
0128         {
0129             info = ItemInfo(scanner.scanFile(ad.destUrl.toLocalFile(),
0130                                              CollectionScanner::NormalScan));
0131         }
0132 
0133         // Copy the digiKam attributes from original file to the new file
0134 
0135         CollectionScanner::copyFileProperties(source, info);
0136 
0137         if (!ad.noWrite)
0138         {
0139             // Write digiKam metadata to the new file
0140 
0141             MetadataHub hub;
0142             hub.load(info);
0143 
0144             ScanController::FileMetadataWrite writeScope(info);
0145             writeScope.changed(hub.writeToMetadata(info, MetadataHub::WRITE_ALL, true));
0146         }
0147         else
0148         {
0149             scanner.scanFile(info, CollectionScanner::CleanScan);
0150         }
0151     }
0152 
0153     Q_EMIT signalFinished(ad);
0154 }
0155 
0156 void ActionThread::slotThreadFinished()
0157 {
0158     if (isEmpty())
0159     {
0160         qCDebug(DIGIKAM_GENERAL_LOG) << "List of Pending Jobs is empty";
0161         Q_EMIT signalQueueProcessed();
0162     }
0163 }
0164 
0165 } // namespace Digikam
0166 
0167 #include "moc_actionthread.cpp"