22 #include <QMouseEvent> 26 #include <QProgressBar> 28 #include <QHeaderView> 40 QVBoxLayout *vLayout =
new QVBoxLayout();
41 vLayout->setMargin( 0 );
42 mTreeView =
new QTreeView();
43 mModel =
new QgsTaskManagerModel( manager,
this );
44 mTreeView->setModel( mModel );
45 connect( mModel, &QgsTaskManagerModel::rowsInserted,
this, &QgsTaskManagerWidget::modelRowsInserted );
46 mTreeView->setHeaderHidden(
true );
47 mTreeView->setRootIsDecorated(
false );
48 mTreeView->setSelectionBehavior( QAbstractItemView::SelectRows );
50 mTreeView->setColumnWidth( QgsTaskManagerModel::Progress, progressColWidth );
52 mTreeView->setColumnWidth( QgsTaskManagerModel::Status, statusColWidth );
53 mTreeView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
54 mTreeView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
55 mTreeView->header()->setStretchLastSection(
false );
56 mTreeView->header()->setSectionResizeMode( QgsTaskManagerModel::Description, QHeaderView::Stretch );
58 connect( mTreeView, &QTreeView::clicked,
this, &QgsTaskManagerWidget::clicked );
60 vLayout->addWidget( mTreeView );
71 void QgsTaskManagerWidget::modelRowsInserted(
const QModelIndex &,
int start,
int end )
73 for (
int row = start; row <=
end; ++row )
75 QgsTask *task = mModel->indexToTask( mModel->index( row, 1 ) );
79 QProgressBar *progressBar =
new QProgressBar();
80 progressBar->setAutoFillBackground(
true );
86 progressBar->setMaximum( 100 );
87 progressBar->setValue( progress );
90 progressBar->setMaximum( 0 );
93 mTreeView->setIndexWidget( mModel->index( row, QgsTaskManagerModel::Progress ), progressBar );
95 QgsTaskStatusWidget *statusWidget =
new QgsTaskStatusWidget(
nullptr, task->
status(), task->
canCancel() );
96 statusWidget->setAutoFillBackground(
true );
98 connect( statusWidget, &QgsTaskStatusWidget::cancelClicked, task, &
QgsTask::cancel );
99 mTreeView->setIndexWidget( mModel->index( row, QgsTaskManagerModel::Status ), statusWidget );
103 void QgsTaskManagerWidget::clicked(
const QModelIndex &index )
105 QgsTask *task = mModel->indexToTask( index );
117 QgsTaskManagerModel::QgsTaskManagerModel(
QgsTaskManager *manager, QObject *parent )
118 : QAbstractItemModel( parent )
119 , mManager( manager )
121 Q_ASSERT( mManager );
126 mRowToTaskIdList << mManager->
taskId( task );
134 QModelIndex QgsTaskManagerModel::index(
int row,
int column,
const QModelIndex &parent )
const 136 if ( column < 0 || column >= columnCount() )
139 return QModelIndex();
142 if ( !parent.isValid() && row >= 0 && row < mRowToTaskIdList.count() )
145 return createIndex( row, column );
149 return QModelIndex();
153 QModelIndex QgsTaskManagerModel::parent(
const QModelIndex &index )
const 158 return QModelIndex();
161 int QgsTaskManagerModel::rowCount(
const QModelIndex &parent )
const 163 if ( !parent.isValid() )
165 return mRowToTaskIdList.count();
174 int QgsTaskManagerModel::columnCount(
const QModelIndex &parent )
const 180 QVariant QgsTaskManagerModel::data(
const QModelIndex &index,
int role )
const 182 if ( !index.isValid() )
185 QgsTask *task = indexToTask( index );
190 case Qt::DisplayRole:
192 switch ( index.column() )
206 return static_cast<int>( task->
status() );
208 case Qt::ToolTipRole:
209 switch ( index.column() )
219 return tr(
"Queued" );
221 return tr(
"On hold" );
224 if ( index.column() == Status && !task->
canCancel() )
225 return tr(
"Running (cannot cancel)" );
227 return tr(
"Running" );
230 return tr(
"Complete" );
232 return tr(
"Terminated" );
249 Qt::ItemFlags QgsTaskManagerModel::flags(
const QModelIndex &index )
const 251 Qt::ItemFlags flags = QAbstractItemModel::flags( index );
253 if ( ! index.isValid() )
258 QgsTask *task = indexToTask( index );
259 if ( index.column() == Status )
262 flags = flags | Qt::ItemIsEditable;
264 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
267 bool QgsTaskManagerModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
271 if ( !index.isValid() )
274 QgsTask *task = indexToTask( index );
278 switch ( index.column() )
282 if ( value.toBool() && task->
canCancel() )
292 void QgsTaskManagerModel::taskAdded(
long id )
294 beginInsertRows( QModelIndex(), mRowToTaskIdList.count(),
295 mRowToTaskIdList.count() );
296 mRowToTaskIdList << id;
300 void QgsTaskManagerModel::taskDeleted(
long id )
302 for (
int row = 0; row < mRowToTaskIdList.count(); ++row )
304 if ( mRowToTaskIdList.at( row ) == id )
306 beginRemoveRows( QModelIndex(), row, row );
307 mRowToTaskIdList.removeAt( row );
314 void QgsTaskManagerModel::progressChanged(
long id,
double progress )
316 Q_UNUSED( progress );
318 QModelIndex index = idToIndex(
id, Progress );
319 if ( !index.isValid() )
324 emit dataChanged( index, index );
327 void QgsTaskManagerModel::statusChanged(
long id,
int status )
335 QModelIndex index = idToIndex(
id, Status );
336 if ( !index.isValid() )
341 emit dataChanged( index, index );
345 QgsTask *QgsTaskManagerModel::indexToTask(
const QModelIndex &index )
const 347 if ( !index.isValid() || index.parent().isValid() )
350 long id = index.row() >= 0 && index.row() < mRowToTaskIdList.count() ? mRowToTaskIdList.at( index.row() ) : -1;
352 return mManager->
task(
id );
357 int QgsTaskManagerModel::idToRow(
long id )
const 359 for (
int row = 0; row < mRowToTaskIdList.count(); ++row )
361 if ( mRowToTaskIdList.at( row ) == id )
369 QModelIndex QgsTaskManagerModel::idToIndex(
long id,
int column )
const 371 int row = idToRow(
id );
373 return QModelIndex();
375 return index( row, column );
383 QgsTaskStatusWidget::QgsTaskStatusWidget( QWidget *parent,
QgsTask::TaskStatus status,
bool canCancel )
385 , mCanCancel( canCancel )
388 setMouseTracking(
true );
391 QSize QgsTaskStatusWidget::sizeHint()
const 393 return QSize( 32, 32 );
396 void QgsTaskStatusWidget::setStatus(
int status )
402 void QgsTaskStatusWidget::paintEvent( QPaintEvent *e )
404 QWidget::paintEvent( e );
434 icon.paint( &p, 1, height() / 2 - 12, 24, 24 );
438 void QgsTaskStatusWidget::mousePressEvent( QMouseEvent * )
441 emit cancelClicked();
444 void QgsTaskStatusWidget::mouseMoveEvent( QMouseEvent * )
453 void QgsTaskStatusWidget::leaveEvent( QEvent * )
482 QgsTaskManagerFloatingWidget::QgsTaskManagerFloatingWidget(
QgsTaskManager *manager, QWidget *parent )
485 setLayout(
new QVBoxLayout() );
489 setMinimumSize( minWidth, minHeight );
490 layout()->addWidget( w );
491 setStyleSheet(
".QgsTaskManagerFloatingWidget { border-top-left-radius: 8px;" 492 "border-top-right-radius: 8px; background-color: rgb(0, 0, 0, 70%); }" );
496 QgsTaskManagerStatusBarWidget::QgsTaskManagerStatusBarWidget(
QgsTaskManager *manager, QWidget *parent )
497 : QToolButton( parent )
498 , mManager( manager )
500 setAutoRaise(
true );
501 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::MinimumExpanding );
502 setLayout(
new QVBoxLayout() );
504 mProgressBar =
new QProgressBar();
505 mProgressBar->setMinimum( 0 );
506 mProgressBar->setMaximum( 0 );
507 layout()->setContentsMargins( 5, 5, 5, 5 );
508 layout()->addWidget( mProgressBar );
510 mFloatingWidget =
new QgsTaskManagerFloatingWidget( manager, parent ? parent->window() : nullptr );
511 mFloatingWidget->setAnchorWidget(
this );
514 mFloatingWidget->hide();
515 connect(
this, &QgsTaskManagerStatusBarWidget::clicked,
this, &QgsTaskManagerStatusBarWidget::toggleDisplay );
524 QSize QgsTaskManagerStatusBarWidget::sizeHint()
const 527 int height = QToolButton::sizeHint().height();
528 return QSize( width, height );
531 void QgsTaskManagerStatusBarWidget::toggleDisplay()
533 if ( mFloatingWidget->isVisible() )
534 mFloatingWidget->hide();
537 mFloatingWidget->show();
538 mFloatingWidget->raise();
542 void QgsTaskManagerStatusBarWidget::overallProgressChanged(
double progress )
544 mProgressBar->setValue( progress );
546 mProgressBar->setMaximum( 0 );
547 else if ( mProgressBar->maximum() == 0 )
548 mProgressBar->setMaximum( 100 );
549 setToolTip( mManager->
activeTasks().at( 0 )->description() );
552 void QgsTaskManagerStatusBarWidget::countActiveTasksChanged(
int count )
556 mProgressBar->setMaximum( 0 );
557 setToolTip( tr(
"%1 active tasks running" ).arg( count ) );
561 void QgsTaskManagerStatusBarWidget::allFinished()
563 mFloatingWidget->hide();
566 mProgressBar->setMaximum( 0 );
567 mProgressBar->setValue( 0 );
570 void QgsTaskManagerStatusBarWidget::showButton()
574 mProgressBar->setMaximum( 100 );
575 mProgressBar->setValue( 0 );
static const double UI_SCALE_FACTOR
UI scaling factor.
void statusChanged(int status)
Will be emitted by task when its status changes.
TaskStatus
Status of tasks.
QList< QgsTask * > tasks() const
Returns all tasks tracked by the manager.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
void progressChanged(double progress)
Will be emitted by task when its progress changes.
Task was terminated or errored.
void countActiveTasksChanged(int count)
Emitted when the number of active tasks changes.
void triggerTask(QgsTask *task)
Triggers a task, e.g.
QString description() const
Returns the task's description.
QgsTask * task(long id) const
Returns the task with matching ID.
void progressChanged(long taskId, double progress)
Will be emitted when a task reports a progress change.
Task is queued but on hold and will not be started.
Abstract base class for long running background tasks.
bool canCancel() const
Returns true if the task can be canceled.
void statusChanged(long taskId, int status)
Will be emitted when a task reports a status change.
Task successfully completed.
Task manager for managing a set of long-running QgsTask tasks.
void taskAdded(long taskId)
Emitted when a new task has been added to the manager.
virtual void cancel()
Notifies the task that it should terminate.
void allTasksFinished()
Emitted when all tasks are complete.
Task is queued and has not begun.
double progress() const
Returns the task's progress (between 0.0 and 100.0)
QList< QgsTask *> activeTasks() const
Returns a list of the active (queued or running) tasks.
Task is currently running.
long taskId(QgsTask *task) const
Returns the unique task ID corresponding to a task managed by the class.
void finalTaskProgressChanged(double progress)
Will be emitted when only a single task remains to complete and that task has reported a progress cha...
TaskStatus status() const
Returns the current task status.