1 /*****************************************************************************
2  * Copyright (C) 2010 Jan Lepper <dehtris@yahoo.de>                          *
3  * Copyright (C) 2010-2019 Krusader Krew [https://krusader.org]              *
4  *                                                                           *
5  * This file is part of Krusader [https://krusader.org].                     *
6  *                                                                           *
7  * Krusader is free software: you can redistribute it and/or modify          *
8  * it under the terms of the GNU General Public License as published by      *
9  * the Free Software Foundation, either version 2 of the License, or         *
10  * (at your option) any later version.                                       *
11  *                                                                           *
12  * Krusader is distributed in the hope that it will be useful,               *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
15  * GNU General Public License for more details.                              *
16  *                                                                           *
17  * You should have received a copy of the GNU General Public License         *
18  * along with Krusader.  If not, see [http://www.gnu.org/licenses/].         *
19  *****************************************************************************/
20 
21 #ifndef JOBMAN_H
22 #define JOBMAN_H
23 
24 // QtCore
25 #include <QAction>
26 // QtWidgets
27 #include <QMessageBox>
28 #include <QPushButton>
29 #include <QProgressBar>
30 
31 #include <KCoreAddons/KJob>
32 #include <KWidgetsAddons/KToolBarPopupAction>
33 
34 class KrJob;
35 
36 /**
37  * @brief The job manager provides a progress dialog and control over (KIO) file operation jobs.
38  *
39  * Job manager does not have a window (or dialog). All functions are provided via toolbar actions.
40  * Icon, text and tooltip are already set but shortcuts are not set here.
41  *
42  * If job managers queue mode is activated, only the first job (incoming via manageJob()) is started
43  * and more incoming jobs are delayed: If the running job finishes, the next job in line is
44  * started.
45  *
46  * NOTE: The desktop system (e.g. KDE Plasma Shell) may also can control the jobs.
47  * Reference: plasma-workspace/kuiserver/progresslistdelegate.h
48  *
49  * NOTE: If a job still exists, Krusader does not exit on quit() and waits until the job is
50  * finished. If the job is paused, this takes forever. Call waitForJobs() before exit to prevent
51  * this.
52  *
53  * About undoing jobs: If jobs are recorded (all KrJobs are, some in FileSystem) we can undo them
54  * with FileUndoManager (which is a singleton) here.
55  * It would be great if each job in the job list could be undone individually but FileUndoManager
56  * is currently (Frameworks 5.27) only able to undo the last recorded job.
57  */
58 class JobMan : public QObject
59 {
60     Q_OBJECT
61 
62 public:
63     /** Job start mode for new jobs. */
64     enum StartMode {
65         /** Enqueue or start job - depending on QueueMode. */
66         Default,
67         /** Enqueue job. I.e. start if no other jobs are running. */
68         Enqueue,
69         /** Job is always started. */
70         Start,
71         /** Job is always not started now. */
72         Delay
73     };
74 
75     explicit JobMan(QObject *parent = 0);
76     /** Toolbar action icon for pausing/starting all jobs with drop down menu showing all jobs.*/
controlAction()77     QAction *controlAction() const { return m_controlAction; }
78     /** Toolbar action progress bar showing the average job progress percentage of all jobs.*/
progressAction()79     QAction *progressAction() const { return m_progressAction; }
80     /** Toolbar action combo box for changing the .*/
modeAction()81     QAction *modeAction() const { return m_modeAction; }
undoAction()82     QAction *undoAction() const { return m_undoAction; }
83 
84     /** Wait for all jobs to terminate (blocking!).
85      *
86      * Returns true immediately if there are no jobs and user input is not required. Otherwise a
87      * modal UI dialog is shown and the user can abort all jobs or cancel the dialog.
88      *
89      * @param waitForUserInput if true dialog is only closed after user interaction (button click)
90      * @return true if no jobs are running (anymore) and user wants to quit. Else false
91      */
92     bool waitForJobs(bool waitForUserInput);
93 
94     /** Return if queue mode is enabled or not. */
isQueueModeEnabled()95     bool isQueueModeEnabled() const { return m_queueMode; }
96 
97     /** Display, monitor and give user ability to control a job.
98      *
99      * Whether the job is started now or delayed depends on startMode (and current queue mode flag).
100      */
101     void manageJob(KrJob *krJob, StartMode startMode = Default);
102     /**
103      * Like manageJob(), but for already started jobs.
104      */
105     void manageStartedJob(KrJob *krJob, KJob *job);
106 
107 protected slots:
108     void slotKJobStarted(KJob *krJob);
109     void slotControlActionTriggered();
110     void slotPercent(KJob *, unsigned long);
111     void slotDescription(KJob*,const QString &description, const QPair<QString,QString> &field1,
112                          const QPair<QString,QString> &field2);
113     void slotTerminated(KrJob *krJob);
114     void slotUpdateControlAction();
115     void slotUndoTextChange(const QString &text);
116     void slotUpdateMessageBox();
117 
118 private:
119     void managePrivate(KrJob *job, KJob *kJob = nullptr);
120     void cleanupMenu(); // remove old entries if menu is too long
121     void updateUI();
122     bool jobsAreRunning();
123 
124     QList<KrJob *> m_jobs; // all jobs not terminated (finished or canceled) yet
125     bool m_queueMode;
126 
127     KToolBarPopupAction *m_controlAction;
128     QProgressBar *m_progressBar;
129     QAction *m_progressAction;
130     QAction *m_modeAction;
131     QAction *m_undoAction;
132 
133     QMessageBox *m_messageBox;
134     bool m_autoCloseMessageBox;
135 
136     static const QString sDefaultToolTip;
137 };
138 
139 #endif // JOBMAN_H
140