Skip to content

Commit ebae15f

Browse files
committedDec 5, 2016
Framework for task manager
Adds new classes: - QgsTask. An interface for long-running background tasks - QgsTaskManager. Handles groups of tasks - also available as a global instance for tracking application wide tasks - QgsTaskManagerWidget. A list view for showing active tasks and their progress, and for cancelling them A new dock widget has been added with a task manager widget showing global tasks
1 parent dc697d0 commit ebae15f

14 files changed

+1488
-0
lines changed
 

‎python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
%Include qgsstatisticalsummary.sip
139139
%Include qgsstringstatisticalsummary.sip
140140
%Include qgsstringutils.sip
141+
%Include qgstaskmanager.sip
141142
%Include qgstextrenderer.sip
142143
%Include qgstolerance.sip
143144
%Include qgstracer.sip

‎python/core/qgstaskmanager.sip

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/** \ingroup core
2+
* \class QgsTask
3+
* \brief Interface class for long running tasks which will be handled by a QgsTaskManager
4+
* \note Added in version 2.16
5+
*/
6+
class QgsTask : QObject
7+
{
8+
9+
%TypeHeaderCode
10+
#include <qgstaskmanager.h>
11+
%End
12+
public:
13+
14+
//! Status of tasks
15+
enum TaskStatus
16+
{
17+
Running, /*!< Task is currently running */
18+
Complete, /*!< Task successfully completed */
19+
Terminated, /*!< Task was terminated or errored */
20+
// Paused,
21+
// Queued,
22+
};
23+
24+
/** Constructor for QgsTask.
25+
* @param description text description of task
26+
*/
27+
QgsTask( const QString& description = QString() );
28+
29+
//! Will be called when task has been terminated, either through
30+
//! user interaction or other reason (eg application exit)
31+
//! @note derived classes must ensure they call the base method
32+
virtual void terminate();
33+
34+
//! Returns true if the task is active, ie it is not complete and has
35+
//! not been terminated.
36+
bool isActive() const;
37+
38+
//! Returns the current task status.
39+
TaskStatus status() const;
40+
41+
//! Returns the task's description.
42+
QString description() const;
43+
44+
//! Returns the task's progress (between 0.0 and 100.0)
45+
double progress() const;
46+
47+
signals:
48+
49+
//! Will be emitted by task when its progress changes
50+
//! @param progress percent of progress, from 0.0 - 100.0
51+
//! @note derived classes should not emit this signal directly, instead they should call
52+
//! setProgress()
53+
void progressChanged( double progress );
54+
55+
//! Will be emitted by task when its status changes
56+
//! @param status new task status
57+
//! @note derived classes should not emit this signal directly, instead they should call
58+
//! completed() or stopped()
59+
void statusChanged( int status );
60+
61+
//! Will be emitted by task to indicate its completion.
62+
//! @note derived classes should not emit this signal directly, instead they should call
63+
//! completed()
64+
void taskCompleted();
65+
66+
//! Will be emitted by task if it has terminated for any reason
67+
//! other then completion.
68+
//! @note derived classes should not emit this signal directly, instead they should call
69+
//! stopped()//!
70+
void taskStopped();
71+
72+
protected:
73+
74+
//! Sets the task's current progress. Should be called whenever the
75+
//! task wants to update it's progress. Calling will automatically emit the progressChanged
76+
//! signal.
77+
//! @param progress percent of progress, from 0.0 - 100.0
78+
void setProgress( double progress );
79+
80+
//! Sets the task as completed. Should be called when the task is complete.
81+
//! Calling will automatically emit the statusChanged and taskCompleted signals.
82+
void completed();
83+
84+
//! Sets the task as stopped. Should be called whenever the task ends for any
85+
//! reason other than successful completion.
86+
//! Calling will automatically emit the statusChanged and taskStopped signals.
87+
void stopped();
88+
};
89+
90+
/** \ingroup core
91+
* \class QgsTaskManager
92+
* \brief Task manager for managing a set of long-running QgsTask tasks. This class can be created directly,
93+
* or accessed via a global instance.
94+
* \note Added in version 2.16
95+
*/
96+
class QgsTaskManager : QObject
97+
{
98+
%TypeHeaderCode
99+
#include <qgstaskmanager.h>
100+
%End
101+
public:
102+
103+
/** Returns the global task manager instance pointer, creating the object on the first call.
104+
*/
105+
static QgsTaskManager * instance();
106+
107+
/** Constructor for QgsTaskManager.
108+
* @param parent parent QObject
109+
*/
110+
QgsTaskManager( QObject* parent /TransferThis/ = nullptr );
111+
112+
virtual ~QgsTaskManager();
113+
114+
/** Adds a task to the manager. Ownership of the task is transferred
115+
* to the manager.
116+
* @param task task to add
117+
* @returns unique task ID
118+
*/
119+
long addTask( QgsTask* task /Transfer/ );
120+
121+
/** Deletes the specified task, first terminating it if it is currently
122+
* running.
123+
* @param id task ID
124+
* @returns true if task was found and deleted
125+
*/
126+
bool deleteTask( long id );
127+
128+
/** Deletes the specified task, first terminating it if it is currently
129+
* running.
130+
* @param task task to delete
131+
* @returns true if task was contained in manager and deleted
132+
*/
133+
bool deleteTask( QgsTask* task );
134+
135+
/** Returns the task with matching ID.
136+
* @param id task ID
137+
* @returns task if found, or nullptr
138+
*/
139+
QgsTask* task( long id ) const;
140+
141+
/** Returns all tasks tracked by the manager.
142+
*/
143+
QList<QgsTask*> tasks() const;
144+
145+
//! Returns the number of tasks tracked by the manager.
146+
int count() const;
147+
148+
/** Returns the unique task ID corresponding to a task managed by the class.
149+
* @param task task to find
150+
* @returns task ID, or -1 if task not found
151+
*/
152+
long taskId( QgsTask* task ) const;
153+
154+
signals:
155+
156+
//! Will be emitted when a task reports a progress change
157+
//! @param taskId ID of task
158+
//! @param progress percent of progress, from 0.0 - 100.0
159+
void progressChanged( long taskId, double progress );
160+
161+
//! Will be emitted when a task reports a status change
162+
//! @param taskId ID of task
163+
//! @param status new task status
164+
void statusChanged( long taskId, int status );
165+
166+
//! Emitted when a new task has been added to the manager
167+
//! @param taskId ID of task
168+
void taskAdded( long taskId );
169+
170+
//! Emitted when a task is about to be deleted
171+
//! @param taskId ID of task
172+
void taskAboutToBeDeleted( long taskId );
173+
174+
};

