summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets/qtabbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets/qtabbar.cpp')
-rw-r--r--src/gui/widgets/qtabbar.cpp2376
1 files changed, 0 insertions, 2376 deletions
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
deleted file mode 100644
index c5d0892122..0000000000
--- a/src/gui/widgets/qtabbar.cpp
+++ /dev/null
@@ -1,2376 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qlayoutengine_p.h"
-#include "qabstractitemdelegate.h"
-#include "qapplication.h"
-#include "qbitmap.h"
-#include "qcursor.h"
-#include "qevent.h"
-#include "qpainter.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "qstylepainter.h"
-#include "qtabwidget.h"
-#include "qtooltip.h"
-#include "qwhatsthis.h"
-#include "private/qtextengine_p.h"
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-
-#include "qdebug.h"
-#include "private/qtabbar_p.h"
-
-#ifndef QT_NO_TABBAR
-
-#ifdef Q_WS_MAC
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-#ifndef QT_NO_STYLE_S60
-#include "qs60style.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-
-inline static bool verticalTabs(QTabBar::Shape shape)
-{
- return shape == QTabBar::RoundedWest
- || shape == QTabBar::RoundedEast
- || shape == QTabBar::TriangularWest
- || shape == QTabBar::TriangularEast;
-}
-
-void QTabBarPrivate::updateMacBorderMetrics()
-{
-#if (defined Q_WS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- Q_Q(QTabBar);
- ::HIContentBorderMetrics metrics;
-
- // TODO: get metrics to preserve the bottom value
- // TODO: test tab bar position
-
- OSWindowRef window = qt_mac_window_for(q);
-
- // push base line separator down to the client are so we can paint over it (Carbon)
- metrics.top = (documentMode && q->isVisible()) ? 1 : 0;
- metrics.bottom = 0;
- metrics.left = 0;
- metrics.right = 0;
- qt_mac_updateContentBorderMetricts(window, metrics);
-#if QT_MAC_USE_COCOA
- // In Cocoa we need to keep track of the drawRect method.
- // If documentMode is enabled we need to change it, unless
- // a toolbar is present.
- // Notice that all the information is kept in the window,
- // that's why we get the private widget for it instead of
- // the private widget for this widget.
- QWidgetPrivate *privateWidget = qt_widget_private(q->window());
- if(privateWidget)
- privateWidget->changeMethods = documentMode;
- // Since in Cocoa there is no simple way to remove the baseline, so we just ask the
- // top level to do the magic for us.
- privateWidget->syncUnifiedMode();
-#endif // QT_MAC_USE_COCOA
- }
-#endif
-}
-
-/*!
- Initialize \a option with the values from the tab at \a tabIndex. This method
- is useful for subclasses when they need a QStyleOptionTab, QStyleOptionTabV2,
- or QStyleOptionTabV3 but don't want to fill in all the information themselves.
- This function will check the version of the QStyleOptionTab and fill in the
- additional values for a QStyleOptionTabV2 and QStyleOptionTabV3.
-
- \sa QStyleOption::initFrom() QTabWidget::initStyleOption()
-*/
-void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
-{
- Q_D(const QTabBar);
- int totalTabs = d->tabList.size();
-
- if (!option || (tabIndex < 0 || tabIndex >= totalTabs))
- return;
-
- const QTabBarPrivate::Tab &tab = d->tabList.at(tabIndex);
- option->initFrom(this);
- option->state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
- option->rect = tabRect(tabIndex);
- bool isCurrent = tabIndex == d->currentIndex;
- option->row = 0;
- if (tabIndex == d->pressedIndex)
- option->state |= QStyle::State_Sunken;
- if (isCurrent)
- option->state |= QStyle::State_Selected;
- if (isCurrent && hasFocus())
- option->state |= QStyle::State_HasFocus;
- if (!tab.enabled)
- option->state &= ~QStyle::State_Enabled;
- if (isActiveWindow())
- option->state |= QStyle::State_Active;
- if (!d->dragInProgress && option->rect == d->hoverRect)
- option->state |= QStyle::State_MouseOver;
- option->shape = d->shape;
- option->text = tab.text;
-
- if (tab.textColor.isValid())
- option->palette.setColor(foregroundRole(), tab.textColor);
-
- option->icon = tab.icon;
- if (QStyleOptionTabV2 *optionV2 = qstyleoption_cast<QStyleOptionTabV2 *>(option))
- optionV2->iconSize = iconSize(); // Will get the default value then.
-
- if (QStyleOptionTabV3 *optionV3 = qstyleoption_cast<QStyleOptionTabV3 *>(option)) {
- optionV3->leftButtonSize = tab.leftWidget ? tab.leftWidget->size() : QSize();
- optionV3->rightButtonSize = tab.rightWidget ? tab.rightWidget->size() : QSize();
- optionV3->documentMode = d->documentMode;
- }
-
- if (tabIndex > 0 && tabIndex - 1 == d->currentIndex)
- option->selectedPosition = QStyleOptionTab::PreviousIsSelected;
- else if (tabIndex < totalTabs - 1 && tabIndex + 1 == d->currentIndex)
- option->selectedPosition = QStyleOptionTab::NextIsSelected;
- else
- option->selectedPosition = QStyleOptionTab::NotAdjacent;
-
- bool paintBeginning = (tabIndex == 0) || (d->dragInProgress && tabIndex == d->pressedIndex + 1);
- bool paintEnd = (tabIndex == totalTabs - 1) || (d->dragInProgress && tabIndex == d->pressedIndex - 1);
- if (paintBeginning) {
- if (paintEnd)
- option->position = QStyleOptionTab::OnlyOneTab;
- else
- option->position = QStyleOptionTab::Beginning;
- } else if (paintEnd) {
- option->position = QStyleOptionTab::End;
- } else {
- option->position = QStyleOptionTab::Middle;
- }
-
-#ifndef QT_NO_TABWIDGET
- if (const QTabWidget *tw = qobject_cast<const QTabWidget *>(parentWidget())) {
- if (tw->cornerWidget(Qt::TopLeftCorner) || tw->cornerWidget(Qt::BottomLeftCorner))
- option->cornerWidgets |= QStyleOptionTab::LeftCornerWidget;
- if (tw->cornerWidget(Qt::TopRightCorner) || tw->cornerWidget(Qt::BottomRightCorner))
- option->cornerWidgets |= QStyleOptionTab::RightCornerWidget;
- }
-#endif
-
- QRect textRect = style()->subElementRect(QStyle::SE_TabBarTabText, option, this);
- option->text = fontMetrics().elidedText(option->text, d->elideMode, textRect.width(),
- Qt::TextShowMnemonic);
-}
-
-/*!
- \class QTabBar
- \brief The QTabBar class provides a tab bar, e.g. for use in tabbed dialogs.
-
- \ingroup basicwidgets
-
-
- QTabBar is straightforward to use; it draws the tabs using one of
- the predefined \link QTabBar::Shape shapes\endlink, and emits a
- signal when a tab is selected. It can be subclassed to tailor the
- look and feel. Qt also provides a ready-made \l{QTabWidget}.
-
- Each tab has a tabText(), an optional tabIcon(), an optional
- tabToolTip(), optional tabWhatsThis() and optional tabData().
- The tabs's attributes can be changed with setTabText(), setTabIcon(),
- setTabToolTip(), setTabWhatsThis and setTabData(). Each tabs can be
- enabled or disabled individually with setTabEnabled().
-
- Each tab can display text in a distinct color. The current text color
- for a tab can be found with the tabTextColor() function. Set the text
- color for a particular tab with setTabTextColor().
-
- Tabs are added using addTab(), or inserted at particular positions
- using insertTab(). The total number of tabs is given by
- count(). Tabs can be removed from the tab bar with
- removeTab(). Combining removeTab() and insertTab() allows you to
- move tabs to different positions.
-
- The \l shape property defines the tabs' appearance. The choice of
- shape is a matter of taste, although tab dialogs (for preferences
- and similar) invariably use \l RoundedNorth.
- Tab controls in windows other than dialogs almost
- always use either \l RoundedSouth or \l TriangularSouth. Many
- spreadsheets and other tab controls in which all the pages are
- essentially similar use \l TriangularSouth, whereas \l
- RoundedSouth is used mostly when the pages are different (e.g. a
- multi-page tool palette). The default in QTabBar is \l
- RoundedNorth.
-
- The most important part of QTabBar's API is the currentChanged()
- signal. This is emitted whenever the current tab changes (even at
- startup, when the current tab changes from 'none'). There is also
- a slot, setCurrentIndex(), which can be used to select a tab
- programmatically. The function currentIndex() returns the index of
- the current tab, \l count holds the number of tabs.
-
- QTabBar creates automatic mnemonic keys in the manner of QAbstractButton;
- e.g. if a tab's label is "\&Graphics", Alt+G becomes a shortcut
- key for switching to that tab.
-
- The following virtual functions may need to be reimplemented in
- order to tailor the look and feel or store extra data with each
- tab:
-
- \list
- \i tabSizeHint() calcuates the size of a tab.
- \i tabInserted() notifies that a new tab was added.
- \i tabRemoved() notifies that a tab was removed.
- \i tabLayoutChange() notifies that the tabs have been re-laid out.
- \i paintEvent() paints all tabs.
- \endlist
-
- For subclasses, you might also need the tabRect() functions which
- returns the visual geometry of a single tab.
-
- \table 100%
- \row \o \inlineimage plastique-tabbar.png Screenshot of a Plastique style tab bar
- \o A tab bar shown in the Plastique widget style.
- \row \o \inlineimage plastique-tabbar-truncated.png Screenshot of a truncated Plastique tab bar
- \o A truncated tab bar shown in the Plastique widget style.
- \endtable
-
- \sa QTabWidget
-*/
-
-/*!
- \enum QTabBar::Shape
-
- This enum type lists the built-in shapes supported by QTabBar. Treat these
- as hints as some styles may not render some of the shapes. However,
- position should be honored.
-
- \value RoundedNorth The normal rounded look above the pages
-
- \value RoundedSouth The normal rounded look below the pages
-
- \value RoundedWest The normal rounded look on the left side of the pages
-
- \value RoundedEast The normal rounded look on the right side the pages
-
- \value TriangularNorth Triangular tabs above the pages.
-
- \value TriangularSouth Triangular tabs similar to those used in
- the Excel spreadsheet, for example
-
- \value TriangularWest Triangular tabs on the left of the pages.
-
- \value TriangularEast Triangular tabs on the right of the pages.
- \omitvalue RoundedAbove
- \omitvalue RoundedBelow
- \omitvalue TriangularAbove
- \omitvalue TriangularBelow
-*/
-
-/*!
- \fn void QTabBar::currentChanged(int index)
-
- This signal is emitted when the tab bar's current tab changes. The
- new current has the given \a index, or -1 if there isn't a new one
- (for example, if there are no tab in the QTabBar)
-*/
-
-/*!
- \fn void QTabBar::tabCloseRequested(int index)
- \since 4.5
-
- This signal is emitted when the close button on a tab is clicked.
- The \a index is the index that should be removed.
-
- \sa setTabsClosable()
-*/
-
-/*!
- \fn void QTabBar::tabMoved(int from, int to)
- \since 4.5
-
- This signal is emitted when the tab has moved the tab
- at index position \a from to index position \a to.
-
- note: QTabWidget will automatically move the page when
- this signal is emitted from its tab bar.
-
- \sa moveTab()
-*/
-
-int QTabBarPrivate::extraWidth() const
-{
- Q_Q(const QTabBar);
- return 2 * qMax(q->style()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, q),
- QApplication::globalStrut().width());
-}
-
-void QTabBarPrivate::init()
-{
- Q_Q(QTabBar);
- leftB = new QToolButton(q);
- leftB->setAutoRepeat(true);
- QObject::connect(leftB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs()));
- leftB->hide();
- rightB = new QToolButton(q);
- rightB->setAutoRepeat(true);
- QObject::connect(rightB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs()));
- rightB->hide();
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- leftB->setFocusPolicy(Qt::NoFocus);
- rightB->setFocusPolicy(Qt::NoFocus);
- q->setFocusPolicy(Qt::NoFocus);
- } else
-#endif
- q->setFocusPolicy(Qt::TabFocus);
- q->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
- elideMode = Qt::TextElideMode(q->style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, q));
- useScrollButtons = !q->style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, q);
-}
-
-QTabBarPrivate::Tab *QTabBarPrivate::at(int index)
-{
- return validIndex(index)?&tabList[index]:0;
-}
-
-const QTabBarPrivate::Tab *QTabBarPrivate::at(int index) const
-{
- return validIndex(index)?&tabList[index]:0;
-}
-
-int QTabBarPrivate::indexAtPos(const QPoint &p) const
-{
- Q_Q(const QTabBar);
- if (q->tabRect(currentIndex).contains(p))
- return currentIndex;
- for (int i = 0; i < tabList.count(); ++i)
- if (tabList.at(i).enabled && q->tabRect(i).contains(p))
- return i;
- return -1;
-}
-
-void QTabBarPrivate::layoutTabs()
-{
- Q_Q(QTabBar);
- scrollOffset = 0;
- layoutDirty = false;
- QSize size = q->size();
- int last, available;
- int maxExtent;
- int i;
- bool vertTabs = verticalTabs(shape);
- int tabChainIndex = 0;
-
- Qt::Alignment tabAlignment = Qt::Alignment(q->style()->styleHint(QStyle::SH_TabBar_Alignment, 0, q));
- QVector<QLayoutStruct> tabChain(tabList.count() + 2);
-
- // We put an empty item at the front and back and set its expansive attribute
- // depending on tabAlignment.
- tabChain[tabChainIndex].init();
- tabChain[tabChainIndex].expansive = (tabAlignment != Qt::AlignLeft)
- && (tabAlignment != Qt::AlignJustify);
- tabChain[tabChainIndex].empty = true;
- ++tabChainIndex;
-
- // We now go through our list of tabs and set the minimum size and the size hint
- // This will allow us to elide text if necessary. Since we don't set
- // a maximum size, tabs will EXPAND to fill up the empty space.
- // Since tab widget is rather *ahem* strict about keeping the geometry of the
- // tab bar to its absolute minimum, this won't bleed through, but will show up
- // if you use tab bar on its own (a.k.a. not a bug, but a feature).
- // Update: if expanding is false, we DO set a maximum size to prevent the tabs
- // being wider than necessary.
- if (!vertTabs) {
- int minx = 0;
- int x = 0;
- int maxHeight = 0;
- for (i = 0; i < tabList.count(); ++i, ++tabChainIndex) {
- QSize sz = q->tabSizeHint(i);
- tabList[i].maxRect = QRect(x, 0, sz.width(), sz.height());
- x += sz.width();
- maxHeight = qMax(maxHeight, sz.height());
- sz = minimumTabSizeHint(i);
- tabList[i].minRect = QRect(minx, 0, sz.width(), sz.height());
- minx += sz.width();
- tabChain[tabChainIndex].init();
- tabChain[tabChainIndex].sizeHint = tabList.at(i).maxRect.width();
- tabChain[tabChainIndex].minimumSize = sz.width();
- tabChain[tabChainIndex].empty = false;
- tabChain[tabChainIndex].expansive = true;
-
- if (!expanding)
- tabChain[tabChainIndex].maximumSize = tabChain[tabChainIndex].sizeHint;
- }
-
- last = minx;
- available = size.width();
- maxExtent = maxHeight;
- } else {
- int miny = 0;
- int y = 0;
- int maxWidth = 0;
- for (i = 0; i < tabList.count(); ++i, ++tabChainIndex) {
- QSize sz = q->tabSizeHint(i);
- tabList[i].maxRect = QRect(0, y, sz.width(), sz.height());
- y += sz.height();
- maxWidth = qMax(maxWidth, sz.width());
- sz = minimumTabSizeHint(i);
- tabList[i].minRect = QRect(0, miny, sz.width(), sz.height());
- miny += sz.height();
- tabChain[tabChainIndex].init();
- tabChain[tabChainIndex].sizeHint = tabList.at(i).maxRect.height();
- tabChain[tabChainIndex].minimumSize = sz.height();
- tabChain[tabChainIndex].empty = false;
- tabChain[tabChainIndex].expansive = true;
-
- if (!expanding)
- tabChain[tabChainIndex].maximumSize = tabChain[tabChainIndex].sizeHint;
- }
-
- last = miny;
- available = size.height();
- maxExtent = maxWidth;
- }
-
- Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure.
- // Mirror our front item.
- tabChain[tabChainIndex].init();
- tabChain[tabChainIndex].expansive = (tabAlignment != Qt::AlignRight)
- && (tabAlignment != Qt::AlignJustify);
- tabChain[tabChainIndex].empty = true;
-
- // Do the calculation
- qGeomCalc(tabChain, 0, tabChain.count(), 0, qMax(available, last), 0);
-
- // Use the results
- for (i = 0; i < tabList.count(); ++i) {
- const QLayoutStruct &lstruct = tabChain.at(i + 1);
- if (!vertTabs)
- tabList[i].rect.setRect(lstruct.pos, 0, lstruct.size, maxExtent);
- else
- tabList[i].rect.setRect(0, lstruct.pos, maxExtent, lstruct.size);
- }
-
- if (useScrollButtons && tabList.count() && last > available) {
- int extra = extraWidth();
-#ifndef QT_NO_STYLE_S60
- QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style());
-#endif
- if (!vertTabs) {
- Qt::LayoutDirection ld = q->layoutDirection();
- QRect arrows = QStyle::visualRect(ld, q->rect(),
- QRect(available - extra, 0, extra, size.height()));
- int buttonOverlap = q->style()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, q);
-
- if (ld == Qt::LeftToRight) {
-// In S60style, tab scroll buttons are layoutted separately, on the sides of the tabbar.
-#ifndef QT_NO_STYLE_S60
- if (s60Style) {
- rightB->setGeometry(arrows.left() + extra / 2, arrows.top(), extra / 2, arrows.height());
- leftB->setGeometry(0, arrows.top(), extra / 2, arrows.height());
- } else {
-#endif
- leftB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
- rightB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
- extra/2, arrows.height());
-#ifndef QT_NO_STYLE_S60
- }
-#endif
- leftB->setArrowType(Qt::LeftArrow);
- rightB->setArrowType(Qt::RightArrow);
- } else {
-#ifndef QT_NO_STYLE_S60
- if (s60Style) {
- rightB->setGeometry(arrows.left() + extra / 2, arrows.top(), extra / 2, arrows.height());
- leftB->setGeometry(0, arrows.top(), extra / 2, arrows.height());
- } else {
-#endif
- rightB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
- leftB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
- extra/2, arrows.height());
-#ifndef QT_NO_STYLE_S60
- }
-#endif
- rightB->setArrowType(Qt::LeftArrow);
- leftB->setArrowType(Qt::RightArrow);
- }
- } else {
-#ifndef QT_NO_STYLE_S60
- if (s60Style) {
- QRect arrows = QRect(0, 0, size.width(), available );
- leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra / 2);
- leftB->setArrowType(Qt::UpArrow);
- rightB->setGeometry(arrows.left(), arrows.bottom() - extra / 2 + 1,
- arrows.width(), extra / 2);
- rightB->setArrowType(Qt::DownArrow);
- } else {
-#endif
- QRect arrows = QRect(0, available - extra, size.width(), extra );
- leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra/2);
- leftB->setArrowType(Qt::UpArrow);
- rightB->setGeometry(arrows.left(), arrows.bottom() - extra/2 + 1,
- arrows.width(), extra/2);
- rightB->setArrowType(Qt::DownArrow);
-#ifndef QT_NO_STYLE_S60
- }
-#endif
- }
- leftB->setEnabled(scrollOffset > 0);
- rightB->setEnabled(last - scrollOffset >= available - extra);
- leftB->show();
- rightB->show();
- } else {
- rightB->hide();
- leftB->hide();
- }
-
- layoutWidgets();
- q->tabLayoutChange();
-}
-
-void QTabBarPrivate::makeVisible(int index)
-{
- Q_Q(QTabBar);
- if (!validIndex(index) || leftB->isHidden())
- return;
-
- const QRect tabRect = tabList.at(index).rect;
- const int oldScrollOffset = scrollOffset;
- const bool horiz = !verticalTabs(shape);
- const int available = (horiz ? q->width() : q->height()) - extraWidth();
- const int start = horiz ? tabRect.left() : tabRect.top();
- const int end = horiz ? tabRect.right() : tabRect.bottom();
- if (start < scrollOffset) // too far left
- scrollOffset = start - (index ? 8 : 0);
- else if (end > scrollOffset + available) // too far right
- scrollOffset = end - available + 1;
-
- leftB->setEnabled(scrollOffset > 0);
- const int last = horiz ? tabList.last().rect.right() : tabList.last().rect.bottom();
- rightB->setEnabled(last - scrollOffset >= available);
- if (oldScrollOffset != scrollOffset) {
- q->update();
- layoutWidgets();
- }
-}
-
-void QTabBarPrivate::layoutTab(int index)
-{
- Q_Q(QTabBar);
- Q_ASSERT(index >= 0);
-
- Tab &tab = tabList[index];
- bool vertical = verticalTabs(shape);
- if (!(tab.leftWidget || tab.rightWidget))
- return;
-
- QStyleOptionTabV3 opt;
- q->initStyleOption(&opt, index);
- if (tab.leftWidget) {
- QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabLeftButton, &opt, q);
- QPoint p = rect.topLeft();
- if ((index == pressedIndex) || paintWithOffsets) {
- if (vertical)
- p.setY(p.y() + tabList[index].dragOffset);
- else
- p.setX(p.x() + tabList[index].dragOffset);
- }
- tab.leftWidget->move(p);
- }
- if (tab.rightWidget) {
- QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabRightButton, &opt, q);
- QPoint p = rect.topLeft();
- if ((index == pressedIndex) || paintWithOffsets) {
- if (vertical)
- p.setY(p.y() + tab.dragOffset);
- else
- p.setX(p.x() + tab.dragOffset);
- }
- tab.rightWidget->move(p);
- }
-}
-
-void QTabBarPrivate::layoutWidgets(int start)
-{
- Q_Q(QTabBar);
- for (int i = start; i < q->count(); ++i) {
- layoutTab(i);
- }
-}
-
-void QTabBarPrivate::_q_closeTab()
-{
- Q_Q(QTabBar);
- QObject *object = q->sender();
- int tabToClose = -1;
- QTabBar::ButtonPosition closeSide = (QTabBar::ButtonPosition)q->style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, q);
- for (int i = 0; i < tabList.count(); ++i) {
- if (closeSide == QTabBar::LeftSide) {
- if (tabList.at(i).leftWidget == object) {
- tabToClose = i;
- break;
- }
- } else {
- if (tabList.at(i).rightWidget == object) {
- tabToClose = i;
- break;
- }
- }
- }
- if (tabToClose != -1)
- emit q->tabCloseRequested(tabToClose);
-}
-
-void QTabBarPrivate::_q_scrollTabs()
-{
- Q_Q(QTabBar);
- const QObject *sender = q->sender();
- int i = -1;
- if (!verticalTabs(shape)) {
- if (sender == leftB) {
- for (i = tabList.count() - 1; i >= 0; --i) {
- if (tabList.at(i).rect.left() - scrollOffset < 0) {
- makeVisible(i);
- return;
- }
- }
- } else if (sender == rightB) {
- int availableWidth = q->width() - extraWidth();
- for (i = 0; i < tabList.count(); ++i) {
- if (tabList.at(i).rect.right() - scrollOffset > availableWidth) {
- makeVisible(i);
- return;
- }
- }
- }
- } else { // vertical
- if (sender == leftB) {
- for (i = tabList.count() - 1; i >= 0; --i) {
- if (tabList.at(i).rect.top() - scrollOffset < 0) {
- makeVisible(i);
- return;
- }
- }
- } else if (sender == rightB) {
- int available = q->height() - extraWidth();
- for (i = 0; i < tabList.count(); ++i) {
- if (tabList.at(i).rect.bottom() - scrollOffset > available) {
- makeVisible(i);
- return;
- }
- }
- }
- }
-}
-
-void QTabBarPrivate::refresh()
-{
- Q_Q(QTabBar);
-
- // be safe in case a subclass is also handling move with the tabs
- if (pressedIndex != -1
- && movable
- && QApplication::mouseButtons() == Qt::NoButton) {
- moveTabFinished(pressedIndex);
- if (!validIndex(pressedIndex))
- pressedIndex = -1;
- }
-
- if (!q->isVisible()) {
- layoutDirty = true;
- } else {
- layoutTabs();
- makeVisible(currentIndex);
- q->update();
- q->updateGeometry();
- }
-}
-
-/*!
- Creates a new tab bar with the given \a parent.
-*/
-QTabBar::QTabBar(QWidget* parent)
- :QWidget(*new QTabBarPrivate, parent, 0)
-{
- Q_D(QTabBar);
- d->init();
-}
-
-
-/*!
- Destroys the tab bar.
-*/
-QTabBar::~QTabBar()
-{
-}
-
-/*!
- \property QTabBar::shape
- \brief the shape of the tabs in the tab bar
-
- Possible values for this property are described by the Shape enum.
-*/
-
-
-QTabBar::Shape QTabBar::shape() const
-{
- Q_D(const QTabBar);
- return d->shape;
-}
-
-void QTabBar::setShape(Shape shape)
-{
- Q_D(QTabBar);
- if (d->shape == shape)
- return;
- d->shape = shape;
- d->refresh();
-}
-
-/*!
- \property QTabBar::drawBase
- \brief defines whether or not tab bar should draw its base.
-
- If true then QTabBar draws a base in relation to the styles overlab.
- Otherwise only the tabs are drawn.
-
- \sa QStyle::pixelMetric() QStyle::PM_TabBarBaseOverlap QStyleOptionTabBarBaseV2
-*/
-
-void QTabBar::setDrawBase(bool drawBase)
-{
- Q_D(QTabBar);
- if (d->drawBase == drawBase)
- return;
- d->drawBase = drawBase;
- update();
-}
-
-bool QTabBar::drawBase() const
-{
- Q_D(const QTabBar);
- return d->drawBase;
-}
-
-/*!
- Adds a new tab with text \a text. Returns the new
- tab's index.
-*/
-int QTabBar::addTab(const QString &text)
-{
- return insertTab(-1, text);
-}
-
-/*!
- \overload
-
- Adds a new tab with icon \a icon and text \a
- text. Returns the new tab's index.
-*/
-int QTabBar::addTab(const QIcon& icon, const QString &text)
-{
- return insertTab(-1, icon, text);
-}
-
-/*!
- Inserts a new tab with text \a text at position \a index. If \a
- index is out of range, the new tab is appened. Returns the new
- tab's index.
-*/
-int QTabBar::insertTab(int index, const QString &text)
-{
- return insertTab(index, QIcon(), text);
-}
-
-/*!\overload
-
- Inserts a new tab with icon \a icon and text \a text at position
- \a index. If \a index is out of range, the new tab is
- appended. Returns the new tab's index.
-
- If the QTabBar was empty before this function is called, the inserted tab
- becomes the current tab.
-
- Inserting a new tab at an index less than or equal to the current index
- will increment the current index, but keep the current tab.
-*/
-int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
-{
- Q_D(QTabBar);
- if (!d->validIndex(index)) {
- index = d->tabList.count();
- d->tabList.append(QTabBarPrivate::Tab(icon, text));
- } else {
- d->tabList.insert(index, QTabBarPrivate::Tab(icon, text));
- }
-#ifndef QT_NO_SHORTCUT
- d->tabList[index].shortcutId = grabShortcut(QKeySequence::mnemonic(text));
-#endif
- d->refresh();
- if (d->tabList.count() == 1)
- setCurrentIndex(index);
- else if (index <= d->currentIndex)
- ++d->currentIndex;
-
- if (d->closeButtonOnTabs) {
- QStyleOptionTabV3 opt;
- initStyleOption(&opt, index);
- ButtonPosition closeSide = (ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this);
- QAbstractButton *closeButton = new CloseButton(this);
- connect(closeButton, SIGNAL(clicked()), this, SLOT(_q_closeTab()));
- setTabButton(index, closeSide, closeButton);
- }
-
- for (int i = 0; i < d->tabList.count(); ++i) {
- if (d->tabList[i].lastTab >= index)
- ++d->tabList[i].lastTab;
- }
-
- tabInserted(index);
- return index;
-}
-
-
-/*!
- Removes the tab at position \a index.
-
- \sa SelectionBehavior
- */
-void QTabBar::removeTab(int index)
-{
- Q_D(QTabBar);
- if (d->validIndex(index)) {
-#ifndef QT_NO_SHORTCUT
- releaseShortcut(d->tabList.at(index).shortcutId);
-#endif
- if (d->tabList[index].leftWidget) {
- d->tabList[index].leftWidget->hide();
- d->tabList[index].leftWidget->deleteLater();
- d->tabList[index].leftWidget = 0;
- }
- if (d->tabList[index].rightWidget) {
- d->tabList[index].rightWidget->hide();
- d->tabList[index].rightWidget->deleteLater();
- d->tabList[index].rightWidget = 0;
- }
-
- int newIndex = d->tabList[index].lastTab;
- d->tabList.removeAt(index);
- for (int i = 0; i < d->tabList.count(); ++i) {
- if (d->tabList[i].lastTab == index)
- d->tabList[i].lastTab = -1;
- if (d->tabList[i].lastTab > index)
- --d->tabList[i].lastTab;
- }
- if (index == d->currentIndex) {
- // The current tab is going away, in order to make sure
- // we emit that "current has changed", we need to reset this
- // around.
- d->currentIndex = -1;
- if (d->tabList.size() > 0) {
- switch(d->selectionBehaviorOnRemove) {
- case SelectPreviousTab:
- if (newIndex > index)
- newIndex--;
- if (d->validIndex(newIndex))
- break;
- // else fallthrough
- case SelectRightTab:
- newIndex = index;
- if (newIndex >= d->tabList.size())
- newIndex = d->tabList.size() - 1;
- break;
- case SelectLeftTab:
- newIndex = index - 1;
- if (newIndex < 0)
- newIndex = 0;
- break;
- default:
- break;
- }
-
- if (d->validIndex(newIndex)) {
- // don't loose newIndex's old through setCurrentIndex
- int bump = d->tabList[newIndex].lastTab;
- setCurrentIndex(newIndex);
- d->tabList[newIndex].lastTab = bump;
- }
- } else {
- emit currentChanged(-1);
- }
- } else if (index < d->currentIndex) {
- setCurrentIndex(d->currentIndex - 1);
- }
- d->refresh();
- tabRemoved(index);
- }
-}
-
-
-/*!
- Returns true if the tab at position \a index is enabled; otherwise
- returns false.
-*/
-bool QTabBar::isTabEnabled(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->enabled;
- return false;
-}
-
-/*!
- If \a enabled is true then the tab at position \a index is
- enabled; otherwise the item at position \a index is disabled.
-*/
-void QTabBar::setTabEnabled(int index, bool enabled)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index)) {
- tab->enabled = enabled;
-#ifndef QT_NO_SHORTCUT
- setShortcutEnabled(tab->shortcutId, enabled);
-#endif
- update();
- if (!enabled && index == d->currentIndex)
- setCurrentIndex(d->validIndex(index+1)?index+1:0);
- else if (enabled && !d->validIndex(d->currentIndex))
- setCurrentIndex(index);
- }
-}
-
-
-/*!
- Returns the text of the tab at position \a index, or an empty
- string if \a index is out of range.
-*/
-QString QTabBar::tabText(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->text;
- return QString();
-}
-
-/*!
- Sets the text of the tab at position \a index to \a text.
-*/
-void QTabBar::setTabText(int index, const QString &text)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index)) {
- tab->text = text;
-#ifndef QT_NO_SHORTCUT
- releaseShortcut(tab->shortcutId);
- tab->shortcutId = grabShortcut(QKeySequence::mnemonic(text));
- setShortcutEnabled(tab->shortcutId, tab->enabled);
-#endif
- d->refresh();
- }
-}
-
-/*!
- Returns the text color of the tab with the given \a index, or a invalid
- color if \a index is out of range.
-
- \sa setTabTextColor()
-*/
-QColor QTabBar::tabTextColor(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->textColor;
- return QColor();
-}
-
-/*!
- Sets the color of the text in the tab with the given \a index to the specified \a color.
-
- If an invalid color is specified, the tab will use the QTabBar foreground role instead.
-
- \sa tabTextColor()
-*/
-void QTabBar::setTabTextColor(int index, const QColor &color)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index)) {
- tab->textColor = color;
- update(tabRect(index));
- }
-}
-
-/*!
- Returns the icon of the tab at position \a index, or a null icon
- if \a index is out of range.
-*/
-QIcon QTabBar::tabIcon(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->icon;
- return QIcon();
-}
-
-/*!
- Sets the icon of the tab at position \a index to \a icon.
-*/
-void QTabBar::setTabIcon(int index, const QIcon & icon)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index)) {
- bool simpleIconChange = (!icon.isNull() && !tab->icon.isNull());
- tab->icon = icon;
- if (simpleIconChange)
- update(tabRect(index));
- else
- d->refresh();
- }
-}
-
-#ifndef QT_NO_TOOLTIP
-/*!
- Sets the tool tip of the tab at position \a index to \a tip.
-*/
-void QTabBar::setTabToolTip(int index, const QString & tip)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index))
- tab->toolTip = tip;
-}
-
-/*!
- Returns the tool tip of the tab at position \a index, or an empty
- string if \a index is out of range.
-*/
-QString QTabBar::tabToolTip(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->toolTip;
- return QString();
-}
-#endif // QT_NO_TOOLTIP
-
-#ifndef QT_NO_WHATSTHIS
-/*!
- \since 4.1
-
- Sets the What's This help text of the tab at position \a index
- to \a text.
-*/
-void QTabBar::setTabWhatsThis(int index, const QString &text)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index))
- tab->whatsThis = text;
-}
-
-/*!
- \since 4.1
-
- Returns the What's This help text of the tab at position \a index,
- or an empty string if \a index is out of range.
-*/
-QString QTabBar::tabWhatsThis(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->whatsThis;
- return QString();
-}
-
-#endif // QT_NO_WHATSTHIS
-
-/*!
- Sets the data of the tab at position \a index to \a data.
-*/
-void QTabBar::setTabData(int index, const QVariant & data)
-{
- Q_D(QTabBar);
- if (QTabBarPrivate::Tab *tab = d->at(index))
- tab->data = data;
-}
-
-/*!
- Returns the data of the tab at position \a index, or a null
- variant if \a index is out of range.
-*/
-QVariant QTabBar::tabData(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index))
- return tab->data;
- return QVariant();
-}
-
-/*!
- Returns the visual rectangle of the tab at position \a
- index, or a null rectangle if \a index is out of range.
-*/
-QRect QTabBar::tabRect(int index) const
-{
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index)) {
- if (d->layoutDirty)
- const_cast<QTabBarPrivate*>(d)->layoutTabs();
- QRect r = tab->rect;
- if (verticalTabs(d->shape))
- r.translate(0, -d->scrollOffset);
- else
- r.translate(-d->scrollOffset, 0);
- if (!verticalTabs(d->shape))
- r = QStyle::visualRect(layoutDirection(), rect(), r);
- return r;
- }
- return QRect();
-}
-
-/*!
- \since 4.3
- Returns the index of the tab that covers \a position or -1 if no
- tab covers \a position;
-*/
-
-int QTabBar::tabAt(const QPoint &position) const
-{
- Q_D(const QTabBar);
- if (d->validIndex(d->currentIndex)
- && tabRect(d->currentIndex).contains(position)) {
- return d->currentIndex;
- }
- const int max = d->tabList.size();
- for (int i = 0; i < max; ++i) {
- if (tabRect(i).contains(position)) {
- return i;
- }
- }
- return -1;
-}
-
-/*!
- \property QTabBar::currentIndex
- \brief the index of the tab bar's visible tab
-
- The current index is -1 if there is no current tab.
-*/
-
-int QTabBar::currentIndex() const
-{
- Q_D(const QTabBar);
- if (d->validIndex(d->currentIndex))
- return d->currentIndex;
- return -1;
-}
-
-
-void QTabBar::setCurrentIndex(int index)
-{
- Q_D(QTabBar);
- if (d->dragInProgress && d->pressedIndex != -1)
- return;
-
- int oldIndex = d->currentIndex;
- if (d->validIndex(index) && d->currentIndex != index) {
- d->currentIndex = index;
- update();
- d->makeVisible(index);
- d->tabList[index].lastTab = oldIndex;
- if (oldIndex >= 0 && oldIndex < count())
- d->layoutTab(oldIndex);
- d->layoutTab(index);
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- QAccessible::updateAccessibility(this, index + 1, QAccessible::Focus);
- QAccessible::updateAccessibility(this, index + 1, QAccessible::Selection);
- }
-#endif
-#ifdef QT3_SUPPORT
- emit selected(index);
-#endif
- emit currentChanged(index);
- }
-}
-
-/*!
- \property QTabBar::iconSize
- \brief The size for icons in the tab bar
- \since 4.1
-
- The default value is style-dependent. \c iconSize is a maximum
- size; icons that are smaller are not scaled up.
-
- \sa QTabWidget::iconSize
-*/
-QSize QTabBar::iconSize() const
-{
- Q_D(const QTabBar);
- if (d->iconSize.isValid())
- return d->iconSize;
- int iconExtent = style()->pixelMetric(QStyle::PM_TabBarIconSize, 0, this);
- return QSize(iconExtent, iconExtent);
-
-}
-
-void QTabBar::setIconSize(const QSize &size)
-{
- Q_D(QTabBar);
- d->iconSize = size;
- d->layoutDirty = true;
- update();
- updateGeometry();
-}
-
-/*!
- \property QTabBar::count
- \brief the number of tabs in the tab bar
-*/
-
-int QTabBar::count() const
-{
- Q_D(const QTabBar);
- return d->tabList.count();
-}
-
-
-/*!\reimp
- */
-QSize QTabBar::sizeHint() const
-{
- Q_D(const QTabBar);
- if (d->layoutDirty)
- const_cast<QTabBarPrivate*>(d)->layoutTabs();
- QRect r;
- for (int i = 0; i < d->tabList.count(); ++i)
- r = r.united(d->tabList.at(i).maxRect);
- QSize sz = QApplication::globalStrut();
- return r.size().expandedTo(sz);
-}
-
-/*!\reimp
- */
-QSize QTabBar::minimumSizeHint() const
-{
- Q_D(const QTabBar);
- if (d->layoutDirty)
- const_cast<QTabBarPrivate*>(d)->layoutTabs();
- if (!d->useScrollButtons) {
- QRect r;
- for (int i = 0; i < d->tabList.count(); ++i)
- r = r.united(d->tabList.at(i).minRect);
- return r.size().expandedTo(QApplication::globalStrut());
- }
- if (verticalTabs(d->shape))
- return QSize(sizeHint().width(), d->rightB->sizeHint().height() * 2 + 75);
- else
- return QSize(d->rightB->sizeHint().width() * 2 + 75, sizeHint().height());
-}
-
-// Compute the most-elided possible text, for minimumSizeHint
-static QString computeElidedText(Qt::TextElideMode mode, const QString &text)
-{
- if (text.length() <= 3)
- return text;
-
- static const QLatin1String Ellipses("...");
- QString ret;
- switch (mode) {
- case Qt::ElideRight:
- ret = text.left(2) + Ellipses;
- break;
- case Qt::ElideMiddle:
- ret = text.left(1) + Ellipses + text.right(1);
- break;
- case Qt::ElideLeft:
- ret = Ellipses + text.right(2);
- break;
- case Qt::ElideNone:
- ret = text;
- break;
- }
- return ret;
-}
-
-QSize QTabBarPrivate::minimumTabSizeHint(int index)
-{
- Q_Q(QTabBar);
- // ### Qt 5: make this a protected virtual function in QTabBar
- Tab &tab = tabList[index];
- QString oldText = tab.text;
- tab.text = computeElidedText(elideMode, oldText);
- QSize size = q->tabSizeHint(index);
- tab.text = oldText;
- return size;
-}
-
-/*!
- Returns the size hint for the tab at position \a index.
-*/
-QSize QTabBar::tabSizeHint(int index) const
-{
- //Note: this must match with the computations in QCommonStylePrivate::tabLayout
- Q_D(const QTabBar);
- if (const QTabBarPrivate::Tab *tab = d->at(index)) {
- QStyleOptionTabV3 opt;
- initStyleOption(&opt, index);
- opt.text = d->tabList.at(index).text;
- QSize iconSize = tab->icon.isNull() ? QSize(0, 0) : opt.iconSize;
- int hframe = style()->pixelMetric(QStyle::PM_TabBarTabHSpace, &opt, this);
- int vframe = style()->pixelMetric(QStyle::PM_TabBarTabVSpace, &opt, this);
- const QFontMetrics fm = fontMetrics();
-
- int maxWidgetHeight = qMax(opt.leftButtonSize.height(), opt.rightButtonSize.height());
- int maxWidgetWidth = qMax(opt.leftButtonSize.width(), opt.rightButtonSize.width());
-
- int widgetWidth = 0;
- int widgetHeight = 0;
- int padding = 0;
- if (!opt.leftButtonSize.isEmpty()) {
- padding += 4;
- widgetWidth += opt.leftButtonSize.width();
- widgetHeight += opt.leftButtonSize.height();
- }
- if (!opt.rightButtonSize.isEmpty()) {
- padding += 4;
- widgetWidth += opt.rightButtonSize.width();
- widgetHeight += opt.rightButtonSize.height();
- }
- if (!opt.icon.isNull())
- padding += 4;
-
- QSize csz;
- if (verticalTabs(d->shape)) {
- csz = QSize( qMax(maxWidgetWidth, qMax(fm.height(), iconSize.height())) + vframe,
- fm.size(Qt::TextShowMnemonic, tab->text).width() + iconSize.width() + hframe + widgetHeight + padding);
- } else {
- csz = QSize(fm.size(Qt::TextShowMnemonic, tab->text).width() + iconSize.width() + hframe
- + widgetWidth + padding,
- qMax(maxWidgetHeight, qMax(fm.height(), iconSize.height())) + vframe);
- }
-
- QSize retSize = style()->sizeFromContents(QStyle::CT_TabBarTab, &opt, csz, this);
- return retSize;
- }
- return QSize();
-}
-
-/*!
- This virtual handler is called after a new tab was added or
- inserted at position \a index.
-
- \sa tabRemoved()
- */
-void QTabBar::tabInserted(int index)
-{
- Q_UNUSED(index)
-}
-
-/*!
- This virtual handler is called after a tab was removed from
- position \a index.
-
- \sa tabInserted()
- */
-void QTabBar::tabRemoved(int index)
-{
- Q_UNUSED(index)
-}
-
-/*!
- This virtual handler is called whenever the tab layout changes.
-
- \sa tabRect()
- */
-void QTabBar::tabLayoutChange()
-{
-}
-
-
-/*!\reimp
- */
-void QTabBar::showEvent(QShowEvent *)
-{
- Q_D(QTabBar);
- if (d->layoutDirty)
- d->refresh();
- if (!d->validIndex(d->currentIndex))
- setCurrentIndex(0);
- d->updateMacBorderMetrics();
-}
-
-/*!\reimp
- */
-void QTabBar::hideEvent(QHideEvent *)
-{
- Q_D(QTabBar);
- d->updateMacBorderMetrics();
-}
-
-/*!\reimp
- */
-bool QTabBar::event(QEvent *event)
-{
- Q_D(QTabBar);
- if (event->type() == QEvent::HoverMove
- || event->type() == QEvent::HoverEnter) {
- QHoverEvent *he = static_cast<QHoverEvent *>(event);
- if (!d->hoverRect.contains(he->pos())) {
- QRect oldHoverRect = d->hoverRect;
- for (int i = 0; i < d->tabList.count(); ++i) {
- QRect area = tabRect(i);
- if (area.contains(he->pos())) {
- d->hoverRect = area;
- break;
- }
- }
- if (he->oldPos() != QPoint(-1, -1))
- update(oldHoverRect);
- update(d->hoverRect);
- }
- return true;
- } else if (event->type() == QEvent::HoverLeave ) {
- QRect oldHoverRect = d->hoverRect;
- d->hoverRect = QRect();
- update(oldHoverRect);
- return true;
-#ifndef QT_NO_TOOLTIP
- } else if (event->type() == QEvent::ToolTip) {
- if (const QTabBarPrivate::Tab *tab = d->at(tabAt(static_cast<QHelpEvent*>(event)->pos()))) {
- if (!tab->toolTip.isEmpty()) {
- QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), tab->toolTip, this);
- return true;
- }
- }
-#endif // QT_NO_TOOLTIP
-#ifndef QT_NO_WHATSTHIS
- } else if (event->type() == QEvent::QueryWhatsThis) {
- const QTabBarPrivate::Tab *tab = d->at(d->indexAtPos(static_cast<QHelpEvent*>(event)->pos()));
- if (!tab || tab->whatsThis.isEmpty())
- event->ignore();
- return true;
- } else if (event->type() == QEvent::WhatsThis) {
- if (const QTabBarPrivate::Tab *tab = d->at(d->indexAtPos(static_cast<QHelpEvent*>(event)->pos()))) {
- if (!tab->whatsThis.isEmpty()) {
- QWhatsThis::showText(static_cast<QHelpEvent*>(event)->globalPos(),
- tab->whatsThis, this);
- return true;
- }
- }
-#endif // QT_NO_WHATSTHIS
-#ifndef QT_NO_SHORTCUT
- } else if (event->type() == QEvent::Shortcut) {
- QShortcutEvent *se = static_cast<QShortcutEvent *>(event);
- for (int i = 0; i < d->tabList.count(); ++i) {
- const QTabBarPrivate::Tab *tab = &d->tabList.at(i);
- if (tab->shortcutId == se->shortcutId()) {
- setCurrentIndex(i);
- return true;
- }
- }
-#endif
- }
- return QWidget::event(event);
-}
-
-/*!\reimp
- */
-void QTabBar::resizeEvent(QResizeEvent *)
-{
- Q_D(QTabBar);
- if (d->layoutDirty)
- updateGeometry();
- d->layoutTabs();
-
- d->makeVisible(d->currentIndex);
-}
-
-/*!\reimp
- */
-void QTabBar::paintEvent(QPaintEvent *)
-{
- Q_D(QTabBar);
-
- QStyleOptionTabBarBaseV2 optTabBase;
- QTabBarPrivate::initStyleBaseOption(&optTabBase, this, size());
-
- QStylePainter p(this);
- int selected = -1;
- int cut = -1;
- bool rtl = optTabBase.direction == Qt::RightToLeft;
- bool vertical = verticalTabs(d->shape);
- QStyleOptionTab cutTab;
- selected = d->currentIndex;
- if (d->dragInProgress)
- selected = d->pressedIndex;
-
- for (int i = 0; i < d->tabList.count(); ++i)
- optTabBase.tabBarRect |= tabRect(i);
-
- optTabBase.selectedTabRect = tabRect(selected);
-
- if (d->drawBase)
- p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase);
-
- for (int i = 0; i < d->tabList.count(); ++i) {
- QStyleOptionTabV3 tab;
- initStyleOption(&tab, i);
- if (d->paintWithOffsets && d->tabList[i].dragOffset != 0) {
- if (vertical) {
- tab.rect.moveTop(tab.rect.y() + d->tabList[i].dragOffset);
- } else {
- tab.rect.moveLeft(tab.rect.x() + d->tabList[i].dragOffset);
- }
- }
- if (!(tab.state & QStyle::State_Enabled)) {
- tab.palette.setCurrentColorGroup(QPalette::Disabled);
- }
- // If this tab is partially obscured, make a note of it so that we can pass the information
- // along when we draw the tear.
- if (((!vertical && (!rtl && tab.rect.left() < 0)) || (rtl && tab.rect.right() > width()))
- || (vertical && tab.rect.top() < 0)) {
- cut = i;
- cutTab = tab;
- }
- // Don't bother drawing a tab if the entire tab is outside of the visible tab bar.
- if ((!vertical && (tab.rect.right() < 0 || tab.rect.left() > width()))
- || (vertical && (tab.rect.bottom() < 0 || tab.rect.top() > height())))
- continue;
-
- optTabBase.tabBarRect |= tab.rect;
- if (i == selected)
- continue;
-
- p.drawControl(QStyle::CE_TabBarTab, tab);
- }
-
- // Draw the selected tab last to get it "on top"
- if (selected >= 0) {
- QStyleOptionTabV3 tab;
- initStyleOption(&tab, selected);
- if (d->paintWithOffsets && d->tabList[selected].dragOffset != 0) {
- if (vertical)
- tab.rect.moveTop(tab.rect.y() + d->tabList[selected].dragOffset);
- else
- tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset);
- }
- if (!d->dragInProgress)
- p.drawControl(QStyle::CE_TabBarTab, tab);
- else {
- int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0, this);
- d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0));
- }
- }
-
- // Only draw the tear indicator if necessary. Most of the time we don't need too.
- if (d->leftB->isVisible() && cut >= 0) {
- cutTab.rect = rect();
- cutTab.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicator, &cutTab, this);
- p.drawPrimitive(QStyle::PE_IndicatorTabTear, cutTab);
- }
-}
-
-/*
- Given that index at position from moved to position to where return where index goes.
- */
-int QTabBarPrivate::calculateNewPosition(int from, int to, int index) const
-{
- if (index == from)
- return to;
-
- int start = qMin(from, to);
- int end = qMax(from, to);
- if (index >= start && index <= end)
- index += (from < to) ? -1 : 1;
- return index;
-}
-
-/*!
- Moves the item at index position \a from to index position \a to.
- \since 4.5
-
- \sa tabMoved(), tabLayoutChange()
- */
-void QTabBar::moveTab(int from, int to)
-{
- Q_D(QTabBar);
- if (from == to
- || !d->validIndex(from)
- || !d->validIndex(to))
- return;
-
- bool vertical = verticalTabs(d->shape);
- int oldPressedPosition = 0;
- if (d->pressedIndex != -1) {
- // Record the position of the pressed tab before reordering the tabs.
- oldPressedPosition = vertical ? d->tabList[d->pressedIndex].rect.y()
- : d->tabList[d->pressedIndex].rect.x();
- }
-
- // Update the locations of the tabs first
- int start = qMin(from, to);
- int end = qMax(from, to);
- int width = vertical ? d->tabList[from].rect.height() : d->tabList[from].rect.width();
- if (from < to)
- width *= -1;
- bool rtl = isRightToLeft();
- for (int i = start; i <= end; ++i) {
- if (i == from)
- continue;
- if (vertical)
- d->tabList[i].rect.moveTop(d->tabList[i].rect.y() + width);
- else
- d->tabList[i].rect.moveLeft(d->tabList[i].rect.x() + width);
- int direction = -1;
- if (rtl && !vertical)
- direction *= -1;
- if (d->tabList[i].dragOffset != 0)
- d->tabList[i].dragOffset += (direction * width);
- }
-
- if (vertical) {
- if (from < to)
- d->tabList[from].rect.moveTop(d->tabList[to].rect.bottom() + 1);
- else
- d->tabList[from].rect.moveTop(d->tabList[to].rect.top() - width);
- } else {
- if (from < to)
- d->tabList[from].rect.moveLeft(d->tabList[to].rect.right() + 1);
- else
- d->tabList[from].rect.moveLeft(d->tabList[to].rect.left() - width);
- }
-
- // Move the actual data structures
- d->tabList.move(from, to);
-
- // update lastTab locations
- for (int i = 0; i < d->tabList.count(); ++i)
- d->tabList[i].lastTab = d->calculateNewPosition(from, to, d->tabList[i].lastTab);
-
- // update external variables
- d->currentIndex = d->calculateNewPosition(from, to, d->currentIndex);
-
- // If we are in the middle of a drag update the dragStartPosition
- if (d->pressedIndex != -1) {
- d->pressedIndex = d->calculateNewPosition(from, to, d->pressedIndex);
- int newPressedPosition = vertical ? d->tabList[d->pressedIndex].rect.top() : d->tabList[d->pressedIndex].rect.left();
- int diff = oldPressedPosition - newPressedPosition;
- if (isRightToLeft() && !vertical)
- diff *= -1;
- if (vertical)
- d->dragStartPosition.setY(d->dragStartPosition.y() - diff);
- else
- d->dragStartPosition.setX(d->dragStartPosition.x() - diff);
- }
-
- d->layoutWidgets(start);
- update();
- emit tabMoved(from, to);
- emit tabLayoutChange();
-}
-
-void QTabBarPrivate::slide(int from, int to)
-{
- Q_Q(QTabBar);
- if (from == to
- || !validIndex(from)
- || !validIndex(to))
- return;
- bool vertical = verticalTabs(shape);
- int preLocation = vertical ? q->tabRect(from).y() : q->tabRect(from).x();
- q->setUpdatesEnabled(false);
- q->moveTab(from, to);
- q->setUpdatesEnabled(true);
- int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x();
- int length = postLocation - preLocation;
- tabList[to].dragOffset -= length;
- tabList[to].startAnimation(this, ANIMATION_DURATION);
-}
-
-void QTabBarPrivate::moveTab(int index, int offset)
-{
- if (!validIndex(index))
- return;
- tabList[index].dragOffset = offset;
- layoutTab(index); // Make buttons follow tab
- q_func()->update();
-}
-
-/*!\reimp
-*/
-void QTabBar::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QTabBar);
- if (event->button() != Qt::LeftButton) {
- event->ignore();
- return;
- }
- // Be safe!
- if (d->pressedIndex != -1 && d->movable)
- d->moveTabFinished(d->pressedIndex);
-
- d->pressedIndex = d->indexAtPos(event->pos());
-#ifdef Q_WS_MAC
- d->previousPressedIndex = d->pressedIndex;
-#endif
- if (d->validIndex(d->pressedIndex)) {
- QStyleOptionTabBarBaseV2 optTabBase;
- optTabBase.init(this);
- optTabBase.documentMode = d->documentMode;
- if (event->type() == style()->styleHint(QStyle::SH_TabBar_SelectMouseType, &optTabBase, this))
- setCurrentIndex(d->pressedIndex);
- else
- repaint(tabRect(d->pressedIndex));
- if (d->movable) {
- d->dragStartPosition = event->pos();
- }
- }
-}
-
-/*!\reimp
- */
-void QTabBar::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QTabBar);
- if (d->movable) {
- // Be safe!
- if (d->pressedIndex != -1
- && event->buttons() == Qt::NoButton)
- d->moveTabFinished(d->pressedIndex);
-
- // Start drag
- if (!d->dragInProgress && d->pressedIndex != -1) {
- if ((event->pos() - d->dragStartPosition).manhattanLength() > QApplication::startDragDistance()) {
- d->dragInProgress = true;
- d->setupMovableTab();
- }
- }
-
- int offset = (event->pos() - d->dragStartPosition).manhattanLength();
- if (event->buttons() == Qt::LeftButton
- && offset > QApplication::startDragDistance()
- && d->validIndex(d->pressedIndex)) {
- bool vertical = verticalTabs(d->shape);
- int dragDistance;
- if (vertical) {
- dragDistance = (event->pos().y() - d->dragStartPosition.y());
- } else {
- dragDistance = (event->pos().x() - d->dragStartPosition.x());
- }
- d->tabList[d->pressedIndex].dragOffset = dragDistance;
-
- QRect startingRect = tabRect(d->pressedIndex);
- if (vertical)
- startingRect.moveTop(startingRect.y() + dragDistance);
- else
- startingRect.moveLeft(startingRect.x() + dragDistance);
-
- int overIndex;
- if (dragDistance < 0)
- overIndex = tabAt(startingRect.topLeft());
- else
- overIndex = tabAt(startingRect.topRight());
-
- if (overIndex != d->pressedIndex && overIndex != -1) {
- int offset = 1;
- if (isRightToLeft() && !vertical)
- offset *= -1;
- if (dragDistance < 0) {
- dragDistance *= -1;
- offset *= -1;
- }
- for (int i = d->pressedIndex;
- offset > 0 ? i < overIndex : i > overIndex;
- i += offset) {
- QRect overIndexRect = tabRect(overIndex);
- int needsToBeOver = (vertical ? overIndexRect.height() : overIndexRect.width()) / 2;
- if (dragDistance > needsToBeOver)
- d->slide(i + offset, d->pressedIndex);
- }
- }
- // Buttons needs to follow the dragged tab
- d->layoutTab(d->pressedIndex);
-
- update();
- }
-#ifdef Q_WS_MAC
- } else if (!d->documentMode && event->buttons() == Qt::LeftButton && d->previousPressedIndex != -1) {
- int newPressedIndex = d->indexAtPos(event->pos());
- if (d->pressedIndex == -1 && d->previousPressedIndex == newPressedIndex) {
- d->pressedIndex = d->previousPressedIndex;
- update(tabRect(d->pressedIndex));
- } else if(d->pressedIndex != newPressedIndex) {
- d->pressedIndex = -1;
- update(tabRect(d->previousPressedIndex));
- }
-#endif
- }
-
- if (event->buttons() != Qt::LeftButton) {
- event->ignore();
- return;
- }
- QStyleOptionTabBarBaseV2 optTabBase;
- optTabBase.init(this);
- optTabBase.documentMode = d->documentMode;
-}
-
-void QTabBarPrivate::setupMovableTab()
-{
- Q_Q(QTabBar);
- if (!movingTab)
- movingTab = new QWidget(q);
-
- int taboverlap = q->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 ,q);
- QRect grabRect = q->tabRect(pressedIndex);
- grabRect.adjust(-taboverlap, 0, taboverlap, 0);
-
- QPixmap grabImage(grabRect.size());
- grabImage.fill(Qt::transparent);
- QStylePainter p(&grabImage, q);
- p.initFrom(q);
-
- QStyleOptionTabV3 tab;
- q->initStyleOption(&tab, pressedIndex);
- tab.rect.moveTopLeft(QPoint(taboverlap, 0));
- p.drawControl(QStyle::CE_TabBarTab, tab);
- p.end();
-
- QPalette pal;
- pal.setBrush(QPalette::All, QPalette::Window, grabImage);
- movingTab->setPalette(pal);
- movingTab->setGeometry(grabRect);
- movingTab->setAutoFillBackground(true);
- movingTab->raise();
-
- // Re-arrange widget order to avoid overlaps
- if (tabList[pressedIndex].leftWidget)
- tabList[pressedIndex].leftWidget->raise();
- if (tabList[pressedIndex].rightWidget)
- tabList[pressedIndex].rightWidget->raise();
- if (leftB)
- leftB->raise();
- if (rightB)
- rightB->raise();
- movingTab->setVisible(true);
-}
-
-void QTabBarPrivate::moveTabFinished(int index)
-{
- Q_Q(QTabBar);
- bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index);
- bool allAnimationsFinished = true;
-#ifndef QT_NO_ANIMATION
- for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) {
- const Tab &t = tabList.at(i);
- if (t.animation && t.animation->state() == QAbstractAnimation::Running)
- allAnimationsFinished = false;
- }
-#endif //QT_NO_ANIMATION
- if (allAnimationsFinished && cleanup) {
- if(movingTab)
- movingTab->setVisible(false); // We might not get a mouse release
- for (int i = 0; i < tabList.count(); ++i) {
- tabList[i].dragOffset = 0;
- }
- if (pressedIndex != -1 && movable) {
- pressedIndex = -1;
- dragInProgress = false;
- dragStartPosition = QPoint();
- }
- layoutWidgets();
- } else {
- if (!validIndex(index))
- return;
- tabList[index].dragOffset = 0;
- }
- q->update();
-}
-
-/*!\reimp
-*/
-void QTabBar::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QTabBar);
- if (event->button() != Qt::LeftButton) {
- event->ignore();
- return;
- }
-#ifdef Q_WS_MAC
- d->previousPressedIndex = -1;
-#endif
- if (d->movable && d->dragInProgress && d->validIndex(d->pressedIndex)) {
- int length = d->tabList[d->pressedIndex].dragOffset;
- int width = verticalTabs(d->shape)
- ? tabRect(d->pressedIndex).height()
- : tabRect(d->pressedIndex).width();
- int duration = qMin(ANIMATION_DURATION,
- (qAbs(length) * ANIMATION_DURATION) / width);
- d->tabList[d->pressedIndex].startAnimation(d, duration);
- d->dragInProgress = false;
- d->movingTab->setVisible(false);
- d->dragStartPosition = QPoint();
- }
-
- int i = d->indexAtPos(event->pos()) == d->pressedIndex ? d->pressedIndex : -1;
- d->pressedIndex = -1;
- QStyleOptionTabBarBaseV2 optTabBase;
- optTabBase.initFrom(this);
- optTabBase.documentMode = d->documentMode;
- if (style()->styleHint(QStyle::SH_TabBar_SelectMouseType, &optTabBase, this) == QEvent::MouseButtonRelease)
- setCurrentIndex(i);
-}
-
-/*!\reimp
- */
-void QTabBar::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QTabBar);
- if (event->key() != Qt::Key_Left && event->key() != Qt::Key_Right) {
- event->ignore();
- return;
- }
- int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
- d->setCurrentNextEnabledIndex(offset);
-}
-
-/*!\reimp
- */
-#ifndef QT_NO_WHEELEVENT
-void QTabBar::wheelEvent(QWheelEvent *event)
-{
- Q_D(QTabBar);
- int offset = event->delta() > 0 ? -1 : 1;
- d->setCurrentNextEnabledIndex(offset);
- QWidget::wheelEvent(event);
-}
-#endif //QT_NO_WHEELEVENT
-
-void QTabBarPrivate::setCurrentNextEnabledIndex(int offset)
-{
- Q_Q(QTabBar);
- for (int index = currentIndex + offset; validIndex(index); index += offset) {
- if (tabList.at(index).enabled) {
- q->setCurrentIndex(index);
- break;
- }
- }
-}
-
-/*!\reimp
- */
-void QTabBar::changeEvent(QEvent *event)
-{
- Q_D(QTabBar);
- if (event->type() == QEvent::StyleChange) {
- if (!d->elideModeSetByUser)
- d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this));
- if (!d->useScrollButtonsSetByUser)
- d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this);
- d->refresh();
- } else if (event->type() == QEvent::FontChange) {
- d->refresh();
- }
- QWidget::changeEvent(event);
-}
-
-/*!
- \property QTabBar::elideMode
- \brief how to elide text in the tab bar
- \since 4.2
-
- This property controls how items are elided when there is not
- enough space to show them for a given tab bar size.
-
- By default the value is style dependent.
-
- \sa QTabWidget::elideMode usesScrollButtons QStyle::SH_TabBar_ElideMode
-*/
-
-Qt::TextElideMode QTabBar::elideMode() const
-{
- Q_D(const QTabBar);
- return d->elideMode;
-}
-
-void QTabBar::setElideMode(Qt::TextElideMode mode)
-{
- Q_D(QTabBar);
- d->elideMode = mode;
- d->elideModeSetByUser = true;
- d->refresh();
-}
-
-/*!
- \property QTabBar::usesScrollButtons
- \brief Whether or not a tab bar should use buttons to scroll tabs when it
- has many tabs.
- \since 4.2
-
- When there are too many tabs in a tab bar for its size, the tab bar can either choose
- to expand its size or to add buttons that allow you to scroll through the tabs.
-
- By default the value is style dependant.
-
- \sa elideMode QTabWidget::usesScrollButtons QStyle::SH_TabBar_PreferNoArrows
-*/
-bool QTabBar::usesScrollButtons() const
-{
- return d_func()->useScrollButtons;
-}
-
-void QTabBar::setUsesScrollButtons(bool useButtons)
-{
- Q_D(QTabBar);
- d->useScrollButtonsSetByUser = true;
- if (d->useScrollButtons == useButtons)
- return;
- d->useScrollButtons = useButtons;
- d->refresh();
-}
-
-/*!
- \fn void QTabBar::setCurrentTab(int index)
-
- Use setCurrentIndex() instead.
-*/
-
-/*!
- \fn void QTabBar::selected(int index);
-
- Use currentChanged() instead.
-*/
-
-
-/*!
- \property QTabBar::tabsClosable
- \brief Whether or not a tab bar should place close buttons on each tab
- \since 4.5
-
- When tabsClosable is set to true a close button will appear on the tab on
- either the left or right hand side depending upon the style. When the button
- is clicked the tab the signal tabCloseRequested will be emitted.
-
- By default the value is false.
-
- \sa setTabButton(), tabRemoved()
-*/
-
-bool QTabBar::tabsClosable() const
-{
- Q_D(const QTabBar);
- return d->closeButtonOnTabs;
-}
-
-void QTabBar::setTabsClosable(bool closable)
-{
- Q_D(QTabBar);
- if (d->closeButtonOnTabs == closable)
- return;
- d->closeButtonOnTabs = closable;
- ButtonPosition closeSide = (ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this);
- if (!closable) {
- for (int i = 0; i < d->tabList.count(); ++i) {
- if (closeSide == LeftSide && d->tabList[i].leftWidget) {
- d->tabList[i].leftWidget->deleteLater();
- d->tabList[i].leftWidget = 0;
- }
- if (closeSide == RightSide && d->tabList[i].rightWidget) {
- d->tabList[i].rightWidget->deleteLater();
- d->tabList[i].rightWidget = 0;
- }
- }
- } else {
- bool newButtons = false;
- for (int i = 0; i < d->tabList.count(); ++i) {
- if (tabButton(i, closeSide))
- continue;
- newButtons = true;
- QAbstractButton *closeButton = new CloseButton(this);
- connect(closeButton, SIGNAL(clicked()), this, SLOT(_q_closeTab()));
- setTabButton(i, closeSide, closeButton);
- }
- if (newButtons)
- d->layoutTabs();
- }
- update();
-}
-
-/*!
- \enum QTabBar::ButtonPosition
- \since 4.5
-
- This enum type lists the location of the widget on a tab.
-
- \value LeftSide Left side of the tab.
-
- \value RightSide Right side of the tab.
-
-*/
-
-/*!
- \enum QTabBar::SelectionBehavior
- \since 4.5
-
- This enum type lists the behavior of QTabBar when a tab is removed
- and the tab being removed is also the current tab.
-
- \value SelectLeftTab Select the tab to the left of the one being removed.
-
- \value SelectRightTab Select the tab to the right of the one being removed.
-
- \value SelectPreviousTab Select the previously selected tab.
-
-*/
-
-/*!
- \property QTabBar::selectionBehaviorOnRemove
- \brief What tab should be set as current when removeTab is called if
- the removed tab is also the current tab.
- \since 4.5
-
- By default the value is SelectRightTab.
-
- \sa removeTab()
-*/
-
-
-QTabBar::SelectionBehavior QTabBar::selectionBehaviorOnRemove() const
-{
- Q_D(const QTabBar);
- return d->selectionBehaviorOnRemove;
-}
-
-void QTabBar::setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior behavior)
-{
- Q_D(QTabBar);
- d->selectionBehaviorOnRemove = behavior;
-}
-
-/*!
- \property QTabBar::expanding
- \brief When expanding is true QTabBar will expand the tabs to use the empty space.
- \since 4.5
-
- By default the value is true.
-
- \sa QTabWidget::documentMode
-*/
-
-bool QTabBar::expanding() const
-{
- Q_D(const QTabBar);
- return d->expanding;
-}
-
-void QTabBar::setExpanding(bool enabled)
-{
- Q_D(QTabBar);
- if (d->expanding == enabled)
- return;
- d->expanding = enabled;
- d->layoutTabs();
-}
-
-/*!
- \property QTabBar::movable
- \brief This property holds whether the user can move the tabs
- within the tabbar area.
-
- \since 4.5
-
- By default, this property is false;
-*/
-
-bool QTabBar::isMovable() const
-{
- Q_D(const QTabBar);
- return d->movable;
-}
-
-void QTabBar::setMovable(bool movable)
-{
- Q_D(QTabBar);
- d->movable = movable;
-}
-
-
-/*!
- \property QTabBar::documentMode
- \brief Whether or not the tab bar is rendered in a mode suitable for the main window.
- \since 4.5
-
- This property is used as a hint for styles to draw the tabs in a different
- way then they would normally look in a tab widget. On Mac OS X this will
- look similar to the tabs in Safari or Leopard's Terminal.app.
-
- \sa QTabWidget::documentMode
-*/
-bool QTabBar::documentMode() const
-{
- return d_func()->documentMode;
-}
-
-void QTabBar::setDocumentMode(bool enabled)
-{
- Q_D(QTabBar);
-
- d->documentMode = enabled;
- d->updateMacBorderMetrics();
-}
-
-/*!
- Sets \a widget on the tab \a index. The widget is placed
- on the left or right hand side depending upon the \a position.
- \since 4.5
-
- Any previously set widget in \a position is hidden.
-
- The tab bar will take ownership of the widget and so all widgets set here
- will be deleted by the tab bar when it is destroyed unless you separately
- reparent the widget after setting some other widget (or 0).
-
- \sa tabsClosable()
- */
-void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget)
-{
- Q_D(QTabBar);
- if (index < 0 || index >= d->tabList.count())
- return;
- if (widget) {
- widget->setParent(this);
- // make sure our left and right widgets stay on top
- widget->lower();
- widget->show();
- }
- if (position == LeftSide) {
- if (d->tabList[index].leftWidget)
- d->tabList[index].leftWidget->hide();
- d->tabList[index].leftWidget = widget;
- } else {
- if (d->tabList[index].rightWidget)
- d->tabList[index].rightWidget->hide();
- d->tabList[index].rightWidget = widget;
- }
- d->layoutTabs();
- d->refresh();
- update();
-}
-
-/*!
- Returns the widget set a tab \a index and \a position or 0 if
- one is not set.
- */
-QWidget *QTabBar::tabButton(int index, ButtonPosition position) const
-{
- Q_D(const QTabBar);
- if (index < 0 || index >= d->tabList.count())
- return 0;
- if (position == LeftSide)
- return d->tabList.at(index).leftWidget;
- else
- return d->tabList.at(index).rightWidget;
-}
-
-CloseButton::CloseButton(QWidget *parent)
- : QAbstractButton(parent)
-{
- setFocusPolicy(Qt::NoFocus);
-#ifndef QT_NO_CURSOR
- setCursor(Qt::ArrowCursor);
-#endif
-#ifndef QT_NO_TOOLTIP
- setToolTip(tr("Close Tab"));
-#endif
- resize(sizeHint());
-}
-
-QSize CloseButton::sizeHint() const
-{
- ensurePolished();
- int width = style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this);
- int height = style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, this);
- return QSize(width, height);
-}
-
-void CloseButton::enterEvent(QEvent *event)
-{
- if (isEnabled())
- update();
- QAbstractButton::enterEvent(event);
-}
-
-void CloseButton::leaveEvent(QEvent *event)
-{
- if (isEnabled())
- update();
- QAbstractButton::leaveEvent(event);
-}
-
-void CloseButton::paintEvent(QPaintEvent *)
-{
- QPainter p(this);
- QStyleOption opt;
- opt.init(this);
- opt.state |= QStyle::State_AutoRaise;
- if (isEnabled() && underMouse() && !isChecked() && !isDown())
- opt.state |= QStyle::State_Raised;
- if (isChecked())
- opt.state |= QStyle::State_On;
- if (isDown())
- opt.state |= QStyle::State_Sunken;
-
- if (const QTabBar *tb = qobject_cast<const QTabBar *>(parent())) {
- int index = tb->currentIndex();
- QTabBar::ButtonPosition position = (QTabBar::ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tb);
- if (tb->tabButton(index, position) == this)
- opt.state |= QStyle::State_Selected;
- }
-
- style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qtabbar.cpp"
-
-#endif // QT_NO_TABBAR