1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 2006-2009 Licq developers
4  *
5  * Licq is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Licq is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Licq; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "config.h"
21 
22 #include "tabwidget.h"
23 
24 #ifdef USE_KDE
25 # include <QTabBar>
26 #else
27 # include <QWheelEvent>
28 #endif
29 
30 using namespace LicqQtGui;
31 
32 #ifndef USE_KDE
TabBar(QWidget * parent)33 TabBar::TabBar(QWidget* parent)
34   : QTabBar(parent)
35 {
36   // Empty
37 }
38 
setPreviousTab()39 void TabBar::setPreviousTab()
40 {
41   int index = currentIndex() - 1;
42   if (index < 0)
43     index = count() - 1;
44 
45   setCurrentIndex(index);
46 }
47 
setNextTab()48 void TabBar::setNextTab()
49 {
50   int index = currentIndex() + 1;
51   if (index >= count())
52     index = 0;
53 
54   setCurrentIndex(index);
55 }
56 
wheelEvent(QWheelEvent * e)57 void TabBar::wheelEvent(QWheelEvent* e)
58 {
59   if (count() <= 1 || !underMouse())
60   {
61     e->ignore();
62     return;
63   }
64 
65   if (e->delta() > 0)
66     setPreviousTab();
67   else
68     setNextTab();
69 
70   e->accept();
71 }
72 
mousePressEvent(QMouseEvent * e)73 void TabBar::mousePressEvent(QMouseEvent* e)
74 {
75   if ((e->button() & Qt::MouseButtonMask) == Qt::MidButton)
76     myClickedTab = tabAt(e->pos());
77 
78   QTabBar::mousePressEvent(e);
79 }
80 
mouseReleaseEvent(QMouseEvent * e)81 void TabBar::mouseReleaseEvent(QMouseEvent* e)
82 {
83   if ((e->button() & Qt::MouseButtonMask) == Qt::MidButton)
84   {
85     int t = tabAt(e->pos());
86     if (t > -1 && t == myClickedTab)
87       emit mouseMiddleClick(t);
88   }
89 
90   myClickedTab = -1;
91   QTabBar::mouseReleaseEvent(e);
92 }
93 #endif
94 
95 
TabWidget(QWidget * parent)96 TabWidget::TabWidget(QWidget* parent)
97   : TABWIDGET_BASE(parent)
98 {
99 #ifndef USE_KDE
100   TabBar* tb = new TabBar(this);
101   setTabBar(tb);
102   connect(tb, SIGNAL(mouseMiddleClick(int)), SLOT(slot_middleClick(int)));
103 #endif
104 }
105 
setTabColor(QWidget * tab,const QColor & color)106 void TabWidget::setTabColor(QWidget* tab, const QColor& color)
107 {
108   int index = indexOf(tab);
109   if (index != -1)
110 #ifdef USE_KDE
111     setTabTextColor(index, color);
112 #else
113     tabBar()->setTabTextColor(index, color);
114 #endif
115 }
116 
setPreviousPage()117 void TabWidget::setPreviousPage()
118 {
119   int index = tabBar()->currentIndex() - 1;
120   if (index < 0)
121     index = tabBar()->count() - 1;
122 
123   tabBar()->setCurrentIndex(index);
124 }
125 
setNextPage()126 void TabWidget::setNextPage()
127 {
128   int index = tabBar()->currentIndex() + 1;
129   if (index >= tabBar()->count())
130     index = 0;
131 
132   tabBar()->setCurrentIndex(index);
133 }
134 
135 #ifdef USE_KDE
restoreShortcuts()136 void TabWidget::restoreShortcuts()
137 {
138   // KTabWidget destroys any shortcuts so we have the following options:
139   // 1) Don't specify any shortcuts. This is bad since it means qt-gui won't
140   //    have any shortcuts.
141   // 2) Remove shortcuts from strings when compiling for kde. This will result
142   //    in different shortcuts for qt-gui and kde-gui.
143   // 3) Don't use KTabWidget. We want the rest of the function and look of kde
144   //    so using KTabWidget is preferred.
145   // 4) Restore our shortcuts every time KTabWidget has messed with them.
146   //    This is an ugly workaround but it'll work as a compromise.
147 
148   for (int i = 0; i < count(); ++i)
149     QTabWidget::setTabText(i, tabText(i).replace("&&", "&"));
150 }
151 
setTabText(int index,const QString & label)152 void TabWidget::setTabText(int index, const QString& label)
153 {
154   TABWIDGET_BASE::setTabText(index, label);
155   restoreShortcuts();
156 }
157 
resizeEvent(QResizeEvent * event)158 void TabWidget::resizeEvent(QResizeEvent* event)
159 {
160   TABWIDGET_BASE::resizeEvent(event);
161   restoreShortcuts();
162 }
163 #endif
164 
165 #ifndef USE_KDE
wheelEvent(QWheelEvent * e)166 void TabWidget::wheelEvent(QWheelEvent* e)
167 {
168   if (count() <= 1)
169   {
170     e->ignore();
171     return;
172   }
173 
174   const QTabBar* tabs = tabBar();
175   const bool cursorAboveTabBar = (e->y() < tabs->y());
176   const bool cursorBelowTabBar = (e->y() > (tabs->y() + tabs->height()));
177   if (cursorAboveTabBar || cursorBelowTabBar)
178   {
179     e->ignore();
180     return;
181   }
182 
183   if (e->delta() > 0)
184     setPreviousPage();
185   else
186     setNextPage();
187 
188   e->accept();
189 }
190 
slot_middleClick(int t)191 void TabWidget::slot_middleClick(int t)
192 {
193   QWidget* p = widget(t);
194   if (p)
195     emit mouseMiddleClick(p);
196 }
197 #endif
198