File indexing completed on 2024-04-28 05:45:45

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2014-2020 Andrius Štikonas <andrius@stikonas.eu>
0004     SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-3.0-or-later
0007 */
0008 
0009 #include "core/operationrunner.h"
0010 #include "core/operationstack.h"
0011 #include "ops/operation.h"
0012 #include "util/report.h"
0013 
0014 #include <QDBusInterface>
0015 #include <QDBusReply>
0016 #include <QMutex>
0017 
0018 /** Constructs an OperationRunner.
0019     @param ostack the OperationStack to act on
0020 */
0021 OperationRunner::OperationRunner(QObject* parent, OperationStack& ostack) :
0022     QThread(parent),
0023     m_OperationStack(ostack),
0024     m_Report(nullptr),
0025     m_SuspendMutex(),
0026     m_Cancelling(false)
0027 {
0028 }
0029 
0030 /** Runs the operations in the OperationStack. */
0031 void OperationRunner::run()
0032 {
0033     Q_ASSERT(m_Report);
0034 
0035     setCancelling(false);
0036 
0037     bool status = true;
0038 
0039     // Disable Plasma removable device automounting
0040     QStringList modules;
0041     QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("sessionBus"));
0042     const QString plasmaVersionMajor = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION"));
0043     QDBusInterface kdedInterface( QStringLiteral("org.kde.kded") + plasmaVersionMajor, QStringLiteral("/kded"), QStringLiteral("org.kde.kded") + plasmaVersionMajor, bus );
0044     QDBusReply<QStringList> reply = kdedInterface.call( QStringLiteral("loadedModules") );
0045     if ( reply.isValid() )
0046         modules = reply.value();
0047     QString automounterService = QStringLiteral("device_automounter");
0048     bool automounter = modules.contains(automounterService);
0049     if (automounter)
0050         kdedInterface.call( QStringLiteral("unloadModule"), automounterService );
0051 
0052     for (int i = 0; i < numOperations(); i++) {
0053         suspendMutex().lock();
0054         suspendMutex().unlock();
0055 
0056         if (!status || isCancelling()) {
0057             break;
0058         }
0059 
0060         Operation* op = operationStack().operations()[i];
0061         op->setStatus(Operation::StatusRunning);
0062 
0063         Q_EMIT opStarted(i + 1, op);
0064 
0065         connect(op, &Operation::progress, this, &OperationRunner::progressSub);
0066 
0067         status = op->execute(report());
0068         op->preview();
0069 
0070         disconnect(op, &Operation::progress, this, &OperationRunner::progressSub);
0071 
0072         Q_EMIT opFinished(i + 1, op);
0073     }
0074 
0075     if (automounter)
0076         kdedInterface.call( QStringLiteral("loadModule"), automounterService );
0077 
0078     if (!status)
0079         Q_EMIT error();
0080     else if (isCancelling())
0081         Q_EMIT cancelled();
0082     else
0083         Q_EMIT finished();
0084 }
0085 
0086 /** @return the number of Operations to run */
0087 qint32 OperationRunner::numOperations() const
0088 {
0089     return operationStack().operations().size();
0090 }
0091 
0092 /** @return the number of Jobs to run */
0093 qint32 OperationRunner::numJobs() const
0094 {
0095     qint32 result = 0;
0096 
0097     for (const auto &op :  operationStack().operations())
0098         result += op->jobs().size();
0099 
0100     return result;
0101 }
0102 
0103 /** @param op the number of the Operation to get a description for
0104     @return the Operation's description
0105 */
0106 QString OperationRunner::description(qint32 op) const
0107 {
0108     Q_ASSERT(op >= 0);
0109     Q_ASSERT(op < operationStack().size());
0110 
0111     return operationStack().operations()[op]->description();
0112 }
0113 
0114 #include "moc_operationrunner.cpp"