File indexing completed on 2025-01-19 03:55:51

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2015-06-15
0007  * Description : IO Jobs thread for file system jobs
0008  *
0009  * SPDX-FileCopyrightText: 2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com>
0010  * SPDX-FileCopyrightText: 2018 by Maik Qualmann <metzpinguin at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "iojobsthread.h"
0017 
0018 // Qt includes
0019 
0020 #include <QFileInfo>
0021 #include <QDir>
0022 
0023 // Local includes
0024 
0025 #include "iojob.h"
0026 #include "iojobdata.h"
0027 #include "digikam_debug.h"
0028 #include "coredb.h"
0029 #include "coredbaccess.h"
0030 
0031 namespace Digikam
0032 {
0033 
0034 class Q_DECL_HIDDEN IOJobsThread::Private
0035 {
0036 
0037 public:
0038 
0039     explicit Private()
0040       : jobsCount (0),
0041         isCanceled(false),
0042         jobData   (nullptr)
0043     {
0044     }
0045 
0046     int         jobsCount;
0047     bool        isCanceled;
0048 
0049     IOJobData*  jobData;
0050 
0051     QStringList errorsList;
0052 };
0053 
0054 IOJobsThread::IOJobsThread(QObject* const parent)
0055     : ActionThreadBase(parent),
0056       d(new Private)
0057 {
0058     setObjectName(QLatin1String("IOJobsThread"));
0059 }
0060 
0061 IOJobsThread::~IOJobsThread()
0062 {
0063     delete d->jobData;
0064     delete d;
0065 }
0066 
0067 void IOJobsThread::copyOrMove(IOJobData* const data)
0068 {
0069     d->jobData  = data;
0070 
0071     ActionJobCollection collection;
0072 
0073     int threads = qMin(maximumNumberOfThreads(),
0074                        data->sourceUrls().count());
0075 
0076     for (int i = 0 ; i < threads ; ++i)
0077     {
0078         CopyOrMoveJob* const j = new CopyOrMoveJob(data);
0079 
0080         connectOneJob(j);
0081 
0082         collection.insert(j, 0);
0083         d->jobsCount++;
0084     }
0085 
0086     appendJobs(collection);
0087 }
0088 
0089 void IOJobsThread::deleteFiles(IOJobData* const data)
0090 {
0091     d->jobData = data;
0092 
0093     ActionJobCollection collection;
0094 
0095     int threads = qMin(maximumNumberOfThreads(),
0096                        data->sourceUrls().count());
0097 
0098     for (int i = 0 ; i < threads ; ++i)
0099     {
0100         DeleteJob* const j = new DeleteJob(data);
0101 
0102         connectOneJob(j);
0103 
0104         collection.insert(j, 0);
0105         d->jobsCount++;
0106     }
0107 
0108     appendJobs(collection);
0109 }
0110 
0111 void IOJobsThread::renameFile(IOJobData* const data)
0112 {
0113     d->jobData             = data;
0114     ActionJobCollection collection;
0115 
0116     RenameFileJob* const j = new RenameFileJob(data);
0117 
0118     connectOneJob(j);
0119 
0120     connect(j, SIGNAL(signalRenameFailed(QUrl)),
0121             this, SIGNAL(signalRenameFailed(QUrl)));
0122 
0123     collection.insert(j, 0);
0124     d->jobsCount++;
0125 
0126     appendJobs(collection);
0127 }
0128 
0129 void IOJobsThread::listDTrashItems(const QString& collectionPath)
0130 {
0131     ActionJobCollection collection;
0132 
0133     DTrashItemsListingJob* const j = new DTrashItemsListingJob(collectionPath);
0134 
0135     connect(j, SIGNAL(trashItemInfo(DTrashItemInfo)),
0136             this, SIGNAL(collectionTrashItemInfo(DTrashItemInfo)));
0137 
0138     connect(j, SIGNAL(signalDone()),
0139             this, SIGNAL(signalFinished()));
0140 
0141     collection.insert(j, 0);
0142 
0143     appendJobs(collection);
0144 }
0145 
0146 void IOJobsThread::restoreDTrashItems(IOJobData* const data)
0147 {
0148     d->jobData = data;
0149     ActionJobCollection collection;
0150 
0151     RestoreDTrashItemsJob* const j = new RestoreDTrashItemsJob(data);
0152 
0153     connectOneJob(j);
0154 
0155     collection.insert(j, 0);
0156     d->jobsCount++;
0157 
0158     appendJobs(collection);
0159 }
0160 
0161 void IOJobsThread::emptyDTrashItems(IOJobData* const data)
0162 {
0163     d->jobData = data;
0164     ActionJobCollection collection;
0165 
0166     EmptyDTrashItemsJob* const j = new EmptyDTrashItemsJob(data);
0167 
0168     connectOneJob(j);
0169 
0170     collection.insert(j, 0);
0171     d->jobsCount++;
0172 
0173     appendJobs(collection);
0174 }
0175 
0176 void IOJobsThread::buildTrashCounters()
0177 {
0178     ActionJobCollection collection;
0179 
0180     BuildTrashCountersJob* const j = new BuildTrashCountersJob();
0181 
0182     connect(j, SIGNAL(signalTrashCountersMap(QMap<QString,int>)),
0183             this, SIGNAL(signalTrashCountersMap(QMap<QString,int>)));
0184 
0185     connect(j, SIGNAL(signalDone()),
0186             this, SIGNAL(signalFinished()));
0187 
0188     collection.insert(j, 0);
0189 
0190     appendJobs(collection);
0191 }
0192 
0193 bool IOJobsThread::isCanceled() const
0194 {
0195     return d->isCanceled;
0196 }
0197 
0198 bool IOJobsThread::hasErrors() const
0199 {
0200     return !d->errorsList.isEmpty();
0201 }
0202 
0203 QStringList& IOJobsThread::errorsList() const
0204 {
0205     return d->errorsList;
0206 }
0207 
0208 IOJobData* IOJobsThread::jobData() const
0209 {
0210     return d->jobData;
0211 }
0212 
0213 void IOJobsThread::connectOneJob(IOJob* const j)
0214 {
0215     connect(j, SIGNAL(signalError(QString)),
0216             this, SLOT(slotError(QString)));
0217 
0218     connect(j, SIGNAL(signalDone()),
0219             this, SLOT(slotOneJobFinished()));
0220 
0221     connect(j, SIGNAL(signalOneProccessed(QUrl)),
0222             this, SIGNAL(signalOneProccessed(QUrl)),
0223             Qt::BlockingQueuedConnection);
0224 }
0225 
0226 void IOJobsThread::slotOneJobFinished()
0227 {
0228     d->jobsCount--;
0229 
0230     if (d->jobsCount == 0)
0231     {
0232         Q_EMIT signalFinished();
0233         qCDebug(DIGIKAM_IOJOB_LOG) << "Thread Finished";
0234     }
0235 }
0236 
0237 void IOJobsThread::slotError(const QString& errString)
0238 {
0239     d->errorsList.append(errString);
0240 }
0241 
0242 void IOJobsThread::slotCancel()
0243 {
0244     d->isCanceled = true;
0245     ActionThreadBase::cancel();
0246 }
0247 
0248 } // namespace Digikam
0249 
0250 #include "moc_iojobsthread.cpp"