File indexing completed on 2024-04-14 03:54:04

0001 /*
0002     SPDX-FileCopyrightText: 2021 Kai Uwe Broulik <kde@broulik.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "kjobcreator.h"
0008 
0009 #include <QApplication>
0010 #include <QIcon>
0011 #include <QPushButton>
0012 
0013 #include <KUiServerJobTracker>
0014 #include <KUiServerV2JobTracker>
0015 #include <KWidgetJobTracker>
0016 
0017 #include <limits>
0018 
0019 TestJob::TestJob(QObject *parent)
0020     : KJob(parent)
0021 {
0022 }
0023 
0024 void TestJob::start()
0025 {
0026     m_started = true;
0027 }
0028 
0029 bool TestJob::started() const
0030 {
0031     return m_started;
0032 }
0033 
0034 void TestJob::finish()
0035 {
0036     emitResult();
0037 }
0038 
0039 void TestJob::setPercentage(int percent)
0040 {
0041     setPercent(percent);
0042 }
0043 
0044 void TestJob::setProcessedMiB(double bytes)
0045 {
0046     setProcessedAmount(KJob::Bytes, bytes * 1024 * 1024);
0047 }
0048 
0049 void TestJob::setTotalMiB(double bytes)
0050 {
0051     setTotalAmount(KJob::Bytes, bytes * 1024 * 1024);
0052 }
0053 
0054 void TestJob::setProcessedFiles(int files)
0055 {
0056     setProcessedAmount(KJob::Files, files);
0057 }
0058 
0059 void TestJob::setTotalFiles(int files)
0060 {
0061     setTotalAmount(KJob::Files, files);
0062 }
0063 
0064 void TestJob::setProcessedDirectories(int directories)
0065 {
0066     setProcessedAmount(KJob::Directories, directories);
0067 }
0068 
0069 void TestJob::setTotalDirectories(int directories)
0070 {
0071     setTotalAmount(KJob::Directories, directories);
0072 }
0073 
0074 void TestJob::setProcessedItems(int items)
0075 {
0076     setProcessedAmount(KJob::Items, items);
0077 }
0078 
0079 void TestJob::setTotalItems(int items)
0080 {
0081     setTotalAmount(KJob::Items, items);
0082 }
0083 
0084 void TestJob::setSpeedMiB(double speed)
0085 {
0086     emitSpeed(speed * 1024 * 1024);
0087 }
0088 
0089 void TestJob::setErrorState(int errorCode, const QString &errorTest)
0090 {
0091     setError(errorCode);
0092     setErrorText(errorTest);
0093 }
0094 
0095 void TestJob::setSuspendable(bool suspendable)
0096 {
0097     auto caps = capabilities();
0098     caps.setFlag(KJob::Suspendable, suspendable);
0099     setCapabilities(caps);
0100 }
0101 
0102 void TestJob::setKillable(bool killable)
0103 {
0104     auto caps = capabilities();
0105     caps.setFlag(KJob::Killable, killable);
0106     setCapabilities(caps);
0107 }
0108 
0109 bool TestJob::doKill()
0110 {
0111     // TODO add checkbox for testing what happens when you try to kill a job that refuses?
0112     return true;
0113 }
0114 
0115 bool TestJob::doSuspend()
0116 {
0117     return true;
0118 }
0119 
0120 bool TestJob::doResume()
0121 {
0122     return true;
0123 }
0124 
0125 TestDialog::TestDialog(QWidget *parent)
0126     : QDialog(parent)
0127 {
0128     m_ui.setupUi(this);
0129 
0130     m_ui.desktopEntry->setText(QGuiApplication::desktopFileName());
0131 
0132     m_ui.processedBytes->setMaximum(std::numeric_limits<double>::max());
0133     m_ui.totalBytes->setMaximum(m_ui.processedBytes->maximum());
0134     m_ui.processedFiles->setMaximum(std::numeric_limits<int>::max());
0135     m_ui.totalFiles->setMaximum(m_ui.processedFiles->maximum());
0136     m_ui.processedDirectories->setMaximum(std::numeric_limits<int>::max());
0137     m_ui.totalDirectories->setMaximum(m_ui.processedDirectories->maximum());
0138     m_ui.processedItems->setMaximum(std::numeric_limits<int>::max());
0139     m_ui.totalItems->setMaximum(m_ui.processedItems->maximum());
0140 
0141     m_ui.speed->setMaximum(std::numeric_limits<double>::max());
0142 
0143     m_ui.createButton->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
0144     m_ui.startButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
0145     m_ui.suspendButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
0146     m_ui.killButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop")));
0147     m_ui.finishButton->setIcon(QIcon::fromTheme(QStringLiteral("view-task")));
0148 
0149     updateUiState();
0150 
0151     connect(m_ui.desktopEntry, &QLineEdit::editingFinished, this, [this] {
0152         QGuiApplication::setDesktopFileName(m_ui.desktopEntry->text());
0153         updateUiState();
0154     });
0155 
0156     connect(m_ui.destUrl, &QLineEdit::editingFinished, this, &TestDialog::updateJob);
0157 
0158     connect(m_ui.emitDescriptionButton, &QPushButton::clicked, this, [this] {
0159         Q_EMIT m_job->description(m_job,
0160                                   m_ui.title->text(),
0161                                   qMakePair(m_ui.descriptionLabel1->text(), m_ui.descriptionValue1->text()),
0162                                   qMakePair(m_ui.descriptionLabel2->text(), m_ui.descriptionValue2->text()));
0163     });
0164 
0165     connect(m_ui.percent, &QSlider::valueChanged, this, &TestDialog::updateJob);
0166     connect(m_ui.processedBytes, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TestDialog::updateJob);
0167     connect(m_ui.totalBytes, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TestDialog::updateJob);
0168     connect(m_ui.processedFiles, qOverload<int>(&QSpinBox::valueChanged), this, &TestDialog::updateJob);
0169     connect(m_ui.totalFiles, qOverload<int>(&QSpinBox::valueChanged), this, &TestDialog::updateJob);
0170     connect(m_ui.processedDirectories, qOverload<int>(&QSpinBox::valueChanged), this, &TestDialog::updateJob);
0171     connect(m_ui.totalDirectories, qOverload<int>(&QSpinBox::valueChanged), this, &TestDialog::updateJob);
0172     connect(m_ui.processedItems, qOverload<int>(&QSpinBox::valueChanged), this, &TestDialog::updateJob);
0173     connect(m_ui.totalItems, qOverload<int>(&QSpinBox::valueChanged), this, &TestDialog::updateJob);
0174     connect(m_ui.speed, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TestDialog::updateJob);
0175 
0176     connect(m_ui.infoMessage, &QLineEdit::returnPressed, m_ui.emitInfoMessage, &QPushButton::click);
0177     connect(m_ui.emitInfoMessage, &QPushButton::clicked, this, [this] {
0178         Q_EMIT m_job->infoMessage(m_job, m_ui.infoMessage->text());
0179     });
0180 
0181     connect(m_ui.errorCombo, qOverload<int>(&QComboBox::activated), this, &TestDialog::updateJob);
0182     connect(m_ui.errorText, &QLineEdit::editingFinished, this, &TestDialog::updateJob);
0183 
0184     connect(m_ui.suspendableCheck, &QCheckBox::toggled, this, &TestDialog::updateJob);
0185     connect(m_ui.killableCheck, &QCheckBox::toggled, this, &TestDialog::updateJob);
0186 
0187     connect(m_ui.createButton, &QPushButton::clicked, this, [this] {
0188         Q_ASSERT(!m_job);
0189         m_job = new TestJob(this);
0190         connect(m_job, &KJob::finished, this, [this] {
0191             m_job = nullptr;
0192             m_registeredWithWidgetTracker = false;
0193             m_registeredWithUiServerTracker = false;
0194             m_registeredWithUiServerV2Tracker = false;
0195             updateUiState();
0196         });
0197         connect(m_job, &KJob::suspended, this, &TestDialog::updateUiState);
0198         connect(m_job, &KJob::resumed, this, &TestDialog::updateUiState);
0199 
0200         // KJob auto-calculates percent based on processed/total amount, so sync that back into the UI
0201         connect(m_job, &KJob::percentChanged, this, [this](KJob *job, unsigned long percent) {
0202             Q_UNUSED(job);
0203             m_ui.percent->setValue(percent);
0204         });
0205 
0206         updateJob();
0207         updateUiState();
0208     });
0209     connect(m_ui.startButton, &QPushButton::clicked, this, [this] {
0210         m_job->start();
0211         updateUiState();
0212     });
0213     connect(m_ui.suspendButton, &QPushButton::clicked, this, [this] {
0214         if (m_job->isSuspended()) {
0215             m_job->resume();
0216         } else {
0217             m_job->suspend();
0218         }
0219     });
0220     connect(m_ui.killButton, &QPushButton::clicked, this, [this] {
0221         m_job->kill();
0222     });
0223     connect(m_ui.finishButton, &QPushButton::clicked, this, [this] {
0224         m_job->finish();
0225     });
0226 
0227     connect(m_ui.registerKWidgetJobTracker, &QPushButton::clicked, this, [this] {
0228         if (!m_widgetTracker) {
0229             // not passing "parent" so it spawns a new window
0230             m_widgetTracker.reset(new KWidgetJobTracker(nullptr));
0231         }
0232         m_widgetTracker->registerJob(m_job.data());
0233         m_registeredWithWidgetTracker = true;
0234         updateUiState();
0235     });
0236     connect(m_ui.registerKUIServerJobTracker, &QPushButton::clicked, this, [this] {
0237         if (!m_uiServerTracker) {
0238             m_uiServerTracker.reset(new KUiServerJobTracker(nullptr));
0239         }
0240         m_uiServerTracker->registerJob(m_job.data());
0241         m_registeredWithUiServerTracker = true;
0242         updateUiState();
0243     });
0244     connect(m_ui.registerKUIServerV2JobTracker, &QPushButton::clicked, this, [this] {
0245         if (!m_uiServerV2Tracker) {
0246             m_uiServerV2Tracker.reset(new KUiServerV2JobTracker(nullptr));
0247         }
0248         m_uiServerV2Tracker->registerJob(m_job.data());
0249         m_registeredWithUiServerV2Tracker = true;
0250         updateUiState();
0251     });
0252 }
0253 
0254 TestDialog::~TestDialog() = default;
0255 
0256 void TestDialog::closeEvent(QCloseEvent *event)
0257 {
0258     Q_UNUSED(event)
0259     if (m_job) {
0260         m_job->kill(KJob::EmitResult);
0261     }
0262 }
0263 
0264 void TestDialog::updateUiState()
0265 {
0266     m_ui.destUrl->setEnabled(m_job);
0267 
0268     m_ui.emitDescriptionButton->setEnabled(m_job);
0269     m_ui.emitInfoMessage->setEnabled(m_job);
0270 
0271     m_ui.processedBytes->setEnabled(m_job);
0272     m_ui.totalBytes->setEnabled(m_job);
0273     m_ui.processedFiles->setEnabled(m_job);
0274     m_ui.totalFiles->setEnabled(m_job);
0275     m_ui.processedDirectories->setEnabled(m_job);
0276     m_ui.totalDirectories->setEnabled(m_job);
0277     m_ui.processedItems->setEnabled(m_job);
0278     m_ui.totalItems->setEnabled(m_job);
0279 
0280     m_ui.percent->setEnabled(m_job);
0281     m_ui.speed->setEnabled(m_job);
0282     m_ui.errorCombo->setEnabled(m_job);
0283     m_ui.errorText->setEnabled(m_job);
0284 
0285     m_ui.createButton->setEnabled(!m_job);
0286     m_ui.startButton->setEnabled(m_job && !m_job->started());
0287     m_ui.suspendButton->setEnabled(m_job);
0288     m_ui.suspendButton->setChecked(m_job && m_job->isSuspended());
0289     m_ui.killButton->setEnabled(m_job);
0290     m_ui.finishButton->setEnabled(m_job);
0291 
0292     m_ui.registerKWidgetJobTracker->setEnabled(m_job && !m_registeredWithWidgetTracker);
0293     m_ui.registerKUIServerJobTracker->setEnabled(m_job && !m_registeredWithUiServerTracker);
0294     m_ui.registerKUIServerV2JobTracker->setEnabled(m_job && !m_registeredWithUiServerV2Tracker && !QGuiApplication::desktopFileName().isEmpty());
0295 }
0296 
0297 void TestDialog::updateJob()
0298 {
0299     if (!m_job) {
0300         return;
0301     }
0302 
0303     m_job->setProperty("destUrl", m_ui.destUrl->text());
0304     m_job->setProperty("immediateProgressReporting", m_ui.immediateCheck->isChecked());
0305     m_job->setFinishedNotificationHidden(m_ui.transientCheck->isChecked());
0306 
0307     m_job->setPercentage(m_ui.percent->value());
0308 
0309     m_job->setProcessedMiB(m_ui.processedBytes->value());
0310     m_job->setTotalMiB(m_ui.totalBytes->value());
0311     m_job->setProcessedFiles(m_ui.processedFiles->value());
0312     m_job->setTotalFiles(m_ui.totalFiles->value());
0313     m_job->setProcessedDirectories(m_ui.processedDirectories->value());
0314     m_job->setTotalDirectories(m_ui.totalDirectories->value());
0315     m_job->setProcessedItems(m_ui.processedItems->value());
0316     m_job->setTotalItems(m_ui.totalItems->value());
0317 
0318     m_job->setSpeedMiB(m_ui.speed->value());
0319 
0320     m_job->setErrorState(m_ui.errorCombo->currentIndex(), m_ui.errorText->text());
0321 
0322     m_job->setSuspendable(m_ui.suspendableCheck->isChecked());
0323     m_job->setKillable(m_ui.killableCheck->isChecked());
0324 }
0325 
0326 int main(int argc, char **argv)
0327 {
0328     QApplication app(argc, argv);
0329     app.setApplicationName(QStringLiteral("kjobcreator"));
0330     app.setDesktopFileName(QStringLiteral("org.kde.dolphin"));
0331 
0332     TestDialog dialog;
0333     dialog.show();
0334 
0335     return app.exec();
0336 }
0337 
0338 #include "moc_kjobcreator.cpp"