Hello all,

The attached patch makes it possible to switch between tabs in qt-gui's 
messageview using the mousewheel (the same way as in konqueror).

The patch implements the wheelEvent handler for the tab bar and for the tab 
widget. CETabBar::wheelEvent handles the case when the cursor is on top of 
one of the tabs and CETabWidget::wheelEvent handles the case when the cursor 
is on the empty space to the right (or left) of the tabs.

I've created two versions of the patch. The only difference between the two is 
that patch 2 moves the logic for switching tabs to the CETabBar instead of 
having the same code in three places (CETabBar, CETabWidget and 
UserEventTabDlg).

Best regards
// Erik

-- 
Oh, people can come up with statistics to prove anything. 
14% of people know that.
  -- Homer Simpson

Erik Johansson
http://ejohansson.se
Index: src/ewidgets.h
===================================================================
--- src/ewidgets.h	(revision 4386)
+++ src/ewidgets.h	(working copy)
@@ -106,6 +106,7 @@
   
 protected:
   virtual void paintLabel(QPainter *, const QRect &, QTab *, bool) const;
+  virtual void wheelEvent(QWheelEvent *e);
   
 private:
   QMap<int, QColor> mTabColors;
@@ -117,6 +118,9 @@
 public:
   CETabWidget(QWidget * = 0, const char * = 0, WFlags = 0);
   void setTabColor(QWidget *, const QColor &);
+
+protected:
+  virtual void wheelEvent(QWheelEvent *e);
 };
 
 /* ----------------------------------------------------------------------------- */
Index: src/ewidgets.cpp
===================================================================
--- src/ewidgets.cpp	(revision 4386)
+++ src/ewidgets.cpp	(working copy)
@@ -12,6 +12,7 @@
 #include <qtabwidget.h>
 #include <qtabbar.h>
 #include <qcursor.h>
+#include <qevent.h>
 #ifdef USE_KDE
 #include <kapp.h>
 #include <kmessagebox.h>
@@ -554,6 +555,24 @@
                       t->isEnabled() ? cg: palette().disabled(),
                       flags, QStyleOption(t));
 }
+
+void CETabBar::wheelEvent(QWheelEvent *e)
+{
+  if (count() <= 1) {
+    e->ignore();
+    return;
+  }
+
+  int tab = currentTab();
+  tab += (e->delta() < 0) ? 1 : -1;
+  if (tab < 0) {
+    tab = count() - 1;
+  }
+  else if (tab >= count()) {
+    tab = 0;
+  }
+  setCurrentTab(tab);
+}
          
 
 //CETabWidget
@@ -570,6 +589,32 @@
     static_cast<CETabBar *>(tabBar())->setTabColor(t->identifier(), color);
 }
 
+void CETabWidget::wheelEvent(QWheelEvent *e)
+{
+  if (count() <= 1) {
+    e->ignore();
+    return;
+  }
+
+  QTabBar *tabs = tabBar();
+  const bool cursorAboveTabBar = (e->y() < tabs->y());
+  const bool cursorBelowTabBar = (e->y() > (tabs->y() + tabs->height()));
+  if (cursorAboveTabBar || cursorBelowTabBar) {
+    e->ignore();
+    return;
+  }
+
+  int tab = currentPageIndex();
+  tab += (e->delta() < 0) ? 1 : -1;
+  if (tab < 0) {
+    tab = count() - 1;
+  }
+  else if (tab >= count()) {
+    tab = 0;
+  }
+  setCurrentPage(tab);
+}
+
 //-----CInfoField::constructor--------------------------------------------------
 CInfoField::CInfoField(QWidget *parent, bool readonly)
   : QLineEdit(parent)
Index: src/usereventdlg.cpp
===================================================================
--- src/usereventdlg.cpp	(revision 4386)
+++ src/usereventdlg.cpp	(working copy)
@@ -470,22 +470,14 @@
 void UserEventTabDlg::moveLeft()
 {
 #if QT_VERSION >= 300
-  int index = tabw->currentPageIndex();
-  if (index > 0)
-    tabw->setCurrentPage(index - 1);
-  else // leftmost tab is selected, rotate!
-    tabw->setCurrentPage(tabw->count() - 1);
+  tabw->setPreviousPage();
 #endif
 }
 
 void UserEventTabDlg::moveRight()
 {
 #if QT_VERSION >= 300
-  int index = tabw->currentPageIndex();
-  if (index < tabw->count() - 1)
-    tabw->setCurrentPage(index + 1);
-  else // rightmost tab is selected, rotate!
-    tabw->setCurrentPage(0);
+  tabw->setNextPage();
 #endif
 }
 
