Skip to content
Permalink
Browse files
Tasks are treated as progressless until they first report a progress
  • Loading branch information
nyalldawson committed Dec 5, 2016
1 parent 4dc3dd9 commit 466b0b96b7da70d0e8809076082293fb986cd7e7
@@ -44,7 +44,6 @@ class QgsTask : QObject, QRunnable
enum Flag
{
CanCancel, //!< Task can be cancelled
CanReportProgress, //!< Task will report its progress
AllFlags, //!< Task supports all flags
};
typedef QFlags<QgsTask::Flag> Flags;
@@ -92,30 +92,15 @@ class QgsTaskManagerModel: QAbstractItemModel
Qt::ItemFlags flags( const QModelIndex & index ) const;
bool setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );

};


/** \ingroup gui
* \class QgsProgressBarDelegate
* A delegate for showing a progress bar within a view
* @note introduced in QGIS 2.16
*/
class QgsProgressBarDelegate : QStyledItemDelegate
{
%TypeHeaderCode
#include <qgstaskmanagerwidget.h>
%End
public:

/** Constructor for QgsProgressBarDelegate
* @param parent parent object
/**
* Returns the task associated with a specified model index, or nullptr if no
* task was found.
*/
QgsProgressBarDelegate( QObject* parent /TransferThis/ = nullptr );
QgsTask* indexToTask( const QModelIndex& index ) const;

void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
};


/** \ingroup gui
* \class QgsProgressBarDelegate
* A delegate for showing task status within a view. Clicks on the delegate will cause the task to be cancelled (via the model).
@@ -62,6 +62,10 @@ void QgsTask::run()
mOverallStatus = Running;
emit statusChanged( Running );
emit begun();

// force initial emission of progressChanged, but respect if task has had initial progress manually set
setProgress( mProgress );

TaskResult result = _run();
switch ( result )
{
@@ -72,8 +72,7 @@ class CORE_EXPORT QgsTask : public QObject, public QRunnable
enum Flag
{
CanCancel = 1 << 1, //!< Task can be cancelled
CanReportProgress = 1 << 2, //!< Task will report its progress
AllFlags = CanCancel | CanReportProgress, //!< Task supports all flags
AllFlags = CanCancel, //!< Task supports all flags
};
Q_DECLARE_FLAGS( Flags, Flag )

@@ -44,8 +44,9 @@ QgsTaskManagerWidget::QgsTaskManagerWidget( QgsTaskManager *manager, QWidget *pa
vLayout->addWidget( toolbar );
#endif
mTreeView = new QTreeView();
mTreeView->setModel( new QgsTaskManagerModel( manager, this ) );
mTreeView->setItemDelegateForColumn( 1, new QgsProgressBarDelegate( this ) );
mModel = new QgsTaskManagerModel( manager, this );
mTreeView->setModel( mModel );
connect( mModel, &QgsTaskManagerModel::rowsInserted, this, &QgsTaskManagerWidget::modelRowsInserted );
mTreeView->setItemDelegateForColumn( 2, new QgsTaskStatusDelegate( this ) );
mTreeView->setHeaderHidden( true );
mTreeView->setRootIsDecorated( false );
@@ -57,6 +58,38 @@ QgsTaskManagerWidget::QgsTaskManagerWidget( QgsTaskManager *manager, QWidget *pa
setLayout( vLayout );
}

QgsTaskManagerWidget::~QgsTaskManagerWidget()
{
delete mModel;
}


void QgsTaskManagerWidget::modelRowsInserted( const QModelIndex&, int start, int end )
{
for ( int row = start; row <= end; ++row )
{
QgsTask* task = mModel->indexToTask( mModel->index( row, 1 ) );
if ( !task )
continue;

QProgressBar* progressBar = new QProgressBar();
progressBar->setAutoFillBackground( true );
connect( task, &QgsTask::progressChanged, progressBar, [progressBar]( double progress )
{
//until first progress report, we show a progress bar of interderminant length
if ( progress > 0 )
{
progressBar->setMaximum( 100 );
progressBar->setValue( progress );
}
else
progressBar->setMaximum( 0 );
}
);
mTreeView->setIndexWidget( mModel->index( row, 1 ), progressBar );
}
}


//
// QgsTaskManagerModel
@@ -289,43 +322,6 @@ QModelIndex QgsTaskManagerModel::idToIndex( long id, int column ) const
}



//
// QgsProgressBarDelegate
//

QgsProgressBarDelegate::QgsProgressBarDelegate( QObject *parent )
: QStyledItemDelegate( parent )
{}

void QgsProgressBarDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
QStyledItemDelegate::paint( painter, option, index );

int progress = index.data().toInt();

QStyleOptionProgressBar progressBarOption;
progressBarOption.state = option.state;
progressBarOption.rect = option.rect;
progressBarOption.rect.setTop( option.rect.top() + 1 );
progressBarOption.rect.setHeight( option.rect.height() - 2 );
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.text = QString::number( progress ) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter;

QgsApplication::style()->drawControl( QStyle::CE_ProgressBar, &progressBarOption, painter );
}

QSize QgsProgressBarDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
Q_UNUSED( index );
return QSize( option.rect.width(), option.fontMetrics.height() + 10 );
}


//
// QgsTaskStatusDelegate
//
@@ -449,7 +445,9 @@ void QgsTaskManagerStatusBarWidget::toggleDisplay()
void QgsTaskManagerStatusBarWidget::overallProgressChanged( double progress )
{
mProgressBar->setValue( progress );
if ( mProgressBar->maximum( ) == 0 )
if ( qgsDoubleNear( progress, 0.0 ) )
mProgressBar->setMaximum( 0 );
else if ( mProgressBar->maximum( ) == 0 )
mProgressBar->setMaximum( 100 );
setToolTip( mManager->activeTasks().at( 0 )->description() );
}
@@ -25,6 +25,7 @@ class QgsTaskManager;
class QgsTask;
class QTreeView;
class QProgressBar;
class QgsTaskManagerModel;

/**
* \ingroup gui
@@ -45,9 +46,16 @@ class GUI_EXPORT QgsTaskManagerWidget : public QWidget
*/
QgsTaskManagerWidget( QgsTaskManager* manager, QWidget* parent = nullptr );

