File indexing completed on 2024-04-28 17:06:05

0001 /*
0002     SPDX-FileCopyrightText: 2010 Jan Lepper <dehtris@yahoo.de>
0003     SPDX-FileCopyrightText: 2010-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef JOBMAN_H
0009 #define JOBMAN_H
0010 
0011 // QtCore
0012 #include <QAction>
0013 // QtWidgets
0014 #include <QMessageBox>
0015 #include <QProgressBar>
0016 #include <QPushButton>
0017 
0018 #include <KCoreAddons/KJob>
0019 #include <KWidgetsAddons/KToolBarPopupAction>
0020 
0021 class KrJob;
0022 
0023 /**
0024  * @brief The job manager provides a progress dialog and control over (KIO) file operation jobs.
0025  *
0026  * Job manager does not have a window (or dialog). All functions are provided via toolbar actions.
0027  * Icon, text and tooltip are already set but shortcuts are not set here.
0028  *
0029  * If job managers queue mode is activated, only the first job (incoming via manageJob()) is started
0030  * and more incoming jobs are delayed: If the running job finishes, the next job in line is
0031  * started.
0032  *
0033  * NOTE: The desktop system (e.g. KDE Plasma Shell) may also can control the jobs.
0034  * Reference: plasma-workspace/kuiserver/progresslistdelegate.h
0035  *
0036  * NOTE: If a job still exists, Krusader does not exit on quit() and waits until the job is
0037  * finished. If the job is paused, this takes forever. Call waitForJobs() before exit to prevent
0038  * this.
0039  *
0040  * About undoing jobs: If jobs are recorded (all KrJobs are, some in FileSystem) we can undo them
0041  * with FileUndoManager (which is a singleton) here.
0042  * It would be great if each job in the job list could be undone individually but FileUndoManager
0043  * is currently (Frameworks 5.27) only able to undo the last recorded job.
0044  */
0045 class JobMan : public QObject
0046 {
0047     Q_OBJECT
0048 
0049 public:
0050     /** Job start mode for new jobs. */
0051     enum StartMode {
0052         /** Enqueue or start job - depending on QueueMode. */
0053         Default,
0054         /** Enqueue job. I.e. start if no other jobs are running. */
0055         Enqueue,
0056         /** Job is always started. */
0057         Start,
0058         /** Job is always not started now. */
0059         Delay
0060     };
0061 
0062     explicit JobMan(QObject *parent = nullptr);
0063     /** Toolbar action icon for pausing/starting all jobs with drop down menu showing all jobs.*/
0064     QAction *controlAction() const
0065     {
0066         return m_controlAction;
0067     }
0068     /** Toolbar action progress bar showing the average job progress percentage of all jobs.*/
0069     QAction *progressAction() const
0070     {
0071         return m_progressAction;
0072     }
0073     /** Toolbar action combo box for changing the .*/
0074     QAction *modeAction() const
0075     {
0076         return m_modeAction;
0077     }
0078     QAction *undoAction() const
0079     {
0080         return m_undoAction;
0081     }
0082 
0083     /** Wait for all jobs to terminate (blocking!).
0084      *
0085      * Returns true immediately if there are no jobs and user input is not required. Otherwise a
0086      * modal UI dialog is shown and the user can abort all jobs or cancel the dialog.
0087      *
0088      * @param waitForUserInput if true dialog is only closed after user interaction (button click)
0089      * @return true if no jobs are running (anymore) and user wants to quit. Else false
0090      */
0091     bool waitForJobs(bool waitForUserInput);
0092 
0093     /** Return if queue mode is enabled or not. */
0094     bool isQueueModeEnabled() const
0095     {
0096         return m_queueMode;
0097     }
0098 
0099     /** Display, monitor and give user ability to control a job.
0100      *
0101      * Whether the job is started now or delayed depends on startMode (and current queue mode flag).
0102      */
0103     void manageJob(KrJob *krJob, StartMode startMode = Default);
0104     /**
0105      * Like manageJob(), but for already started jobs.
0106      */
0107     void manageStartedJob(KrJob *krJob, KJob *job);
0108 
0109 protected slots:
0110     void slotKJobStarted(KJob *krJob);
0111     void slotControlActionTriggered();
0112     void slotPercent(KJob *, unsigned long);
0113     void slotDescription(KJob *, const QString &description, const QPair<QString, QString> &field1, const QPair<QString, QString> &field2);
0114     void slotTerminated(KrJob *krJob);
0115     void slotUpdateControlAction();
0116     void slotUndoTextChange(const QString &text);
0117     void slotUpdateMessageBox();
0118 
0119 private:
0120     void managePrivate(KrJob *job, KJob *kJob = nullptr);
0121     void cleanupMenu(); // remove old entries if menu is too long
0122     void updateUI();
0123     bool jobsAreRunning();
0124 
0125     QList<KrJob *> m_jobs; // all jobs not terminated (finished or canceled) yet
0126     bool m_queueMode;
0127 
0128     KToolBarPopupAction *m_controlAction;
0129     QProgressBar *m_progressBar;
0130     QAction *m_progressAction;
0131     QAction *m_modeAction;
0132     QAction *m_undoAction;
0133 
0134     QMessageBox *m_messageBox;
0135     bool m_autoCloseMessageBox;
0136 
0137     static const QString sDefaultToolTip;
0138 };
0139 
0140 #endif // JOBMAN_H