Index: src/ewidgets.h
===================================================================
--- src/ewidgets.h	(revision 4386)
+++ src/ewidgets.h	(working copy)
@@ -103,9 +103,13 @@
   const QColor &tabColor(int) const;
   void setTabColor(int, const QColor &);
   virtual void removeTab(QTab *);
+
+  void setPreviousTab();
+  void setNextTab();
   
 protected:
   virtual void paintLabel(QPainter *, const QRect &, QTab *, bool) const;
+  virtual void wheelEvent(QWheelEvent *e);
   
 private:
   QMap<int, QColor> mTabColors;
@@ -117,6 +121,12 @@
 public:
   CETabWidget(QWidget * = 0, const char * = 0, WFlags = 0);
   void setTabColor(QWidget *, const QColor &);
+
+  void setPreviousPage();
+  void setNextPage();
+
+protected:
+  virtual void wheelEvent(QWheelEvent *e);
 };
 
 /* ----------------------------------------------------------------------------- */
Index: src/ewidgets.cpp
===================================================================
--- src/ewidgets.cpp	(revision 4386)
+++ src/ewidgets.cpp	(working copy)
@@ -12,6 +12,7 @@
 #include <qtabwidget.h>
 #include <qtabbar.h>
 #include <qcursor.h>
+#include <qevent.h>
 #ifdef USE_KDE
 #include <kapp.h>
 #include <kmessagebox.h>
@@ -497,6 +498,24 @@
   QTabBar::removeTab(t);
 }
 
+void CETabBar::setPreviousTab()
+{
+  int tab = currentTab() - 1;
+  if (tab < 0) {
+    tab = count() - 1;
+  }
+  setCurrentTab(tab);
+}
+
+void CETabBar::setNextTab()
+{
+  int tab = currentTab() + 1;
+  if (tab >= count()) {
+    tab = 0;
+  }
+  setCurrentTab(tab);
+}
+
 void CETabBar::paintLabel(QPainter* p, const QRect &br,
                           QTab* t, bool has_focus) const
 {
@@ -554,6 +573,21 @@
                       t->isEnabled() ? cg: palette().disabled(),
                       flags, QStyleOption(t));
 }
+
+void CETabBar::wheelEvent(QWheelEvent *e)
+{
+  if (count() <= 1) {
+    e->ignore();
+    return;
+  }
+
+  if (e->delta() > 0) {
+    setPreviousTab();
+  }
+  else {
+    setNextTab();
+  }
+}
          
 
 //CETabWidget
@@ -570,6 +604,39 @@
     static_cast<CETabBar *>(tabBar())->setTabColor(t->identifier(), color);
 }
 
+void CETabWidget::setPreviousPage()
+{
+  static_cast<CETabBar *>(tabBar())->setPreviousTab();
+}
+
+void CETabWidget::setNextPage()
+{
+  static_cast<CETabBar *>(tabBar())->setNextTab();
+}
+
+void CETabWidget::wheelEvent(QWheelEvent *e)
+{
+  if (count() <= 1) {
+    e->ignore();
+    return;
+  }
+
+  QTabBar *tabs = tabBar();
+  const bool cursorAboveTabBar = (e->y() < tabs->y());
+  const bool cursorBelowTabBar = (e->y() > (tabs->y() + tabs->height()));
+  if (cursorAboveTabBar || cursorBelowTabBar) {
+    e->ignore();
+    return;
+  }
+
+  if (e->delta() > 0) {
+    setPreviousPage();
+  }
+  else {
+    setNextPage();
+  }
+}
+
 //-----CInfoField::constructor--------------------------------------------------
 CInfoField::CInfoField(QWidget *parent, bool readonly)
   : QLineEdit(parent)

Reply via email to