1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qtabwidget.h"
41 
42 #include "private/qapplication_p.h"
43 #include "private/qwidget_p.h"
44 #include "private/qtabbar_p.h"
45 #include "qapplication.h"
46 #include "qbitmap.h"
47 #include "qdesktopwidget.h"
48 #include <private/qdesktopwidget_p.h>
49 #include "qevent.h"
50 #include "qlayout.h"
51 #include "qstackedwidget.h"
52 #include "qstyle.h"
53 #include "qstyleoption.h"
54 #include "qstylepainter.h"
55 #include "qtabbar.h"
56 #include "qtoolbutton.h"
57 
58 QT_BEGIN_NAMESPACE
59 
60 /*!
61     \class QTabWidget
62     \brief The QTabWidget class provides a stack of tabbed widgets.
63 
64     \ingroup organizers
65     \ingroup basicwidgets
66     \inmodule QtWidgets
67 
68     \image windows-tabwidget.png
69 
70     A tab widget provides a tab bar (see QTabBar) and a "page area"
71     that is used to display pages related to each tab. By default, the
72     tab bar is shown above the page area, but different configurations
73     are available (see \l{TabPosition}). Each tab is associated with a
74     different widget (called a page). Only the current page is shown in
75     the page area; all the other pages are hidden. The user can show a
76     different page by clicking on its tab or by pressing its
77     Alt+\e{letter} shortcut if it has one.
78 
79     The normal way to use QTabWidget is to do the following:
80     \list 1
81     \li Create a QTabWidget.
82     \li Create a QWidget for each of the pages in the tab dialog, but
83        do not specify parent widgets for them.
84     \li Insert child widgets into the page widget, using layouts to
85        position them as normal.
86     \li Call addTab() or insertTab() to put the page widgets into the
87        tab widget, giving each tab a suitable label with an optional
88        keyboard shortcut.
89     \endlist
90 
91     The position of the tabs is defined by \l tabPosition, their shape
92     by \l tabShape.
93 
94     The signal currentChanged() is emitted when the user selects a
95     page.
96 
97     The current page index is available as currentIndex(), the current
98     page widget with currentWidget().  You can retrieve a pointer to a
99     page widget with a given index using widget(), and can find the
100     index position of a widget with indexOf(). Use setCurrentWidget()
101     or setCurrentIndex() to show a particular page.
102 
103     You can change a tab's text and icon using setTabText() or
104     setTabIcon(). A tab and its associated page can be removed with
105     removeTab().
106 
107     Each tab is either enabled or disabled at any given time (see
108     setTabEnabled()). If a tab is enabled, the tab text is drawn
109     normally and the user can select that tab. If it is disabled, the
110     tab is drawn in a different way and the user cannot select that
111     tab. Note that even if a tab is disabled, the page can still be
112     visible, for example if all of the tabs happen to be disabled.
113 
114     Tab widgets can be a very good way to split up a complex dialog.
115     An alternative is to use a QStackedWidget for which you provide some
116     means of navigating between pages, for example, a QToolBar or a
117     QListWidget.
118 
119     Most of the functionality in QTabWidget is provided by a QTabBar
120     (at the top, providing the tabs) and a QStackedWidget (most of the
121     area, organizing the individual pages).
122 
123     \sa QTabBar, QStackedWidget, QToolBox, {Tab Dialog Example}
124 */
125 
126 /*!
127     \enum QTabWidget::TabPosition
128 
129     This enum type defines where QTabWidget draws the tab row:
130 
131     \value North  The tabs are drawn above the pages.
132     \value South  The tabs are drawn below the pages.
133     \value West  The tabs are drawn to the left of the pages.
134     \value East  The tabs are drawn to the right of the pages.
135 */
136 
137 /*!
138     \enum QTabWidget::TabShape
139 
140     This enum type defines the shape of the tabs:
141     \value Rounded  The tabs are drawn with a rounded look. This is the default
142                     shape.
143     \value Triangular  The tabs are drawn with a triangular look.
144 */
145 
146 /*!
147     \fn void QTabWidget::currentChanged(int index)
148 
149     This signal is emitted whenever the current page index changes.
150     The parameter is the new current page \a index position, or -1
151     if there isn't a new one (for example, if there are no widgets
152     in the QTabWidget)
153 
154     \sa currentWidget(), currentIndex
155 */
156 
157 /*!
158     \fn void QTabWidget::tabCloseRequested(int index)
159     \since 4.5
160 
161     This signal is emitted when the close button on a tab is clicked.
162     The \a index is the index that should be removed.
163 
164     \sa setTabsClosable()
165 */
166 
167 /*!
168     \fn void QTabWidget::tabBarClicked(int index)
169 
170     This signal is emitted when user clicks on a tab at an \a index.
171 
172     \a index refers to the tab clicked, or -1 if no tab is under the cursor.
173 
174     \since 5.2
175 */
176 
177 /*!
178     \fn void QTabWidget::tabBarDoubleClicked(int index)
179 
180     This signal is emitted when the user double clicks on a tab at an \a index.
181 
182     \a index is the index of a clicked tab, or -1 if no tab is under the cursor.
183 
184     \since 5.2
185 */
186 
187 class QTabWidgetPrivate : public QWidgetPrivate
188 {
189     Q_DECLARE_PUBLIC(QTabWidget)
190 
191 public:
192     QTabWidgetPrivate();
193     ~QTabWidgetPrivate();
194     void updateTabBarPosition();
195     void _q_showTab(int);
196     void _q_removeTab(int);
197     void _q_tabMoved(int from, int to);
198     void init();
isAutoHidden() const199     bool isAutoHidden() const
200     {
201         // see QTabBarPrivate::autoHideTabs()
202         return (tabs->autoHide() && tabs->count() <= 1);
203     }
204 
205     void initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const;
206 
207     QTabBar *tabs;
208     QStackedWidget *stack;
209     QRect panelRect;
210     bool dirty;
211     QTabWidget::TabPosition pos;
212     QTabWidget::TabShape shape;
213     QWidget *leftCornerWidget;
214     QWidget *rightCornerWidget;
215 };
216 
QTabWidgetPrivate()217 QTabWidgetPrivate::QTabWidgetPrivate()
218     : tabs(nullptr), stack(nullptr), dirty(true),
219       pos(QTabWidget::North), shape(QTabWidget::Rounded),
220       leftCornerWidget(nullptr), rightCornerWidget(nullptr)
221 {}
222 
~QTabWidgetPrivate()223 QTabWidgetPrivate::~QTabWidgetPrivate()
224 {}
225 
init()226 void QTabWidgetPrivate::init()
227 {
228     Q_Q(QTabWidget);
229 
230     stack = new QStackedWidget(q);
231     stack->setObjectName(QLatin1String("qt_tabwidget_stackedwidget"));
232     stack->setLineWidth(0);
233     // hack so that QMacStyle::layoutSpacing() can detect tab widget pages
234     stack->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::TabWidget));
235 
236     QObject::connect(stack, SIGNAL(widgetRemoved(int)), q, SLOT(_q_removeTab(int)));
237     QTabBar *tabBar = new QTabBar(q);
238     tabBar->setObjectName(QLatin1String("qt_tabwidget_tabbar"));
239     tabBar->setDrawBase(false);
240     q->setTabBar(tabBar);
241 
242     q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding,
243                                  QSizePolicy::TabWidget));
244 #ifdef QT_KEYPAD_NAVIGATION
245     if (QApplicationPrivate::keypadNavigationEnabled())
246         q->setFocusPolicy(Qt::NoFocus);
247     else
248 #endif
249     q->setFocusPolicy(Qt::TabFocus);
250     q->setFocusProxy(tabs);
251     q->setTabPosition(static_cast<QTabWidget::TabPosition> (q->style()->styleHint(
252                       QStyle::SH_TabWidget_DefaultTabPosition, nullptr, q )));
253 
254 }
255 
256 /*!
257     \reimp
258 */
259 
hasHeightForWidth() const260 bool QTabWidget::hasHeightForWidth() const
261 {
262     Q_D(const QTabWidget);
263     bool has = d->size_policy.hasHeightForWidth();
264     if (!has && d->stack)
265         has = d->stack->hasHeightForWidth();
266     return has;
267 }
268 
269 /*!
270     \internal
271 
272     Initialize only time inexpensive parts of the style option
273     for QTabWidget::setUpLayout()'s non-visible code path.
274 */
initBasicStyleOption(QStyleOptionTabWidgetFrame * option) const275 void QTabWidgetPrivate::initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const
276 {
277     Q_Q(const QTabWidget);
278     option->initFrom(q);
279 
280     if (q->documentMode())
281         option->lineWidth = 0;
282     else
283         option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, q);
284 
285     switch (pos) {
286     case QTabWidget::North:
287         option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
288                                                      : QTabBar::TriangularNorth;
289         break;
290     case QTabWidget::South:
291         option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
292                                                      : QTabBar::TriangularSouth;
293         break;
294     case QTabWidget::West:
295         option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedWest
296                                                      : QTabBar::TriangularWest;
297         break;
298     case QTabWidget::East:
299         option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedEast
300                                                      : QTabBar::TriangularEast;
301         break;
302     }
303 
304     option->tabBarRect = q->tabBar()->geometry();
305 }
306 
307 /*!
308     Initialize \a option with the values from this QTabWidget. This method is useful
309     for subclasses when they need a QStyleOptionTabWidgetFrame, but don't want to fill
310     in all the information themselves.
311 
312     \sa QStyleOption::initFrom(), QTabBar::initStyleOption()
313 */
initStyleOption(QStyleOptionTabWidgetFrame * option) const314 void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
315 {
316     if (!option)
317         return;
318 
319     Q_D(const QTabWidget);
320     d->initBasicStyleOption(option);
321 
322     int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, nullptr, this);
323     QSize t(0, d->stack->frameWidth());
324     if (d->tabs->isVisibleTo(const_cast<QTabWidget *>(this))) {
325         t = d->tabs->sizeHint();
326         if (documentMode()) {
327             if (tabPosition() == East || tabPosition() == West) {
328                 t.setHeight(height());
329             } else {
330                 t.setWidth(width());
331             }
332         }
333     }
334 
335     if (d->rightCornerWidget) {
336         const QSize rightCornerSizeHint = d->rightCornerWidget->sizeHint();
337         const QSize bounds(rightCornerSizeHint.width(), t.height() - exth);
338         option->rightCornerWidgetSize = rightCornerSizeHint.boundedTo(bounds);
339     } else {
340         option->rightCornerWidgetSize = QSize(0, 0);
341     }
342 
343     if (d->leftCornerWidget) {
344         const QSize leftCornerSizeHint = d->leftCornerWidget->sizeHint();
345         const QSize bounds(leftCornerSizeHint.width(), t.height() - exth);
346         option->leftCornerWidgetSize = leftCornerSizeHint.boundedTo(bounds);
347     } else {
348         option->leftCornerWidgetSize = QSize(0, 0);
349     }
350 
351     option->tabBarSize = t;
352 
353     QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
354     selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + option->tabBarRect.topLeft());
355     option->selectedTabRect = selectedTabRect;
356 }
357 
358 /*!
359     Constructs a tabbed widget with parent \a parent.
360 */
QTabWidget(QWidget * parent)361 QTabWidget::QTabWidget(QWidget *parent)
362     : QWidget(*new QTabWidgetPrivate, parent, { })
363 {
364     Q_D(QTabWidget);
365     d->init();
366 }
367 
368 
369 /*!
370     Destroys the tabbed widget.
371 */
~QTabWidget()372 QTabWidget::~QTabWidget()
373 {
374 }
375 
376 /*!
377     \fn int QTabWidget::addTab(QWidget *page, const QString &label)
378 
379     Adds a tab with the given \a page and \a label to the tab widget,
380     and returns the index of the tab in the tab bar. Ownership of \a page
381     is passed on to the QTabWidget.
382 
383     If the tab's \a label contains an ampersand, the letter following
384     the ampersand is used as a shortcut for the tab, e.g. if the
385     label is "Bro\&wse" then Alt+W becomes a shortcut which will
386     move the focus to this tab.
387 
388     \note If you call addTab() after show(), the layout system will try
389     to adjust to the changes in its widgets hierarchy and may cause
390     flicker. To prevent this, you can set the QWidget::updatesEnabled
391     property to false prior to changes; remember to set the property
392     to true when the changes are done, making the widget receive paint
393     events again.
394 
395     \sa insertTab()
396 */
addTab(QWidget * child,const QString & label)397 int QTabWidget::addTab(QWidget *child, const QString &label)
398 {
399     return insertTab(-1, child, label);
400 }
401 
402 
403 /*!
404     \fn int QTabWidget::addTab(QWidget *page, const QIcon &icon, const QString &label)
405     \overload
406 
407     Adds a tab with the given \a page, \a icon, and \a label to the tab
408     widget, and returns the index of the tab in the tab bar. Ownership
409     of \a page is passed on to the QTabWidget.
410 
411     This function is the same as addTab(), but with an additional \a
412     icon.
413 */
addTab(QWidget * child,const QIcon & icon,const QString & label)414 int QTabWidget::addTab(QWidget *child, const QIcon& icon, const QString &label)
415 {
416     return insertTab(-1, child, icon, label);
417 }
418 
419 
420 /*!
421     \fn int QTabWidget::insertTab(int index, QWidget *page, const QString &label)
422 
423     Inserts a tab with the given \a label and \a page into the tab
424     widget at the specified \a index, and returns the index of the
425     inserted tab in the tab bar. Ownership of \a page is passed on to the
426     QTabWidget.
427 
428     The label is displayed in the tab and may vary in appearance depending
429     on the configuration of the tab widget.
430 
431     If the tab's \a label contains an ampersand, the letter following
432     the ampersand is used as a shortcut for the tab, e.g. if the
433     label is "Bro\&wse" then Alt+W becomes a shortcut which will
434     move the focus to this tab.
435 
436     If \a index is out of range, the tab is simply appended.
437     Otherwise it is inserted at the specified position.
438 
439     If the QTabWidget was empty before this function is called, the
440     new page becomes the current page. Inserting a new tab at an index
441     less than or equal to the current index will increment the current
442     index, but keep the current page.
443 
444     \note If you call insertTab() after show(), the layout system will try
445     to adjust to the changes in its widgets hierarchy and may cause
446     flicker. To prevent this, you can set the QWidget::updatesEnabled
447     property to false prior to changes; remember to set the property
448     to true when the changes are done, making the widget receive paint
449     events again.
450 
451     \sa addTab()
452 */
insertTab(int index,QWidget * w,const QString & label)453 int QTabWidget::insertTab(int index, QWidget *w, const QString &label)
454 {
455     return insertTab(index, w, QIcon(), label);
456 }
457 
458 
459 /*!
460     \fn int QTabWidget::insertTab(int index, QWidget *page, const QIcon& icon, const QString &label)
461     \overload
462 
463     Inserts a tab with the given \a label, \a page, and \a icon into
464     the tab widget at the specified \a index, and returns the index of the
465     inserted tab in the tab bar. Ownership of \a page is passed on to the
466     QTabWidget.
467 
468     This function is the same as insertTab(), but with an additional
469     \a icon.
470 */
insertTab(int index,QWidget * w,const QIcon & icon,const QString & label)471 int QTabWidget::insertTab(int index, QWidget *w, const QIcon& icon, const QString &label)
472 {
473     Q_D(QTabWidget);
474     if(!w)
475         return -1;
476     index = d->stack->insertWidget(index, w);
477     d->tabs->insertTab(index, icon, label);
478     setUpLayout();
479     tabInserted(index);
480 
481     return index;
482 }
483 
484 
485 /*!
486     Defines a new \a label for the page at position \a index's tab.
487 
488     If the provided text contains an ampersand character ('&'), a
489     shortcut is automatically created for it. The character that
490     follows the '&' will be used as the shortcut key. Any previous
491     shortcut will be overwritten, or cleared if no shortcut is defined
492     by the text. See the \l {QShortcut#mnemonic}{QShortcut}
493     documentation for details (to display an actual ampersand, use
494     '&&').
495 
496 */
setTabText(int index,const QString & label)497 void QTabWidget::setTabText(int index, const QString &label)
498 {
499     Q_D(QTabWidget);
500     d->tabs->setTabText(index, label);
501     setUpLayout();
502 }
503 
504 /*!
505     Returns the label text for the tab on the page at position \a index.
506 */
507 
tabText(int index) const508 QString QTabWidget::tabText(int index) const
509 {
510     Q_D(const QTabWidget);
511     return d->tabs->tabText(index);
512 }
513 
514 /*!
515     Sets the \a icon for the tab at position \a index.
516 */
setTabIcon(int index,const QIcon & icon)517 void QTabWidget::setTabIcon(int index, const QIcon &icon)
518 {
519     Q_D(QTabWidget);
520     d->tabs->setTabIcon(index, icon);
521     setUpLayout();
522 }
523 
524 /*!
525     Returns the icon for the tab on the page at position \a index.
526 */
527 
tabIcon(int index) const528 QIcon QTabWidget::tabIcon(int index) const
529 {
530     Q_D(const QTabWidget);
531     return d->tabs->tabIcon(index);
532 }
533 
534 /*!
535     Returns \c true if the page at position \a index is enabled; otherwise returns \c false.
536 
537     \sa setTabEnabled(), QWidget::isEnabled()
538 */
539 
isTabEnabled(int index) const540 bool QTabWidget::isTabEnabled(int index) const
541 {
542     Q_D(const QTabWidget);
543     return d->tabs->isTabEnabled(index);
544 }
545 
546 /*!
547     If \a enable is true, the page at position \a index is enabled; otherwise the page at
548     position \a index is disabled. The page's tab is redrawn appropriately.
549 
550     QTabWidget uses QWidget::setEnabled() internally, rather than
551     keeping a separate flag.
552 
553     Note that even a disabled tab/page may be visible. If the page is
554     visible already, QTabWidget will not hide it; if all the pages are
555     disabled, QTabWidget will show one of them.
556 
557     \sa isTabEnabled(), QWidget::setEnabled()
558 */
559 
setTabEnabled(int index,bool enable)560 void QTabWidget::setTabEnabled(int index, bool enable)
561 {
562     Q_D(QTabWidget);
563     d->tabs->setTabEnabled(index, enable);
564     if (QWidget *widget = d->stack->widget(index))
565         widget->setEnabled(enable);
566 }
567 
568 /*!
569     Returns true if the page at position \a index is visible; otherwise returns false.
570 
571     \sa setTabVisible()
572     \since 5.15
573 */
574 
isTabVisible(int index) const575 bool QTabWidget::isTabVisible(int index) const
576 {
577     Q_D(const QTabWidget);
578     return d->tabs->isTabVisible(index);
579 }
580 
581 /*!
582     If \a visible is true, the page at position \a index is visible; otherwise the page at
583     position \a index is hidden. The page's tab is redrawn appropriately.
584 
585     \sa isTabVisible()
586     \since 5.15
587 */
588 
setTabVisible(int index,bool visible)589 void QTabWidget::setTabVisible(int index, bool visible)
590 {
591     Q_D(QTabWidget);
592     QWidget *widget = d->stack->widget(index);
593     bool currentVisible = d->tabs->isTabVisible(d->tabs->currentIndex());
594     d->tabs->setTabVisible(index, visible);
595     if (!visible) {
596         if (widget)
597             widget->setVisible(false);
598     } else if (!currentVisible) {
599         setCurrentIndex(index);
600         if (widget)
601             widget->setVisible(true);
602     }
603     setUpLayout();
604 }
605 
606 /*!
607   \fn void QTabWidget::setCornerWidget(QWidget *widget, Qt::Corner corner)
608 
609   Sets the given \a widget to be shown in the specified \a corner of the
610   tab widget. The geometry of the widget is determined based on the widget's
611   sizeHint() and the style().
612 
613   Only the horizontal element of the \a corner will be used.
614 
615   Passing \nullptr shows no widget in the corner.
616 
617   Any previously set corner widget is hidden.
618 
619   All widgets set here will be deleted by the tab widget when it is
620   destroyed unless you separately reparent the widget after setting
621   some other corner widget (or \nullptr).
622 
623   Note: Corner widgets are designed for \l North and \l South tab positions;
624   other orientations are known to not work properly.
625 
626   \sa cornerWidget(), setTabPosition()
627 */
setCornerWidget(QWidget * widget,Qt::Corner corner)628 void QTabWidget::setCornerWidget(QWidget * widget, Qt::Corner corner)
629 {
630     Q_D(QTabWidget);
631     if (widget && widget->parentWidget() != this)
632         widget->setParent(this);
633 
634     if (corner & Qt::TopRightCorner) {
635         if (d->rightCornerWidget)
636             d->rightCornerWidget->hide();
637         d->rightCornerWidget = widget;
638     } else {
639         if (d->leftCornerWidget)
640             d->leftCornerWidget->hide();
641         d->leftCornerWidget = widget;
642     }
643     setUpLayout();
644 }
645 
646 /*!
647     Returns the widget shown in the \a corner of the tab widget or \nullptr.
648 */
cornerWidget(Qt::Corner corner) const649 QWidget * QTabWidget::cornerWidget(Qt::Corner corner) const
650 {
651     Q_D(const QTabWidget);
652     if (corner & Qt::TopRightCorner)
653         return d->rightCornerWidget;
654     return d->leftCornerWidget;
655 }
656 
657 /*!
658    Removes the tab at position \a index from this stack of widgets.
659    The page widget itself is not deleted.
660 
661    \sa addTab(), insertTab()
662 */
removeTab(int index)663 void QTabWidget::removeTab(int index)
664 {
665     Q_D(QTabWidget);
666     if (QWidget *w = d->stack->widget(index))
667         d->stack->removeWidget(w);
668 }
669 
670 /*!
671     Returns a pointer to the page currently being displayed by the tab
672     dialog. The tab dialog does its best to make sure that this value
673     is never 0 (but if you try hard enough, it can be).
674 
675     \sa currentIndex(), setCurrentWidget()
676 */
677 
currentWidget() const678 QWidget * QTabWidget::currentWidget() const
679 {
680     Q_D(const QTabWidget);
681     return d->stack->currentWidget();
682 }
683 
684 /*!
685     Makes \a widget the current widget. The \a widget used must be a page in
686     this tab widget.
687 
688     \sa addTab(), setCurrentIndex(), currentWidget()
689  */
setCurrentWidget(QWidget * widget)690 void QTabWidget::setCurrentWidget(QWidget *widget)
691 {
692     Q_D(const QTabWidget);
693     d->tabs->setCurrentIndex(indexOf(widget));
694 }
695 
696 
697 /*!
698     \property QTabWidget::currentIndex
699     \brief the index position of the current tab page
700 
701     The current index is -1 if there is no current widget.
702 
703     By default, this property contains a value of -1 because there are initially
704     no tabs in the widget.
705 */
706 
currentIndex() const707 int QTabWidget::currentIndex() const
708 {
709     Q_D(const QTabWidget);
710     return d->tabs->currentIndex();
711 }
712 
setCurrentIndex(int index)713 void QTabWidget::setCurrentIndex(int index)
714 {
715     Q_D(QTabWidget);
716     d->tabs->setCurrentIndex(index);
717 }
718 
719 
720 /*!
721     Returns the index position of the page occupied by the widget \a
722     w, or -1 if the widget cannot be found.
723 */
indexOf(QWidget * w) const724 int QTabWidget::indexOf(QWidget* w) const
725 {
726     Q_D(const QTabWidget);
727     return d->stack->indexOf(w);
728 }
729 
730 
731 /*!
732     \reimp
733 */
resizeEvent(QResizeEvent * e)734 void QTabWidget::resizeEvent(QResizeEvent *e)
735 {
736     QWidget::resizeEvent(e);
737     setUpLayout();
738 }
739 
740 /*!
741     Replaces the dialog's QTabBar heading with the tab bar \a tb. Note
742     that this must be called \e before any tabs have been added, or
743     the behavior is undefined.
744 
745     \sa tabBar()
746 */
setTabBar(QTabBar * tb)747 void QTabWidget::setTabBar(QTabBar* tb)
748 {
749     Q_D(QTabWidget);
750     Q_ASSERT(tb);
751 
752     if (tb->parentWidget() != this) {
753         tb->setParent(this);
754         tb->show();
755     }
756     delete d->tabs;
757     d->tabs = tb;
758     setFocusProxy(d->tabs);
759     connect(d->tabs, SIGNAL(currentChanged(int)),
760             this, SLOT(_q_showTab(int)));
761     connect(d->tabs, SIGNAL(tabMoved(int,int)),
762             this, SLOT(_q_tabMoved(int,int)));
763     connect(d->tabs, SIGNAL(tabBarClicked(int)),
764             this, SIGNAL(tabBarClicked(int)));
765     connect(d->tabs, SIGNAL(tabBarDoubleClicked(int)),
766             this, SIGNAL(tabBarDoubleClicked(int)));
767     if (d->tabs->tabsClosable())
768         connect(d->tabs, SIGNAL(tabCloseRequested(int)),
769                 this, SIGNAL(tabCloseRequested(int)));
770     tb->setExpanding(!documentMode());
771     setUpLayout();
772 }
773 
774 
775 /*!
776     Returns the current QTabBar.
777 
778     \sa setTabBar()
779 */
tabBar() const780 QTabBar* QTabWidget::tabBar() const
781 {
782     Q_D(const QTabWidget);
783     return d->tabs;
784 }
785 
786 /*
787     Ensures that the selected tab's page is visible and appropriately
788     sized.
789 */
790 
_q_showTab(int index)791 void QTabWidgetPrivate::_q_showTab(int index)
792 {
793     Q_Q(QTabWidget);
794     if (index < stack->count() && index >= 0)
795         stack->setCurrentIndex(index);
796     emit q->currentChanged(index);
797 }
798 
_q_removeTab(int index)799 void QTabWidgetPrivate::_q_removeTab(int index)
800 {
801     Q_Q(QTabWidget);
802     tabs->removeTab(index);
803     q->setUpLayout();
804     q->tabRemoved(index);
805 }
806 
_q_tabMoved(int from,int to)807 void QTabWidgetPrivate::_q_tabMoved(int from, int to)
808 {
809     const QSignalBlocker blocker(stack);
810     QWidget *w = stack->widget(from);
811     stack->removeWidget(w);
812     stack->insertWidget(to, w);
813 }
814 
815 /*
816     Set up the layout.
817     Get subrect from the current style, and set the geometry for the
818     stack widget, tab bar and corner widgets.
819 */
setUpLayout(bool onlyCheck)820 void QTabWidget::setUpLayout(bool onlyCheck)
821 {
822     Q_D(QTabWidget);
823     if (onlyCheck && !d->dirty)
824         return; // nothing to do
825 
826     if (!isVisible()) {
827         // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
828         QStyleOptionTabWidgetFrame basicOption;
829         d->initBasicStyleOption(&basicOption);
830         d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &basicOption);
831         d->dirty = true;
832         return; // we'll do it later
833     }
834 
835     QStyleOptionTabWidgetFrame option;
836     initStyleOption(&option);
837     d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
838 
839     QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
840     d->panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this);
841     QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this);
842     QRect leftCornerRect = style()->subElementRect(QStyle::SE_TabWidgetLeftCorner, &option, this);
843     QRect rightCornerRect = style()->subElementRect(QStyle::SE_TabWidgetRightCorner, &option, this);
844 
845     d->tabs->setGeometry(tabRect);
846     d->stack->setGeometry(contentsRect);
847     if (d->leftCornerWidget)
848         d->leftCornerWidget->setGeometry(leftCornerRect);
849     if (d->rightCornerWidget)
850         d->rightCornerWidget->setGeometry(rightCornerRect);
851 
852     if (!onlyCheck)
853         update();
854     updateGeometry();
855 }
856 
857 /*!
858     \internal
859 */
basicSize(bool horizontal,const QSize & lc,const QSize & rc,const QSize & s,const QSize & t)860 static inline QSize basicSize(
861     bool horizontal, const QSize &lc, const QSize &rc, const QSize &s, const QSize &t)
862 {
863     return horizontal
864         ? QSize(qMax(s.width(), t.width() + rc.width() + lc.width()),
865                 s.height() + (qMax(rc.height(), qMax(lc.height(), t.height()))))
866         : QSize(s.width() + (qMax(rc.width(), qMax(lc.width(), t.width()))),
867                 qMax(s.height(), t.height() + rc.height() + lc.height()));
868 }
869 
870 /*!
871     \reimp
872 */
sizeHint() const873 QSize QTabWidget::sizeHint() const
874 {
875     Q_D(const QTabWidget);
876     QSize lc(0, 0), rc(0, 0);
877     QStyleOptionTabWidgetFrame opt;
878     initStyleOption(&opt);
879     opt.state = QStyle::State_None;
880 
881     if (d->leftCornerWidget)
882         lc = d->leftCornerWidget->sizeHint();
883     if(d->rightCornerWidget)
884         rc = d->rightCornerWidget->sizeHint();
885     if (!d->dirty) {
886         QTabWidget *that = const_cast<QTabWidget*>(this);
887         that->setUpLayout(true);
888     }
889     QSize s;
890     for (int i=0; i< d->stack->count(); ++i) {
891         if (const QWidget* w = d->stack->widget(i)) {
892             if (d->tabs->isTabVisible(i))
893                 s = s.expandedTo(w->sizeHint());
894         }
895     }
896     QSize t;
897     if (!d->isAutoHidden()) {
898         t = d->tabs->sizeHint();
899         if (usesScrollButtons())
900             t = t.boundedTo(QSize(200,200));
901         else
902             t = t.boundedTo(QDesktopWidgetPrivate::size());
903     }
904 
905     QSize sz = basicSize(d->pos == North || d->pos == South, lc, rc, s, t);
906 
907     return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this)
908                     .expandedTo(QApplication::globalStrut());
909 }
910 
911 
912 /*!
913     \reimp
914 
915     Returns a suitable minimum size for the tab widget.
916 */
minimumSizeHint() const917 QSize QTabWidget::minimumSizeHint() const
918 {
919     Q_D(const QTabWidget);
920     QSize lc(0, 0), rc(0, 0);
921 
922     if(d->leftCornerWidget)
923         lc = d->leftCornerWidget->minimumSizeHint();
924     if(d->rightCornerWidget)
925         rc = d->rightCornerWidget->minimumSizeHint();
926     if (!d->dirty) {
927         QTabWidget *that = const_cast<QTabWidget*>(this);
928         that->setUpLayout(true);
929     }
930     QSize s(d->stack->minimumSizeHint());
931     QSize t;
932     if (!d->isAutoHidden())
933         t = d->tabs->minimumSizeHint();
934 
935     QSize sz = basicSize(d->pos == North || d->pos == South, lc, rc, s, t);
936 
937     QStyleOptionTabWidgetFrame opt;
938     initStyleOption(&opt);
939     opt.palette = palette();
940     opt.state = QStyle::State_None;
941     return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this)
942                     .expandedTo(QApplication::globalStrut());
943 }
944 
945 /*!
946     \reimp
947 */
heightForWidth(int width) const948 int QTabWidget::heightForWidth(int width) const
949 {
950     Q_D(const QTabWidget);
951     QStyleOptionTabWidgetFrame opt;
952     initStyleOption(&opt);
953     opt.state = QStyle::State_None;
954 
955     QSize zero(0,0);
956     const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this)
957                                   .expandedTo(QApplication::globalStrut());
958 
959     QSize lc(0, 0), rc(0, 0);
960     if (d->leftCornerWidget)
961         lc = d->leftCornerWidget->sizeHint();
962     if(d->rightCornerWidget)
963         rc = d->rightCornerWidget->sizeHint();
964     if (!d->dirty) {
965         QTabWidget *that = const_cast<QTabWidget*>(this);
966         that->setUpLayout(true);
967     }
968     QSize t;
969     if (!d->isAutoHidden()) {
970         t = d->tabs->sizeHint();
971         if (usesScrollButtons())
972             t = t.boundedTo(QSize(200,200));
973         else
974             t = t.boundedTo(QDesktopWidgetPrivate::size());
975     }
976 
977     const bool tabIsHorizontal = (d->pos == North || d->pos == South);
978     const int contentsWidth = width - padding.width();
979     int stackWidth = contentsWidth;
980     if (!tabIsHorizontal)
981         stackWidth -= qMax(t.width(), qMax(lc.width(), rc.width()));
982 
983     int stackHeight = d->stack->heightForWidth(stackWidth);
984     QSize s(stackWidth, stackHeight);
985 
986     QSize contentSize = basicSize(tabIsHorizontal, lc, rc, s, t);
987     return (contentSize + padding).expandedTo(QApplication::globalStrut()).height();
988 }
989 
990 
991 /*!
992     \reimp
993  */
showEvent(QShowEvent *)994 void QTabWidget::showEvent(QShowEvent *)
995 {
996     setUpLayout();
997 }
998 
updateTabBarPosition()999 void QTabWidgetPrivate::updateTabBarPosition()
1000 {
1001     Q_Q(QTabWidget);
1002     switch (pos) {
1003     case QTabWidget::North:
1004         tabs->setShape(shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
1005                                                     : QTabBar::TriangularNorth);
1006         break;
1007     case QTabWidget::South:
1008         tabs->setShape(shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
1009                                                     : QTabBar::TriangularSouth);
1010         break;
1011     case QTabWidget::West:
1012         tabs->setShape(shape == QTabWidget::Rounded ? QTabBar::RoundedWest
1013                                                     : QTabBar::TriangularWest);
1014         break;
1015     case QTabWidget::East:
1016         tabs->setShape(shape == QTabWidget::Rounded ? QTabBar::RoundedEast
1017                                                     : QTabBar::TriangularEast);
1018         break;
1019     }
1020     q->setUpLayout();
1021 }
1022 
1023 /*!
1024     \property QTabWidget::tabPosition
1025     \brief the position of the tabs in this tab widget
1026 
1027     Possible values for this property are described by the TabPosition
1028     enum.
1029 
1030     By default, this property is set to \l North.
1031 
1032     \sa TabPosition
1033 */
tabPosition() const1034 QTabWidget::TabPosition QTabWidget::tabPosition() const
1035 {
1036     Q_D(const QTabWidget);
1037     return d->pos;
1038 }
1039 
setTabPosition(TabPosition pos)1040 void QTabWidget::setTabPosition(TabPosition pos)
1041 {
1042     Q_D(QTabWidget);
1043     if (d->pos == pos)
1044         return;
1045     d->pos = pos;
1046     d->updateTabBarPosition();
1047 }
1048 
1049 /*!
1050     \property QTabWidget::tabsClosable
1051     \brief whether close buttons are automatically added to each tab.
1052 
1053     \since 4.5
1054 
1055     \sa QTabBar::tabsClosable()
1056 */
tabsClosable() const1057 bool QTabWidget::tabsClosable() const
1058 {
1059     return tabBar()->tabsClosable();
1060 }
1061 
setTabsClosable(bool closeable)1062 void QTabWidget::setTabsClosable(bool closeable)
1063 {
1064     if (tabsClosable() == closeable)
1065         return;
1066 
1067     tabBar()->setTabsClosable(closeable);
1068     if (closeable)
1069         connect(tabBar(), SIGNAL(tabCloseRequested(int)),
1070                 this, SIGNAL(tabCloseRequested(int)));
1071     else
1072         disconnect(tabBar(), SIGNAL(tabCloseRequested(int)),
1073                   this, SIGNAL(tabCloseRequested(int)));
1074     setUpLayout();
1075 }
1076 
1077 /*!
1078     \property QTabWidget::movable
1079     \brief This property holds whether the user can move the tabs
1080     within the tabbar area.
1081 
1082     \since 4.5
1083 
1084     By default, this property is \c false;
1085 */
1086 
isMovable() const1087 bool QTabWidget::isMovable() const
1088 {
1089     return tabBar()->isMovable();
1090 }
1091 
setMovable(bool movable)1092 void QTabWidget::setMovable(bool movable)
1093 {
1094     tabBar()->setMovable(movable);
1095 }
1096 
1097 /*!
1098     \property QTabWidget::tabShape
1099     \brief the shape of the tabs in this tab widget
1100 
1101     Possible values for this property are QTabWidget::Rounded
1102     (default) or QTabWidget::Triangular.
1103 
1104     \sa TabShape
1105 */
1106 
tabShape() const1107 QTabWidget::TabShape QTabWidget::tabShape() const
1108 {
1109     Q_D(const QTabWidget);
1110     return d->shape;
1111 }
1112 
setTabShape(TabShape s)1113 void QTabWidget::setTabShape(TabShape s)
1114 {
1115     Q_D(QTabWidget);
1116     if (d->shape == s)
1117         return;
1118     d->shape = s;
1119     d->updateTabBarPosition();
1120 }
1121 
1122 /*!
1123     \reimp
1124  */
event(QEvent * ev)1125 bool QTabWidget::event(QEvent *ev)
1126 {
1127     if (ev->type() == QEvent::LayoutRequest)
1128         setUpLayout();
1129     return QWidget::event(ev);
1130 }
1131 
1132 /*!
1133     \reimp
1134  */
changeEvent(QEvent * ev)1135 void QTabWidget::changeEvent(QEvent *ev)
1136 {
1137     if (ev->type() == QEvent::StyleChange
1138 #ifdef Q_OS_MAC
1139             || ev->type() == QEvent::MacSizeChange
1140 #endif
1141             )
1142         setUpLayout();
1143     QWidget::changeEvent(ev);
1144 }
1145 
1146 
1147 /*!
1148     \reimp
1149  */
keyPressEvent(QKeyEvent * e)1150 void QTabWidget::keyPressEvent(QKeyEvent *e)
1151 {
1152     Q_D(QTabWidget);
1153     if (((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) &&
1154           count() > 1 && e->modifiers() & Qt::ControlModifier)
1155 #ifdef QT_KEYPAD_NAVIGATION
1156           || QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right) && count() > 1
1157 #endif
1158        ) {
1159         int pageCount = d->tabs->count();
1160         int page = currentIndex();
1161         int dx = (e->key() == Qt::Key_Backtab || e->modifiers() & Qt::ShiftModifier) ? -1 : 1;
1162 #ifdef QT_KEYPAD_NAVIGATION
1163         if (QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
1164             dx = e->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
1165 #endif
1166         for (int pass = 0; pass < pageCount; ++pass) {
1167             page+=dx;
1168             if (page < 0
1169 #ifdef QT_KEYPAD_NAVIGATION
1170                 && !e->isAutoRepeat()
1171 #endif
1172                ) {
1173                 page = count() - 1;
1174             } else if (page >= pageCount
1175 #ifdef QT_KEYPAD_NAVIGATION
1176                        && !e->isAutoRepeat()
1177 #endif
1178                       ) {
1179                 page = 0;
1180             }
1181             if (d->tabs->isTabEnabled(page)) {
1182                 setCurrentIndex(page);
1183                 break;
1184             }
1185         }
1186         if (!QApplication::focusWidget())
1187             d->tabs->setFocus();
1188     } else {
1189         e->ignore();
1190     }
1191 }
1192 
1193 /*!
1194     Returns the tab page at index position \a index or \nullptr if the
1195     \a index is out of range.
1196 */
widget(int index) const1197 QWidget *QTabWidget::widget(int index) const
1198 {
1199     Q_D(const QTabWidget);
1200     return d->stack->widget(index);
1201 }
1202 
1203 /*!
1204     \property QTabWidget::count
1205     \brief the number of tabs in the tab bar
1206 
1207     By default, this property contains a value of 0.
1208 */
count() const1209 int QTabWidget::count() const
1210 {
1211     Q_D(const QTabWidget);
1212     return d->tabs->count();
1213 }
1214 
1215 #ifndef QT_NO_TOOLTIP
1216 /*!
1217     Sets the tab tool tip for the page at position \a index to \a tip.
1218 
1219     \sa tabToolTip()
1220 */
setTabToolTip(int index,const QString & tip)1221 void QTabWidget::setTabToolTip(int index, const QString & tip)
1222 {
1223     Q_D(QTabWidget);
1224     d->tabs->setTabToolTip(index, tip);
1225 }
1226 
1227 /*!
1228     Returns the tab tool tip for the page at position \a index or
1229     an empty string if no tool tip has been set.
1230 
1231     \sa setTabToolTip()
1232 */
tabToolTip(int index) const1233 QString QTabWidget::tabToolTip(int index) const
1234 {
1235     Q_D(const QTabWidget);
1236     return d->tabs->tabToolTip(index);
1237 }
1238 #endif // QT_NO_TOOLTIP
1239 
1240 #if QT_CONFIG(whatsthis)
1241 /*!
1242     \since 4.1
1243 
1244     Sets the What's This help text for the page at position \a index
1245     to \a text.
1246 */
setTabWhatsThis(int index,const QString & text)1247 void QTabWidget::setTabWhatsThis(int index, const QString &text)
1248 {
1249     Q_D(QTabWidget);
1250     d->tabs->setTabWhatsThis(index, text);
1251 }
1252 
1253 /*!
1254     \since 4.1
1255 
1256     Returns the What's This help text for the page at position \a index,
1257     or an empty string if no help text has been set.
1258 */
tabWhatsThis(int index) const1259 QString QTabWidget::tabWhatsThis(int index) const
1260 {
1261     Q_D(const QTabWidget);
1262     return d->tabs->tabWhatsThis(index);
1263 }
1264 #endif // QT_CONFIG(whatsthis)
1265 
1266 /*!
1267   This virtual handler is called after a new tab was added or
1268   inserted at position \a index.
1269 
1270   \sa tabRemoved()
1271  */
tabInserted(int index)1272 void QTabWidget::tabInserted(int index)
1273 {
1274     Q_UNUSED(index)
1275 }
1276 
1277 /*!
1278   This virtual handler is called after a tab was removed from
1279   position \a index.
1280 
1281   \sa tabInserted()
1282  */
tabRemoved(int index)1283 void QTabWidget::tabRemoved(int index)
1284 {
1285     Q_UNUSED(index)
1286 }
1287 
1288 /*!
1289     \fn void QTabWidget::paintEvent(QPaintEvent *event)
1290 
1291     Paints the tab widget's tab bar in response to the paint \a event.
1292 */
paintEvent(QPaintEvent *)1293 void QTabWidget::paintEvent(QPaintEvent *)
1294 {
1295     Q_D(QTabWidget);
1296     if (documentMode()) {
1297         QStylePainter p(this, tabBar());
1298         if (QWidget *w = cornerWidget(Qt::TopLeftCorner)) {
1299             QStyleOptionTabBarBase opt;
1300             QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size());
1301             opt.rect.moveLeft(w->x() + opt.rect.x());
1302             opt.rect.moveTop(w->y() + opt.rect.y());
1303             p.drawPrimitive(QStyle::PE_FrameTabBarBase, opt);
1304         }
1305         if (QWidget *w = cornerWidget(Qt::TopRightCorner)) {
1306             QStyleOptionTabBarBase opt;
1307             QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size());
1308             opt.rect.moveLeft(w->x() + opt.rect.x());
1309             opt.rect.moveTop(w->y() + opt.rect.y());
1310             p.drawPrimitive(QStyle::PE_FrameTabBarBase, opt);
1311         }
1312         return;
1313     }
1314     QStylePainter p(this);
1315 
1316     QStyleOptionTabWidgetFrame opt;
1317     initStyleOption(&opt);
1318     opt.rect = d->panelRect;
1319     p.drawPrimitive(QStyle::PE_FrameTabWidget, opt);
1320 }
1321 
1322 /*!
1323     \property QTabWidget::iconSize
1324     \brief The size for icons in the tab bar
1325     \since 4.2
1326 
1327     The default value is style-dependent. This is the maximum size
1328     that the icons will have. Icons are not scaled up if they are of
1329     smaller size.
1330 
1331     \sa QTabBar::iconSize
1332 */
iconSize() const1333 QSize QTabWidget::iconSize() const
1334 {
1335     return d_func()->tabs->iconSize();
1336 }
1337 
setIconSize(const QSize & size)1338 void QTabWidget::setIconSize(const QSize &size)
1339 {
1340     d_func()->tabs->setIconSize(size);
1341 }
1342 
1343 /*!
1344     \property QTabWidget::elideMode
1345     \brief how to elide text in the tab bar
1346     \since 4.2
1347 
1348     This property controls how items are elided when there is not
1349     enough space to show them for a given tab bar size.
1350 
1351     By default the value is style dependant.
1352 
1353     \sa QTabBar::elideMode, usesScrollButtons, QStyle::SH_TabBar_ElideMode
1354 */
elideMode() const1355 Qt::TextElideMode QTabWidget::elideMode() const
1356 {
1357     return d_func()->tabs->elideMode();
1358 }
1359 
setElideMode(Qt::TextElideMode mode)1360 void QTabWidget::setElideMode(Qt::TextElideMode mode)
1361 {
1362     d_func()->tabs->setElideMode(mode);
1363 }
1364 
1365 /*!
1366     \property QTabWidget::usesScrollButtons
1367     \brief Whether or not a tab bar should use buttons to scroll tabs when it
1368     has many tabs.
1369     \since 4.2
1370 
1371     When there are too many tabs in a tab bar for its size, the tab bar can either choose
1372     to expand its size or to add buttons that allow you to scroll through the tabs.
1373 
1374     By default the value is style dependant.
1375 
1376     \sa elideMode, QTabBar::usesScrollButtons, QStyle::SH_TabBar_PreferNoArrows
1377 */
usesScrollButtons() const1378 bool QTabWidget::usesScrollButtons() const
1379 {
1380     return d_func()->tabs->usesScrollButtons();
1381 }
1382 
setUsesScrollButtons(bool useButtons)1383 void QTabWidget::setUsesScrollButtons(bool useButtons)
1384 {
1385     d_func()->tabs->setUsesScrollButtons(useButtons);
1386 }
1387 
1388 /*!
1389     \property QTabWidget::documentMode
1390     \brief Whether or not the tab widget is rendered in a mode suitable for document
1391      pages. This is the same as document mode on \macos.
1392     \since 4.5
1393 
1394     When this property is set the tab widget frame is not rendered. This mode is useful
1395     for showing document-type pages where the page covers most of the tab widget
1396     area.
1397 
1398     \sa elideMode, QTabBar::documentMode, QTabBar::usesScrollButtons, QStyle::SH_TabBar_PreferNoArrows
1399 */
documentMode() const1400 bool QTabWidget::documentMode() const
1401 {
1402     Q_D(const QTabWidget);
1403     return d->tabs->documentMode();
1404 }
1405 
setDocumentMode(bool enabled)1406 void QTabWidget::setDocumentMode(bool enabled)
1407 {
1408     Q_D(QTabWidget);
1409     d->tabs->setDocumentMode(enabled);
1410     d->tabs->setExpanding(!enabled);
1411     d->tabs->setDrawBase(enabled);
1412     setUpLayout();
1413 }
1414 
1415 /*!
1416     \property QTabWidget::tabBarAutoHide
1417     \brief If true, the tab bar is automatically hidden when it contains less
1418     than 2 tabs.
1419     \since 5.4
1420 
1421     By default, this property is false.
1422 
1423     \sa QWidget::visible
1424 */
1425 
tabBarAutoHide() const1426 bool QTabWidget::tabBarAutoHide() const
1427 {
1428     Q_D(const QTabWidget);
1429     return d->tabs->autoHide();
1430 }
1431 
setTabBarAutoHide(bool enabled)1432 void QTabWidget::setTabBarAutoHide(bool enabled)
1433 {
1434     Q_D(QTabWidget);
1435     return d->tabs->setAutoHide(enabled);
1436 }
1437 
1438 /*!
1439     Removes all the pages, but does not delete them. Calling this function
1440     is equivalent to calling removeTab() until the tab widget is empty.
1441 */
clear()1442 void QTabWidget::clear()
1443 {
1444     // ### optimize by introduce QStackedLayout::clear()
1445     while (count())
1446         removeTab(0);
1447 }
1448 
1449 QT_END_NAMESPACE
1450 
1451 #include "moc_qtabwidget.cpp"
1452