From 252bad7c589e03d3e12df02354b00a84d8e3159a Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Thu, 28 Jun 2012 21:04:54 +0400 Subject: Add useful signals to QTabBar and QTabWidget In this patch we introduce tabBarClicked and tabBarDoubleClicked to get a finer grained information on the user interaction with the tab bar. Done-with: kevin.ottens@kdab.com Change-Id: I7be76a556ca09186e98f2e076fe2512d6c5e6773 Reviewed-by: Frederik Gladhorn --- src/widgets/widgets/qtabbar.cpp | 46 ++++++++++++++++++++++ src/widgets/widgets/qtabbar.h | 3 ++ src/widgets/widgets/qtabwidget.cpp | 24 +++++++++++ src/widgets/widgets/qtabwidget.h | 2 + tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp | 42 ++++++++++++++++++++ .../widgets/widgets/qtabwidget/tst_qtabwidget.cpp | 42 ++++++++++++++++++++ 6 files changed, 159 insertions(+) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index b975035dcf..aa7677869c 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -329,6 +329,26 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const \sa moveTab() */ +/*! + \fn void QTabBar::tabBarClicked(int index) + + This signal is emitted when user clicks on a tab at an \a index. + + \a index is the index of a clicked tab, or -1 if no tab is under the cursor. + + \since 5.2 +*/ + +/*! + \fn void QTabBar::tabBarDoubleClicked(int index) + + This signal is emitted when the user double clicks on a tab at \a index. + + \a index refers to the tab clicked, or -1 if no tab is under the cursor. + + \since 5.2 +*/ + int QTabBarPrivate::extraWidth() const { Q_Q(const QTabBar); @@ -1703,11 +1723,37 @@ void QTabBarPrivate::moveTab(int index, int offset) q_func()->update(); } + +/*! + \reimp +*/ +void QTabBar::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_D(QTabBar); + + const QPoint pos = event->pos(); + const bool isEventInCornerButtons = (!d->leftB->isHidden() && d->leftB->geometry().contains(pos)) + || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos)); + if (!isEventInCornerButtons) { + const int index = tabAt(pos); + emit tabBarDoubleClicked(index); + } +} + /*!\reimp */ void QTabBar::mousePressEvent(QMouseEvent *event) { Q_D(QTabBar); + + const QPoint pos = event->pos(); + const bool isEventInCornerButtons = (!d->leftB->isHidden() && d->leftB->geometry().contains(pos)) + || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos)); + if (!isEventInCornerButtons) { + const int index = d->indexAtPos(pos); + emit tabBarClicked(index); + } + if (event->button() != Qt::LeftButton) { event->ignore(); return; diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h index 72c19ab520..1f7b8f6b03 100644 --- a/src/widgets/widgets/qtabbar.h +++ b/src/widgets/widgets/qtabbar.h @@ -173,6 +173,8 @@ Q_SIGNALS: void currentChanged(int index); void tabCloseRequested(int index); void tabMoved(int from, int to); + void tabBarClicked(int index); + void tabBarDoubleClicked(int index); protected: virtual QSize tabSizeHint(int index) const; @@ -186,6 +188,7 @@ protected: void showEvent(QShowEvent *); void hideEvent(QHideEvent *); void paintEvent(QPaintEvent *); + void mouseDoubleClickEvent(QMouseEvent *); void mousePressEvent (QMouseEvent *); void mouseMoveEvent (QMouseEvent *); void mouseReleaseEvent (QMouseEvent *); diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 4df55e2537..9d14c01490 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -172,6 +172,26 @@ QT_BEGIN_NAMESPACE \sa setTabsClosable() */ +/*! + \fn void QTabWidget::tabBarClicked(int index) + + This signal is emitted when user clicks on a tab at an \a index. + + \a index refers to the tab clicked, or -1 if no tab is under the cursor. + + \since 5.2 +*/ + +/*! + \fn void QTabWidget::tabBarDoubleClicked(int index) + + This signal is emitted when the user double clicks on a tab at an \a index. + + \a index is the index of a clicked tab, or -1 if no tab is under the cursor. + + \since 5.2 +*/ + class QTabWidgetPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QTabWidget) @@ -693,6 +713,10 @@ void QTabWidget::setTabBar(QTabBar* tb) this, SLOT(_q_showTab(int))); connect(d->tabs, SIGNAL(tabMoved(int,int)), this, SLOT(_q_tabMoved(int,int))); + connect(d->tabs, SIGNAL(tabBarClicked(int)), + this, SIGNAL(tabBarClicked(int))); + connect(d->tabs, SIGNAL(tabBarDoubleClicked(int)), + this, SIGNAL(tabBarDoubleClicked(int))); if (d->tabs->tabsClosable()) connect(d->tabs, SIGNAL(tabCloseRequested(int)), this, SIGNAL(tabCloseRequested(int))); diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h index 1a1eb2ef2b..83c2e31d28 100644 --- a/src/widgets/widgets/qtabwidget.h +++ b/src/widgets/widgets/qtabwidget.h @@ -151,6 +151,8 @@ public Q_SLOTS: Q_SIGNALS: void currentChanged(int index); void tabCloseRequested(int index); + void tabBarClicked(int index); + void tabBarDoubleClicked(int index); protected: virtual void tabInserted(int index); diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index a188e3bfe1..0dac7d85e4 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -97,6 +97,8 @@ private slots: void changeTitleWhileDoubleClickingTab(); void taskQTBUG_10052_widgetLayoutWhenMoving(); + + void tabBarClicked(); }; // Testing get/set functions @@ -652,5 +654,45 @@ void tst_QTabBar::taskQTBUG_10052_widgetLayoutWhenMoving() QVERIFY(w2.moved); } +void tst_QTabBar::tabBarClicked() +{ + QTabBar tabBar; + tabBar.addTab("0"); + QSignalSpy clickSpy(&tabBar, SIGNAL(tabBarClicked(int))); + QSignalSpy doubleClickSpy(&tabBar, SIGNAL(tabBarDoubleClicked(int))); + + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + Qt::MouseButton button = Qt::LeftButton; + while (button <= Qt::MaxMouseButton) { + const QPoint tabPos = tabBar.tabRect(0).center(); + + QTest::mouseClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0); + + const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y()); + + QTest::mouseClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1); + + button = Qt::MouseButton(button << 1); + } +} + QTEST_MAIN(tst_QTabBar) #include "tst_qtabbar.moc" diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index 5dd9ee9b0f..fa518e6afd 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -110,6 +111,7 @@ class tst_QTabWidget:public QObject { void minimumSizeHint(); void heightForWidth_data(); void heightForWidth(); + void tabBarClicked(); private: int addPage(); @@ -666,6 +668,46 @@ void tst_QTabWidget::heightForWidth() delete window; } +void tst_QTabWidget::tabBarClicked() +{ + QTabWidget tabWidget; + tabWidget.addTab(new QWidget(&tabWidget), "0"); + QSignalSpy clickSpy(&tabWidget, SIGNAL(tabBarClicked(int))); + QSignalSpy doubleClickSpy(&tabWidget, SIGNAL(tabBarDoubleClicked(int))); + + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + QTabBar &tabBar = *tabWidget.tabBar(); + Qt::MouseButton button = Qt::LeftButton; + while (button <= Qt::MaxMouseButton) { + const QPoint tabPos = tabBar.tabRect(0).center(); + + QTest::mouseClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0); + + const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y()); + + QTest::mouseClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1); + + button = Qt::MouseButton(button << 1); + } +} QTEST_MAIN(tst_QTabWidget) #include "tst_qtabwidget.moc" -- cgit v1.2.3