‎python/gui/gui.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
%Include qgstablewidgetbase.sip
162162
%Include qgstabwidget.sip
163163
%Include qgstablewidgetitem.sip
164+
%Include qgstaskmanagerwidget.sip
164165
%Include qgstextannotationitem.sip
165166
%Include qgstextformatwidget.sip
166167
%Include qgstextpreview.sip

‎python/gui/qgstaskmanagerwidget.sip

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/** \ingroup gui
2+
* \class QgsTaskManagerWidget
3+
* A widget which displays tasks from a QgsTaskManager and allows for interaction with the manager
4+
* @see QgsTaskManager
5+
* @note introduced in QGIS 2.16
6+
*/
7+
class QgsTaskManagerWidget : QTreeView
8+
{
9+
%TypeHeaderCode
10+
#include <qgstaskmanagerwidget.h>
11+
%End
12+
public:
13+
14+
/** Constructor for QgsTaskManagerWidget
15+
* @param manager task manager associated with widget
16+
* @param parent parent widget
17+
*/
18+
QgsTaskManagerWidget( QgsTaskManager* manager, QWidget* parent /TransferThis/ = nullptr );
19+
20+
};
21+
22+
23+
/** \ingroup gui
24+
* \class QgsTaskManagerModel
25+
* A model representing a QgsTaskManager
26+
* @see QgsTaskManager
27+
* @note introduced in QGIS 2.16
28+
*/
29+
class QgsTaskManagerModel: QAbstractItemModel
30+
{
31+
%TypeHeaderCode
32+
#include <qgstaskmanagerwidget.h>
33+
%End
34+
public:
35+
36+
/** Constructor for QgsTaskManagerModel
37+
* @param manager task manager for model
38+
* @param parent parent object
39+
*/
40+
explicit QgsTaskManagerModel( QgsTaskManager* manager, QObject* parent /TransferThis/ = nullptr );
41+
42+
//reimplemented QAbstractItemModel methods
43+
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
44+
QModelIndex parent( const QModelIndex &index ) const;
45+
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
46+
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
47+
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
48+
Qt::ItemFlags flags( const QModelIndex & index ) const;
49+
bool setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
50+
51+
};
52+
53+
54+
/** \ingroup gui
55+
* \class QgsProgressBarDelegate
56+
* A delegate for showing a progress bar within a view
57+
* @note introduced in QGIS 2.16
58+
*/
59+
class QgsProgressBarDelegate : QStyledItemDelegate
60+
{
61+
%TypeHeaderCode
62+
#include <qgstaskmanagerwidget.h>
63+
%End
64+
public:
65+
66+
/** Constructor for QgsProgressBarDelegate
67+
* @param parent parent object
68+
*/
69+
QgsProgressBarDelegate( QObject* parent /TransferThis/ = nullptr );
70+
71+
void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
72+
QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
73+
};
74+
75+
/** \ingroup gui
76+
* \class QgsProgressBarDelegate
77+
* A delegate for showing task status within a view. Clicks on the delegate will cause the task to be cancelled (via the model).
78+
* @note introduced in QGIS 2.16
79+
*/
80+
class QgsTaskStatusDelegate : QStyledItemDelegate
81+
{
82+
%TypeHeaderCode
83+
#include <qgstaskmanagerwidget.h>
84+
%End
85+
public:
86+
87+
/** Constructor for QgsTaskStatusDelegate
88+
* @param parent parent object
89+
*/
90+
QgsTaskStatusDelegate( QObject* parent /TransferThis/ = nullptr );
91+
92+
void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
93+
QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
94+
bool editorEvent( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index );
95+
};

