diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index 5292d971ea2..aca4eec0e79 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -1470,6 +1470,22 @@ QStyleOptionTab::QStyleOptionTab(int version) The default value is QSize(-1, -1), i.e. an invalid size; */ +/*! + Constructs a QStyleOptionTabV4 object, initializing the members + variables to their default values. + */ + +QStyleOptionTabV4::QStyleOptionTabV4() : QStyleOptionTab(QStyleOptionTabV4::Version) +{ +} + +/*! + \variable QStyleOptionTabV4::tabIndex + \brief the index for the tab being represented. + + The default value is -1, i.e. a tab not on a tabbar; + */ + #endif // QT_CONFIG(tabbar) /*! diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h index 7f5edf42795..a8ce3b465ee 100644 --- a/src/widgets/styles/qstyleoption.h +++ b/src/widgets/styles/qstyleoption.h @@ -296,6 +296,14 @@ protected: QStyleOptionTab(int version); }; +class Q_WIDGETS_EXPORT QStyleOptionTabV4 : public QStyleOptionTab +{ +public: + enum StyleOptionVersion { Version = 4 }; + QStyleOptionTabV4(); + int tabIndex = -1; +}; + Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionTab::CornerWidgets) typedef Q_DECL_DEPRECATED QStyleOptionTab QStyleOptionTabV2; diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 7e8c9a60507..7fe46e24b64 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -6009,6 +6009,16 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_TabBarTabRightButton: { QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab); if (subRule.hasBox() || !subRule.hasNativeBorder()) { + if (se == SE_TabBarTabText) { + if (const QStyleOptionTabV4 *tab = qstyleoption_cast(opt)) { + const QTabBar *bar = qobject_cast(w); + const QRect optRect = bar && tab->tabIndex != -1 ? bar->tabRect(tab->tabIndex) : opt->rect; + const QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, optRect, opt->direction); + QStyleOptionTabV4 tabCopy(*tab); + tabCopy.rect = subRule.contentsRect(r); + return ParentStyle::subElementRect(se, &tabCopy, w); + } + } return ParentStyle::subElementRect(se, opt, w); } break; diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index aff95b09318..a7b115a1bc6 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -229,6 +229,8 @@ void QTabBarPrivate::initBasicStyleOption(QStyleOptionTab *option, int tabIndex) option->cornerWidgets |= QStyleOptionTab::RightCornerWidget; } #endif + if (QStyleOptionTabV4 *optv4 = qstyleoption_cast(option)) + optv4->tabIndex = tabIndex; } /*! @@ -628,7 +630,7 @@ QRect QTabBarPrivate::normalizedScrollRect(int index) // tab bar itself is in a different orientation. Q_Q(QTabBar); - QStyleOptionTab opt; + QStyleOptionTabV4 opt; q->initStyleOption(&opt, currentIndex); opt.rect = q->rect(); @@ -757,7 +759,7 @@ void QTabBarPrivate::layoutTab(int index) if (!(tab.leftWidget || tab.rightWidget)) return; - QStyleOptionTab opt; + QStyleOptionTabV4 opt; q->initStyleOption(&opt, index); if (tab.leftWidget) { QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabLeftButton, &opt, q); @@ -1003,7 +1005,7 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text) } if (d->closeButtonOnTabs) { - QStyleOptionTab opt; + QStyleOptionTabV4 opt; initStyleOption(&opt, index); ButtonPosition closeSide = (ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, nullptr, this); QAbstractButton *closeButton = new CloseButton(this); @@ -1574,7 +1576,7 @@ 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)) { - QStyleOptionTab opt; + QStyleOptionTabV4 opt; d->initBasicStyleOption(&opt, index); opt.text = d->tabList.at(index).text; QSize iconSize = tab->icon.isNull() ? QSize(0, 0) : opt.iconSize; @@ -1819,7 +1821,7 @@ void QTabBar::paintEvent(QPaintEvent *) for (int i = 0; i < d->tabList.count(); ++i) { if (!d->at(i)->visible) continue; - QStyleOptionTab tab; + QStyleOptionTabV4 tab; initStyleOption(&tab, i); if (d->paintWithOffsets && d->tabList[i].dragOffset != 0) { if (vertical) { @@ -1859,7 +1861,7 @@ void QTabBar::paintEvent(QPaintEvent *) // Draw the selected tab last to get it "on top" if (selected >= 0) { - QStyleOptionTab tab; + QStyleOptionTabV4 tab; initStyleOption(&tab, selected); if (d->paintWithOffsets && d->tabList[selected].dragOffset != 0) { if (vertical) @@ -2209,7 +2211,7 @@ void QTabBarPrivate::setupMovableTab() grabImage.fill(Qt::transparent); QStylePainter p(&grabImage, q); - QStyleOptionTab tab; + QStyleOptionTabV4 tab; q->initStyleOption(&tab, pressedIndex); tab.position = QStyleOptionTab::OnlyOneTab; if (verticalTabs(shape)) diff --git a/tests/manual/widgets/widgets/qtabbar/qtabbar.pro b/tests/manual/widgets/widgets/qtabbar/qtabbar.pro new file mode 100644 index 00000000000..b39c81493ba --- /dev/null +++ b/tests/manual/widgets/widgets/qtabbar/qtabbar.pro @@ -0,0 +1 @@ +SUBDIRS = stylesheet diff --git a/tests/manual/widgets/widgets/qtabbar/stylesheet/main.cpp b/tests/manual/widgets/widgets/qtabbar/stylesheet/main.cpp new file mode 100644 index 00000000000..02393f66f95 --- /dev/null +++ b/tests/manual/widgets/widgets/qtabbar/stylesheet/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** + ** + ** Copyright (C) 2020 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the test suite of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** 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. + ** + ** BSD License Usage + ** Alternatively, you may use this file under the terms of the BSD license + ** as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of The Qt Company Ltd nor the names of its + ** contributors may be used to endorse or promote products derived + ** from this software without specific prior written permission. + ** + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +// This test is for checking that when there is padding set on the stylesheet and the elide mode is +// set that it is correctly shown as elided and not clipped. + +#include +#include +#include + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + app.setStyleSheet("QTabBar::tab { padding-left: 20px; }\n"); + QIcon icon(":/v.ico"); + + QTabBar b; + b.setElideMode(Qt::ElideRight); + b.addTab(icon, "some text"); + b.resize(80,32); + b.show(); + + return app.exec(); +} diff --git a/tests/manual/widgets/widgets/qtabbar/stylesheet/res.qrc b/tests/manual/widgets/widgets/qtabbar/stylesheet/res.qrc new file mode 100644 index 00000000000..9d0bb8e0618 --- /dev/null +++ b/tests/manual/widgets/widgets/qtabbar/stylesheet/res.qrc @@ -0,0 +1,5 @@ + + + v.ico + + diff --git a/tests/manual/widgets/widgets/qtabbar/stylesheet/stylesheet.pro b/tests/manual/widgets/widgets/qtabbar/stylesheet/stylesheet.pro new file mode 100644 index 00000000000..4957503abc5 --- /dev/null +++ b/tests/manual/widgets/widgets/qtabbar/stylesheet/stylesheet.pro @@ -0,0 +1,5 @@ +QT += widgets +TEMPLATE = app +TARGET = stylesheet +RESOURCES += res.qrc +SOURCES += main.cpp diff --git a/tests/manual/widgets/widgets/qtabbar/stylesheet/v.ico b/tests/manual/widgets/widgets/qtabbar/stylesheet/v.ico new file mode 100644 index 00000000000..90dfbc9f9ba Binary files /dev/null and b/tests/manual/widgets/widgets/qtabbar/stylesheet/v.ico differ diff --git a/tests/manual/widgets/widgets/widgets.pro b/tests/manual/widgets/widgets/widgets.pro index 1fccb09d791..5a07e621e87 100644 --- a/tests/manual/widgets/widgets/widgets.pro +++ b/tests/manual/widgets/widgets/widgets.pro @@ -2,4 +2,5 @@ TEMPLATE = subdirs SUBDIRS = bigmenucreator \ defaultUpMenuBar \ multiscreen-menus \ - qtoolbutton/menuOnMultiScreens + qtoolbutton/menuOnMultiScreens \ + qtabbar