diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 12db1ab3ac3..98adaf01194 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -30,6 +30,8 @@ #include "basetreeview.h" +#include "progressindicator.h" + #include #include @@ -54,7 +56,7 @@ class BaseTreeViewPrivate : public QObject public: explicit BaseTreeViewPrivate(BaseTreeView *parent) - : q(parent), m_settings(0), m_expectUserChanges(false) + : q(parent), m_settings(0), m_expectUserChanges(false), m_progressIndicator(0) {} bool eventFilter(QObject *, QEvent *event) @@ -211,6 +213,7 @@ public: QSettings *m_settings; QString m_settingsKey; bool m_expectUserChanges; + ProgressIndicator *m_progressIndicator; }; class BaseTreeViewDelegate : public QItemDelegate @@ -310,6 +313,32 @@ void BaseTreeView::mousePressEvent(QMouseEvent *ev) d->toggleColumnWidth(columnAt(ev->x())); } +/*! + Shows a round spinning progress indicator on top of the tree view. + Creates a progress indicator widget if necessary. + \sa hideProgressIndicator() + */ +void BaseTreeView::showProgressIndicator() +{ + if (!d->m_progressIndicator) { + d->m_progressIndicator = new ProgressIndicator(ProgressIndicator::Large); + d->m_progressIndicator->attachToWidget(this); + } + d->m_progressIndicator->show(); +} + +/*! + Hides the round spinning progress indicator that was shown with + BaseTreeView::showProgressIndicator(). Note that the progress indicator widget is not + destroyed. + \sa showProgressIndicator() + */ +void BaseTreeView::hideProgressIndicator() +{ + QTC_ASSERT(d->m_progressIndicator, return); + d->m_progressIndicator->hide(); +} + void BaseTreeView::setSettings(QSettings *settings, const QByteArray &key) { QTC_ASSERT(!d->m_settings, qDebug() << "DUPLICATED setSettings" << key); diff --git a/src/libs/utils/basetreeview.h b/src/libs/utils/basetreeview.h index 0710888a814..1577f88f823 100644 --- a/src/libs/utils/basetreeview.h +++ b/src/libs/utils/basetreeview.h @@ -59,6 +59,9 @@ public: virtual void rowClicked(const QModelIndex &) {} void mousePressEvent(QMouseEvent *ev); + void showProgressIndicator(); + void hideProgressIndicator(); + public slots: void setAlternatingRowColorsHelper(bool on) { setAlternatingRowColors(on); } diff --git a/src/libs/utils/progressindicator.cpp b/src/libs/utils/progressindicator.cpp index 10e0f9a5d13..f1a6f3e905c 100644 --- a/src/libs/utils/progressindicator.cpp +++ b/src/libs/utils/progressindicator.cpp @@ -29,26 +29,40 @@ ****************************************************************************/ #include "progressindicator.h" + +#include "qtcassert.h" #include "stylehelper.h" +#include #include #include using namespace Utils; -ProgressIndicator::ProgressIndicator(Size size, QWidget *parent) +ProgressIndicator::ProgressIndicator(IndicatorSize size, QWidget *parent) : QWidget(parent), m_rotation(0) { setAttribute(Qt::WA_TransparentForMouseEvents); + m_timer.setSingleShot(false); + connect(&m_timer, &QTimer::timeout, this, &ProgressIndicator::step); + setIndicatorSize(size); +} + +void ProgressIndicator::setIndicatorSize(ProgressIndicator::IndicatorSize size) +{ m_size = size; m_rotationStep = size == Small ? 45 : 30; + m_timer.setInterval(size == Small ? 100 : 80); m_pixmap.load(StyleHelper::dpiSpecificImageFile( size == Small ? QLatin1String(":/utils/images/progressindicator_small.png") : QLatin1String(":/utils/images/progressindicator_big.png"))); - m_timer.setInterval(size == Small ? 100 : 80); - m_timer.setSingleShot(false); - connect(&m_timer, &QTimer::timeout, this, &ProgressIndicator::step); + updateGeometry(); +} + +ProgressIndicator::IndicatorSize ProgressIndicator::indicatorSize() const +{ + return m_size; } QSize ProgressIndicator::sizeHint() const @@ -56,6 +70,16 @@ QSize ProgressIndicator::sizeHint() const return m_pixmap.size() / m_pixmap.devicePixelRatio(); } +void ProgressIndicator::attachToWidget(QWidget *parent) +{ + if (parentWidget()) + parentWidget()->removeEventFilter(this); + setParent(parent); + parent->installEventFilter(this); + resizeToParent(); + raise(); +} + void ProgressIndicator::paintEvent(QPaintEvent *) { QPainter p(this); @@ -82,9 +106,23 @@ void ProgressIndicator::hideEvent(QHideEvent *) m_timer.stop(); } +bool ProgressIndicator::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == parent() && ev->type() == QEvent::Resize) { + resizeToParent(); + } + return QWidget::eventFilter(obj, ev); +} + void ProgressIndicator::step() { m_rotation = (m_rotation + m_rotationStep + 360) % 360; update(); } +void ProgressIndicator::resizeToParent() +{ + QTC_ASSERT(parentWidget(), return); + setGeometry(QRect(QPoint(0, 0), parentWidget()->size())); +} + diff --git a/src/libs/utils/progressindicator.h b/src/libs/utils/progressindicator.h index c75fcbe0dc9..a34365b2ddc 100644 --- a/src/libs/utils/progressindicator.h +++ b/src/libs/utils/progressindicator.h @@ -45,24 +45,31 @@ class QTCREATOR_UTILS_EXPORT ProgressIndicator : public QWidget { Q_OBJECT public: - enum Size { + enum IndicatorSize { Small, Large }; - explicit ProgressIndicator(Size size, QWidget *parent = 0); + explicit ProgressIndicator(IndicatorSize size, QWidget *parent = 0); + + void setIndicatorSize(IndicatorSize size); + IndicatorSize indicatorSize() const; QSize sizeHint() const; + void attachToWidget(QWidget *parent); + protected: void paintEvent(QPaintEvent *); void showEvent(QShowEvent *); void hideEvent(QHideEvent *); + bool eventFilter(QObject *obj, QEvent *ev); private: void step(); + void resizeToParent(); - ProgressIndicator::Size m_size; + ProgressIndicator::IndicatorSize m_size; int m_rotationStep; int m_rotation; QTimer m_timer;