Api + test cleanups

This commit is contained in:
Nyall Dawson 2016-04-19 22:24:34 +10:00
parent 6021d7806e
commit e29dd79432
7 changed files with 100 additions and 31 deletions

View File

@ -20,20 +20,36 @@ class QgsTask : QObject
Terminated, /*!< Task was terminated or errored */
};
//! Task flags
enum Flag
{
CancelSupport, //!< Task can be cancelled
ProgressReport, //!< Task will report its progress
AllFlags, //!< Task supports all flags
};
typedef QFlags<QgsTask::Flag> Flags;
/** Constructor for QgsTask.
* @param description text description of task
* @param flags task flags
*/
QgsTask( const QString& description = QString() );
QgsTask( const QString& description = QString(), const Flags& flags = AllFlags );
//! Returns the flags associated with the task.
Flags flags() const;
//! Starts the task.
void start();
//! Notifies the task that it should terminate.
//! @see isCancelled()
void terminate();
void cancel();
//! Returns true if the task can be cancelled.
bool canCancel() const;
//! Returns true if the task is active, ie it is not complete and has
//! not been terminated.
//! not been cancelled.
bool isActive() const;
//! Returns the current task status.
@ -104,6 +120,8 @@ class QgsTask : QObject
};
QFlags<QgsTask::Flag> operator|(QgsTask::Flag f1, QFlags<QgsTask::Flag> f2);
/** \ingroup core
* \class QgsTaskManager
* \brief Task manager for managing a set of long-running QgsTask tasks. This class can be created directly,
@ -169,7 +187,7 @@ class QgsTaskManager : QObject
long taskId( QgsTask* task ) const;
//! Instructs all tasks tracked by the manager to terminate.
void terminateAll();
void cancelAll();
signals:

View File

@ -4,7 +4,7 @@
* @see QgsTaskManager
* @note introduced in QGIS 2.16
*/
class QgsTaskManagerWidget : QTreeView
class QgsTaskManagerWidget : QWidget
{
%TypeHeaderCode
#include <qgstaskmanagerwidget.h>

View File

@ -23,8 +23,9 @@
// QgsTask
//
QgsTask::QgsTask( const QString &name )
QgsTask::QgsTask( const QString &name, const Flags& flags )
: QObject()
, mFlags( flags )
, mDescription( name )
, mStatus( Queued )
, mProgress( 0.0 )
@ -39,7 +40,7 @@ void QgsTask::start()
run();
}
void QgsTask::terminate()
void QgsTask::cancel()
{
mShouldTerminate = true;
}
@ -89,7 +90,7 @@ QgsTaskManager::QgsTaskManager( QObject* parent )
QgsTaskManager::~QgsTaskManager()
{
//first tell all tasks to cancel
terminateAll();
cancelAll();
//then clean them up, including waiting for them to terminate
QMap< long, TaskInfo >::const_iterator it = mTasks.constBegin();
@ -166,7 +167,7 @@ long QgsTaskManager::taskId( QgsTask *task ) const
return -1;
}
void QgsTaskManager::terminateAll()
void QgsTaskManager::cancelAll()
{
QMap< long, TaskInfo >::iterator it = mTasks.begin();
for ( ; it != mTasks.end(); ++it )
@ -174,7 +175,7 @@ void QgsTaskManager::terminateAll()
QgsTask* task = it.value().task;
if ( task->isActive() )
{
task->terminate();
task->cancel();
}
}
}
@ -209,7 +210,7 @@ bool QgsTaskManager::cleanupAndDeleteTask( QgsTask *task )
return false;
if ( task->isActive() )
task->terminate();
task->cancel();
// wait for task to terminate
QMap< long, TaskInfo >::iterator it = mTasks.begin();

View File

