1
/****************************************************************************
3
** Implementation of QTabBar class.
5
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
7
** This file is part of the widgets module of the Qt Toolkit.
9
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12
****************************************************************************/
14
#include "qapplication.h"
21
#include "qstyleoption.h"
23
#include "qtabwidget.h"
24
#include "qtoolbutton.h"
26
#include "qstylepainter.h"
27
#include <private/qinternal_p.h>
28
#ifndef QT_NO_ACCESSIBILITY
29
#include "qaccessible.h"
33
#include "private/qwidget_p.h"
36
class QTabBarPrivate : public QWidgetPrivate
38
Q_DECLARE_PUBLIC(QTabBar)
41
:currentIndex(-1), pressedIndex(-1),
42
shape(QTabBar::RoundedNorth),
43
layoutDirty(false), drawBase(true), scrollOffset(0){}
53
inline Tab():enabled(true), shortcutId(0){}
54
inline Tab(const QIcon &ico, const QString &txt):enabled(true), shortcutId(0), text(txt), icon(ico){}
57
QString text, toolTip;
65
int extraWidth() const;
68
const Tab *at(int index) const;
70
int indexAtPos(const QPoint &p) const;
72
inline bool validIndex(int index) const { return index >= 0 && index < tabList.count(); }
74
QToolButton* rightB; // right or bottom
75
QToolButton* leftB; // left or top
76
void scrollTabs(); // private slot
82
void makeVisible(int index);
83
QStyleOptionTab getStyleOption(int tab) const;
87
QStyleOptionTab QTabBarPrivate::getStyleOption(int tab) const
91
const QTabBarPrivate::Tab *ptab = &tabList.at(tab);
93
opt.state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
94
opt.rect = q->tabRect(tab);
95
bool isCurrent = tab == currentIndex;
97
if (tab == pressedIndex)
98
opt.state |= QStyle::State_Sunken;
100
opt.state |= QStyle::State_Selected;
101
if (isCurrent && q->hasFocus())
102
opt.state |= QStyle::State_HasFocus;
103
if (q->isEnabled() && ptab->enabled)
104
opt.state |= QStyle::State_Enabled;
105
if (q->isActiveWindow())
106
opt.state |= QStyle::State_Active;
107
if (opt.rect == hoverRect)
108
opt.state |= QStyle::State_MouseOver;
110
opt.text = ptab->text;
111
opt.icon = ptab->icon;
113
int totalTabs = tabList.size();
115
if (tab > 0 && tab - 1 == currentIndex)
116
opt.selectedPosition = QStyleOptionTab::PreviousIsSelected;
117
else if (tab < totalTabs - 1 && tab + 1 == currentIndex)
118
opt.selectedPosition = QStyleOptionTab::NextIsSelected;
120
opt.selectedPosition = QStyleOptionTab::NotAdjacent;
124
opt.position = QStyleOptionTab::Beginning;
126
opt.position = QStyleOptionTab::OnlyOneTab;
127
} else if (tab == totalTabs - 1) {
128
opt.position = QStyleOptionTab::End;
130
opt.position = QStyleOptionTab::Middle;
132
if (const QTabWidget *tw = qobject_cast<const QTabWidget *>(q->parentWidget())) {
133
if (tw->cornerWidget(Qt::TopLeftCorner) || tw->cornerWidget(Qt::BottomLeftCorner))
134
opt.cornerWidgets |= QStyleOptionTab::LeftCornerWidget;
135
if (tw->cornerWidget(Qt::TopRightCorner) || tw->cornerWidget(Qt::BottomRightCorner))
136
opt.cornerWidgets |= QStyleOptionTab::RightCornerWidget;
143
\brief The QTabBar class provides a tab bar, e.g. for use in tabbed dialogs.
148
QTabBar is straightforward to use; it draws the tabs using one of
149
the predefined \link QTabBar::Shape shapes\endlink, and emits a
150
signal when a tab is selected. It can be subclassed to tailor the
151
look and feel. Qt also provides a ready-made \l{QTabWidget}.
153
Each tab has a tabText(), an optional tabIcon(), an optional
154
tabToolTip(), and optional tabData(). The tabs's attributes can be
155
changed with setTabText(), setTabIcon(), setTabToolTip(), and
156
setTabData(). Each tabs can be enabled or disabled individually
157
with setTabEnabled().
159
Tabs are added using addTab(), or inserted at particular positions
160
using insertTab(). The total number of tabs is given by
161
count(). Tabs can be removed from the tab bar with
162
removeTab(). Combining removeTab() and insertTab() allows you to
163
move tabs to different positions.
165
The \l shape property defines the tabs' appearance. The choice of
166
shape is a matter of taste, although tab dialogs (for preferences
167
and similar) invariably use \c RoundedNorth.
168
Tab controls in windows other than dialogs almost
169
always use either \c RoundedSouth or \c TriangularSouth. Many
170
spreadsheets and other tab controls in which all the pages are
171
essentially similar use \c TriangularSouth, whereas \c
172
RoundedSouth is used mostly when the pages are different (e.g. a
173
multi-page tool palette). The default in QTabBar is \c
176
The most important part of QTabBar's API is the currentChanged()
177
signal. This is emitted whenever the current tab changes (even at
178
startup, when the current tab changes from 'none'). There is also
179
a slot, setCurrentIndex(), which can be used to select a tab
180
programmatically. The function currentIndex() returns the index of
181
the current tab, \l count holds the number of tabs.
183
QTabBar creates automatic mnemonic keys in the manner of QAbstractButton;
184
e.g. if a tab's label is "\&Graphics", Alt+G becomes a shortcut
185
key for switching to that tab.
187
The following virtual functions may need to be reimplemented in
188
order to tailor the look and feel or store extra data with each
192
\i tabSizeHint() calcuates the size of a tab.
193
\i tabInserted() notifies that a new tab was added.
194
\i tabRemoved() notifies that a tab was removed.
195
\i tabLayoutChange() notifies that the tabs have been re-laid out.
196
\i paintEvent() paints all tabs.
199
For subclasses, you might also need the tabRect() functions which
200
returns the visual geometry of a single tab.
202
\inlineimage qtabbar-m.png Screenshot in Motif style
203
\inlineimage qtabbar-w.png Screenshot in Windows style
209
This enum type lists the built-in shapes supported by QTabBar. Treat these
210
as hints as some styles may not render some of the shapes. However,
211
position should be honored.
213
\value RoundedNorth The normal rounded look above the pages
215
\value RoundedSouth The normal rounded look below the pages
217
\value RoundedWest The normal rounded look on the left side of the pages
219
\value RoundedEast The normal rounded look on the right side the pages
221
\value TriangularNorth Triangular tabs above the pages.
223
\value TriangularSouth Triangular tabs similar to those used in
224
the Excel spreadsheet, for example
226
\value TriangularWest Triangular tabs on the left of the pages.
228
\value TriangularEast Triangular tabs on the right of the pages.
229
\omitvalue RoundedAbove
230
\omitvalue RoundedBelow
231
\omitvalue TriangularAbove
232
\omitvalue TriangularBelow
236
\fn void QTabBar::currentChanged(int index)
238
This signal is emitted when the tab bar's current tab changes. The
239
new current has the given \a index.
242
int QTabBarPrivate::extraWidth() const
245
return 2 * qMax(q->style()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, q),
246
QApplication::globalStrut().width());
249
void QTabBarPrivate::init()
252
leftB = new QToolButton(q);
253
QObject::connect(leftB, SIGNAL(clicked()), q, SLOT(scrollTabs()));
255
rightB = new QToolButton(q);
256
QObject::connect(rightB, SIGNAL(clicked()), q, SLOT(scrollTabs()));
258
q->setFocusPolicy(Qt::TabFocus);
259
q->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
262
QTabBarPrivate::Tab *QTabBarPrivate::at(int index)
264
return validIndex(index)?&tabList[index]:0;
267
const QTabBarPrivate::Tab *QTabBarPrivate::at(int index) const
269
return validIndex(index)?&tabList[index]:0;
272
int QTabBarPrivate::indexAtPos(const QPoint &p) const
275
if (q->tabRect(currentIndex).contains(p))
277
for (int i = 0; i < tabList.count(); ++i)
278
if (tabList.at(i).enabled && q->tabRect(i).contains(p))
283
inline static bool verticalTabs(QTabBar::Shape shape)
285
return shape == QTabBar::RoundedWest
286
|| shape == QTabBar::RoundedEast
287
|| shape == QTabBar::TriangularWest
288
|| shape == QTabBar::TriangularEast;
292
void QTabBarPrivate::layoutTabs()
297
QSize size = q->size();
299
bool vertTabs = verticalTabs(shape);
304
for (i = 0; i < tabList.count(); ++i) {
305
QSize sz = q->tabSizeHint(i);
306
tabList[i].rect = QRect(x, 0, sz.width(), sz.height());
307
maxHeight = qMax(maxHeight, sz.height());
311
// Go through the list again and make sure we have a consistent height
312
for (i = 0; i < tabList.count(); ++i)
313
tabList[i].rect.setHeight(maxHeight);
316
available = size.width();
321
for (i = 0; i < tabList.count(); ++i) {
322
QSize sz = q->tabSizeHint(i);
323
tabList[i].rect = QRect(0, y, sz.width(), sz.height());
324
maxWidth = qMax(0, sz.width());
329
for (i = 0; i < tabList.count(); ++i)
330
tabList[i].rect.setWidth(maxWidth);
333
available = size.height();
336
if (tabList.count() && last > available) {
337
int extra = extraWidth();
339
Qt::LayoutDirection ld = q->layoutDirection();
340
QRect arrows = QStyle::visualRect(ld, q->rect(),
341
QRect(available - extra, 0, extra, size.height()));
342
if (ld == Qt::LeftToRight) {
343
leftB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
344
rightB->setGeometry(arrows.right() - extra/2 + 1, arrows.top(),
345
extra/2, arrows.height());
346
leftB->setArrowType(Qt::LeftArrow);
347
rightB->setArrowType(Qt::RightArrow);
349
rightB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
350
leftB->setGeometry(arrows.right() - extra/2 + 1, arrows.top(),
351
extra/2, arrows.height());
352
rightB->setArrowType(Qt::LeftArrow);
353
leftB->setArrowType(Qt::RightArrow);
356
QRect arrows = QRect(0, available - extra, size.width(), extra );
357
leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra/2);
358
leftB->setArrowType(Qt::UpArrow);
359
rightB->setGeometry(arrows.left(), arrows.bottom() - extra/2 + 1,
360
arrows.width(), extra/2);
361
rightB->setArrowType(Qt::DownArrow);
363
leftB->setEnabled(scrollOffset > 0);
364
rightB->setEnabled(last - scrollOffset >= available - extra);
372
q->tabLayoutChange();
375
void QTabBarPrivate::makeVisible(int index)
378
if (!validIndex(index) || leftB->isHidden())
380
const QRect tabRect = tabList.at(index).rect;
382
const int oldScrollOffset = scrollOffset;
383
const bool horiz = !verticalTabs(shape);
384
const int available = (horiz ? q->width() : q->height()) - extraWidth();
385
const int start = horiz ? tabRect.left() : tabRect.top();
386
const int end = horiz ? tabRect.right() : tabRect.bottom();
387
if (start < scrollOffset) // too far left
388
scrollOffset = start - (index?8:0);
389
else if (end > scrollOffset + available) // too far right
390
scrollOffset = end - available + 1;
392
if (scrollOffset && end < available) // need scrolling at all?
395
leftB->setEnabled(scrollOffset > 0);
396
const int last = horiz ? tabList.last().rect.right() : tabList.last().rect.bottom();
397
rightB->setEnabled(last - scrollOffset >= available);
398
if (oldScrollOffset != scrollOffset)
403
void QTabBarPrivate::scrollTabs()
406
const QObject *sender = q->sender();
408
if (!verticalTabs(shape)) {
409
if (sender == leftB) {
410
for (i = tabList.count() - 1; i >= 0; --i) {
411
if (tabList.at(i).rect.left() - scrollOffset < 0) {
416
} else if (sender == rightB) {
417
int availableWidth = q->width() - extraWidth();
418
for (i = 0; i < tabList.count(); ++i) {
419
if (tabList.at(i).rect.right() - scrollOffset > availableWidth) {
426
if (sender == leftB) {
427
for (i = tabList.count() - 1; i >= 0; --i) {
428
if (tabList.at(i).rect.top() - scrollOffset < 0) {
433
} else if (sender == rightB) {
434
int available = q->height() - extraWidth();
435
for (i = 0; i < tabList.count(); ++i) {
436
if (tabList.at(i).rect.bottom() - scrollOffset > available) {
445
void QTabBarPrivate::refresh()
448
if (!q->isVisible()) {
458
Creates a new tab bar with the given \a parent.
460
QTabBar::QTabBar(QWidget* parent)
461
:QWidget(*new QTabBarPrivate, parent, 0)
469
Destroys the tab bar.
476
\property QTabBar::shape
477
\brief the shape of the tabs in the tab bar
479
The value of this property is one of the following: \c
480
RoundedNorth (default), \c RoundedSouth, \c TriangularNorth or \c
487
QTabBar::Shape QTabBar::shape() const
493
void QTabBar::setShape(Shape shape)
496
if (d->shape == shape)
504
\property QTabBar::drawBase
505
\brief defines whether or not tabbar should draw it's base.
507
If true then QTabBar draws a base in relation to the styles overlab.
508
Otherwise only the tabs are drawn.
510
\sa QStyle::pixelMetric() QStyle::PM_TabBarBaseOverlap
513
void QTabBar::setDrawBase(bool drawBase)
516
d->drawBase = drawBase;
519
bool QTabBar::drawBase() const
527
Adds a new tab with text \a text. Returns the new
530
int QTabBar::addTab(const QString &text)
532
return insertTab(-1, text);
538
Adds a new tab with icon \a icon and text \a
539
text. Returns the new tab's index.
541
int QTabBar::addTab(const QIcon& icon, const QString &text)
543
return insertTab(-1, icon, text);
547
Inserts a new tab with text \a text at position \a index. If \a
548
index is out of range, the new tab is appened. Returns the new
551
int QTabBar::insertTab(int index, const QString &text)
553
return insertTab(index, QIcon(), text);
558
Inserts a new tab with icon \a icon and text \a text at position
559
\a index. If \a index is out of range, the new tab is
560
appended. Returns the new tab's index.
562
int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
565
if (!d->validIndex(index)) {
566
index = d->tabList.count();
567
d->tabList.append(QTabBarPrivate::Tab(icon, text));
569
d->tabList.insert(index, QTabBarPrivate::Tab(icon, text));
571
d->tabList[index].shortcutId = grabShortcut(QKeySequence::mnemonic(text));
579
Removes the tab at position \a index.
581
void QTabBar::removeTab(int index)
584
if (d->validIndex(index)) {
585
releaseShortcut(d->tabList.at(index).shortcutId);
586
d->tabList.removeAt(index);
587
if (index == d->currentIndex)
588
setCurrentIndex(d->validIndex(index+1)?index+1:0);
596
Returns true if the tab at position \a index is enabled; otherwise
599
bool QTabBar::isTabEnabled(int index) const
602
if (const QTabBarPrivate::Tab *tab = d->at(index))
608
If \a enabled is true then the tab at position \a index is
609
enabled; otherwise the item at position \a index is disabled.
611
void QTabBar::setTabEnabled(int index, bool enabled)
614
if (QTabBarPrivate::Tab *tab = d->at(index)) {
615
tab->enabled = enabled;
617
if (!enabled && index == d->currentIndex)
618
setCurrentIndex(d->validIndex(index+1)?index+1:0);
619
else if (enabled && !d->validIndex(d->currentIndex))
620
setCurrentIndex(index);
626
Returns the text of the tab at position \a index, or an empty
627
string if \a index is out of range.
629
QString QTabBar::tabText(int index) const
632
if (const QTabBarPrivate::Tab *tab = d->at(index))
638
Sets the text of the tab at position \a index to \a text.
640
void QTabBar::setTabText(int index, const QString &text)
643
if (QTabBarPrivate::Tab *tab = d->at(index)) {
645
releaseShortcut(tab->shortcutId);
646
tab->shortcutId = grabShortcut(QKeySequence::mnemonic(text));
653
Returns the icon of the tab at position \a index, or a null icon
654
if \a index is out of range.
656
QIcon QTabBar::tabIcon(int index) const
659
if (const QTabBarPrivate::Tab *tab = d->at(index))
665
Sets the icon of the tab at position \a index to \a icon.
667
void QTabBar::setTabIcon(int index, const QIcon & icon)
670
if (QTabBarPrivate::Tab *tab = d->at(index)) {
678
Sets the tool tip of the tab at position \a index to \a tip.
680
void QTabBar::setTabToolTip(int index, const QString & tip)
683
if (QTabBarPrivate::Tab *tab = d->at(index))
688
Returns the tool tip of the tab at position \a index, or an empty
689
string if \a index is out of range.
691
QString QTabBar::tabToolTip(int index) const
694
if (const QTabBarPrivate::Tab *tab = d->at(index))
700
Sets the data of the tab at position \a index to \a data.
702
void QTabBar::setTabData(int index, const QVariant & data)
705
if (QTabBarPrivate::Tab *tab = d->at(index))
710
Returns the datad of the tab at position \a index, or a null
711
variant if \a index is out of range.
713
QVariant QTabBar::tabData(int index) const
716
if (const QTabBarPrivate::Tab *tab = d->at(index))
722
Returns the visual rectangle of the of the tab at position \a
723
index, or a null rectangle if \a index is out of range.
725
QRect QTabBar::tabRect(int index) const
728
if (const QTabBarPrivate::Tab *tab = d->at(index)) {
730
const_cast<QTabBarPrivate*>(d)->layoutTabs();
732
if (verticalTabs(d->shape))
733
r.translate(0, -d->scrollOffset);
735
r.translate(-d->scrollOffset, 0);
736
return QStyle::visualRect(layoutDirection(), rect(), r);
742
\property QTabBar::currentIndex
743
\brief the index of the tab bar's visible tab
746
int QTabBar::currentIndex() const
749
if (d->validIndex(d->currentIndex))
750
return d->currentIndex;
755
void QTabBar::setCurrentIndex(int index)
758
if (d->validIndex(index)) {
759
d->currentIndex = index;
761
d->makeVisible(index);
763
emit selected(index);
765
emit currentChanged(index);
771
\property QTabBar::count
772
\brief the number of tabs in the tab bar
775
int QTabBar::count() const
778
return d->tabList.count();
784
QSize QTabBar::sizeHint() const
788
const_cast<QTabBarPrivate*>(d)->layoutTabs();
790
for (int i = 0; i < d->tabList.count(); ++i)
791
r = r.unite(d->tabList.at(i).rect);
792
QSize sz = QApplication::globalStrut();
793
return r.size().expandedTo(sz);
798
QSize QTabBar::minimumSizeHint() const
801
if (style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this))
803
if (verticalTabs(d->shape))
804
return QSize(sizeHint().width(), d->rightB->sizeHint().height() * 2 + 75);
806
return QSize(d->rightB->sizeHint().width() * 2 + 75, sizeHint().height());
810
Returns the size hint for the tab at position \a index.
812
QSize QTabBar::tabSizeHint(int index) const
815
if (const QTabBarPrivate::Tab *tab = d->at(index)) {
816
QStyleOptionTab opt = d->getStyleOption(index);
817
int iconExtent = style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, this);
818
QSize iconSize = tab->icon.isNull() ? QSize() : QSize(iconExtent, iconExtent);
819
int hframe = style()->pixelMetric(QStyle::PM_TabBarTabHSpace, &opt, this);
820
int vframe = style()->pixelMetric(QStyle::PM_TabBarTabVSpace, &opt, this);
821
const QFontMetrics fm = fontMetrics();
822
QSize csz(fm.size(Qt::TextShowMnemonic, tab->text).width() + iconSize.width() + hframe,
823
qMax(fm.height(), iconSize.height()) + vframe);
824
if (verticalTabs(d->shape))
827
return style()->sizeFromContents(QStyle::CT_TabBarTab, &opt, csz, this);
833
This virtual handler is called after a new tab was added or
834
inserted at position \a index.
838
void QTabBar::tabInserted(int index)
844
This virtual handler is called after a tab was removed from
849
void QTabBar::tabRemoved(int index)
855
This virtual handler is called whenever the tab layout changes.
859
void QTabBar::tabLayoutChange()
866
void QTabBar::showEvent(QShowEvent *)
871
if (!d->validIndex(d->currentIndex))
879
bool QTabBar::event(QEvent *e)
882
if (e->type() == QEvent::HoverMove
883
|| e->type() == QEvent::HoverEnter) {
884
QHoverEvent *he = static_cast<QHoverEvent *>(e);
885
if (!d->hoverRect.contains(he->pos())) {
886
QRect oldHoverRect = d->hoverRect;
887
for (int i = 0; i < d->tabList.count(); ++i) {
888
QRect area = tabRect(i);
889
if (area.contains(he->pos())) {
894
if (he->oldPos() != QPoint(-1, -1))
895
update(oldHoverRect);
896
update(d->hoverRect);
898
} else if (e->type() == QEvent::HoverLeave ) {
899
QRect oldHoverRect = d->hoverRect;
900
d->hoverRect = QRect();
901
update(oldHoverRect);
902
} else if (e->type() == QEvent::ToolTip) {
903
if (const QTabBarPrivate::Tab *tab = d->at(d->indexAtPos(static_cast<QHelpEvent*>(e)->pos()))) {
904
if (!tab->toolTip.isEmpty()) {
905
QToolTip::showText(static_cast<QHelpEvent*>(e)->globalPos(), tab->toolTip, this);
909
} else if (e->type() == QEvent::Shortcut) {
910
QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
911
for (int i = 0; i < d->tabList.count(); ++i) {
912
const QTabBarPrivate::Tab *tab = &d->tabList.at(i);
913
if (tab->shortcutId == se->shortcutId()) {
919
return QWidget::event(e);
924
void QTabBar::resizeEvent(QResizeEvent *)
928
d->makeVisible(d->currentIndex);
933
void QTabBar::paintEvent(QPaintEvent *)
936
QStyleOptionTab tabOverlap;
937
tabOverlap.shape = d->shape;
938
int overlap = style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, &tabOverlap, this);
939
QWidget *theParent = parentWidget();
940
QStyleOptionTabBarBase optTabBase;
941
optTabBase.init(this);
942
optTabBase.shape = d->shape;
943
if (theParent && overlap > 0) {
944
QPainter::setRedirected(theParent, this, pos());
946
switch (tabOverlap.shape) {
947
case QTabBar::RoundedNorth:
948
case QTabBar::TriangularNorth:
949
rect.setRect(0, height()-overlap, width(), overlap);
951
case QTabBar::RoundedSouth:
952
case QTabBar::TriangularSouth:
953
rect.setRect(0, 0, width(), overlap);
955
case QTabBar::RoundedEast:
956
case QTabBar::TriangularEast:
957
rect.setRect(0, 0, overlap, height());
959
case QTabBar::RoundedWest:
960
case QTabBar::TriangularWest:
961
rect.setRect(width()-overlap, 0, overlap, height());
964
optTabBase.rect = rect;
966
QApplication::sendEvent(theParent, &e);
967
QPainter::restoreRedirected(theParent);
969
QStylePainter p(this);
972
bool rtl = optTabBase.direction == Qt::RightToLeft;
973
bool verticalTabs = (d->shape == QTabBar::RoundedWest || d->shape == QTabBar::RoundedEast
974
|| d->shape == QTabBar::TriangularWest
975
|| d->shape == QTabBar::TriangularEast);
976
QStyleOptionTab cutTab;
977
QStyleOptionTab selectedTab;
978
for (int i = 0; i < d->tabList.count(); ++i) {
979
QStyleOptionTab tab = d->getStyleOption(i);
980
// If this tab is partially obscured, make a note of it so that we can pass the information
981
// along when we draw the tear.
982
if ((!verticalTabs && (!rtl && tab.rect.left() < 0) || (rtl && tab.rect.right() > width()))
983
|| (verticalTabs && tab.rect.top() < 0)) {
987
// Don't bother drawing a tab if the entire tab is outside of the visible tab bar.
988
if ((!verticalTabs && (tab.rect.right() < 0 || tab.rect.left() > width()))
989
|| (verticalTabs && (tab.rect.bottom() < 0 || tab.rect.top() > height())))
992
optTabBase.tabBarRect |= tab.rect;
993
if (i == d->currentIndex) {
996
optTabBase.selectedTabRect = tab.rect;
999
p.drawControl(QStyle::CE_TabBarTab, tab);
1002
// Draw the selected tab last to get it "on top"
1003
if (selected >= 0) {
1004
QStyleOptionTab tab = d->getStyleOption(selected);
1005
p.drawControl(QStyle::CE_TabBarTab, tab);
1008
p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase);
1010
// Only draw the tear indicator if necessary. Most of the time we don't need too.
1011
if (d->leftB->isVisible() && cut >= 0) {
1012
cutTab.rect = rect();
1013
cutTab.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicator, &cutTab, this);
1014
p.drawPrimitive(QStyle::PE_IndicatorTabTear, cutTab);
1020
void QTabBar::mousePressEvent (QMouseEvent *e)
1023
if (e->button() != Qt::LeftButton) {
1027
d->pressedIndex = d->indexAtPos(e->pos());
1028
if (d->pressedIndex >= 0) {
1029
if (e->type() == style()->styleHint(QStyle::SH_TabBar_SelectMouseType, 0, this))
1030
setCurrentIndex(d->pressedIndex);
1032
repaint(tabRect(d->pressedIndex));
1038
void QTabBar::mouseMoveEvent (QMouseEvent *e)
1041
if (e->buttons() != Qt::LeftButton) {
1045
if (style()->styleHint(QStyle::SH_TabBar_SelectMouseType, 0, this)
1046
== QEvent::MouseButtonRelease) {
1047
int i = d->indexAtPos(e->pos());
1048
if (i != d->pressedIndex) {
1049
int oldIndex = d->pressedIndex;
1050
d->pressedIndex = -1;
1052
repaint(tabRect(oldIndex));
1053
if ((d->pressedIndex = i) >= 0)
1054
repaint(tabRect(i));
1061
void QTabBar::mouseReleaseEvent (QMouseEvent *e)
1064
if (e->button() != Qt::LeftButton)
1067
int i = d->indexAtPos(e->pos()) == d->pressedIndex ? d->pressedIndex : -1;
1068
d->pressedIndex = -1;
1069
if (e->type() == style()->styleHint(QStyle::SH_TabBar_SelectMouseType, 0, this))
1075
void QTabBar::keyPressEvent(QKeyEvent *e)
1078
if (e->key() != Qt::Key_Left && e->key() != Qt::Key_Right) {
1082
int dx = e->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
1083
for (int index = d->currentIndex + dx; d->validIndex(index); index += dx) {
1084
if (d->tabList.at(index).enabled) {
1085
setCurrentIndex(index);
1093
void QTabBar::changeEvent(QEvent *e)
1097
QWidget::changeEvent(e);
1102
\fn void QTabBar::setCurrentTab(int index)
1104
Use setCurrentIndex() instead.
1108
\fn void QTabBar::selected(int index);
1110
Use currentChanged() instead.
1114
#include "moc_qtabbar.cpp"