‎src/app/qgisapp.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@
221221
#include "qgsstatusbarscalewidget.h"
222222
#include "qgsstyle.h"
223223
#include "qgssvgannotationitem.h"
224+
#include "qgstaskmanager.h"
225+
#include "qgstaskmanagerwidget.h"
224226
#include "qgssymbolselectordialog.h"
225227
#include "qgstextannotationitem.h"
226228
#include "qgstipgui.h"
@@ -851,6 +853,13 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
851853
QMainWindow::addDockWidget( Qt::BottomDockWidgetArea, mUserInputDockWidget );
852854
mUserInputDockWidget->setFloating( true );
853855

856+
// create the task manager dock on starting QGIS - this is like the browser
857+
mTaskManagerDock = new QDockWidget( tr( "Task Manager" ), this );
858+
mTaskManagerDock->setObjectName( "TaskManager" );
859+
addDockWidget( Qt::RightDockWidgetArea, mTaskManagerDock );
860+
mTaskManagerDock->setWidget( new QgsTaskManagerWidget( QgsTaskManager::instance(), mTaskManagerDock ) );
861+
mTaskManagerDock->hide();
862+
854863
// create the GPS tool on starting QGIS - this is like the browser
855864
mpGpsWidget = new QgsGPSInformationWidget( mMapCanvas );
856865
//create the dock widget
@@ -1139,6 +1148,7 @@ QgisApp::QgisApp()
11391148
, mOverviewDock( nullptr )
11401149
, mpGpsDock( nullptr )
11411150
, mLogDock( nullptr )
1151+
, mTaskManagerDock( nullptr )
11421152
, mNonEditMapTool( nullptr )
11431153
, mScaleWidget( nullptr )
11441154
, mMagnifierWidget( nullptr )

‎src/app/qgisapp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
15601560
QgsDockWidget *mOverviewDock;
15611561
QgsDockWidget *mpGpsDock;
15621562
QgsDockWidget *mLogDock;
1563+
QDockWidget *mTaskManagerDock;
15631564

15641565
#ifdef Q_OS_MAC
15651566
//! Window menu action to select this window

‎src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ SET(QGIS_CORE_SRCS
211211
qgsstatisticalsummary.cpp
212212
qgsstringstatisticalsummary.cpp
213213
qgsstringutils.cpp
214+
qgstaskmanager.cpp
214215
qgstextlabelfeature.cpp
215216
qgstextrenderer.cpp
216217
qgstolerance.cpp
@@ -495,6 +496,7 @@ SET(QGIS_CORE_MOC_HDRS
495496
qgsrelationmanager.h
496497
qgsrunprocess.h
497498
qgssnappingutils.h
499+
qgstaskmanager.h
498500
qgstracer.h
499501
qgstrackedvectorlayertools.h
500502
qgstransaction.h

0 commit comments

Comments
 (0)
Please sign in to comment.