Skip to content

Commit

Permalink
Improvements to task manager ui
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 5, 2016
1 parent 5da2513 commit d270b4f
Show file tree
Hide file tree
Showing 12 changed files with 460 additions and 10 deletions.
19 changes: 19 additions & 0 deletions python/core/qgstaskmanager.sip
Expand Up @@ -235,6 +235,17 @@ class QgsTaskManager : QObject
*/
QStringList dependentLayers( long taskId ) const;

/** Returns a list of the active (queued or running) tasks.
* @see countActiveTasks()
*/
QList< QgsTask* > activeTasks() const;

/** Returns the number of active (queued or running) tasks.
* @see activeTasks()
* @see countActiveTasksChanged()
*/
int countActiveTasks() const;

signals:

//! Will be emitted when a task reports a progress change
Expand All @@ -255,4 +266,12 @@ class QgsTaskManager : QObject
//! @param taskId ID of task
void taskAboutToBeDeleted( long taskId );

//! Emitted when all tasks are complete
//! @see countActiveTasksChanged()
void allTasksFinished();

//! Emitted when the number of active tasks changes
//! @see countActiveTasks()
void countActiveTasksChanged( int count );

};
80 changes: 80 additions & 0 deletions python/gui/qgsfloatingwidget.sip
@@ -0,0 +1,80 @@
/** \ingroup gui
* \class QgsFloatingWidget
* A QWidget subclass for creating widgets which float outside of the normal Qt layout
* system. Floating widgets use an "anchor widget" to determine how they are anchored
* within their parent widget.
* \note Added in version 2.16
*/

class QgsFloatingWidget : QWidget
{
%TypeHeaderCode
#include <qgsfloatingwidget.h>
%End

public:

//! Reference points for anchoring widget position
enum AnchorPoint
{
TopLeft, //!< Top-left of widget
TopMiddle, //!< Top center of widget
TopRight, //!< Top-right of widget
MiddleLeft, //!< Middle left of widget
Middle, //!< Middle of widget
MiddleRight, //!< Middle right of widget
BottomLeft, //!< Bottom-left of widget
BottomMiddle, //!< Bottom center of widget
BottomRight, //!< Bottom-right of widget
};

/** Constructor for QgsFloatingWidget.
* @param parent parent widget
*/
QgsFloatingWidget( QWidget* parent /TransferThis/ = nullptr );

/** Sets the widget to "anchor" the floating widget to. The floating widget will be repositioned whenever the
* anchor widget moves or is resized so that it maintains the same relative position to the anchor widget.
* @param widget anchor widget. Both the floating widget and the anchor widget must share some common parent.
* @see anchorWidget()
*/
void setAnchorWidget( QWidget* widget );

/** Returns the widget that the floating widget is "anchored" tto. The floating widget will be repositioned whenever the
* anchor widget moves or is resized so that it maintains the same relative position to the anchor widget.
* @see setAnchorWidget()
*/
QWidget* anchorWidget();

/** Returns the floating widget's anchor point, which corresponds to the point on the widget which should remain
* fixed in the same relative position whenever the widget's parent is resized or moved.
* @see setAnchorPoint()
*/
AnchorPoint anchorPoint() const;

/** Sets the floating widget's anchor point, which corresponds to the point on the widget which should remain
* fixed in the same relative position whenever the widget's parent is resized or moved.
* @param point anchor point
* @see anchorPoint()
*/
void setAnchorPoint( AnchorPoint point );

/** Returns the anchor widget's anchor point, which corresponds to the point on the anchor widget which
* the floating widget should "attach" to. The floating widget should remain fixed in the same relative position
* to this anchor widget whenever the widget's parent is resized or moved.
* @see setAnchorWidgetPoint()
*/
AnchorPoint anchorWidgetPoint() const;

/** Returns the anchor widget's anchor point, which corresponds to the point on the anchor widget which
* the floating widget should "attach" to. The floating widget should remain fixed in the same relative position
* to this anchor widget whenever the widget's parent is resized or moved.
* @see setAnchorWidgetPoint()
*/
void setAnchorWidgetPoint( AnchorPoint point );

protected:
void showEvent( QShowEvent* e );
virtual void paintEvent( QPaintEvent* e );

};
44 changes: 44 additions & 0 deletions python/gui/qgstaskmanagerwidget.sip
Expand Up @@ -19,6 +19,50 @@ class QgsTaskManagerWidget : QWidget

};

