From 54ca39afec6c3a175da085a704772b28f42bc274 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Tue, 10 Jul 2012 15:57:36 +0400 Subject: [PATCH] Add the QTabBar::changeCurrentOnDrag property. This property indicates that the current tab will change whilst dragging over the tabbar [ChangeLog][QtWidgets][QTabBar] Added changeCurrentOnDrag property. Change-Id: Ib7d5a7613c9cd8432b84c523f66c02cd6c3c3c81 Reviewed-by: David Faure --- src/widgets/styles/qcommonstyle.cpp | 3 ++ src/widgets/styles/qstyle.cpp | 4 ++ src/widgets/styles/qstyle.h | 1 + src/widgets/widgets/qtabbar.cpp | 71 +++++++++++++++++++++++++++++ src/widgets/widgets/qtabbar.h | 5 ++ src/widgets/widgets/qtabbar_p.h | 9 +++- 6 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index d8b67edff8..cc24c79c09 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5109,6 +5109,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_TabBar_CloseButtonPosition: ret = QTabBar::RightSide; break; + case SH_TabBar_ChangeCurrentDelay: + ret = 500; + break; #endif case SH_DockWidget_ButtonsHaveFrame: ret = true; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 8774d71c0c..fb5a5c9003 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1930,6 +1930,10 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SH_Splitter_OpaqueResize Determines if resizing is opaque This enum value has been introduced in Qt 5.2 + \value SH_TabBar_ChangeCurrentDelay Determines the delay before the current + tab is changed while dragging over the tabbar, in milliseconds. This + enum value has been introduced in Qt 5.4 + \sa styleHint() */ diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index ea012faf46..87fd7656ea 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -704,6 +704,7 @@ public: SH_Splitter_OpaqueResize, SH_ComboBox_UseNativePopup, SH_LineEdit_PasswordMaskDelay, + SH_TabBar_ChangeCurrentDelay, // Add new style hint values here SH_CustomBase = 0xf0000000 diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index e8fdc65711..1d33a9bf3a 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -588,6 +588,16 @@ void QTabBarPrivate::makeVisible(int index) } } +void QTabBarPrivate::killSwitchTabTimer() +{ + Q_Q(QTabBar); + if (switchTabTimerId) { + q->killTimer(switchTabTimerId); + switchTabTimerId = 0; + } + switchTabCurrentIndex = -1; +} + void QTabBarPrivate::layoutTab(int index) { Q_Q(QTabBar); @@ -1527,6 +1537,26 @@ bool QTabBar::event(QEvent *event) } else if (event->type() == QEvent::Move) { d->updateMacBorderMetrics(); return QWidget::event(event); + +#ifndef QT_NO_DRAGANDDROP + } else if (event->type() == QEvent::DragEnter) { + if (d->changeCurrentOnDrag) + event->accept(); + } else if (event->type() == QEvent::DragMove) { + if (d->changeCurrentOnDrag) { + const int tabIndex = tabAt(static_cast(event)->pos()); + if (isTabEnabled(tabIndex) && d->switchTabCurrentIndex != tabIndex) { + d->switchTabCurrentIndex = tabIndex; + if (d->switchTabTimerId) + killTimer(d->switchTabTimerId); + d->switchTabTimerId = startTimer(style()->styleHint(QStyle::SH_TabBar_ChangeCurrentDelay)); + } + event->ignore(); + } + } else if (event->type() == QEvent::DragLeave || event->type() == QEvent::Drop) { + d->killSwitchTabTimer(); + event->ignore(); +#endif } return QWidget::event(event); } @@ -2044,6 +2074,21 @@ void QTabBar::changeEvent(QEvent *event) QWidget::changeEvent(event); } +/*! + \reimp +*/ +void QTabBar::timerEvent(QTimerEvent *event) +{ + Q_D(QTabBar); + if (event->timerId() == d->switchTabTimerId) { + killTimer(d->switchTabTimerId); + d->switchTabTimerId = 0; + setCurrentIndex(d->switchTabCurrentIndex); + d->switchTabCurrentIndex = -1; + } + QWidget::timerEvent(event); +} + /*! \property QTabBar::elideMode \brief how to elide text in the tab bar @@ -2306,6 +2351,32 @@ void QTabBar::setAutoHide(bool hide) setVisible(true); } +/*! + \property QTabBar::changeCurrentOnDrag + \brief If true, then the current tab is automatically changed when dragging + over the tabbar. + \since 5.4 + + \note You should also set acceptDrops property to true to make this feature + work. + + By default, this property is false. +*/ + +bool QTabBar::changeCurrentOnDrag() const +{ + Q_D(const QTabBar); + return d->changeCurrentOnDrag; +} + +void QTabBar::setChangeCurrentOnDrag(bool change) +{ + Q_D(QTabBar); + d->changeCurrentOnDrag = change; + if (!change) + d->killSwitchTabTimer(); +} + /*! Sets \a widget on the tab \a index. The widget is placed on the left or right hand side depending upon the \a position. diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h index a1616b1524..34c3d93114 100644 --- a/src/widgets/widgets/qtabbar.h +++ b/src/widgets/widgets/qtabbar.h @@ -71,6 +71,7 @@ class Q_WIDGETS_EXPORT QTabBar: public QWidget Q_PROPERTY(bool movable READ isMovable WRITE setMovable) Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode) Q_PROPERTY(bool autoHide READ autoHide WRITE setAutoHide) + Q_PROPERTY(bool changeCurrentOnDrag READ changeCurrentOnDrag WRITE setChangeCurrentOnDrag) public: explicit QTabBar(QWidget* parent=0); @@ -170,6 +171,9 @@ public: bool autoHide() const; void setAutoHide(bool hide); + bool changeCurrentOnDrag() const; + void setChangeCurrentOnDrag(bool change); + public Q_SLOTS: void setCurrentIndex(int index); @@ -200,6 +204,7 @@ protected: #endif void keyPressEvent(QKeyEvent *); void changeEvent(QEvent *); + void timerEvent(QTimerEvent *event); void initStyleOption(QStyleOptionTab *option, int tabIndex) const; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index 1238057e2a..bc6153dd34 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -77,7 +77,8 @@ public: :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), drawBase(true), scrollOffset(0), elideModeSetByUser(false), useScrollButtonsSetByUser(false), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), - dragInProgress(false), documentMode(false), autoHide(false), movingTab(0) + dragInProgress(false), documentMode(false), autoHide(false), changeCurrentOnDrag(false), + switchTabCurrentIndex(-1), switchTabTimerId(0), movingTab(0) #ifdef Q_WS_MAC , previousPressedIndex(-1) #endif @@ -203,6 +204,10 @@ public: bool dragInProgress; bool documentMode; bool autoHide; + bool changeCurrentOnDrag; + + int switchTabCurrentIndex; + int switchTabTimerId; QWidget *movingTab; #ifdef Q_WS_MAC @@ -242,6 +247,8 @@ public: } } + void killSwitchTabTimer(); + }; class CloseButton : public QAbstractButton