@ -44,20 +44,36 @@ class CORE_EXPORT QgsTask : public QObject
Terminated, /*!< Task was terminated or errored */
};
//! Task flags
enum Flag
{
CancelSupport = 1 << 1, //!< Task can be cancelled
ProgressReport = 1 << 2, //!< Task will report its progress
AllFlags = CancelSupport | ProgressReport, //!< Task supports all flags
};
Q_DECLARE_FLAGS( Flags, Flag )
/** Constructor for QgsTask.
* @param description text description of task
* @param flags task flags
*/
QgsTask( const QString& description = QString() );
QgsTask( const QString& description = QString(), const Flags& flags = AllFlags );
//! Returns the flags associated with the task.
Flags flags() const { return mFlags; }
//! Starts the task.
void start();
//! Notifies the task that it should terminate.
//! @see isCancelled()
void terminate();
void cancel();
//! Returns true if the task can be cancelled.
bool canCancel() const { return mFlags & CancelSupport; }
//! Returns true if the task is active, ie it is not complete and has
//! not been terminated.
//! not been cancelled.
bool isActive() const { return mStatus == Running; }
//! Returns the current task status.
@ -128,6 +144,7 @@ class CORE_EXPORT QgsTask : public QObject
private:
Flags mFlags;
QString mDescription;
TaskStatus mStatus;
double mProgress;
@ -135,6 +152,8 @@ class CORE_EXPORT QgsTask : public QObject
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsTask::Flags )
/** \ingroup core
* \class QgsTaskManager
* \brief Task manager for managing a set of long-running QgsTask tasks. This class can be created directly,
@ -200,7 +219,7 @@ class CORE_EXPORT QgsTaskManager : public QObject
long taskId( QgsTask* task ) const;
//! Instructs all tasks tracked by the manager to terminate.
void terminateAll();
void cancelAll();
signals:

View File

@ -20,29 +20,41 @@
#include "qgsapplication.h"
#include <QPainter>
#include <QMouseEvent>
#include <QTreeView>
#include <QLayout>
#include <QToolBar>
#include <QAction>
//
// QgsTaskManagerWidget
//
QgsTaskManagerWidget::QgsTaskManagerWidget( QgsTaskManager *manager, QWidget *parent )
: QTreeView( parent )
: QWidget( parent )
{
Q_ASSERT( manager );
setModel( new QgsTaskManagerModel( manager, this ) );
QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->setMargin( 0 );
#if 0
QToolBar* toolbar = new QToolBar();
toolbar->setIconSize( QSize( 16, 16 ) );
toolbar->addAction( new QAction( "test", this ) );
vLayout->addWidget( toolbar );
#endif
mTreeView = new QTreeView();
mTreeView->setModel( new QgsTaskManagerModel( manager, this ) );
mTreeView->setItemDelegateForColumn( 1, new QgsProgressBarDelegate( this ) );
mTreeView->setItemDelegateForColumn( 2, new QgsTaskStatusDelegate( this ) );
mTreeView->setHeaderHidden( true );
mTreeView->setRootIsDecorated( false );
mTreeView->setSelectionBehavior( QAbstractItemView::SelectRows );
vLayout->addWidget( mTreeView );
setItemDelegateForColumn( 1, new QgsProgressBarDelegate( this ) );
setItemDelegateForColumn( 2, new QgsTaskStatusDelegate( this ) );
setHeaderHidden( true );
setRootIsDecorated( false );
setSelectionBehavior( QAbstractItemView::SelectRows );
setLayout( vLayout );
}
//
// QgsTaskManagerModel
//
@ -178,7 +190,7 @@ bool QgsTaskManagerModel::setData( const QModelIndex &index, const QVariant &val
case Status:
{
if ( value.toBool() )
task->terminate();
task->cancel();
return true;
}

View File

@ -17,11 +17,11 @@
#ifndef QGSTASKMANAGERWIDGET_H
#define QGSTASKMANAGERWIDGET_H
#include <QTreeView>
#include <QStyledItemDelegate>
class QgsTaskManager;
class QgsTask;
class QTreeView;
/** \ingroup gui
* \class QgsTaskManagerWidget
@ -29,7 +29,7 @@ class QgsTask;
* @see QgsTaskManager
* @note introduced in QGIS 2.16
*/
class GUI_EXPORT QgsTaskManagerWidget : public QTreeView
class GUI_EXPORT QgsTaskManagerWidget : public QWidget
{
Q_OBJECT
@ -41,6 +41,9 @@ class GUI_EXPORT QgsTaskManagerWidget : public QTreeView
*/
QgsTaskManagerWidget( QgsTaskManager* manager, QWidget* parent = nullptr );
private:
QTreeView* mTreeView;
};

View File

@ -27,6 +27,7 @@ class TestTask : public QgsTask
public:
TestTask( const QString& desc = QString() ) : QgsTask( desc ), runCalled( false ) {}
TestTask( const QString& desc, const QgsTask::Flags& flags ) : QgsTask( desc, flags ), runCalled( false ) {}
void emitProgressChanged( double progress ) { setProgress( progress ); }
void emitTaskStopped() { stopped(); }
@ -59,7 +60,9 @@ class TestTerminationTask : public TestTask
void run() override
{
QTest::qSleep( 1000 );
while ( !isCancelled() )
{}
stopped();
}
};
@ -112,6 +115,8 @@ void TestQgsTaskManager::task()
QCOMPARE( task->status(), QgsTask::Queued );
QCOMPARE( task->description(), QString( "desc" ) );
QVERIFY( !task->isActive() );
QVERIFY( task->canCancel() );
QVERIFY( task->flags() & QgsTask::ProgressReport );
QSignalSpy startedSpy( task.data(), SIGNAL( begun() ) );
QSignalSpy statusSpy( task.data(), SIGNAL( statusChanged( int ) ) );
@ -143,6 +148,16 @@ void TestQgsTaskManager::task()
QCOMPARE( completeSpy.count(), 1 );
QCOMPARE( statusSpy2.count(), 1 );
QCOMPARE( static_cast< QgsTask::TaskStatus >( statusSpy2.last().at( 0 ).toInt() ), QgsTask::Complete );
// test flags
task.reset( new TestTask( "desc", QgsTask::ProgressReport ) );
QVERIFY( !task->canCancel() );
QVERIFY( task->flags() & QgsTask::ProgressReport );
QVERIFY( !( task->flags() & QgsTask::CancelSupport ) );
task.reset( new TestTask( "desc", QgsTask::CancelSupport ) );
QVERIFY( task->canCancel() );
QVERIFY( !( task->flags() & QgsTask::ProgressReport ) );
QVERIFY( task->flags() & QgsTask::CancelSupport );
}
@ -237,8 +252,9 @@ void TestQgsTaskManager::taskTerminationBeforeDelete()
TestTask* task = new TestTerminationTask();
manager->addTask( task );
//SHOULD NOT BE NEEDED...
task->start();
// wait till task spins up
while ( !task->isActive() )
{}
// if task is not terminated assert will trip
delete manager;