/** \ingroup gui
* \class QgsTaskManagerFloatingWidget
* A widget which displays tasks from a QgsTaskManager and allows for interaction with the manager
* @see QgsTaskManager
* @note introduced in QGIS 2.16
*/
class QgsTaskManagerFloatingWidget : QgsFloatingWidget
{
%TypeHeaderCode
#include <qgstaskmanagerwidget.h>
%End

public:

/** Constructor for QgsTaskManagerWidget
* @param manager task manager associated with widget
* @param parent parent widget
*/
QgsTaskManagerFloatingWidget( QgsTaskManager* manager, QWidget* parent = nullptr );

};

/** \ingroup gui
* \class QgsTaskManagerFloatingWidget
* A widget which displays tasks from a QgsTaskManager and allows for interaction with the manager
* @see QgsTaskManager
* @note introduced in QGIS 2.16
*/
class QgsTaskManagerStatusBarWidget : QToolButton
{
%TypeHeaderCode
#include <qgstaskmanagerwidget.h>
%End

public:

/** Constructor for QgsTaskManagerStatusBarWidget
* @param manager task manager associated with widget
* @param parent parent widget
*/
QgsTaskManagerStatusBarWidget( QgsTaskManager* manager, QWidget* parent = nullptr );

};


/** \ingroup gui
* \class QgsTaskManagerModel
Expand Down
9 changes: 1 addition & 8 deletions src/app/qgisapp.cpp
Expand Up @@ -853,13 +853,6 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
QMainWindow::addDockWidget( Qt::BottomDockWidgetArea, mUserInputDockWidget );
mUserInputDockWidget->setFloating( true );

// create the task manager dock on starting QGIS - this is like the browser
mTaskManagerDock = new QDockWidget( tr( "Task Manager" ), this );
mTaskManagerDock->setObjectName( "TaskManager" );
addDockWidget( Qt::RightDockWidgetArea, mTaskManagerDock );
mTaskManagerDock->setWidget( new QgsTaskManagerWidget( QgsTaskManager::instance(), mTaskManagerDock ) );
mTaskManagerDock->hide();

// create the GPS tool on starting QGIS - this is like the browser
mpGpsWidget = new QgsGPSInformationWidget( mMapCanvas );
//create the dock widget
Expand Down Expand Up @@ -1148,8 +1141,8 @@ QgisApp::QgisApp()
, mOverviewDock( nullptr )
, mpGpsDock( nullptr )
, mLogDock( nullptr )
, mTaskManagerDock( nullptr )
, mNonEditMapTool( nullptr )
, mTaskManagerWidget( nullptr )
, mScaleWidget( nullptr )
, mMagnifierWidget( nullptr )
, mCoordsEdit( nullptr )
Expand Down
4 changes: 3 additions & 1 deletion src/app/qgisapp.h
Expand Up @@ -78,6 +78,7 @@ class QgsSnappingWidget;
class QgsStatusBarCoordinatesWidget;
class QgsStatusBarMagnifierWidget;
class QgsStatusBarScaleWidget;
class QgsTaskManagerStatusBarWidget;
class QgsTransactionGroup;
class QgsUndoWidget;
class QgsUserInputDockWidget;
Expand Down Expand Up @@ -1560,7 +1561,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsDockWidget *mOverviewDock;
QgsDockWidget *mpGpsDock;
QgsDockWidget *mLogDock;
QDockWidget *mTaskManagerDock;

#ifdef Q_OS_MAC
//! Window menu action to select this window
Expand Down Expand Up @@ -1673,6 +1673,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow

QgsMapTool *mNonEditMapTool;

QgsTaskManagerStatusBarWidget* mTaskManagerWidget;

QgsStatusBarScaleWidget* mScaleWidget;

//! zoom widget
Expand Down
21 changes: 21 additions & 0 deletions src/core/qgstaskmanager.cpp
Expand Up @@ -312,6 +312,7 @@ QStringList QgsTaskManager::dependentLayers( long taskId ) const

void QgsTaskManager::taskProgressChanged( double progress )
{
QMutexLocker ml( mTaskMutex );
QgsTask* task = qobject_cast< QgsTask* >( sender() );

//find ID of task
Expand All @@ -320,6 +321,10 @@ void QgsTaskManager::taskProgressChanged( double progress )
return;

emit progressChanged( id, progress );
if ( mActiveTasks.count() == 1 )
{
emit progressChanged( progress );
}
}

void QgsTaskManager::taskStatusChanged( int status )
Expand Down Expand Up @@ -393,13 +398,29 @@ bool QgsTaskManager::cleanupAndDeleteTask( QgsTask *task )
void QgsTaskManager::processQueue()
{
QMutexLocker ml( mTaskMutex );
int prevActiveCount = mActiveTasks.count();
mActiveTasks.clear();
for ( QMap< long, TaskInfo >::iterator it = mTasks.begin(); it != mTasks.end(); ++it )
{
QgsTask* task = it.value().task;
if ( task && task->status() == QgsTask::Queued && dependenciesSatisified( taskId( task ) ) )
{
mTasks[ it.key()].future = QtConcurrent::run( task, &QgsTask::start );
}

if ( task && ( task->status() != QgsTask::Complete && task->status() != QgsTask::Terminated ) )
{
mActiveTasks << task;
}
}

if ( mActiveTasks.isEmpty() )
{
emit allTasksFinished();
}
if ( prevActiveCount != mActiveTasks.count() )
{
emit countActiveTasksChanged( mActiveTasks.count() );
}
}

Expand Down
27 changes: 27 additions & 0 deletions src/core/qgstaskmanager.h
Expand Up @@ -266,13 +266,29 @@ class CORE_EXPORT QgsTaskManager : public QObject
*/
QStringList dependentLayers( long taskId ) const;