~QgsTaskManagerWidget();

private slots:

void modelRowsInserted( const QModelIndex& index, int start, int end );

private:

QTreeView* mTreeView;
QgsTaskManagerModel* mModel;
};

/**
@@ -138,6 +146,12 @@ class GUI_EXPORT QgsTaskManagerModel: public QAbstractItemModel
Qt::ItemFlags flags( const QModelIndex & index ) const override;
bool setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ) override;

/**
* Returns the task associated with a specified model index, or nullptr if no
* task was found.
*/
QgsTask* indexToTask( const QModelIndex& index ) const;

private slots:

void taskAdded( long id );
@@ -163,33 +177,11 @@ class GUI_EXPORT QgsTaskManagerModel: public QAbstractItemModel

QList< long > mRowToTaskIdList;

QgsTask* indexToTask( const QModelIndex& index ) const;

int idToRow( long id ) const;
QModelIndex idToIndex( long id, int column ) const;
};


/**
* \ingroup gui
* \class QgsProgressBarDelegate
* A delegate for showing a progress bar within a view.
* \note added in QGIS 3.0
*/
class GUI_EXPORT QgsProgressBarDelegate : public QStyledItemDelegate
{
Q_OBJECT

public:

/** Constructor for QgsProgressBarDelegate
* @param parent parent object
*/
QgsProgressBarDelegate( QObject* parent = nullptr );

void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
};

/**
* \ingroup gui
* \class QgsTaskStatusDelegate
@@ -228,7 +228,7 @@ void TestQgsTaskManager::task()
QCOMPARE( task->description(), QString( "desc" ) );
QVERIFY( !task->isActive() );
QVERIFY( task->canCancel() );
QVERIFY( task->flags() & QgsTask::CanReportProgress );
QVERIFY( task->flags() & QgsTask::CanCancel );

QSignalSpy startedSpy( task.data(), &QgsTask::begun );
QSignalSpy statusSpy( task.data(), &QgsTask::statusChanged );
@@ -271,13 +271,11 @@ void TestQgsTaskManager::task()
QCOMPARE( task->status(), QgsTask::Terminated );

// test flags
task.reset( new TestTask( "desc", QgsTask::CanReportProgress ) );
task.reset( new TestTask( "desc", 0 ) );
QVERIFY( !task->canCancel() );
QVERIFY( task->flags() & QgsTask::CanReportProgress );
QVERIFY( !( task->flags() & QgsTask::CanCancel ) );
task.reset( new TestTask( "desc", QgsTask::CanCancel ) );
QVERIFY( task->canCancel() );
QVERIFY( !( task->flags() & QgsTask::CanReportProgress ) );
QVERIFY( task->flags() & QgsTask::CanCancel );
}

0 comments on commit 466b0b9

Please sign in to comment.