summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qtabwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qtabwidget.cpp')
-rw-r--r--src/widgets/widgets/qtabwidget.cpp216
1 files changed, 118 insertions, 98 deletions
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 8a848554e3..5e7c266ef6 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -1,50 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtabwidget.h"
+#include "private/qapplication_p.h"
#include "private/qwidget_p.h"
#include "private/qtabbar_p.h"
#include "qapplication.h"
#include "qbitmap.h"
-#include "qdesktopwidget.h"
-#include <private/qdesktopwidget_p.h>
#include "qevent.h"
#include "qlayout.h"
#include "qstackedwidget.h"
@@ -56,6 +19,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\class QTabWidget
\brief The QTabWidget class provides a stack of tabbed widgets.
@@ -191,9 +156,9 @@ public:
QTabWidgetPrivate();
~QTabWidgetPrivate();
void updateTabBarPosition();
- void _q_showTab(int);
- void _q_removeTab(int);
- void _q_tabMoved(int from, int to);
+ void showTab(int);
+ void removeTab(int);
+ void tabMoved(int from, int to);
void init();
bool isAutoHidden() const
{
@@ -214,9 +179,9 @@ public:
};
QTabWidgetPrivate::QTabWidgetPrivate()
- : tabs(0), stack(0), dirty(true),
+ : tabs(nullptr), stack(nullptr), dirty(true),
pos(QTabWidget::North), shape(QTabWidget::Rounded),
- leftCornerWidget(0), rightCornerWidget(0)
+ leftCornerWidget(nullptr), rightCornerWidget(nullptr)
{}
QTabWidgetPrivate::~QTabWidgetPrivate()
@@ -227,28 +192,28 @@ void QTabWidgetPrivate::init()
Q_Q(QTabWidget);
stack = new QStackedWidget(q);
- stack->setObjectName(QLatin1String("qt_tabwidget_stackedwidget"));
+ stack->setObjectName("qt_tabwidget_stackedwidget"_L1);
stack->setLineWidth(0);
// hack so that QMacStyle::layoutSpacing() can detect tab widget pages
stack->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::TabWidget));
- QObject::connect(stack, SIGNAL(widgetRemoved(int)), q, SLOT(_q_removeTab(int)));
+ QObjectPrivate::connect(stack, &QStackedWidget::widgetRemoved, this, &QTabWidgetPrivate::removeTab);
QTabBar *tabBar = new QTabBar(q);
- tabBar->setObjectName(QLatin1String("qt_tabwidget_tabbar"));
+ tabBar->setObjectName("qt_tabwidget_tabbar"_L1);
tabBar->setDrawBase(false);
q->setTabBar(tabBar);
q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding,
QSizePolicy::TabWidget));
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled())
+ if (QApplicationPrivate::keypadNavigationEnabled())
q->setFocusPolicy(Qt::NoFocus);
else
#endif
q->setFocusPolicy(Qt::TabFocus);
q->setFocusProxy(tabs);
q->setTabPosition(static_cast<QTabWidget::TabPosition> (q->style()->styleHint(
- QStyle::SH_TabWidget_DefaultTabPosition, 0, q )));
+ QStyle::SH_TabWidget_DefaultTabPosition, nullptr, q )));
}
@@ -279,7 +244,7 @@ void QTabWidgetPrivate::initBasicStyleOption(QStyleOptionTabWidgetFrame *option)
if (q->documentMode())
option->lineWidth = 0;
else
- option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
+ option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, q);
switch (pos) {
case QTabWidget::North:
@@ -318,7 +283,7 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
Q_D(const QTabWidget);
d->initBasicStyleOption(option);
- int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0, this);
+ int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, nullptr, this);
QSize t(0, d->stack->frameWidth());
if (d->tabs->isVisibleTo(const_cast<QTabWidget *>(this))) {
t = d->tabs->sizeHint();
@@ -358,7 +323,7 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
Constructs a tabbed widget with parent \a parent.
*/
QTabWidget::QTabWidget(QWidget *parent)
- : QWidget(*new QTabWidgetPrivate, parent, 0)
+ : QWidget(*new QTabWidgetPrivate, parent, { })
{
Q_D(QTabWidget);
d->init();
@@ -470,7 +435,7 @@ int QTabWidget::insertTab(int index, QWidget *w, const QString &label)
int QTabWidget::insertTab(int index, QWidget *w, const QIcon& icon, const QString &label)
{
Q_D(QTabWidget);
- if(!w)
+ if (!w)
return -1;
index = d->stack->insertWidget(index, w);
d->tabs->insertTab(index, icon, label);
@@ -543,8 +508,8 @@ bool QTabWidget::isTabEnabled(int index) const
}
/*!
- If \a enable is true, the page at position \a index is enabled; otherwise the page at position \a index is
- disabled. The page's tab is redrawn appropriately.
+ If \a enable is true, the page at position \a index is enabled; otherwise the page at
+ position \a index is disabled. The page's tab is redrawn appropriately.
QTabWidget uses QWidget::setEnabled() internally, rather than
keeping a separate flag.
@@ -565,6 +530,44 @@ void QTabWidget::setTabEnabled(int index, bool enable)
}
/*!
+ Returns true if the page at position \a index is visible; otherwise returns false.
+
+ \sa setTabVisible()
+ \since 5.15
+*/
+
+bool QTabWidget::isTabVisible(int index) const
+{
+ Q_D(const QTabWidget);
+ return d->tabs->isTabVisible(index);
+}
+
+/*!
+ If \a visible is true, the page at position \a index is visible; otherwise the page at
+ position \a index is hidden. The page's tab is redrawn appropriately.
+
+ \sa isTabVisible()
+ \since 5.15
+*/
+
+void QTabWidget::setTabVisible(int index, bool visible)
+{
+ Q_D(QTabWidget);
+ QWidget *widget = d->stack->widget(index);
+ bool currentVisible = d->tabs->isTabVisible(d->tabs->currentIndex());
+ d->tabs->setTabVisible(index, visible);
+ if (!visible) {
+ if (widget)
+ widget->setVisible(false);
+ } else if (!currentVisible) {
+ setCurrentIndex(index);
+ if (widget)
+ widget->setVisible(true);
+ }
+ setUpLayout();
+}
+
+/*!
\fn void QTabWidget::setCornerWidget(QWidget *widget, Qt::Corner corner)
Sets the given \a widget to be shown in the specified \a corner of the
@@ -573,13 +576,13 @@ void QTabWidget::setTabEnabled(int index, bool enable)
Only the horizontal element of the \a corner will be used.
- Passing 0 shows no widget in the corner.
+ Passing \nullptr shows no widget in the corner.
Any previously set corner widget is hidden.
All widgets set here will be deleted by the tab widget when it is
destroyed unless you separately reparent the widget after setting
- some other corner widget (or 0).
+ some other corner widget (or \nullptr).
Note: Corner widgets are designed for \l North and \l South tab positions;
other orientations are known to not work properly.
@@ -605,7 +608,7 @@ void QTabWidget::setCornerWidget(QWidget * widget, Qt::Corner corner)
}
/*!
- Returns the widget shown in the \a corner of the tab widget or 0.
+ Returns the widget shown in the \a corner of the tab widget or \nullptr.
*/
QWidget * QTabWidget::cornerWidget(Qt::Corner corner) const
{
@@ -682,7 +685,7 @@ void QTabWidget::setCurrentIndex(int index)
Returns the index position of the page occupied by the widget \a
w, or -1 if the widget cannot be found.
*/
-int QTabWidget::indexOf(QWidget* w) const
+int QTabWidget::indexOf(const QWidget *w) const
{
Q_D(const QTabWidget);
return d->stack->indexOf(w);
@@ -717,17 +720,17 @@ void QTabWidget::setTabBar(QTabBar* tb)
delete d->tabs;
d->tabs = tb;
setFocusProxy(d->tabs);
- connect(d->tabs, SIGNAL(currentChanged(int)),
- this, SLOT(_q_showTab(int)));
- connect(d->tabs, SIGNAL(tabMoved(int,int)),
- this, SLOT(_q_tabMoved(int,int)));
- connect(d->tabs, SIGNAL(tabBarClicked(int)),
- this, SIGNAL(tabBarClicked(int)));
- connect(d->tabs, SIGNAL(tabBarDoubleClicked(int)),
- this, SIGNAL(tabBarDoubleClicked(int)));
+ QObjectPrivate::connect(d->tabs, &QTabBar::currentChanged,
+ d, &QTabWidgetPrivate::showTab);
+ QObjectPrivate::connect(d->tabs, &QTabBar::tabMoved,
+ d, &QTabWidgetPrivate::tabMoved);
+ connect(d->tabs, &QTabBar::tabBarClicked,
+ this, &QTabWidget::tabBarClicked);
+ connect(d->tabs, &QTabBar::tabBarDoubleClicked,
+ this, &QTabWidget::tabBarDoubleClicked);
if (d->tabs->tabsClosable())
- connect(d->tabs, SIGNAL(tabCloseRequested(int)),
- this, SIGNAL(tabCloseRequested(int)));
+ connect(d->tabs, &QTabBar::tabCloseRequested,
+ this, &QTabWidget::tabCloseRequested);
tb->setExpanding(!documentMode());
setUpLayout();
}
@@ -749,7 +752,7 @@ QTabBar* QTabWidget::tabBar() const
sized.
*/
-void QTabWidgetPrivate::_q_showTab(int index)
+void QTabWidgetPrivate::showTab(int index)
{
Q_Q(QTabWidget);
if (index < stack->count() && index >= 0)
@@ -757,7 +760,7 @@ void QTabWidgetPrivate::_q_showTab(int index)
emit q->currentChanged(index);
}
-void QTabWidgetPrivate::_q_removeTab(int index)
+void QTabWidgetPrivate::removeTab(int index)
{
Q_Q(QTabWidget);
tabs->removeTab(index);
@@ -765,7 +768,7 @@ void QTabWidgetPrivate::_q_removeTab(int index)
q->tabRemoved(index);
}
-void QTabWidgetPrivate::_q_tabMoved(int from, int to)
+void QTabWidgetPrivate::tabMoved(int from, int to)
{
const QSignalBlocker blocker(stack);
QWidget *w = stack->widget(from);
@@ -841,26 +844,31 @@ QSize QTabWidget::sizeHint() const
if (d->leftCornerWidget)
lc = d->leftCornerWidget->sizeHint();
- if(d->rightCornerWidget)
+ if (d->rightCornerWidget)
rc = d->rightCornerWidget->sizeHint();
if (!d->dirty) {
QTabWidget *that = const_cast<QTabWidget*>(this);
that->setUpLayout(true);
}
- QSize s(d->stack->sizeHint());
+ QSize s;
+ for (int i=0; i< d->stack->count(); ++i) {
+ if (const QWidget* w = d->stack->widget(i)) {
+ if (d->tabs->isTabVisible(i))
+ s = s.expandedTo(w->sizeHint());
+ }
+ }
QSize t;
if (!d->isAutoHidden()) {
t = d->tabs->sizeHint();
if (usesScrollButtons())
t = t.boundedTo(QSize(200,200));
else
- t = t.boundedTo(QDesktopWidgetPrivate::size());
+ t = t.boundedTo(QGuiApplication::primaryScreen()->virtualGeometry().size());
}
QSize sz = basicSize(d->pos == North || d->pos == South, lc, rc, s, t);
- return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this)
- .expandedTo(QApplication::globalStrut());
+ return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this);
}
@@ -874,9 +882,9 @@ QSize QTabWidget::minimumSizeHint() const
Q_D(const QTabWidget);
QSize lc(0, 0), rc(0, 0);
- if(d->leftCornerWidget)
+ if (d->leftCornerWidget)
lc = d->leftCornerWidget->minimumSizeHint();
- if(d->rightCornerWidget)
+ if (d->rightCornerWidget)
rc = d->rightCornerWidget->minimumSizeHint();
if (!d->dirty) {
QTabWidget *that = const_cast<QTabWidget*>(this);
@@ -893,8 +901,7 @@ QSize QTabWidget::minimumSizeHint() const
initStyleOption(&opt);
opt.palette = palette();
opt.state = QStyle::State_None;
- return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this)
- .expandedTo(QApplication::globalStrut());
+ return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this);
}
/*!
@@ -908,13 +915,12 @@ int QTabWidget::heightForWidth(int width) const
opt.state = QStyle::State_None;
QSize zero(0,0);
- const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this)
- .expandedTo(QApplication::globalStrut());
+ const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this);
QSize lc(0, 0), rc(0, 0);
if (d->leftCornerWidget)
lc = d->leftCornerWidget->sizeHint();
- if(d->rightCornerWidget)
+ if (d->rightCornerWidget)
rc = d->rightCornerWidget->sizeHint();
if (!d->dirty) {
QTabWidget *that = const_cast<QTabWidget*>(this);
@@ -926,7 +932,7 @@ int QTabWidget::heightForWidth(int width) const
if (usesScrollButtons())
t = t.boundedTo(QSize(200,200));
else
- t = t.boundedTo(QDesktopWidgetPrivate::size());
+ t = t.boundedTo(QGuiApplication::primaryScreen()->virtualSize());
}
const bool tabIsHorizontal = (d->pos == North || d->pos == South);
@@ -939,7 +945,7 @@ int QTabWidget::heightForWidth(int width) const
QSize s(stackWidth, stackHeight);
QSize contentSize = basicSize(tabIsHorizontal, lc, rc, s, t);
- return (contentSize + padding).expandedTo(QApplication::globalStrut()).height();
+ return (contentSize + padding).height();
}
@@ -1108,14 +1114,14 @@ void QTabWidget::keyPressEvent(QKeyEvent *e)
if (((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) &&
count() > 1 && e->modifiers() & Qt::ControlModifier)
#ifdef QT_KEYPAD_NAVIGATION
- || QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right) && count() > 1
+ || QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right) && count() > 1
#endif
) {
int pageCount = d->tabs->count();
int page = currentIndex();
int dx = (e->key() == Qt::Key_Backtab || e->modifiers() & Qt::ShiftModifier) ? -1 : 1;
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
+ if (QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
dx = e->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
#endif
for (int pass = 0; pass < pageCount; ++pass) {
@@ -1133,7 +1139,7 @@ void QTabWidget::keyPressEvent(QKeyEvent *e)
) {
page = 0;
}
- if (d->tabs->isTabEnabled(page)) {
+ if (d->tabs->isTabEnabled(page) && d->tabs->isTabVisible(page)) {
setCurrentIndex(page);
break;
}
@@ -1146,8 +1152,8 @@ void QTabWidget::keyPressEvent(QKeyEvent *e)
}
/*!
- Returns the tab page at index position \a index or 0 if the \a
- index is out of range.
+ Returns the tab page at index position \a index or \nullptr if the
+ \a index is out of range.
*/
QWidget *QTabWidget::widget(int index) const
{
@@ -1167,7 +1173,7 @@ int QTabWidget::count() const
return d->tabs->count();
}
-#ifndef QT_NO_TOOLTIP
+#if QT_CONFIG(tooltip)
/*!
Sets the tab tool tip for the page at position \a index to \a tip.
@@ -1190,7 +1196,7 @@ QString QTabWidget::tabToolTip(int index) const
Q_D(const QTabWidget);
return d->tabs->tabToolTip(index);
}
-#endif // QT_NO_TOOLTIP
+#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(whatsthis)
/*!
@@ -1226,7 +1232,7 @@ QString QTabWidget::tabWhatsThis(int index) const
*/
void QTabWidget::tabInserted(int index)
{
- Q_UNUSED(index)
+ Q_UNUSED(index);
}
/*!
@@ -1237,7 +1243,7 @@ void QTabWidget::tabInserted(int index)
*/
void QTabWidget::tabRemoved(int index)
{
- Q_UNUSED(index)
+ Q_UNUSED(index);
}
/*!
@@ -1303,7 +1309,7 @@ void QTabWidget::setIconSize(const QSize &size)
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 dependant.
+ By default the value is style dependent.
\sa QTabBar::elideMode, usesScrollButtons, QStyle::SH_TabBar_ElideMode
*/
@@ -1326,7 +1332,7 @@ void QTabWidget::setElideMode(Qt::TextElideMode mode)
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.
+ By default the value is style dependent.
\sa elideMode, QTabBar::usesScrollButtons, QStyle::SH_TabBar_PreferNoArrows
*/
@@ -1401,6 +1407,20 @@ void QTabWidget::clear()
removeTab(0);
}
+QTabBar::Shape _q_tb_tabBarShapeFrom(QTabWidget::TabShape shape, QTabWidget::TabPosition position)
+{
+ const bool rounded = (shape == QTabWidget::Rounded);
+ if (position == QTabWidget::North)
+ return rounded ? QTabBar::RoundedNorth : QTabBar::TriangularNorth;
+ if (position == QTabWidget::South)
+ return rounded ? QTabBar::RoundedSouth : QTabBar::TriangularSouth;
+ if (position == QTabWidget::East)
+ return rounded ? QTabBar::RoundedEast : QTabBar::TriangularEast;
+ if (position == QTabWidget::West)
+ return rounded ? QTabBar::RoundedWest : QTabBar::TriangularWest;
+ return QTabBar::RoundedNorth;
+}
+
QT_END_NAMESPACE
#include "moc_qtabwidget.cpp"