/** Returns a list of the active (queued or running) tasks.
* @see countActiveTasks()
*/
QList< QgsTask* > activeTasks() const { return mActiveTasks; }

/** Returns the number of active (queued or running) tasks.
* @see activeTasks()
* @see countActiveTasksChanged()
*/
int countActiveTasks() const { return mActiveTasks.count(); }

signals:

//! Will be emitted when a task reports a progress change
//! @param taskId ID of task
//! @param progress percent of progress, from 0.0 - 100.0
void progressChanged( long taskId, double progress );

//! Will be emitted when only a single task remains to complete
//! and that task has reported a progress change
//! @param progress percent of progress, from 0.0 - 100.0
void progressChanged( double progress );

//! Will be emitted when a task reports a status change
//! @param taskId ID of task
//! @param status new task status
Expand All @@ -286,6 +302,14 @@ class CORE_EXPORT QgsTaskManager : public QObject
//! @param taskId ID of task
void taskAboutToBeDeleted( long taskId );

//! Emitted when all tasks are complete
//! @see countActiveTasksChanged()
void allTasksFinished();

//! Emitted when the number of active tasks changes
//! @see countActiveTasks()
void countActiveTasksChanged( int count );

private slots:

void taskProgressChanged( double progress );
Expand Down Expand Up @@ -313,6 +337,9 @@ class CORE_EXPORT QgsTaskManager : public QObject
//! Tracks the next unique task ID
long mNextTaskId;

//! List of active (queued or running) tasks
QList< QgsTask* > mActiveTasks;

bool cleanupAndDeleteTask( QgsTask* task );

//! Process the queue of outstanding jobs and starts up any
Expand Down
12 changes: 11 additions & 1 deletion src/gui/qgsfloatingwidget.cpp
Expand Up @@ -15,7 +15,8 @@

#include "qgsfloatingwidget.h"
#include <QEvent>

#include <QStyleOption>
#include <QPainter>

//
// QgsFloatingWidget
Expand Down Expand Up @@ -69,6 +70,15 @@ void QgsFloatingWidget::showEvent( QShowEvent *e )
QWidget::showEvent( e );
}

void QgsFloatingWidget::paintEvent( QPaintEvent* e )
{
Q_UNUSED( e );
QStyleOption opt;
opt.init( this );
QPainter p( this );
style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
}

void QgsFloatingWidget::anchorPointChanged()
{
if ( mAnchorWidget )
Expand Down
4 changes: 4 additions & 0 deletions src/gui/qgsfloatingwidget.h
Expand Up @@ -46,6 +46,9 @@ class GUI_EXPORT QgsFloatingWidget: public QWidget
BottomRight, //!< Bottom-right of widget
};

/** Constructor for QgsFloatingWidget.
* @param parent parent widget
*/
QgsFloatingWidget( QWidget* parent = nullptr );

/** Sets the widget to "anchor" the floating widget to. The floating widget will be repositioned whenever the
Expand Down Expand Up @@ -90,6 +93,7 @@ class GUI_EXPORT QgsFloatingWidget: public QWidget

protected:
void showEvent( QShowEvent* e ) override;
virtual void paintEvent( QPaintEvent* e ) override;

private slots:

Expand Down

0 comments on commit d270b4f

Please sign in to comment.