File indexing completed on 2024-04-28 05:47:24

0001 /*****************************************************************************
0002  *   Copyright 2007 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 
0023 #include <qtcurve-utils/qtprops.h>
0024 
0025 #include "qtcurve_p.h"
0026 #include "qtcurve_fonthelper.h"
0027 #include "argbhelper.h"
0028 #include "utils.h"
0029 #include "shortcuthandler.h"
0030 #include "windowmanager.h"
0031 #include "blurhelper.h"
0032 #include <common/config_file.h>
0033 
0034 #include "shadowhelper.h"
0035 
0036 #include <QFormLayout>
0037 #include <QProgressBar>
0038 #include <QToolButton>
0039 #include <QAbstractItemView>
0040 #include <QDialog>
0041 #include <QSplitter>
0042 #include <QMdiSubWindow>
0043 #include <QMainWindow>
0044 #include <QComboBox>
0045 #include <QTreeView>
0046 #include <QGroupBox>
0047 #include <QListView>
0048 #include <QCheckBox>
0049 #include <QRadioButton>
0050 #include <QTextEdit>
0051 #include <QFontMetrics>
0052 #include <QDial>
0053 #include <QLabel>
0054 #include <QStackedLayout>
0055 #include <QMenuBar>
0056 #include <QMouseEvent>
0057 #include <QScrollBar>
0058 #include <QWizard>
0059 #include <QDialogButtonBox>
0060 #include <QPushButton>
0061 #include <QHeaderView>
0062 #include <QLineEdit>
0063 #include <QDir>
0064 #include <QSettings>
0065 #include <QPixmapCache>
0066 #include <QTextStream>
0067 #include <QFileDialog>
0068 #include <QToolBox>
0069 #include <QFontDatabase>
0070 
0071 #include <QDebug>
0072 
0073 #ifdef QTC_QT5_ENABLE_KDE
0074 #include <QPrintDialog>
0075 #include <KIconThemes/KIconLoader>
0076 #include <KWidgetsAddons/KTitleWidget>
0077 #include <KXmlGui/KAboutApplicationDialog>
0078 #endif
0079 
0080 #include <qtcurve-utils/color.h>
0081 
0082 namespace QtCurve {
0083 
0084 template<typename T>
0085 static inline int
0086 horizontalAdvance(const QFontMetrics &fm, T &&text)
0087 {
0088 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
0089     return fm.horizontalAdvance(std::forward<T>(text));
0090 #else
0091     return fm.width(std::forward<T>(text));
0092 #endif
0093 }
0094 
0095 static const char *constBoldProperty = "qtc-set-bold";
0096 
0097 Style::FontHelper::FontHelper()
0098     : m_fntDB(new QFontDatabase())
0099 {}
0100 
0101 Style::FontHelper::~FontHelper()
0102 {
0103     delete m_fntDB;
0104 }
0105 
0106 QFont Style::FontHelper::fontStripStyleName(const QFont &f) const
0107 {
0108     const QString &styleName = f.styleName();
0109     if (styleName.isEmpty()) {
0110         // we can simply return the input font
0111         return f;
0112     } else {
0113         // Check for a mismatch between styleString and styleName; when
0114         // found the font probably had a style name set directly instead of
0115         // receiving it e.g. via the FontDialog. This means its attributes
0116         // may still correspond to the original font, not to the current style.
0117         // Do a database lookup to get a consistent QFont instance to work with,
0118         // so that methods like setWeight(), setStyle() will work as expected.
0119         QFont g = (m_fntDB->styleString(f) != styleName) ?
0120             m_fntDB->font(f.family(), styleName, f.pointSize())
0121             : QFont(f.family(), f.pointSize(), f.weight());
0122         if (auto s = f.pixelSize() > 0) {
0123             g.setPixelSize(s);
0124         }
0125         g.setStyleHint(f.styleHint(), f.styleStrategy());
0126         g.setStyle(f.style());
0127         if (f.underline()) {
0128             g.setUnderline(true);
0129         }
0130         if (f.strikeOut()) {
0131             g.setStrikeOut(true);
0132         }
0133         if (f.fixedPitch()) {
0134             g.setFixedPitch(true);
0135         }
0136         return g;
0137     }
0138 }
0139 
0140 void Style::FontHelper::setBold(QWidget *widget)
0141 {
0142     QVariant prop(widget->property(constBoldProperty));
0143     if (!prop.isValid() || !prop.toBool()) {
0144         QFont font = fontStripStyleName(widget->font());
0145         if (!font.bold()) {
0146             font.setBold(true);
0147             widget->setFont(font);
0148             widget->setProperty(constBoldProperty, true);
0149         }
0150     }
0151 }
0152 
0153 void Style::FontHelper::unSetBold(QWidget *widget)
0154 {
0155     QVariant prop(widget->property(constBoldProperty));
0156     if (prop.isValid() && prop.toBool()) {
0157         QFont font = fontStripStyleName(widget->font());
0158         font.setBold(false);
0159         widget->setFont(font);
0160         widget->setProperty(constBoldProperty, false);
0161     }
0162 }
0163 
0164 void
0165 Style::polish(QApplication *app)
0166 {
0167     // appName = getFile(app->arguments()[0]);
0168 
0169     if (appName == "kwin" || appName == "kwin_x11" || appName == "kwin_wayland") {
0170         theThemedApp = APP_KWIN;
0171     } else if (appName == "systemsettings" || appName == "systemsettings5") {
0172         theThemedApp = APP_SYSTEMSETTINGS;
0173     } else if ("plasma" == appName || appName.startsWith("plasma-")) {
0174         theThemedApp = APP_PLASMA;
0175     } else if ("krunner" == appName || "krunner_lock" == appName ||
0176                "kscreenlocker" == appName) {
0177         theThemedApp = APP_KRUNNER;
0178     } else if ("kontact" == appName) {
0179         theThemedApp = APP_KONTACT;
0180     } else if ("k3b" == appName) {
0181         theThemedApp = APP_K3B;
0182     } else if("arora" == appName) {
0183         theThemedApp = APP_ARORA;
0184     } else if("rekonq" == appName) {
0185         theThemedApp = APP_REKONQ;
0186     } else if("QtCreator" == QCoreApplication::applicationName()) {
0187         theThemedApp = APP_QTCREATOR;
0188     } else if("kdevelop" == appName || "kdevelop.bin" == appName) {
0189         theThemedApp = APP_KDEVELOP;
0190     } else if("soffice.bin" == appName) {
0191         theThemedApp = APP_OPENOFFICE;
0192     } else if("kdmgreet" == appName) {
0193         opts.forceAlternateLvCols = false;
0194     }
0195 
0196     qtcInfo("QtCurve: Application name: \"%s\"\n",
0197             appName.toLatin1().constData());
0198 
0199     if (theThemedApp == APP_REKONQ)
0200         opts.statusbarHiding=0;
0201     if(opts.menubarHiding)
0202         m_saveMenuBarStatus=opts.menubarApps.contains("kde") || opts.menubarApps.contains(appName);
0203     if(opts.statusbarHiding)
0204         m_saveStatusBarStatus=opts.statusbarApps.contains("kde") || opts.statusbarApps.contains(appName);
0205 
0206     if(!qtcIsFlatBgnd(opts.bgndAppearance) && opts.noBgndGradientApps.contains(appName))
0207         opts.bgndAppearance = APPEARANCE_FLAT;
0208     if(IMG_NONE!=opts.bgndImage.type && opts.noBgndImageApps.contains(appName))
0209         opts.bgndImage.type=IMG_NONE;
0210     if(SHADE_NONE!=opts.menuStripe && opts.noMenuStripeApps.contains(appName))
0211         opts.menuStripe=SHADE_NONE;
0212 
0213     if((100!=opts.bgndOpacity || 100!=opts.dlgOpacity) && (opts.noBgndOpacityApps.contains(appName) || appName.endsWith(".kss")))
0214         opts.bgndOpacity=opts.dlgOpacity=100;
0215     if (100 != opts.menuBgndOpacity &&
0216         opts.noMenuBgndOpacityApps.contains(appName))
0217         opts.menuBgndOpacity = 100;
0218 
0219     if (APP_KWIN == theThemedApp) {
0220         opts.bgndAppearance = APPEARANCE_FLAT;
0221     } else if(APP_OPENOFFICE == theThemedApp) {
0222         opts.scrollbarType=SCROLLBAR_WINDOWS;
0223         if(APPEARANCE_FADE == opts.menuitemAppearance)
0224             opts.menuitemAppearance = APPEARANCE_FLAT;
0225         opts.borderMenuitems=opts.etchEntry=false;
0226 
0227         if(opts.useHighlightForMenu && blendOOMenuHighlight(QApplication::palette(), m_highlightCols[ORIGINAL_SHADE]))
0228         {
0229             m_ooMenuCols=new QColor [TOTAL_SHADES+1];
0230             shadeColors(tint(popupMenuCols()[ORIGINAL_SHADE], m_highlightCols[ORIGINAL_SHADE], 0.5), m_ooMenuCols);
0231         }
0232         opts.menubarHiding=opts.statusbarHiding=HIDE_NONE;
0233         opts.square|=SQUARE_POPUP_MENUS|SQUARE_TOOLTIPS;
0234         if(!qtcIsFlatBgnd(opts.menuBgndAppearance) && 0 == opts.lighterPopupMenuBgnd)
0235             opts.lighterPopupMenuBgnd=1; // shade so that we dont have 3d-ish borders...
0236         opts.menuBgndAppearance = APPEARANCE_FLAT;
0237     }
0238 
0239     ParentStyleClass::polish(app);
0240     if (opts.hideShortcutUnderline) {
0241         app->installEventFilter(m_shortcutHandler);
0242     }
0243 }
0244 
0245 void Style::polish(QPalette &palette)
0246 {
0247     int  contrast(QSettings(QLatin1String("Trolltech")).value("/Qt/KDE/contrast", DEFAULT_CONTRAST).toInt());
0248     bool newContrast(false);
0249 
0250     if(contrast<0 || contrast>10)
0251         contrast=DEFAULT_CONTRAST;
0252 
0253     if (contrast != opts.contrast) {
0254         opts.contrast = contrast;
0255         newContrast = true;
0256     }
0257 
0258     bool newHighlight(newContrast ||
0259                       m_highlightCols[ORIGINAL_SHADE]!=palette.color(QPalette::Active, QPalette::Highlight)),
0260         newGray(newContrast ||
0261                 m_backgroundCols[ORIGINAL_SHADE]!=palette.color(QPalette::Active, QPalette::Background)),
0262         newButton(newContrast ||
0263                   m_buttonCols[ORIGINAL_SHADE]!=palette.color(QPalette::Active, QPalette::Button)),
0264         newSlider(m_sliderCols && m_highlightCols!=m_sliderCols && SHADE_BLEND_SELECTED == opts.shadeSliders &&
0265                   (newButton || newHighlight)),
0266         newDefBtn(m_defBtnCols &&
0267                   (opts.defBtnIndicator != IND_COLORED ||
0268                    opts.shadeSliders != SHADE_BLEND_SELECTED) &&
0269                   noneOf(opts.defBtnIndicator, IND_SELECTED, IND_GLOW) &&
0270                   (newContrast || newButton || newHighlight)),
0271         newComboBtn(m_comboBtnCols &&
0272                     noneOf(m_comboBtnCols, m_highlightCols, m_sliderCols) &&
0273                     opts.comboBtn == SHADE_BLEND_SELECTED &&
0274                     (newButton || newHighlight)),
0275         newSortedLv(m_sortedLvColors && ((SHADE_BLEND_SELECTED == opts.sortedLv && m_defBtnCols!=m_sortedLvColors &&
0276                                             m_sliderCols!=m_sortedLvColors && m_comboBtnCols!=m_sortedLvColors) ||
0277                                            SHADE_DARKEN == opts.sortedLv) &&
0278                     (newContrast || (opts.lvButton ? newButton : newGray))),
0279         newCheckRadioSelCols(m_checkRadioSelCols && ((SHADE_BLEND_SELECTED == opts.crColor && m_defBtnCols!=m_checkRadioSelCols &&
0280                                                        m_sliderCols!=m_checkRadioSelCols && m_comboBtnCols!=m_checkRadioSelCols &&
0281                                                        m_sortedLvColors!=m_checkRadioSelCols) ||
0282                                                       SHADE_DARKEN == opts.crColor) &&
0283                              (newContrast || newButton)),
0284         newProgressCols(m_progressCols && SHADE_BLEND_SELECTED == opts.progressColor &&
0285                         m_sliderCols!=m_progressCols && m_comboBtnCols!=m_progressCols &&
0286                         m_sortedLvColors!=m_progressCols && m_checkRadioSelCols!=m_progressCols && (newContrast || newButton));
0287 
0288     if (newGray) {
0289         shadeColors(palette.color(QPalette::Active, QPalette::Background), m_backgroundCols);
0290         if (oneOf(opts.bgndImage.type, IMG_PLAIN_RINGS, IMG_BORDERED_RINGS,
0291                   IMG_SQUARE_RINGS) ||
0292             oneOf(opts.menuBgndImage.type, IMG_PLAIN_RINGS,
0293                   IMG_BORDERED_RINGS, IMG_SQUARE_RINGS)) {
0294             qtcCalcRingAlphas(&m_backgroundCols[ORIGINAL_SHADE]);
0295             if (m_usePixmapCache) {
0296                 QPixmapCache::clear();
0297             }
0298         }
0299     }
0300 
0301     if (newButton)
0302         shadeColors(palette.color(QPalette::Active, QPalette::Button),
0303                     m_buttonCols);
0304 
0305     if (newHighlight)
0306         shadeColors(palette.color(QPalette::Active, QPalette::Highlight),
0307                     m_highlightCols);
0308 
0309 // Dont set these here, they will be updated in setDecorationColors()...
0310 //     shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), m_focusCols);
0311 //     if(opts.coloredMouseOver)
0312 //         shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), m_mouseOverCols);
0313 
0314     setMenuColors(palette.color(QPalette::Active, QPalette::Background));
0315 
0316     if (newSlider) {
0317         shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0318                              m_buttonCols[ORIGINAL_SHADE]), m_sliderCols);
0319     }
0320 
0321     if (newDefBtn) {
0322         if (opts.defBtnIndicator == IND_TINT) {
0323             shadeColors(tint(m_buttonCols[ORIGINAL_SHADE],
0324                              m_highlightCols[ORIGINAL_SHADE],
0325                              DEF_BNT_TINT), m_defBtnCols);
0326         } else if (opts.defBtnIndicator != IND_GLOW) {
0327             shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0328                                  m_buttonCols[ORIGINAL_SHADE]), m_defBtnCols);
0329         }
0330     }
0331 
0332     if (newComboBtn) {
0333         shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0334                              m_buttonCols[ORIGINAL_SHADE]), m_comboBtnCols);
0335     }
0336     if (newSortedLv) {
0337         if (opts.sortedLv == SHADE_BLEND_SELECTED) {
0338             shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0339                                  opts.lvButton ? m_buttonCols[ORIGINAL_SHADE] :
0340                                  m_backgroundCols[ORIGINAL_SHADE]),
0341                         m_sortedLvColors);
0342         } else {
0343             shadeColors(shade(opts.lvButton ? m_buttonCols[ORIGINAL_SHADE] :
0344                               m_backgroundCols[ORIGINAL_SHADE],
0345                               LV_HEADER_DARK_FACTOR), m_sortedLvColors);
0346         }
0347     }
0348 
0349     if (m_sidebarButtonsCols && opts.shadeSliders != SHADE_BLEND_SELECTED &&
0350         opts.defBtnIndicator != IND_COLORED) {
0351         shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0352                              m_buttonCols[ORIGINAL_SHADE]),
0353                     m_sidebarButtonsCols);
0354     }
0355 
0356     switch (opts.shadeCheckRadio) {
0357     default:
0358         m_checkRadioCol = palette.color(QPalette::Active,
0359                                          opts.crButton ? QPalette::ButtonText :
0360                                          QPalette::Text);
0361         break;
0362     case SHADE_BLEND_SELECTED:
0363     case SHADE_SELECTED:
0364         m_checkRadioCol = palette.color(QPalette::Active, QPalette::Highlight);
0365         break;
0366     case SHADE_CUSTOM:
0367         m_checkRadioCol = opts.customCheckRadioColor;
0368     }
0369 
0370     if (newCheckRadioSelCols) {
0371         if (opts.crColor == SHADE_BLEND_SELECTED) {
0372             shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0373                                  m_buttonCols[ORIGINAL_SHADE]),
0374                         m_checkRadioSelCols);
0375         } else {
0376             shadeColors(shade(m_buttonCols[ORIGINAL_SHADE],
0377                               LV_HEADER_DARK_FACTOR), m_checkRadioSelCols);
0378         }
0379     }
0380     if (newProgressCols) {
0381         shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE],
0382                              m_backgroundCols[ORIGINAL_SHADE]),
0383                     m_progressCols);
0384     }
0385     if (theThemedApp == APP_OPENOFFICE && opts.useHighlightForMenu &&
0386         (newGray || newHighlight)) {
0387         if (blendOOMenuHighlight(palette, m_highlightCols[ORIGINAL_SHADE])) {
0388             if (!m_ooMenuCols) {
0389                 m_ooMenuCols = new QColor[TOTAL_SHADES + 1];
0390             }
0391             shadeColors(tint(popupMenuCols()[ORIGINAL_SHADE],
0392                              m_highlightCols[ORIGINAL_SHADE], 0.5),
0393                         m_ooMenuCols);
0394         } else if (m_ooMenuCols) {
0395             delete []m_ooMenuCols;
0396             m_ooMenuCols = 0L;
0397         }
0398     }
0399 
0400     palette.setColor(QPalette::Active, QPalette::Light, m_backgroundCols[0]);
0401     palette.setColor(QPalette::Active, QPalette::Dark,
0402                      m_backgroundCols[QTC_STD_BORDER]);
0403     palette.setColor(QPalette::Inactive, QPalette::Light, m_backgroundCols[0]);
0404     palette.setColor(QPalette::Inactive, QPalette::Dark,
0405                      m_backgroundCols[QTC_STD_BORDER]);
0406     palette.setColor(QPalette::Inactive, QPalette::WindowText,
0407                      palette.color(QPalette::Active, QPalette::WindowText));
0408     palette.setColor(QPalette::Disabled, QPalette::Light, m_backgroundCols[0]);
0409     palette.setColor(QPalette::Disabled, QPalette::Dark,
0410                      m_backgroundCols[QTC_STD_BORDER]);
0411 
0412     palette.setColor(QPalette::Disabled, QPalette::Base,
0413                      palette.color(QPalette::Active, QPalette::Background));
0414     palette.setColor(QPalette::Disabled, QPalette::Background,
0415                      palette.color(QPalette::Active, QPalette::Background));
0416 
0417     // Fix KDE4's palette...
0418     if (palette.color(QPalette::Active, QPalette::Highlight) !=
0419         palette.color(QPalette::Inactive, QPalette::Highlight)) {
0420         m_inactiveChangeSelectionColor = true;
0421     }
0422     for (int i = QPalette::WindowText;i < QPalette::NColorRoles;i++) {
0423         // if (i != QPalette::Highlight && i != QPalette::HighlightedText)
0424         palette.setColor(QPalette::Inactive, (QPalette::ColorRole)i,
0425                          palette.color(QPalette::Active,
0426                                        (QPalette::ColorRole)i));
0427     }
0428 
0429     // Force this to be re-generated!
0430     if (opts.menuStripe == SHADE_BLEND_SELECTED) {
0431         opts.customMenuStripeColor = Qt::black;
0432     }
0433 #ifdef QTC_QT5_ENABLE_KDE
0434     // Only set palette here...
0435     if (qApp) {
0436         setDecorationColors();
0437     }
0438 #endif
0439 }
0440 
0441 void Style::polish(QWidget *widget)
0442 {
0443     // TODO:
0444     //      Reorganize this polish function
0445     if (!widget)
0446         return;
0447 
0448     prePolish(widget);
0449     QtcQWidgetProps qtcProps(widget);
0450     bool enableMouseOver(opts.highlightFactor || opts.coloredMouseOver);
0451 
0452     if (opts.buttonEffect != EFFECT_NONE && !USE_CUSTOM_ALPHAS(opts) &&
0453         isNoEtchWidget(widget)) {
0454         qtcProps->noEtch = true;
0455     }
0456 
0457     m_windowManager->registerWidget(widget);
0458     m_shadowHelper->registerWidget(widget);
0459 
0460     // Need to register all widgets to blur helper, in order to have proper
0461     // blur_behind region set have proper regions removed for opaque widgets.
0462     // Note: that the helper does nothing as long as compositing and ARGB are
0463     // not enabled
0464     const bool isDialog = qtcIsDialog(widget->window());
0465     if ((opts.menuBgndOpacity != 100 &&
0466          (qobject_cast<QMenu*>(widget) ||
0467           // TODO temporary solution only
0468           widget->inherits("QComboBoxPrivateContainer"))) ||
0469         (opts.bgndOpacity != 100 && (!widget->window() || !isDialog)) ||
0470         (opts.dlgOpacity != 100 && (!widget->window() || isDialog))) {
0471         m_blurHelper->registerWidget(widget);
0472     }
0473 
0474     // Sometimes get background errors with QToolBox (e.g. in Bespin config),
0475     // and setting WA_StyledBackground seems to fix this,..
0476     if (qtcIsCustomBgnd(opts) ||
0477         oneOf(opts.groupBox, FRAME_SHADED, FRAME_FADED)) {
0478         switch (widget->windowType()) {
0479         case Qt::Window:
0480         case Qt::Sheet:
0481         case Qt::Dialog: {
0482             // For non-transparent widgets, only need to set
0483             // WA_StyledBackground - and PE_Widget will be called to
0484             // render background...
0485             widget->setAttribute(Qt::WA_StyledBackground);
0486             break;
0487         }
0488         case Qt::Popup:
0489             // we currently don't want that kind of gradient on menus etc
0490         case Qt::Drawer:
0491         case Qt::Tool:
0492             // this we exclude as it is used for dragging of icons etc
0493         default:
0494             break;
0495         }
0496         if (qobject_cast<QSlider*>(widget)) {
0497             widget->setBackgroundRole(QPalette::NoRole);
0498         }
0499         if (widget->autoFillBackground() && widget->parentWidget() &&
0500             widget->parentWidget()->objectName() == "qt_scrollarea_viewport" &&
0501             qtcCheckType<QAbstractScrollArea>(getParent<2>(widget)) &&
0502             qtcCheckType<QToolBox>(getParent<3>(widget))) {
0503             widget->parentWidget()->setAutoFillBackground(false);
0504             widget->setAutoFillBackground(false);
0505         }
0506     }
0507     if (qobject_cast<QMdiSubWindow*>(widget)) {
0508         widget->setAttribute(Qt::WA_StyledBackground);
0509     }
0510     if (opts.menubarHiding && qobject_cast<QMainWindow*>(widget) &&
0511         static_cast<QMainWindow*>(widget)->menuWidget()) {
0512         widget->installEventFilter(this);
0513         if (m_saveMenuBarStatus)
0514             static_cast<QMainWindow*>(widget)->menuWidget()
0515                 ->installEventFilter(this);
0516         if (m_saveMenuBarStatus && qtcMenuBarHidden(appName)) {
0517             static_cast<QMainWindow*>(widget)->menuWidget()->setHidden(true);
0518             if (BLEND_TITLEBAR || opts.menubarHiding & HIDE_KWIN ||
0519                 opts.windowBorder & WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR)
0520                 emitMenuSize(static_cast<QMainWindow*>(widget)->menuWidget(), 0);
0521         }
0522     }
0523 
0524     if (opts.statusbarHiding && qobject_cast<QMainWindow*>(widget)) {
0525         QList<QStatusBar*> sb = getStatusBars(widget);
0526 
0527         if (sb.count()) {
0528             widget->installEventFilter(this);
0529             for (QStatusBar *statusBar: const_(sb)) {
0530                 if (m_saveStatusBarStatus) {
0531                     statusBar->installEventFilter(this);
0532                 }
0533                 if (m_saveStatusBarStatus && qtcStatusBarHidden(appName)) {
0534                     statusBar->setHidden(true);
0535                 }
0536             }
0537             setSbProp(widget);
0538             emitStatusBarState(sb.first());
0539         }
0540     }
0541 
0542     // Enable hover effects in all itemviews
0543     if (QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>(widget))
0544     {
0545         QWidget *viewport=itemView->viewport();
0546         viewport->setAttribute(Qt::WA_Hover);
0547 
0548         if(opts.forceAlternateLvCols &&
0549            viewport->autoFillBackground() && // Dolphins Folders panel
0550            //255==viewport->palette().color(itemView->viewport()->backgroundRole()).alpha() && // KFilePlacesView
0551            !widget->inherits("KFilePlacesView") &&
0552            // Exclude non-editable combo popup...
0553            !(opts.gtkComboMenus && widget->inherits("QComboBoxListView") &&
0554              qtcCheckType<QComboBox>(getParent<2>(widget)) &&
0555              !static_cast<QComboBox*>(getParent<2>(widget))->isEditable()) &&
0556            // Exclude KAboutDialog...
0557            !qtcCheckKDEType(getParent<5>(widget), KAboutApplicationDialog) &&
0558            (qobject_cast<QTreeView*>(widget) ||
0559             (qobject_cast<QListView*>(widget) &&
0560              ((QListView*)widget)->viewMode() != QListView::IconMode)))
0561             itemView->setAlternatingRowColors(true);
0562     }
0563 
0564     if(APP_KONTACT==theThemedApp && qobject_cast<QToolButton *>(widget))
0565         ((QToolButton *)widget)->setAutoRaise(true);
0566 
0567     if(enableMouseOver &&
0568        (qobject_cast<QPushButton*>(widget) ||
0569         qobject_cast<QAbstractButton*>(widget) ||
0570         qobject_cast<QComboBox*>(widget) ||
0571         qobject_cast<QAbstractSpinBox*>(widget) ||
0572         qobject_cast<QCheckBox*>(widget) ||
0573         qobject_cast<QGroupBox*>(widget) ||
0574         qobject_cast<QRadioButton*>(widget) ||
0575         qobject_cast<QSplitterHandle*>(widget) ||
0576         qobject_cast<QSlider*>(widget) ||
0577         qobject_cast<QHeaderView*>(widget) ||
0578         qobject_cast<QTabBar*>(widget) ||
0579         qobject_cast<QAbstractScrollArea*>(widget) ||
0580         qobject_cast<QTextEdit*>(widget) ||
0581         qobject_cast<QLineEdit*>(widget) ||
0582         qobject_cast<QDial*>(widget) ||
0583         // qobject_cast<QDockWidget*>(widget) ||
0584         widget->inherits("QWorkspaceTitleBar") ||
0585         widget->inherits("QDockSeparator") ||
0586         widget->inherits("QDockWidgetSeparator")))
0587         widget->setAttribute(Qt::WA_Hover, true);
0588 
0589     if (qobject_cast<QSplitterHandle*>(widget)) {
0590         widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
0591     } else if (qobject_cast<QScrollBar*>(widget)) {
0592         if(enableMouseOver)
0593             widget->setAttribute(Qt::WA_Hover, true);
0594         widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
0595         if (!opts.gtkScrollViews) {
0596             widget->installEventFilter(this);
0597         }
0598     } else if (qobject_cast<QAbstractScrollArea*>(widget) &&
0599                widget->inherits("KFilePlacesView")) {
0600         if (qtcIsCustomBgnd(opts))
0601             polishScrollArea(static_cast<QAbstractScrollArea*>(widget), true);
0602         widget->installEventFilter(this);
0603     } else if (qobject_cast<QProgressBar*>(widget)) {
0604         if (widget->palette().color(QPalette::Inactive,
0605                                     QPalette::HighlightedText) !=
0606             widget->palette().color(QPalette::Active,
0607                                     QPalette::HighlightedText)) {
0608             QPalette pal(widget->palette());
0609             pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
0610                          pal.color(QPalette::Active,
0611                                    QPalette::HighlightedText));
0612             widget->setPalette(pal);
0613         }
0614 
0615         if (opts.boldProgress)
0616             m_fntHelper->setBold(widget);
0617         widget->installEventFilter(this);
0618     } else if (qobject_cast<QMenuBar*>(widget)) {
0619         if (BLEND_TITLEBAR || opts.menubarHiding & HIDE_KWIN ||
0620             opts.windowBorder &
0621             WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR) {
0622             emitMenuSize(widget, PREVIEW_MDI == m_isPreview ||
0623                          !widget->isVisible() ? 0 : widget->rect().height());
0624         }
0625         if (qtcIsCustomBgnd(opts))
0626             widget->setBackgroundRole(QPalette::NoRole);
0627 
0628         widget->setAttribute(Qt::WA_Hover, true);
0629 
0630         // if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars)
0631         widget->installEventFilter(this);
0632 
0633         setMenuTextColors(widget, true);
0634     } else if(qobject_cast<QLabel*>(widget)) {
0635         widget->installEventFilter(this);
0636         if (opts.windowDrag == WM_DRAG_ALL &&
0637             ((QLabel*)widget)->textInteractionFlags()
0638             .testFlag(Qt::TextSelectableByMouse) &&
0639             qtcCheckType<QFrame>(widget->parentWidget()) &&
0640             qtcCheckKDEType(getParent<2>(widget), KTitleWidget))
0641             ((QLabel*)widget)->setTextInteractionFlags(
0642                 ((QLabel*)widget)->textInteractionFlags() &
0643                 ~Qt::TextSelectableByMouse);
0644     } else if (qobject_cast<QAbstractScrollArea*>(widget)) {
0645         if (qtcIsCustomBgnd(opts))
0646             polishScrollArea(static_cast<QAbstractScrollArea *>(widget));
0647         if (!opts.gtkScrollViews && (((QFrame*)widget)->frameWidth() > 0)) {
0648             widget->installEventFilter(this);
0649         }
0650         if (APP_KONTACT == theThemedApp && widget->parentWidget()) {
0651             QWidget *frame = scrollViewFrame(widget->parentWidget());
0652 
0653             if (frame) {
0654                 frame->installEventFilter(this);
0655                 m_sViewContainers[frame].insert(widget);
0656                 connect(qtcSlot(widget, destroyed),
0657                         qtcSlot(this, widgetDestroyed));
0658                 connect(qtcSlot(frame, destroyed),
0659                         qtcSlot(this, widgetDestroyed));
0660             }
0661         }
0662     } else if (qobject_cast<QDialog*>(widget) &&
0663                widget->inherits("QPrintPropertiesDialog") &&
0664                widget->parentWidget() && widget->parentWidget()->window() &&
0665                widget->window() && widget->window()->windowTitle().isEmpty() &&
0666                !widget->parentWidget()->window()->windowTitle().isEmpty()) {
0667         widget->window()->setWindowTitle(widget->parentWidget()->window()
0668                                          ->windowTitle());
0669     } else if (widget->inherits("QWhatsThat")) {
0670         QPalette pal(widget->palette());
0671         QColor   shadow(pal.shadow().color());
0672 
0673         shadow.setAlpha(32);
0674         pal.setColor(QPalette::Shadow, shadow);
0675         widget->setPalette(pal);
0676         widget->setMask(QRegion(widget->rect().adjusted(0, 0, -6, -6))+QRegion(widget->rect().adjusted(6, 6, 0, 0)));
0677     } else if (qobject_cast<QDockWidget*>(widget) &&
0678                qtcCheckType<QSplitter>(widget->parentWidget()) &&
0679                qtcCheckType(getParent<2>(widget), "KFileWidget"))
0680         ((QDockWidget*)widget)->setTitleBarWidget(new QtCurveDockWidgetTitleBar(widget));
0681 
0682     if (widget->inherits("QTipLabel") && !qtcIsFlat(opts.tooltipAppearance)) {
0683         widget->setBackgroundRole(QPalette::NoRole);
0684         // TODO: turn this into addAlphaChannel
0685         widget->setAttribute(Qt::WA_TranslucentBackground);
0686     }
0687 
0688     if (!widget->isWindow())
0689         if (QFrame *frame = qobject_cast<QFrame*>(widget)) {
0690             // kill ugly frames...
0691             if (QFrame::Box == frame->frameShape() ||
0692                 QFrame::Panel == frame->frameShape() ||
0693                 QFrame::WinPanel == frame->frameShape()) {
0694                 frame->setFrameShape(QFrame::StyledPanel);
0695             }
0696             //else if (QFrame::HLine==frame->frameShape() || QFrame::VLine==frame->frameShape())
0697             widget->installEventFilter(this);
0698 
0699             if (qtcCheckKDEType(widget->parent(), KTitleWidget)) {
0700                 if (qtcIsCustomBgnd(opts)) {
0701                     frame->setAutoFillBackground(false);
0702                 } else {
0703                     frame->setBackgroundRole(QPalette::Window);
0704                 }
0705                 QLayout *layout(frame->layout());
0706                 if (layout) {
0707                     layout->setMargin(0);
0708                 }
0709             }
0710 
0711             QComboBox *p = nullptr;
0712             if (opts.gtkComboMenus &&
0713                 (p = qtcObjCast<QComboBox>(getParent<2>(widget))) &&
0714                 !p->isEditable()) {
0715                 QPalette pal(widget->palette());
0716                 QColor   col(popupMenuCols()[ORIGINAL_SHADE]);
0717 
0718                 if (!qtcIsFlatBgnd(opts.menuBgndAppearance) ||
0719                    100 != opts.menuBgndOpacity ||
0720                     !(opts.square & SQUARE_POPUP_MENUS))
0721                     col.setAlphaF(0);
0722 
0723                 pal.setBrush(QPalette::Active, QPalette::Base, col);
0724                 pal.setBrush(QPalette::Active, QPalette::Window, col);
0725                 widget->setPalette(pal);
0726                 if(opts.shadePopupMenu)
0727                     setMenuTextColors(widget, false);
0728             }
0729         }
0730 
0731     if (qobject_cast<QMenu*>(widget)) {
0732         if (opts.lighterPopupMenuBgnd || opts.shadePopupMenu) {
0733             QPalette pal(widget->palette());
0734             pal.setBrush(QPalette::Active, QPalette::Window,
0735                          popupMenuCols()[ORIGINAL_SHADE]);
0736             widget->setPalette(pal);
0737             if (opts.shadePopupMenu) {
0738                 setMenuTextColors(widget, false);
0739             }
0740         }
0741         if (opts.menuBgndOpacity != 100 ||
0742             !(opts.square & SQUARE_POPUP_MENUS)) {
0743             widget->setAttribute(Qt::WA_NoSystemBackground);
0744             addAlphaChannel(widget);
0745         }
0746     }
0747 
0748     if ((!qtcIsFlatBgnd(opts.menuBgndAppearance) ||
0749          opts.menuBgndOpacity != 100 ||
0750          !(opts.square & SQUARE_POPUP_MENUS)) &&
0751         widget->inherits("QComboBoxPrivateContainer")) {
0752         widget->installEventFilter(this);
0753         widget->setAttribute(Qt::WA_NoSystemBackground);
0754         addAlphaChannel(widget);
0755     }
0756 
0757     bool parentIsToolbar(false);
0758 
0759     // Using dark menubars - konqueror's combo box texts get messed up. Seems
0760     // to be when a plain QWidget has widget->setBackgroundRole(QPalette::Window);
0761     // and widget->setAutoFillBackground(false); set (below). These only happen
0762     // if 'parentIsToolbar' - so dont bather detecting this if the widget
0763     // is a plain QWidget
0764     //
0765     // QWidget QComboBoxListView QComboBoxPrivateContainer SearchBarCombo KToolBar KonqMainWindow
0766     // QWidget KCompletionBox KLineEdit SearchBarCombo KToolBar KonqMainWindow
0767     if(strcmp(widget->metaObject()->className(), "QWidget"))
0768     {
0769         QWidget *wid=widget ? widget->parentWidget() : 0L;
0770 
0771         while(wid && !parentIsToolbar) {
0772             parentIsToolbar=qobject_cast<QToolBar*>(wid);
0773             wid=wid->parentWidget();
0774         }
0775     }
0776 
0777     if (APP_QTCREATOR == theThemedApp &&
0778         qobject_cast<QMainWindow*>(widget) &&
0779         static_cast<QMainWindow*>(widget)->menuWidget()) {
0780         // As of 2.8.1, QtCreator still uses it's own style by default.
0781         // Have no idea what the **** they are thinking.
0782         static_cast<QMainWindow*>(widget)->menuWidget()->setStyle(this);
0783     }
0784 
0785     if (APP_QTCREATOR == theThemedApp && qobject_cast<QDialog*>(widget) &&
0786         qtcCheckKDEType(widget, QFileDialog)) {
0787 
0788         QToolBar *tb = getToolBarChild(widget);
0789         if (tb) {
0790             int size = pixelMetric(PM_ToolBarIconSize);
0791             tb->setIconSize(QSize(size, size));
0792             tb->setMinimumSize(QSize(size + 14, size + 14));
0793             setStyleRecursive(tb, this, size + 4);
0794         }
0795     }
0796 
0797     if(parentIsToolbar && (qobject_cast<QComboBox *>(widget) ||
0798                            qobject_cast<QLineEdit *>(widget)))
0799         widget->setFont(QApplication::font());
0800 
0801     if (qobject_cast<QMenuBar*>(widget) || qobject_cast<QToolBar*>(widget) ||
0802         parentIsToolbar)
0803         widget->setBackgroundRole(QPalette::Window);
0804 
0805     if (!qtcIsFlat(opts.toolbarAppearance) && parentIsToolbar) {
0806         widget->setAutoFillBackground(false);
0807     }
0808 
0809     if (theThemedApp == APP_SYSTEMSETTINGS &&
0810         qobject_cast<QTabWidget*>(getParent<2>(widget)) &&
0811         qobject_cast<QFrame*>(widget) &&
0812         ((QFrame*)widget)->frameShape() != QFrame::NoFrame &&
0813         qobject_cast<QFrame*>(widget->parentWidget())) {
0814         ((QFrame*)widget)->setFrameShape(QFrame::NoFrame);
0815     }
0816 
0817     if (QLayout *layout = widget->layout()) {
0818         // explicitly check public layout classes,
0819         // QMainWindowLayout doesn't work here
0820         if (qobject_cast<QBoxLayout*>(layout) ||
0821             qobject_cast<QFormLayout*>(layout) ||
0822             qobject_cast<QGridLayout*>(layout) ||
0823             qobject_cast<QStackedLayout*>(layout)) {
0824             polishLayout(layout);
0825         }
0826     }
0827 
0828     if ((theThemedApp == APP_K3B &&
0829          widget->inherits("K3b::ThemedHeader") &&
0830          qobject_cast<QFrame*>(widget)) ||
0831         widget->inherits("KColorPatch")) {
0832         ((QFrame*)widget)->setLineWidth(0);
0833         ((QFrame*)widget)->setFrameShape(QFrame::NoFrame);
0834     }
0835 
0836     if (theThemedApp == APP_KDEVELOP && !opts.stdSidebarButtons &&
0837         widget->inherits("Sublime::IdealButtonBarWidget") && widget->layout()) {
0838         widget->layout()->setSpacing(0);
0839         widget->layout()->setMargin(0);
0840     }
0841 
0842     QWidget *window=widget->window();
0843 
0844     if ((100 != opts.bgndOpacity && qtcIsWindow(window)) ||
0845         (100 != opts.dlgOpacity && qtcIsDialog(window))) {
0846         widget->installEventFilter(this);
0847         if (widget->inherits("KFilePlacesView")) {
0848             widget->setAutoFillBackground(false);
0849             widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
0850         }
0851     }
0852 
0853 #ifdef QTC_QT5_ENABLE_KDE
0854     // Make file selection button in QPrintDialog appear more KUrlRequester like...
0855     if (qtcCheckType<QPrintDialog>(getParent<3>(widget)) &&
0856         qobject_cast<QToolButton*>(widget) &&
0857         qobject_cast<QGroupBox*>(widget->parentWidget()) &&
0858         static_cast<QToolButton*>(widget)->text() == QLatin1String("...")) {
0859         static_cast<QToolButton*>(widget)->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
0860         static_cast<QToolButton*>(widget)->setAutoRaise(false);
0861     }
0862 #endif
0863 }
0864 
0865 void
0866 Style::unpolish(QApplication *app)
0867 {
0868     if (opts.hideShortcutUnderline)
0869         app->removeEventFilter(m_shortcutHandler);
0870     ParentStyleClass::unpolish(app);
0871 }
0872 
0873 void Style::unpolish(QWidget *widget)
0874 {
0875     if (!widget)
0876         return;
0877     widget->removeEventFilter(this);
0878     m_windowManager->unregisterWidget(widget);
0879     m_shadowHelper->unregisterWidget(widget);
0880     m_blurHelper->unregisterWidget(widget);
0881 
0882     // Sometimes get background errors with QToolBox (e.g. in Bespin config),
0883     // and setting WA_StyledBackground seems to fix this,..
0884     if (qtcIsCustomBgnd(opts) || opts.groupBox == FRAME_SHADED ||
0885         opts.groupBox == FRAME_FADED) {
0886         switch (widget->windowType()) {
0887         case Qt::Window:
0888         case Qt::Sheet:
0889         case Qt::Dialog:
0890             widget->setAttribute(Qt::WA_StyledBackground, false);
0891             break;
0892         case Qt::Popup:
0893             // we currently don't want that kind of gradient on menus etc
0894         case Qt::Drawer:
0895         case Qt::Tool:
0896             // this we exclude as it is used for dragging of icons etc
0897         default:
0898             break;
0899         }
0900 
0901         if (qobject_cast<QSlider*>(widget)) {
0902             widget->setBackgroundRole(QPalette::Window);
0903         }
0904     }
0905 
0906     if (qobject_cast<QMdiSubWindow*>(widget))
0907         widget->setAttribute(Qt::WA_StyledBackground, false);
0908 
0909     if (opts.menubarHiding && qobject_cast<QMainWindow*>(widget) &&
0910         static_cast<QMainWindow*>(widget)->menuWidget()) {
0911         if (m_saveMenuBarStatus) {
0912             static_cast<QMainWindow*>(widget)->menuWidget()
0913                 ->removeEventFilter(this);
0914         }
0915     }
0916 
0917     if (opts.statusbarHiding && qobject_cast<QMainWindow*>(widget)) {
0918         if (m_saveStatusBarStatus) {
0919             for (QStatusBar *statusBar: getStatusBars(widget)) {
0920                 statusBar->removeEventFilter(this);
0921             }
0922         }
0923     }
0924 
0925     if(qobject_cast<QPushButton*>(widget) ||
0926        qobject_cast<QComboBox*>(widget) ||
0927        qobject_cast<QAbstractSpinBox*>(widget) ||
0928        qobject_cast<QCheckBox*>(widget) ||
0929        qobject_cast<QGroupBox*>(widget) ||
0930        qobject_cast<QRadioButton*>(widget) ||
0931        qobject_cast<QSplitterHandle*>(widget) ||
0932        qobject_cast<QSlider*>(widget) ||
0933        qobject_cast<QHeaderView*>(widget) ||
0934        qobject_cast<QTabBar*>(widget) ||
0935        qobject_cast<QAbstractScrollArea*>(widget) ||
0936        qobject_cast<QTextEdit*>(widget) ||
0937        qobject_cast<QLineEdit*>(widget) ||
0938        qobject_cast<QDial*>(widget) ||
0939        // qobject_cast<QDockWidget *>(widget) ||
0940        widget->inherits("QWorkspaceTitleBar") ||
0941        widget->inherits("QDockSeparator") ||
0942        widget->inherits("QDockWidgetSeparator"))
0943         widget->setAttribute(Qt::WA_Hover, false);
0944     if (qobject_cast<QScrollBar*>(widget)) {
0945         widget->setAttribute(Qt::WA_Hover, false);
0946         if (opts.round != ROUND_NONE && !opts.flatSbarButtons)
0947             widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
0948     } else if (qobject_cast<QProgressBar*>(widget)) {
0949         if(opts.boldProgress)
0950             m_fntHelper->unSetBold(widget);
0951         m_progressBars.remove((QProgressBar *)widget);
0952     } else if (qobject_cast<QMenuBar*>(widget)) {
0953         widget->setAttribute(Qt::WA_Hover, false);
0954 
0955         if(qtcIsCustomBgnd(opts))
0956             widget->setBackgroundRole(QPalette::Background);
0957 
0958         if(SHADE_WINDOW_BORDER==opts.shadeMenubars || opts.customMenuTextColor || SHADE_BLEND_SELECTED==opts.shadeMenubars ||
0959            SHADE_SELECTED==opts.shadeMenubars || (SHADE_CUSTOM==opts.shadeMenubars &&TOO_DARK(m_menubarCols[ORIGINAL_SHADE])))
0960             widget->setPalette(QApplication::palette());
0961     } else if (/*!opts.gtkScrollViews && */
0962         qobject_cast<QAbstractScrollArea*>(widget)) {
0963         if (APP_KONTACT==theThemedApp && widget->parentWidget()) {
0964             QWidget *frame = scrollViewFrame(widget->parentWidget());
0965             if (frame) {
0966                 if (m_sViewContainers.contains(frame)) {
0967                     m_sViewContainers[frame].remove(widget);
0968                     if (0 == m_sViewContainers[frame].count()) {
0969                         frame->removeEventFilter(this);
0970                         m_sViewContainers.remove(frame);
0971                         disconnect(frame, &QWidget::destroyed,
0972                                    this, &Style::widgetDestroyed);
0973                     }
0974                 }
0975             }
0976         }
0977     } else if (qobject_cast<QDockWidget *>(widget) &&
0978                ((QDockWidget*)widget)->titleBarWidget() &&
0979                qobject_cast<QtCurveDockWidgetTitleBar*>(
0980                    ((QDockWidget*)widget)->titleBarWidget()) &&
0981                qtcCheckType<QSplitter>(widget->parentWidget()) &&
0982                getParent<3>(widget) &&
0983                qtcCheckType(getParent<2>(widget), "KFileWidget")) {
0984         delete ((QDockWidget *)widget)->titleBarWidget();
0985         ((QDockWidget*)widget)->setTitleBarWidget(0L);
0986     } else if (opts.boldProgress && "CE_CapacityBar"==widget->objectName()) {
0987         m_fntHelper->unSetBold(widget);
0988     }
0989 
0990     if (widget->inherits("QTipLabel") && !qtcIsFlat(opts.tooltipAppearance)) {
0991         widget->setAttribute(Qt::WA_NoSystemBackground, false);
0992         widget->clearMask();
0993     }
0994 
0995     if (!widget->isWindow())
0996         if (QFrame *frame = qobject_cast<QFrame *>(widget)) {
0997             if (qtcCheckKDEType(widget->parent(), KTitleWidget)) {
0998                 if(qtcIsCustomBgnd(opts)) {
0999                     frame->setAutoFillBackground(true);
1000                 } else {
1001                     frame->setBackgroundRole(QPalette::Base);
1002                 }
1003                 QLayout *layout(frame->layout());
1004 
1005                 if(layout) {
1006                     layout->setMargin(6);
1007                 }
1008             }
1009 
1010             QComboBox *p = nullptr;
1011             if (opts.gtkComboMenus &&
1012                 (p = qtcObjCast<QComboBox>(getParent<2>(widget))) &&
1013                 !p->isEditable()) {
1014                 widget->setPalette(QApplication::palette());
1015             }
1016         }
1017 
1018     if (qobject_cast<QMenu*>(widget)) {
1019         // TODO remove these
1020         widget->setAttribute(Qt::WA_NoSystemBackground, false);
1021         widget->clearMask();
1022 
1023         if (opts.lighterPopupMenuBgnd || opts.shadePopupMenu) {
1024             widget->setPalette(QApplication::palette());
1025         }
1026     }
1027 
1028     if((!qtcIsFlatBgnd(opts.menuBgndAppearance) || 100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) &&
1029        widget->inherits("QComboBoxPrivateContainer")) {
1030         widget->setAttribute(Qt::WA_NoSystemBackground, false);
1031         widget->clearMask();
1032     }
1033 
1034     if (widget && (qobject_cast<QMenuBar*>(widget) ||
1035                    qobject_cast<QToolBar*>(widget) ||
1036                    qobject_cast<QToolBar*>(widget->parent()))) {
1037         widget->setBackgroundRole(QPalette::Button);
1038     }
1039 }
1040 
1041 bool Style::eventFilter(QObject *object, QEvent *event)
1042 {
1043     if (qobject_cast<QMenuBar*>(object) &&
1044         dynamic_cast<QMouseEvent*>(event)) {
1045         if (updateMenuBarEvent((QMouseEvent*)event, (QMenuBar*)object)) {
1046             return true;
1047         }
1048     }
1049 
1050     if (event->type() == QEvent::Show &&
1051         qobject_cast<QAbstractScrollArea*>(object) &&
1052         object->inherits("KFilePlacesView")) {
1053         QWidget *view = ((QAbstractScrollArea*)object)->viewport();
1054         QPalette palette = view->palette();
1055         QColor color = ((QWidget*)object)->palette().window().color();
1056 
1057         if (qtcIsCustomBgnd(opts))
1058             color.setAlphaF(0.0);
1059 
1060         palette.setColor(view->backgroundRole(), color);
1061         view->setPalette(palette);
1062         object->removeEventFilter(this);
1063     }
1064 
1065     bool isSViewCont = (APP_KONTACT == theThemedApp &&
1066                         m_sViewContainers.contains((QWidget*)object));
1067     if ((!opts.gtkScrollViews &&
1068          qobject_cast<QAbstractScrollArea*>(object)) || isSViewCont) {
1069         QPoint pos;
1070         switch (event->type()) {
1071         case QEvent::MouseMove:
1072         case QEvent::MouseButtonPress:
1073         case QEvent::MouseButtonRelease:
1074             pos = ((QMouseEvent*)event)->pos();
1075             break;
1076         case QEvent::Wheel:
1077             pos=((QWheelEvent*)event)->pos();
1078         default:
1079             break;
1080         }
1081 
1082         if (!pos.isNull()) {
1083             QAbstractScrollArea *area = 0L;
1084             QPoint mapped(pos);
1085 
1086             if (isSViewCont) {
1087                 QSet<QWidget*>::ConstIterator it =
1088                     m_sViewContainers[(QWidget*)object].begin();
1089                 QSet<QWidget*>::ConstIterator end =
1090                     m_sViewContainers[(QWidget*)object].end();
1091 
1092                 for (;it != end && !area;++it) {
1093                     if ((*it)->isVisible()) {
1094                         mapped = (*it)->mapFrom((QWidget*)object, pos);
1095                         if ((*it)->rect().adjusted(0, 0, 4, 4).contains(mapped)) {
1096                             area = (QAbstractScrollArea*)(*it);
1097                         }
1098                     }
1099                 }
1100             } else {
1101                 area = (QAbstractScrollArea*)object;
1102             }
1103 
1104             if (area) {
1105                 QScrollBar *sbars[2] = {
1106                     area->verticalScrollBar(),
1107                     area->horizontalScrollBar()
1108                 };
1109 
1110                 for (int i = 0;i < 2;++i) {
1111                     if (sbars[i]) {
1112                         QRect r(i ? 0 : area->rect().right()-3,
1113                                 i ? area->rect().bottom()-3 : 0,
1114                                 sbars[i]->rect().width(),
1115                                 sbars[i]->rect().height());
1116 
1117                         if (r.contains(pos) ||
1118                             (sbars[i] == m_sViewSBar &&
1119                              (QEvent::MouseMove == event->type() ||
1120                               QEvent::MouseButtonRelease == event->type()))) {
1121                             if (QEvent::Wheel != event->type()) {
1122                                 struct HackEvent : public QMouseEvent {
1123                                     void set(const QPoint &mapped, bool vert)
1124                                         {
1125                                             l = QPointF(vert ? 0 : mapped.x(),
1126                                                         vert ? mapped.y() : 0);
1127                                             s = QPointF(s.x() + (vert ? 0 : -3),
1128                                                         s.y() + (vert ? -3 : 0));
1129                                         }
1130                                 };
1131                                 ((HackEvent*)event)->set(mapped, 0 == i);
1132                             }
1133                             sbars[i]->event(event);
1134                             if (QEvent::MouseButtonPress == event->type()) {
1135                                 m_sViewSBar = sbars[i];
1136                             } else if (QEvent::MouseButtonRelease ==
1137                                        event->type()) {
1138                                 m_sViewSBar = 0L;
1139                             }
1140                             return true;
1141                         }
1142                     }
1143                 }
1144             }
1145         }
1146     }
1147 
1148     switch((int)(event->type())) {
1149     case QEvent::Timer:
1150     case QEvent::Move:
1151         return false; // just for performance - they can occur really often
1152     case QEvent::Resize:
1153         if(!(opts.square & SQUARE_POPUP_MENUS) &&
1154            object->inherits("QComboBoxPrivateContainer")) {
1155             QWidget *widget = static_cast<QWidget*>(object);
1156             if (Utils::hasAlphaChannel(widget)) {
1157                 widget->clearMask();
1158             } else {
1159                 widget->setMask(windowMask(widget->rect(),
1160                                            opts.round > ROUND_SLIGHT));
1161             }
1162             return false;
1163         } else if ((BLEND_TITLEBAR ||
1164                  opts.windowBorder &
1165                  WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR ||
1166                  opts.menubarHiding & HIDE_KWIN) &&
1167                 qobject_cast<QMenuBar*>(object)) {
1168             QResizeEvent *re = static_cast<QResizeEvent*>(event);
1169 
1170             if (re->size().height() != re->oldSize().height()) {
1171                 emitMenuSize((QMenuBar*)object,
1172                              PREVIEW_MDI == m_isPreview ||
1173                              !((QMenuBar*)object)->isVisible() ? 0 :
1174                              re->size().height());
1175             }
1176         }
1177         break;
1178     case QEvent::ShortcutOverride:
1179         if ((opts.menubarHiding || opts.statusbarHiding) &&
1180             qobject_cast<QMainWindow*>(object)) {
1181             QMainWindow *window = static_cast<QMainWindow*>(object);
1182 
1183             if (window->isVisible()) {
1184                 if (opts.menubarHiding & HIDE_KEYBOARD &&
1185                     window->menuWidget()) {
1186                     QKeyEvent *k = static_cast<QKeyEvent*>(event);
1187 
1188                     if (k->modifiers() & Qt::ControlModifier &&
1189                         k->modifiers() & Qt::AltModifier &&
1190                         Qt::Key_M == k->key()) {
1191                         toggleMenuBar(window);
1192                     }
1193                 }
1194                 if (opts.statusbarHiding & HIDE_KEYBOARD) {
1195                     QKeyEvent *k = static_cast<QKeyEvent*>(event);
1196 
1197                     if(k->modifiers()&Qt::ControlModifier && k->modifiers()&Qt::AltModifier && Qt::Key_S==k->key())
1198                         toggleStatusBar(window);
1199                 }
1200             }
1201         }
1202         break;
1203     case QEvent::ShowToParent:
1204         if (qobject_cast<QMenuBar *>(object)) {
1205             if(opts.menubarHiding && m_saveMenuBarStatus && qtcMenuBarHidden(appName))
1206                 static_cast<QMenuBar *>(object)->setHidden(true);
1207 #ifdef Q_OS_MACOS
1208                 if (opts.nonnativeMenubarApps.contains(appName)) {
1209                     QMenuBar *mnb = static_cast<QMenuBar*>(object);
1210                     if (mnb->isNativeMenuBar()) {
1211                         mnb->setNativeMenuBar(false);
1212                         mnb->setHidden(false);
1213                         mnb->setVisible(true);
1214                         if (!opts.currentNonnativeMenubarApps.contains(appName)) {
1215                             opts.currentNonnativeMenubarApps << appName;
1216                         }
1217                     }
1218                 } else if ((QGuiApplication::platformName() == QLatin1String("cocoa"))
1219                         && opts.currentNonnativeMenubarApps.contains(appName)) {
1220                     // only force the native menubar on applications that were forced
1221                     // to use something else before!
1222                     static_cast<QMenuBar*>(object)->setNativeMenuBar(true);
1223                     opts.currentNonnativeMenubarApps.remove(appName);
1224                 }
1225 #endif
1226         }
1227         if(opts.statusbarHiding && m_saveStatusBarStatus && qobject_cast<QStatusBar *>(object) &&
1228            qtcStatusBarHidden(appName))
1229             static_cast<QStatusBar *>(object)->setHidden(true);
1230         break;
1231     case QEvent::PaletteChange: {
1232         QWidget *widget = qtcToWidget(object);
1233 
1234         if (widget && widget->isWindow() &&
1235             (qtcIsDialog(widget) || qtcIsWindow(widget))) {
1236             setBgndProp(widget, opts.bgndAppearance,
1237                         IMG_NONE != opts.bgndImage.type);
1238         }
1239         break;
1240     }
1241     case QEvent::Paint: {
1242         if ((!qtcIsFlatBgnd(opts.menuBgndAppearance) ||
1243              opts.menuBgndImage.type != IMG_NONE ||
1244              opts.menuBgndOpacity != 100 ||
1245              !(opts.square & SQUARE_POPUP_MENUS)) &&
1246             object->inherits("QComboBoxPrivateContainer")) {
1247             QWidget *widget = qtcToWidget(object);
1248             QPainter p(widget);
1249             QRect r(widget->rect());
1250             double radius = opts.round >= ROUND_FULL ? 5.0 : 2.5;
1251             QStyleOption opt;
1252             opt.init(widget);
1253             const QColor *use(popupMenuCols(&opt));
1254 
1255             p.setClipRegion(static_cast<QPaintEvent*>(event)->region());
1256             if (!opts.popupBorder) {
1257                 p.setRenderHint(QPainter::Antialiasing, true);
1258                 p.setPen(use[ORIGINAL_SHADE]);
1259                 p.drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, radius));
1260                 QPAINTER_RENDERHINT_AA_MAYBE_OFF(&p);
1261             }
1262             if (!(opts.square&SQUARE_POPUP_MENUS))
1263                 p.setClipRegion(windowMask(r, opts.round>ROUND_SLIGHT),
1264                                 Qt::IntersectClip);
1265 
1266             // In case the gradient uses alpha, we need to fill with the background colour - this makes it consistent with Gtk.
1267             if(100==opts.menuBgndOpacity)
1268                 p.fillRect(r, opt.palette.brush(QPalette::Background));
1269             drawBackground(&p, widget, BGND_MENU);
1270             if (opts.popupBorder) {
1271                 EGradientBorder border=qtcGetGradient(opts.menuBgndAppearance, &opts)->border;
1272 
1273                 p.setClipping(false);
1274                 p.setPen(use[QTC_STD_BORDER]);
1275                 // For now dont round combos - getting weird effects with shadow/clipping in Gtk2 style :-(
1276                 if(opts.square&SQUARE_POPUP_MENUS) // || isCombo)
1277                     drawRect(&p, r);
1278                 else
1279                 {
1280                     p.setRenderHint(QPainter::Antialiasing, true);
1281                     p.drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, radius));
1282                 }
1283 
1284                 if(qtcUseBorder(border) && APPEARANCE_FLAT!=opts.menuBgndAppearance)
1285                 {
1286                     QRect ri(r.adjusted(1, 1, -1, -1));
1287 
1288                     p.setPen(use[0]);
1289                     if(GB_LIGHT==border)
1290                     {
1291                         if(opts.square&SQUARE_POPUP_MENUS) // || isCombo)
1292                             drawRect(&p, ri);
1293                         else
1294                             p.drawPath(buildPath(ri, WIDGET_OTHER, ROUNDED_ALL, radius-1.0));
1295                     }
1296                     else if(opts.square&SQUARE_POPUP_MENUS) // || isCombo)
1297                     {
1298                         if(GB_3D!=border)
1299                         {
1300                             p.drawLine(ri.x(), ri.y(), ri.x()+ri.width()-1,  ri.y());
1301                             p.drawLine(ri.x(), ri.y(), ri.x(), ri.y()+ri.height()-1);
1302                         }
1303                         p.setPen(use[FRAME_DARK_SHADOW]);
1304                         p.drawLine(ri.x(), ri.y()+ri.height()-1, ri.x()+ri.width()-1,  ri.y()+ri.height()-1);
1305                         p.drawLine(ri.x()+ri.width()-1, ri.y(), ri.x()+ri.width()-1,  ri.y()+ri.height()-1);
1306                     }
1307                     else
1308                     {
1309                         QPainterPath tl,
1310                             br;
1311 
1312                         buildSplitPath(ri, ROUNDED_ALL, radius-1.0, tl, br);
1313                         if(GB_3D!=border)
1314                             p.drawPath(tl);
1315                         p.setPen(use[FRAME_DARK_SHADOW]);
1316                         p.drawPath(br);
1317                     }
1318                 }
1319             }
1320         } else if (m_clickedLabel == object &&
1321                    qobject_cast<QLabel*>(object) &&
1322                    ((QLabel*)object)->buddy() &&
1323                    ((QLabel*)object)->buddy()->isEnabled()) {
1324             // paint focus rect
1325             QLabel                *lbl = (QLabel *)object;
1326             QPainter              painter(lbl);
1327             QStyleOptionFocusRect opts;
1328 
1329             opts.palette = lbl->palette();
1330             opts.rect    = QRect(0, 0, lbl->width(), lbl->height());
1331             drawPrimitive(PE_FrameFocusRect, &opts, &painter, lbl);
1332         } else {
1333             QFrame *frame = qobject_cast<QFrame*>(object);
1334 
1335             if (frame)
1336             {
1337                 if(QFrame::HLine==frame->frameShape() || QFrame::VLine==frame->frameShape())
1338                 {
1339                     QPainter painter(frame);
1340                     QRect    r(QFrame::HLine==frame->frameShape()
1341                                ? QRect(frame->rect().x(), frame->rect().y()+ (frame->rect().height()/2), frame->rect().width(), 1)
1342                                : QRect(frame->rect().x()+(frame->rect().width()/2),  frame->rect().y(), 1, frame->rect().height()));
1343 
1344                     drawFadedLine(&painter, r, backgroundColors(frame->palette().window().color())[QTC_STD_BORDER], true, true,
1345                                   QFrame::HLine==frame->frameShape());
1346                     return true;
1347                 }
1348                 else
1349                     return false;
1350             }
1351         }
1352         break;
1353     }
1354     case QEvent::MouseButtonPress:
1355         if(dynamic_cast<QMouseEvent*>(event) && qobject_cast<QLabel*>(object) && ((QLabel *)object)->buddy())
1356         {
1357             QLabel      *lbl = (QLabel *)object;
1358             QMouseEvent *mev = (QMouseEvent *)event;
1359 
1360             if (lbl->rect().contains(mev->pos()))
1361             {
1362                 m_clickedLabel=lbl;
1363                 lbl->repaint();
1364             }
1365         }
1366         break;
1367     case QEvent::MouseButtonRelease:
1368         if(dynamic_cast<QMouseEvent*>(event) && qobject_cast<QLabel*>(object) && ((QLabel *)object)->buddy())
1369         {
1370             QLabel      *lbl = (QLabel *)object;
1371             QMouseEvent *mev = (QMouseEvent *)event;
1372 
1373             if(m_clickedLabel)
1374             {
1375                 m_clickedLabel=0;
1376                 lbl->update();
1377             }
1378 
1379             // set focus to the buddy...
1380             if (lbl->rect().contains(mev->pos()))
1381                 ((QLabel *)object)->buddy()->setFocus(Qt::ShortcutFocusReason);
1382         }
1383         break;
1384     case QEvent::StyleChange:
1385     case QEvent::Show:
1386     {
1387         QProgressBar *bar = qobject_cast<QProgressBar *>(object);
1388 
1389         if(bar)
1390         {
1391             m_progressBars.insert(bar);
1392             if (!m_progressBarAnimateTimer) {
1393                 if (opts.animatedProgress || (0 == bar->minimum() && 0 == bar->maximum())) {
1394                     // we know we'll need a timer, start it at once
1395                     if (!m_timer.isValid())
1396                         m_timer.start();
1397                     m_progressBarAnimateFps = constProgressBarFps;
1398                     m_progressBarAnimateTimer = startTimer(1000/m_progressBarAnimateFps);
1399                 }
1400             }
1401         } else if (!(opts.square & SQUARE_POPUP_MENUS) &&
1402                    object->inherits("QComboBoxPrivateContainer")) {
1403             QWidget *widget = static_cast<QWidget*>(object);
1404             if (Utils::hasAlphaChannel(widget)) {
1405                 widget->clearMask();
1406             } else {
1407                 widget->setMask(windowMask(widget->rect(),
1408                                            opts.round > ROUND_SLIGHT));
1409             }
1410             return false;
1411         } else if ((BLEND_TITLEBAR ||
1412                   opts.windowBorder &
1413                   WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR ||
1414                   opts.menubarHiding & HIDE_KWIN) &&
1415                  qobject_cast<QMenuBar*>(object)) {
1416             QMenuBar *mb=(QMenuBar*)object;
1417             emitMenuSize((QMenuBar*)mb, PREVIEW_MDI==m_isPreview ||
1418                          !((QMenuBar *)mb)->isVisible() ? 0 :
1419                          mb->size().height(), true);
1420         } else if (QEvent::Show==event->type()) {
1421             QWidget *widget = qtcToWidget(object);
1422 
1423             if(widget && widget->isWindow() &&
1424                (qtcIsWindow(widget) || qtcIsDialog(widget))) {
1425                 setBgndProp(widget, opts.bgndAppearance,
1426                             IMG_NONE != opts.bgndImage.type);
1427                 int opacity = (qtcIsDialog(widget) ? opts.dlgOpacity :
1428                                opts.bgndOpacity);
1429                 setOpacityProp(widget, (unsigned short)opacity);
1430             }
1431         }
1432         break;
1433     }
1434     case QEvent::Close:
1435     case QEvent::Destroy:
1436     case QEvent::Hide: {
1437         if ((BLEND_TITLEBAR ||
1438              opts.windowBorder &
1439              WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR ||
1440              opts.menubarHiding & HIDE_KWIN) &&
1441            qobject_cast<QMenuBar*>(object)) {
1442             QMenuBar *mb = (QMenuBar*)object;
1443             emitMenuSize((QMenuBar*)mb, 0);
1444         }
1445         // if(m_hoverWidget && object==m_hoverWidget) {
1446         //     // m_pos.setX(-1);
1447         //     // m_pos.setY(-1);
1448         //     m_hoverWidget=0L;
1449         // }
1450 
1451         // The Destroy event is sent from ~QWidget, which happens after ~QProgressBar - therefore, we can't cast to a QProgressBar.
1452         // So we have to check on object.
1453         if (object && !m_progressBars.isEmpty()) {
1454             m_progressBars.remove(reinterpret_cast<QProgressBar*>(object));
1455             if (m_progressBars.isEmpty() && m_progressBarAnimateTimer) {
1456                 killTimer(m_progressBarAnimateTimer);
1457                 m_progressBarAnimateTimer = 0;
1458             }
1459         }
1460         break;
1461     }
1462     case QEvent::Enter:
1463         break;
1464     case QEvent::Leave:
1465         // if(m_hoverWidget && object==m_hoverWidget)
1466         // {
1467         //     // m_pos.setX(-1);
1468         //     // m_pos.setY(-1);
1469         //     m_hoverWidget=0L;
1470         //     ((QWidget *)object)->repaint();
1471         // }
1472         break;
1473     case QEvent::MouseMove:  // Only occurs for widgets with mouse tracking enabled
1474         break;
1475     case QEvent::FocusIn:
1476     case QEvent::FocusOut:
1477         break;
1478     case QEvent::WindowActivate:
1479         if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars && qobject_cast<QMenuBar *>(object))
1480         {
1481             m_active=true;
1482             ((QWidget *)object)->repaint();
1483             return false;
1484         }
1485         break;
1486     case QEvent::WindowDeactivate:
1487         if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars && qobject_cast<QMenuBar *>(object))
1488         {
1489             m_active=false;
1490             ((QWidget *)object)->repaint();
1491             return false;
1492         }
1493         break;
1494     default:
1495         break;
1496     }
1497 
1498     return ParentStyleClass::eventFilter(object, event);
1499 }
1500 
1501 void Style::timerEvent(QTimerEvent *event)
1502 {
1503     if (event->timerId() == m_progressBarAnimateTimer) {
1504         bool hasAnimation = false;
1505         m_animateStep = m_timer.elapsed() / (1000 / constProgressBarFps);
1506         for (QProgressBar *bar: const_(m_progressBars)) {
1507             if ((opts.animatedProgress && 0 == m_animateStep % 2 &&
1508                  bar->value() != bar->minimum() &&
1509                  bar->value() != bar->maximum()) ||
1510                 (0 == bar->minimum() && 0 == bar->maximum())) {
1511                 bar->update();
1512                 hasAnimation = true;
1513             }
1514         }
1515         if (Q_UNLIKELY(!hasAnimation && m_progressBarAnimateFps == constProgressBarFps)) {
1516             // go back to "idling frequency" mode.
1517             killTimer(m_progressBarAnimateTimer);
1518             m_progressBarAnimateTimer = 0;
1519         }
1520     }
1521 
1522     event->ignore();
1523 }
1524 
1525 int
1526 Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
1527                    const QWidget *widget) const
1528 {
1529     prePolish(widget);
1530     switch((unsigned)metric) {
1531     case PM_ToolTipLabelFrameWidth:
1532         if (opts.round != ROUND_NONE && !(opts.square & SQUARE_TOOLTIPS))
1533             return 3;
1534         return ParentStyleClass::pixelMetric(metric, option, widget);
1535     case PM_MdiSubWindowFrameWidth:
1536         return 3;
1537     case PM_DockWidgetTitleMargin:
1538         if (!(opts.dwtSettings & DWT_TEXT_ALIGN_AS_PER_TITLEBAR) ||
1539             opts.titlebarAlignment == ALIGN_LEFT)
1540             return 4;
1541         return 0;
1542     case PM_DockWidgetTitleBarButtonMargin:
1543         return 4;
1544     case PM_DockWidgetFrameWidth:
1545         return 2;
1546     case PM_ToolBarExtensionExtent:
1547         return 15;
1548 #ifndef QTC_QT5_ENABLE_KDE
1549     case PM_SmallIconSize:
1550         return 16;
1551     case PM_ToolBarIconSize:
1552         return 22;
1553     case PM_IconViewIconSize:
1554     case PM_LargeIconSize:
1555         return 32;
1556 #else
1557     case PM_TabCloseIndicatorWidth:
1558     case PM_TabCloseIndicatorHeight:
1559     case PM_SmallIconSize:
1560     case PM_ButtonIconSize:
1561         return KIconLoader::global()->currentSize(KIconLoader::Small);
1562     case PM_ToolBarIconSize:
1563         return KIconLoader::global()->currentSize(KIconLoader::Toolbar);
1564     case PM_IconViewIconSize:
1565     case PM_LargeIconSize:
1566         return KIconLoader::global()->currentSize(KIconLoader::Dialog);
1567     case PM_MessageBoxIconSize:
1568         // TODO return KIconLoader::global()->currentSize(KIconLoader::MessageBox);
1569         return KIconLoader::SizeHuge;
1570 #endif
1571     case PM_SubMenuOverlap:
1572         return -2;
1573     case PM_ScrollView_ScrollBarSpacing:
1574         return opts.etchEntry ? 2 : 3;
1575     case PM_MenuPanelWidth:
1576         return (opts.popupBorder ?
1577                 pixelMetric(PM_DefaultFrameWidth, option, widget) : 0);
1578     case PM_SizeGripSize:
1579         return SIZE_GRIP_SIZE;
1580     case PM_TabBarScrollButtonWidth:
1581         return 18;
1582     case PM_HeaderMargin:
1583         return 3;
1584     case PM_DefaultChildMargin:
1585         return isOOWidget(widget) ? 2 : 6;
1586     case PM_DefaultTopLevelMargin:
1587         return 9;
1588     case PM_LayoutHorizontalSpacing:
1589     case PM_LayoutVerticalSpacing:
1590         return -1; // use layoutSpacing
1591     case PM_DefaultLayoutSpacing:
1592         return 6;
1593     case PM_LayoutLeftMargin:
1594     case PM_LayoutTopMargin:
1595     case PM_LayoutRightMargin:
1596     case PM_LayoutBottomMargin:
1597         return pixelMetric((option && (option->state & State_Window)) ||
1598                            (widget && widget->isWindow()) ?
1599                            PM_DefaultTopLevelMargin : PM_DefaultChildMargin,
1600                            option, widget);
1601     case PM_MenuBarItemSpacing:
1602         return 0;
1603     case PM_ToolBarItemMargin:
1604         // with two locked toolbars together the last/first items are too close when there is no frame,
1605         // so add a margin instead.
1606         return opts.toolbarBorders == TB_NONE ? 1 : 0;
1607     case PM_ToolBarItemSpacing:
1608         return opts.tbarBtns == TBTN_JOINED ? 0 : 1;
1609     case PM_ToolBarFrameWidth:
1610         return opts.toolbarBorders == TB_NONE ? 0 : 1;
1611     case PM_FocusFrameVMargin:
1612     case PM_FocusFrameHMargin:
1613         return 2;
1614     case PM_MenuBarVMargin:
1615     case PM_MenuBarHMargin:
1616         // Bangarang (media player) has a 4 pixel high menubar at the top -
1617         // when it doesn't actually have a menubar! Seems to be because of
1618         // the return 2 below (which was previously always returned unless
1619         // XBar support and size was 0). So, if we are askes for these metrics
1620         // for a widet whose size<6, then return 0.
1621         return widget && widget->size().height() < 6 ? 0 : 2;
1622     case PM_MenuHMargin:
1623     case PM_MenuVMargin:
1624         return 0;
1625     case PM_MenuButtonIndicator:
1626         return ((opts.buttonEffect != EFFECT_NONE ? 10 : 9) +
1627                 (!widget || qobject_cast<const QToolButton*>(widget) ? 6 : 0));
1628     case PM_ButtonMargin:
1629         return (opts.buttonEffect != EFFECT_NONE ? (opts.thin & THIN_BUTTONS) ?
1630                 4 : 6 : (opts.thin & THIN_BUTTONS) ? 2 : 4) + MAX_ROUND_BTN_PAD;
1631     case PM_TabBarTabShiftVertical:
1632         return 2;
1633     case PM_TabBarTabShiftHorizontal:
1634         return 0;
1635     case PM_ButtonShiftHorizontal:
1636         // return Qt::RightToLeft==QApplication::layoutDirection() ? -1 : 1;
1637     case PM_ButtonShiftVertical:
1638         return (theThemedApp == APP_KDEVELOP && !opts.stdSidebarButtons &&
1639                 widget && isMultiTabBarTab(getButton(widget, 0L)) ? 0 : 1);
1640     case PM_ButtonDefaultIndicator:
1641         return 0;
1642     case PM_DefaultFrameWidth:
1643         if (opts.gtkComboMenus &&
1644             qtcCheckType(widget,"QComboBoxPrivateContainer")) {
1645             return (opts.gtkComboMenus ?
1646                     (opts.borderMenuitems ||
1647                      !(opts.square & SQUARE_POPUP_MENUS) ? 2 : 1) : 0);
1648         }
1649         if ((!opts.gtkScrollViews || (opts.square & SQUARE_SCROLLVIEW)) &&
1650             isKateView(widget))
1651             return (opts.square&SQUARE_SCROLLVIEW) ? 1 : 0;
1652 
1653         if ((opts.square & SQUARE_SCROLLVIEW) && widget && !opts.etchEntry &&
1654             (qobject_cast<const QAbstractScrollArea*>(widget) ||
1655              isKontactPreviewPane(widget)))
1656             return ((opts.gtkScrollViews || opts.thinSbarGroove ||
1657                      !opts.borderSbarGroove) && (!opts.highlightScrollViews) ?
1658                     1 : 2);
1659 
1660         if  (!qtcDrawMenuBorder(opts) && !opts.borderMenuitems &&
1661              opts.square & SQUARE_POPUP_MENUS &&
1662              qobject_cast<const QMenu*>(widget))
1663             return 1;
1664 
1665         if (opts.buttonEffect != EFFECT_NONE && opts.etchEntry &&
1666             (!widget || // !isFormWidget(widget) &&
1667             qobject_cast<const QLineEdit*>(widget) ||
1668              qobject_cast<const QAbstractScrollArea*>(widget)
1669              /*|| isKontactPreviewPane(widget)*/)) {
1670             return 3;
1671         } else {
1672             return 2;
1673         }
1674     case PM_SpinBoxFrameWidth:
1675         return opts.buttonEffect != EFFECT_NONE && opts.etchEntry ? 3 : 2;
1676     case PM_IndicatorWidth:
1677     case PM_IndicatorHeight:
1678     case PM_ExclusiveIndicatorWidth:
1679     case PM_ExclusiveIndicatorHeight:
1680         // TODO??
1681         // case PM_CheckListControllerSize:
1682         // case PM_CheckListButtonSize:
1683         return opts.buttonEffect != EFFECT_NONE ? opts.crSize+2 : opts.crSize;
1684     case PM_TabBarTabOverlap:
1685         return TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1;
1686     case PM_ProgressBarChunkWidth:
1687         return 4;
1688     // case PM_DockWindowHandleExtent:
1689     //     return 10;
1690     case PM_DockWidgetSeparatorExtent:
1691     case PM_SplitterWidth:
1692         return LINE_1DOT==opts.splitters ? 7 : 6;
1693     case PM_ToolBarHandleExtent:
1694         return LINE_1DOT==opts.handles ? 7 : 8;
1695     case PM_ScrollBarSliderMin:
1696         // Leave a minimum of 21 pixels (which is the size used by Oxygen)
1697         // See https://github.com/QtCurve/qtcurve-qt4/issues/7
1698         // and https://bugs.kde.org/show_bug.cgi?id=317690
1699         return qtcMax(opts.sliderWidth, 20) + 1;
1700     case PM_SliderThickness: {
1701         int glowSize = (opts.buttonEffect != EFFECT_NONE &&
1702                         opts.coloredMouseOver == MO_GLOW ? 2 : 0);
1703         if (opts.sliderStyle == SLIDER_CIRCULAR) {
1704             return CIRCULAR_SLIDER_SIZE + 6 + glowSize;
1705         } else if (opts.sliderStyle == SLIDER_TRIANGULAR) {
1706             return 19 + glowSize;
1707         } else {
1708             return (SLIDER_SIZE + glowSize +
1709                     (oneOf(opts.sliderStyle, SLIDER_PLAIN_ROTATED,
1710                            SLIDER_ROUND_ROTATED) ? 11 : 6));
1711         }
1712     }
1713     case PM_SliderControlThickness: {
1714         int glowSize = (opts.buttonEffect != EFFECT_NONE &&
1715                         opts.coloredMouseOver == MO_GLOW ? 2 : 0);
1716         if (opts.sliderStyle == SLIDER_CIRCULAR) {
1717             return CIRCULAR_SLIDER_SIZE + glowSize;
1718         } else if (opts.sliderStyle == SLIDER_TRIANGULAR) {
1719             return 11 + glowSize;
1720         } else {
1721             return (SLIDER_SIZE + glowSize +
1722                     (oneOf(opts.sliderStyle, SLIDER_PLAIN_ROTATED,
1723                            SLIDER_ROUND_ROTATED) ? 6 : -2));
1724         }
1725     }
1726     case PM_SliderTickmarkOffset:
1727         return opts.sliderStyle == SLIDER_TRIANGULAR ? 5 : 4;
1728     case PM_SliderSpaceAvailable:
1729         if (auto slider = styleOptCast<QStyleOptionSlider>(option)) {
1730             int size = pixelMetric(PM_SliderControlThickness, slider, widget);
1731 
1732             if (slider->tickPosition & QSlider::TicksBelow)
1733                 ++size;
1734             if (slider->tickPosition & QSlider::TicksAbove)
1735                 ++size;
1736             return size;
1737         }
1738         return ParentStyleClass::pixelMetric(metric, option, widget);
1739     case PM_SliderLength: {
1740         int glowSize = (opts.buttonEffect != EFFECT_NONE &&
1741                         opts.coloredMouseOver == MO_GLOW ? 2 : 0);
1742         if (opts.sliderStyle == SLIDER_CIRCULAR) {
1743             return CIRCULAR_SLIDER_SIZE + glowSize;
1744         } else if (opts.sliderStyle == SLIDER_TRIANGULAR) {
1745             return 11 + glowSize;
1746         } else {
1747             return (SLIDER_SIZE + glowSize +
1748                     (oneOf(opts.sliderStyle, SLIDER_PLAIN_ROTATED,
1749                            SLIDER_ROUND_ROTATED) ? -2 : 6));
1750         }
1751     }
1752     case PM_ScrollBarExtent:
1753         return opts.sliderWidth;
1754     case PM_MaximumDragDistance:
1755         return -1;
1756     case PM_TabBarTabHSpace:
1757         return 14;
1758     case PM_TabBarTabVSpace:
1759         return opts.highlightTab ? 10 : 8;
1760     case PM_TitleBarHeight:
1761         return qMax(widget ? widget->fontMetrics().lineSpacing() :
1762                     option ? option->fontMetrics.lineSpacing() : 0, 24);
1763     case PM_MenuBarPanelWidth:
1764         return 0;
1765     case QtC_Round:
1766         return (int)((opts.square & SQUARE_WINDOWS && opts.round>ROUND_SLIGHT) ?
1767                      ROUND_SLIGHT : opts.round);
1768     case QtC_WindowBorder:
1769         return opts.windowBorder;
1770     case QtC_CustomBgnd:
1771         return qtcIsCustomBgnd(opts);
1772     case QtC_TitleAlignment:
1773         switch (opts.titlebarAlignment) {
1774         default:
1775         case ALIGN_LEFT:
1776             return Qt::AlignLeft;
1777         case ALIGN_CENTER:
1778             return Qt::AlignHCenter | Qt::AlignVCenter;
1779         case ALIGN_FULL_CENTER:
1780             return Qt::AlignHCenter;
1781         case ALIGN_RIGHT:
1782             return Qt::AlignRight;
1783         }
1784     case QtC_TitleBarButtons:
1785         return opts.titlebarButtons;
1786     case QtC_TitleBarIcon:
1787         return opts.titlebarIcon;
1788     case QtC_TitleBarIconColor:
1789         return titlebarIconColor(option).rgb();
1790     case QtC_TitleBarEffect:
1791         return opts.titlebarEffect;
1792     case QtC_BlendMenuAndTitleBar:
1793         return BLEND_TITLEBAR;
1794     case QtC_ShadeMenubarOnlyWhenActive:
1795         return opts.shadeMenubarOnlyWhenActive;
1796     case QtC_ToggleButtons:
1797         return ((opts.menubarHiding & HIDE_KWIN   ? 0x1 : 0) +
1798                 (opts.statusbarHiding & HIDE_KWIN ? 0x2 : 0));
1799     case QtC_MenubarColor:
1800         return m_menubarCols[ORIGINAL_SHADE].rgb();
1801     case QtC_TitleBarApp:
1802         return (!option || option->state & State_Active ?
1803                 opts.titlebarAppearance : opts.inactiveTitlebarAppearance);
1804         // The following was a somewhat hackyish fix for konqueror's show close
1805         // button on tab setting...... its hackish in the way that I'm assuming
1806         // when KTabBar is positioning the close button and it asks for these
1807         // options, it only passes in a QStyleOption  not a QStyleOptionTab
1808         // Now that KTabBar is deprecated and (KF5) code should use QTabBar instead
1809         // it isn't certain these hacks ought to be preserved.
1810     case PM_TabBarBaseHeight:
1811         if (qtcCheckKDEType(widget, QTabBar) &&
1812             !styleOptCast<QStyleOptionTab>(option)) {
1813             return 10;
1814         }
1815         return ParentStyleClass::pixelMetric(metric, option, widget);
1816     case PM_TabBarBaseOverlap:
1817         if (qtcCheckKDEType(widget, QTabBar) &&
1818             !styleOptCast<QStyleOptionTab>(option)) {
1819             return 0;
1820         }
1821         // Fall through!
1822     default:
1823         return ParentStyleClass::pixelMetric(metric, option, widget);
1824     }
1825 }
1826 
1827 int
1828 Style::styleHint(StyleHint hint, const QStyleOption *option,
1829                  const QWidget *widget, QStyleHintReturn *returnData) const
1830 {
1831     prePolish(widget);
1832     switch (hint) {
1833     case SH_ToolTip_Mask:
1834     case SH_Menu_Mask:
1835         if ((SH_ToolTip_Mask == hint && (opts.square & SQUARE_TOOLTIPS)) ||
1836             (SH_Menu_Mask == hint && (opts.square & SQUARE_POPUP_MENUS))) {
1837             return ParentStyleClass::styleHint(hint, option, widget, returnData);
1838         } else {
1839             if (!Utils::hasAlphaChannel(widget) &&
1840                 (!widget || widget->isWindow())) {
1841                 if (auto mask =
1842                     styleOptCast<QStyleHintReturnMask>(returnData)) {
1843                     mask->region = windowMask(option->rect,
1844                                               opts.round > ROUND_SLIGHT);
1845                 }
1846             }
1847             return true;
1848         }
1849     case SH_ComboBox_ListMouseTracking:
1850     case SH_PrintDialog_RightAlignButtons:
1851     case SH_ItemView_ArrowKeysNavigateIntoChildren:
1852     case SH_ToolBox_SelectedPageTitleBold:
1853     case SH_ScrollBar_MiddleClickAbsolutePosition:
1854     case SH_SpinControls_DisableOnBounds:
1855     case SH_Slider_SnapToValue:
1856     case SH_FontDialog_SelectAssociatedText:
1857     case SH_Menu_MouseTracking:
1858         return true;
1859     case SH_UnderlineShortcut:
1860         return ((widget && opts.hideShortcutUnderline) ?
1861                 m_shortcutHandler->showShortcut(widget) : true);
1862     case SH_GroupBox_TextLabelVerticalAlignment:
1863         if (auto frame = styleOptCast<QStyleOptionGroupBox>(option)) {
1864             if (frame->features & QStyleOptionFrame::Flat) {
1865                 return Qt::AlignVCenter;
1866             }
1867         }
1868         if (opts.gbLabel & GB_LBL_INSIDE) {
1869             return Qt::AlignBottom;
1870         } else if (opts.gbLabel & GB_LBL_OUTSIDE) {
1871             return Qt::AlignTop;
1872         } else {
1873             return Qt::AlignVCenter;
1874         }
1875     case SH_MessageBox_CenterButtons:
1876     case SH_ProgressDialog_CenterCancelButton:
1877     case SH_DitherDisabledText:
1878     case SH_EtchDisabledText:
1879     case SH_Menu_AllowActiveAndDisabled:
1880     case SH_ItemView_ShowDecorationSelected:
1881         // Controls whether the highlighting of listview/treeview
1882         // items highlights whole line.
1883     case SH_MenuBar_AltKeyNavigation:
1884         return false;
1885     case SH_ItemView_ChangeHighlightOnFocus:
1886         // gray out selected items when losing focus.
1887         return false;
1888     case SH_WizardStyle:
1889         return QWizard::ClassicStyle;
1890     case SH_RubberBand_Mask: {
1891         auto opt = styleOptCast<QStyleOptionRubberBand>(option);
1892         if (!opt) {
1893             return true;
1894         }
1895         if (auto mask = styleOptCast<QStyleHintReturnMask>(returnData)) {
1896             mask->region = option->rect;
1897             mask->region -= option->rect.adjusted(1,1,-1,-1);
1898         }
1899         return true;
1900     }
1901     case SH_Menu_SubMenuPopupDelay:
1902         return opts.menuDelay;
1903 #if QT_VERSION >= QT_VERSION_CHECK(5,5,0)
1904     case SH_Menu_SloppySubMenus:
1905         return opts.menuCloseDelay > 0;
1906     case SH_Menu_SubMenuSloppyCloseTimeout:
1907         return opts.menuCloseDelay;
1908 #endif
1909     case SH_ToolButton_PopupDelay:
1910         return 250;
1911     case SH_ComboBox_PopupFrameStyle:
1912         return opts.popupBorder || !(opts.square&SQUARE_POPUP_MENUS) ? QFrame::StyledPanel|QFrame::Plain : QFrame::NoFrame;
1913     case SH_TabBar_Alignment:
1914         return Qt::AlignLeft;
1915     case SH_Header_ArrowAlignment:
1916         return Qt::AlignLeft;
1917     case SH_WindowFrame_Mask:
1918         if (auto mask = styleOptCast<QStyleHintReturnMask>(returnData)) {
1919             const QRect &r = option->rect;
1920             switch ((opts.square & SQUARE_WINDOWS &&
1921                      opts.round > ROUND_SLIGHT) ? ROUND_SLIGHT : opts.round) {
1922             case ROUND_NONE:
1923                 mask->region = r;
1924                 break;
1925             case ROUND_SLIGHT:
1926                 mask->region = QRegion(r.x() + 1, r.y(),
1927                                        r.width() - 2, r.height());
1928                 mask->region += QRegion(r.x() + 0, r.y() + 1,
1929                                         1, r.height() - 2);
1930                 mask->region += QRegion(r.x() + r.width() - 1, r.y() + 1,
1931                                         1, r.height() - 2);
1932                 break;
1933             default: // ROUND_FULL
1934                 mask->region = QRegion(r.x() + 5, r.y(),
1935                                        r.width() - 10, r.height());
1936                 mask->region += QRegion(r.x() + 0, r.y() + 5,
1937                                         1, r.height() - 5);
1938                 mask->region += QRegion(r.x() + 1, r.y() + 3,
1939                                         1, r.height() - 2);
1940                 mask->region += QRegion(r.x() + 2, r.y() + 2,
1941                                         1, r.height() - 1);
1942                 mask->region += QRegion(r.x() + 3, r.y() + 1,
1943                                         2, r.height());
1944                 mask->region += QRegion(r.x() + r.width() - 1, r.y() + 5,
1945                                         1, r.height() - 5);
1946                 mask->region += QRegion(r.x() + r.width() - 2, r.y() + 3,
1947                                         1, r.height() - 2);
1948                 mask->region += QRegion(r.x() + r.width() - 3, r.y() + 2,
1949                                         1, r.height() - 1);
1950                 mask->region += QRegion(r.x() + r.width() - 5, r.y() + 1,
1951                                         2, r.height() - 0);
1952             }
1953         }
1954         return 1;
1955     case SH_TitleBar_NoBorder:
1956     case SH_TitleBar_AutoRaise:
1957         return 1;
1958     case SH_MainWindow_SpaceBelowMenuBar:
1959         return 0;
1960     case SH_DialogButtonLayout:
1961         if (opts.gtkButtonOrder)
1962             return QDialogButtonBox::GnomeLayout;
1963         return QDialogButtonBox::KdeLayout;
1964     case SH_MessageBox_TextInteractionFlags:
1965         return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
1966     case SH_LineEdit_PasswordCharacter:
1967         if (opts.passwordChar) {
1968             int chars[4] = {opts.passwordChar, 0x25CF, 0x2022, 0};
1969             const QFontMetrics &fm(option ? option->fontMetrics :
1970                                    (widget ? widget->fontMetrics() :
1971                                     QFontMetrics(QFont())));
1972             for (int i = 0;chars[i];i++) {
1973                 if (fm.inFont(QChar(chars[i]))) {
1974                     return chars[i];
1975                 }
1976             }
1977             return '*';
1978         } else {
1979             return '\0';
1980         }
1981     case SH_MenuBar_MouseTracking:
1982         // Always return 1, as setting to 0 dissables the effect when
1983         // a menu is shown.
1984         return 1; // opts.menubarMouseOver ? 1 : 0;
1985     case SH_ScrollView_FrameOnlyAroundContents:
1986         return (widget && widget->isWindow() ? false :
1987                 opts.gtkScrollViews &&
1988                 !qtcCheckType(widget, "QComboBoxListView"));
1989     case SH_ComboBox_Popup:
1990         if (opts.gtkComboMenus) {
1991             if (auto cmb = styleOptCast<QStyleOptionComboBox>(option)) {
1992                 return !cmb->editable;
1993             }
1994         }
1995         return 0;
1996     case SH_FormLayoutFormAlignment:
1997         // KDE4 HIG, align the contents in a form layout to the left
1998         return Qt::AlignLeft | Qt::AlignTop;
1999     case SH_FormLayoutLabelAlignment:
2000         // KDE4  HIG, align the labels in a form layout to the right
2001         return Qt::AlignRight;
2002     case SH_FormLayoutFieldGrowthPolicy:
2003         return QFormLayout::ExpandingFieldsGrow;
2004     case SH_FormLayoutWrapPolicy:
2005         return QFormLayout::DontWrapRows;
2006 #ifdef QTC_QT5_ENABLE_KDE
2007     case SH_DialogButtonBox_ButtonsHaveIcons:{
2008         KConfigGroup cg(m_kdeGlobals, "KDE");
2009         return cg.readEntry("ShowIconsOnPushButtons", false);
2010     }
2011     case SH_ItemView_ActivateItemOnSingleClick:{
2012         KConfigGroup cg(m_kdeGlobals, "KDE");
2013         return cg.readEntry("SingleClick", false);
2014     }
2015 #endif
2016     case SH_Widget_Animate:
2017         return false;
2018     case SH_Menu_SupportsSections:
2019         return true;
2020     default:
2021 #ifdef QTC_QT5_ENABLE_KDE
2022         // Tell the calling app that we can handle certain custom widgets...
2023         if (hint >= SH_CustomBase && widget) {
2024             if (widget->objectName() == "CE_CapacityBar") {
2025                 if (opts.boldProgress) {
2026                     m_fntHelper->setBold(const_cast<QWidget*>(widget));
2027                 }
2028                 return CE_QtC_KCapacityBar;
2029             }
2030         }
2031 #endif
2032         return ParentStyleClass::styleHint(hint, option, widget, returnData);
2033     }
2034 }
2035 
2036 QPalette Style::standardPalette() const
2037 {
2038     return ParentStyleClass::standardPalette();
2039 }
2040 
2041 void Style::initFontTickData(const QFont &font, const QWidget*) const
2042 {
2043     if (opts.onlyTicksInMenu && opts.fontTickWidth <= 0) {
2044         opts.tickFont = font;
2045 #ifndef Q_OS_MACOS
2046         opts.tickFont.setBold(true);
2047 #else
2048         opts.tickFont.setFamily(QStringLiteral("Apple Symbols"));
2049         opts.tickFont.setBold(false);
2050 #endif
2051         // adjust the size so the tickmark looks just about right
2052         opts.tickFont.setPointSizeF(opts.tickFont.pointSizeF() * 1.3);
2053         opts.fontTickWidth = horizontalAdvance(QFontMetrics(opts.tickFont), opts.menuTick);
2054     }
2055 }
2056 
2057 static bool menuTickCompensation(const Options &opts, int refWidth, int &dx)
2058 {
2059     if (opts.onlyTicksInMenu && opts.fontTickWidth > refWidth) {
2060         dx = opts.fontTickWidth - refWidth;
2061         return true;
2062     }
2063     return false;
2064 }
2065 
2066 void
2067 Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
2068                      QPainter *painter, const QWidget *widget) const
2069 {
2070     prePolish(widget);
2071     bool (Style::*drawFunc)(PrimitiveElement, const QStyleOption*,
2072                             QPainter*, const QWidget*) const = nullptr;
2073     switch ((unsigned)element) {
2074     case PE_IndicatorTabClose:
2075         drawFunc = &Style::drawPrimitiveIndicatorTabClose;
2076         break;
2077     case PE_Widget:
2078         drawFunc = &Style::drawPrimitiveWidget;
2079         break;
2080     case PE_PanelScrollAreaCorner:
2081         drawFunc = &Style::drawPrimitivePanelScrollAreaCorner;
2082         break;
2083     case PE_IndicatorBranch:
2084         drawFunc = &Style::drawPrimitiveIndicatorBranch;
2085         break;
2086     case PE_IndicatorViewItemCheck:
2087         drawFunc = &Style::drawPrimitiveIndicatorViewItemCheck;
2088         break;
2089     case PE_IndicatorHeaderArrow:
2090         drawFunc = &Style::drawPrimitiveIndicatorHeaderArrow;
2091         break;
2092     case PE_IndicatorArrowUp:
2093     case PE_IndicatorArrowDown:
2094     case PE_IndicatorArrowLeft:
2095     case PE_IndicatorArrowRight:
2096         drawFunc = &Style::drawPrimitiveIndicatorArrow;
2097         break;
2098     case PE_IndicatorSpinMinus:
2099     case PE_IndicatorSpinPlus:
2100     case PE_IndicatorSpinUp:
2101     case PE_IndicatorSpinDown:
2102         drawFunc = &Style::drawPrimitiveIndicatorSpin;
2103         break;
2104     case PE_IndicatorToolBarSeparator:
2105         drawFunc = &Style::drawPrimitiveIndicatorToolBarSeparator;
2106         break;
2107     case PE_FrameGroupBox:
2108         drawFunc = &Style::drawPrimitiveFrameGroupBox;
2109         break;
2110     case PE_Frame:
2111         drawFunc = &Style::drawPrimitiveFrame;
2112         break;
2113     case PE_PanelMenuBar:
2114         drawFunc = &Style::drawPrimitivePanelMenuBar;
2115         break;
2116     case PE_FrameTabBarBase:
2117         drawFunc = &Style::drawPrimitiveFrameTabBarBase;
2118         break;
2119     case PE_FrameStatusBar:
2120     case PE_FrameMenu:
2121         initFontTickData(widget ? widget->font() : QApplication::font("QMenu"), widget);
2122         drawFunc = &Style::drawPrimitiveFrameStatusBarOrMenu;
2123         break;
2124     case PE_FrameDockWidget:
2125         drawFunc = &Style::drawPrimitiveFrameDockWidget;
2126         break;
2127     case PE_FrameButtonTool:
2128     case PE_PanelButtonTool:
2129     case PE_IndicatorButtonDropDown:
2130         drawFunc = &Style::drawPrimitiveButtonTool;
2131         break;
2132     case PE_IndicatorDockWidgetResizeHandle:
2133         drawFunc = &Style::drawPrimitiveIndicatorDockWidgetResizeHandle;
2134         break;
2135     case PE_PanelLineEdit:
2136         drawFunc = &Style::drawPrimitivePanelLineEdit;
2137         break;
2138     case PE_FrameLineEdit:
2139         drawFunc = &Style::drawPrimitiveFrameLineEdit;
2140         break;
2141     case PE_IndicatorMenuCheckMark:
2142     case PE_IndicatorCheckBox:
2143         drawFunc = &Style::drawPrimitiveIndicatorCheckBox;
2144         break;
2145     case PE_IndicatorRadioButton:
2146         drawFunc = &Style::drawPrimitiveIndicatorRadioButton;
2147         break;
2148     case PE_IndicatorToolBarHandle:
2149         drawFunc = &Style::drawPrimitiveIndicatorToolBarHandle;
2150         break;
2151     case PE_FrameFocusRect:
2152         drawFunc = &Style::drawPrimitiveFrameFocusRect;
2153         break;
2154     case PE_FrameButtonBevel:
2155     case PE_PanelButtonBevel:
2156     case PE_PanelButtonCommand:
2157         drawFunc = &Style::drawPrimitiveButton;
2158         break;
2159     case PE_FrameDefaultButton:
2160         drawFunc = &Style::drawPrimitiveNone;
2161         break;
2162     case PE_FrameWindow:
2163         drawFunc = &Style::drawPrimitiveFrameWindow;
2164         break;
2165     case PE_FrameTabWidget:
2166         drawFunc = &Style::drawPrimitiveFrameTabWidget;
2167         break;
2168     case PE_PanelItemViewItem:
2169         drawFunc = &Style::drawPrimitivePanelItemViewItem;
2170         break;
2171     case QtC_PE_DrawBackground:
2172         drawFunc = &Style::drawPrimitiveQtcBackground;
2173         break;
2174     case PE_PanelTipLabel:
2175         drawFunc = &Style::drawPrimitivePanelTipLabel;
2176         break;
2177     case PE_PanelMenu:
2178         initFontTickData(widget ? widget->font() : QApplication::font("QMenu"), widget);
2179         drawFunc = &Style::drawPrimitivePanelMenu;
2180         break;
2181     default:
2182         break;
2183     }
2184     painter->save();
2185     if (!drawFunc ||
2186         qtcUnlikely(!(this->*drawFunc)(element, option, painter, widget))) {
2187         ParentStyleClass::drawPrimitive(element, option, painter, widget);
2188     }
2189     painter->restore();
2190 }
2191 
2192 void
2193 Style::drawControl(ControlElement element, const QStyleOption *option,
2194                    QPainter *painter, const QWidget *widget) const
2195 {
2196     prePolish(widget);
2197     QRect r = option->rect;
2198     const State &state = option->state;
2199     const QPalette &palette = option->palette;
2200     bool reverse = option->direction == Qt::RightToLeft;
2201 
2202     switch ((unsigned)element) {
2203     case CE_QtC_SetOptions:
2204         if (auto preview = styleOptCast<PreviewOption>(option)) {
2205             if (!painter && widget &&
2206                 widget->objectName() == QLatin1String("QtCurveConfigDialog")) {
2207                 Style *that = (Style*)this;
2208                 opts = preview->opts;
2209                 qtcCheckConfig(&opts);
2210                 that->init(true);
2211             }
2212         }
2213         break;
2214     case CE_QtC_Preview:
2215         if (auto preview = styleOptCast<PreviewOption>(option)) {
2216             if (widget &&
2217                 widget->objectName() ==
2218                 QLatin1String("QtCurveConfigDialog-GradientPreview")) {
2219                 Options old = opts;
2220                 const QColor *use(buttonColors(option));
2221                 opts = preview->opts;
2222 
2223                 drawLightBevelReal(painter, r, option, widget, ROUNDED_ALL,
2224                                    getFill(option, use, false, false), use,
2225                                    true, WIDGET_STD_BUTTON, false, opts.round,
2226                                    false);
2227                 opts = old;
2228             }
2229         }
2230         break;
2231     case CE_QtC_KCapacityBar:
2232         if (auto bar = styleOptCast<QStyleOptionProgressBar>(option)) {
2233             QStyleOptionProgressBar mod = *bar;
2234 
2235             if (mod.rect.height() > 16 &&
2236                 (qtcCheckType<QStatusBar>(widget->parentWidget()) ||
2237                  qtcCheckType(widget->parentWidget(), "DolphinStatusBar"))) {
2238                 int m = (mod.rect.height() - 16) / 2;
2239                 mod.rect.adjust(0, m, 0, -m);
2240             }
2241             drawControl(CE_ProgressBarGroove, &mod, painter, widget);
2242             if (opts.buttonEffect != EFFECT_NONE && opts.borderProgress)
2243                 mod.rect.adjust(1, 1, -1, -1);
2244             drawControl(CE_ProgressBarContents, &mod, painter, widget);
2245             drawControl(CE_ProgressBarLabel, &mod, painter, widget);
2246         }
2247         break;
2248     case CE_ToolBoxTabShape: {
2249         auto tb = styleOptCast<QStyleOptionToolBox>(option);
2250         if (!(tb && widget))
2251             break;
2252         const QColor *use =
2253             backgroundColors(widget->palette().color(QPalette::Window));
2254         QPainterPath path;
2255         int y = r.height() * 15 / 100;
2256 
2257         painter->save();
2258         if (reverse) {
2259             path.moveTo(r.left() + 52, r.top());
2260             path.cubicTo(QPointF(r.left() + 50 - 8, r.top()),
2261                          QPointF(r.left() + 50 - 10, r.top() + y),
2262                          QPointF(r.left() + 50 - 10, r.top() + y));
2263             path.lineTo(r.left() + 18 + 9, r.bottom() - y);
2264             path.cubicTo(QPointF(r.left() + 18 + 9, r.bottom() - y),
2265                          QPointF(r.left() + 19 + 6, r.bottom() - 1 - 0.3),
2266                          QPointF(r.left() + 19, r.bottom() - 1 - 0.3));
2267         } else {
2268             path.moveTo(r.right() - 52, r.top());
2269             path.cubicTo(QPointF(r.right() - 50 + 8, r.top()),
2270                          QPointF(r.right() - 50 + 10, r.top() + y),
2271                          QPointF(r.right() - 50 + 10, r.top() + y));
2272             path.lineTo(r.right() - 18 - 9, r.bottom() - y);
2273             path.cubicTo(QPointF(r.right() - 18 - 9, r.bottom() - y),
2274                          QPointF(r.right() - 19 - 6, r.bottom() - 1 - 0.3),
2275                          QPointF(r.right() - 19, r.bottom() - 1 - 0.3));
2276         }
2277 
2278         painter->setRenderHint(QPainter::Antialiasing, true);
2279         painter->translate(0, 1);
2280         painter->setPen(use[0]);
2281         painter->drawPath(path);
2282         painter->translate(0, -1);
2283         painter->setPen(use[4]);
2284         painter->drawPath(path);
2285         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
2286         if (reverse) {
2287             painter->drawLine(r.left() + 50 - 1, r.top(), r.right(), r.top());
2288             painter->drawLine(r.left() + 20, r.bottom() - 2,
2289                               r.left(), r.bottom() - 2);
2290             painter->setPen(use[0]);
2291             painter->drawLine(r.left() + 50, r.top() + 1,
2292                               r.right(), r.top() + 1);
2293             painter->drawLine(r.left() + 20, r.bottom() - 1,
2294                               r.left(), r.bottom() - 1);
2295         } else {
2296             painter->drawLine(r.left(), r.top(), r.right() - 50 + 1, r.top());
2297             painter->drawLine(r.right() - 20, r.bottom() - 2,
2298                               r.right(), r.bottom() - 2);
2299             painter->setPen(use[0]);
2300             painter->drawLine(r.left(), r.top() + 1,
2301                               r.right() - 50, r.top() + 1);
2302             painter->drawLine(r.right() - 20, r.bottom() - 1,
2303                               r.right(), r.bottom() - 1);
2304         }
2305         painter->restore();
2306         break;
2307     }
2308     case CE_MenuScroller: {
2309         const QColor *use = popupMenuCols();
2310         painter->fillRect(r, use[ORIGINAL_SHADE]);
2311         painter->setPen(use[QTC_STD_BORDER]);
2312         drawRect(painter, r);
2313         drawPrimitive(((state & State_DownArrow) ? PE_IndicatorArrowDown :
2314                        PE_IndicatorArrowUp), option, painter, widget);
2315         break;
2316     }
2317     case CE_RubberBand: {
2318         // Rubber band used in such things as iconview.
2319         if (r.width() > 0 && r.height() > 0) {
2320             painter->save();
2321             QColor c(m_highlightCols[ORIGINAL_SHADE]);
2322 
2323             painter->setClipRegion(r);
2324             painter->setPen(c);
2325             c.setAlpha(50);
2326             painter->setBrush(c);
2327             drawRect(painter, r);
2328             painter->restore();
2329         }
2330         break;
2331     }
2332     case CE_Splitter: {
2333         const QColor *use = buttonColors(option);
2334         const QColor *border = borderColors(option, use);
2335         // In Amarok nightly (2.2) State_Horizontal doesn't
2336         // seem to always be set...
2337         bool horiz = (state & State_Horizontal ||
2338                       (r.height() > 6 && r.height() > r.width()));
2339 
2340         painter->save();
2341         if (/*qtcIsFlatBgnd(opts.bgndAppearance) || */
2342             state & State_MouseOver && state & State_Enabled) {
2343             QColor color(palette.color(QPalette::Active, QPalette::Window));
2344 
2345             if (state & State_MouseOver && state & State_Enabled &&
2346                 opts.splitterHighlight) {
2347                 if (ROUND_NONE != opts.round) {
2348                     painter->save();
2349                     painter->setRenderHint(QPainter::Antialiasing, true);
2350                     double radius =
2351                         qtcGetRadius(&opts, r.width(), r.height(),
2352                                      WIDGET_OTHER, RADIUS_SELECTION);
2353 
2354                     drawBevelGradient(shade(palette.window().color(),
2355                                             TO_FACTOR(opts.splitterHighlight)),
2356                                       painter, r,
2357                                       buildPath(QRectF(r), WIDGET_OTHER,
2358                                                 ROUNDED_ALL, radius),
2359                                       !(state & State_Horizontal), false,
2360                                       opts.selectionAppearance,
2361                                       WIDGET_SELECTION, false);
2362                     painter->restore();
2363                 } else {
2364                     drawBevelGradient(shade(palette.window().color(),
2365                                             TO_FACTOR(opts.splitterHighlight)),
2366                                       painter, r, !(state & State_Horizontal),
2367                                       false, opts.selectionAppearance,
2368                                       WIDGET_SELECTION);
2369                 }
2370             } else {
2371                 painter->fillRect(r, color);
2372             }
2373         }
2374 
2375         switch (opts.splitters) {
2376         case LINE_NONE:
2377             break;
2378         case LINE_1DOT:
2379             painter->drawPixmap(r.x() + ((r.width() - 5) / 2),
2380                                 r.y() + ((r.height() - 5) / 2),
2381                                 *getPixmap(border[QTC_STD_BORDER],
2382                                            PIX_DOT, 1.0));
2383             break;
2384         default:
2385         case LINE_DOTS:
2386             drawDots(painter, r, horiz, NUM_SPLITTER_DASHES, 1, border, 0, 5);
2387             break;
2388         case LINE_FLAT:
2389         case LINE_SUNKEN:
2390         case LINE_DASHES:
2391             drawLines(painter, r, horiz, NUM_SPLITTER_DASHES, 3,
2392                       border, 0, 3, opts.splitters);
2393         }
2394         painter->restore();
2395         break;
2396     }
2397     case CE_SizeGrip: {
2398         QPolygon triangle(3);
2399         Qt::Corner corner;
2400         int size = SIZE_GRIP_SIZE - 2;
2401 
2402         if (auto sgrp = styleOptCast<QStyleOptionSizeGrip>(option)) {
2403             corner = sgrp->corner;
2404         } else if (option->direction == Qt::RightToLeft) {
2405             corner = Qt::BottomLeftCorner;
2406         } else {
2407             corner = Qt::BottomRightCorner;
2408         }
2409 
2410         switch (corner) {
2411         case Qt::BottomLeftCorner:
2412             triangle.putPoints(0, 3, 0, 0, size, size, 0, size);
2413             triangle.translate(r.x(), r.y() + (r.height() -
2414                                                (SIZE_GRIP_SIZE - 1)));
2415             break;
2416         case Qt::BottomRightCorner:
2417             triangle.putPoints(0, 3, size, 0, size, size, 0, size);
2418             triangle.translate(r.x() + (r.width() - (SIZE_GRIP_SIZE - 1)),
2419                                r.y() + (r.height() - (SIZE_GRIP_SIZE - 1)));
2420             break;
2421         case Qt::TopRightCorner:
2422             triangle.putPoints(0, 3, 0, 0, size, 0, size, size);
2423             triangle.translate(r.x() + (r.width() - (SIZE_GRIP_SIZE - 1)),
2424                                r.y());
2425             break;
2426         case Qt::TopLeftCorner:
2427             triangle.putPoints(0, 3, 0, 0, size, 0, 0, size);
2428             triangle.translate(r.x(), r.y());
2429         }
2430         painter->save();
2431         painter->setPen(m_backgroundCols[2]);
2432         painter->setBrush(m_backgroundCols[2]);
2433         painter->drawPolygon(triangle);
2434         painter->restore();
2435         break;
2436     }
2437     case CE_ToolBar:
2438         if (auto toolbar = styleOptCast<QStyleOptionToolBar>(option)) {
2439             if (!widget || !widget->parent() ||
2440                 qobject_cast<QMainWindow*>(widget->parent())) {
2441                 painter->save();
2442                 drawMenuOrToolBarBackground(
2443                     widget, painter, r, option, false,
2444                     oneOf(toolbar->toolBarArea, Qt::NoToolBarArea,
2445                           Qt::BottomToolBarArea, Qt::TopToolBarArea));
2446                 if (opts.toolbarBorders != TB_NONE) {
2447                     const QColor *use = backgroundColors(option);
2448                     bool dark = oneOf(opts.toolbarBorders,
2449                                       TB_DARK, TB_DARK_ALL);
2450 
2451                     if (oneOf(opts.toolbarBorders, TB_DARK_ALL, TB_LIGHT_ALL)) {
2452                         painter->setPen(use[0]);
2453                         painter->drawLine(r.x(), r.y(),
2454                                           r.x() + r.width() - 1, r.y());
2455                         painter->drawLine(r.x(), r.y(),
2456                                           r.x(), r.y() + r.height() - 1);
2457                         painter->setPen(use[dark ? 3 : 4]);
2458                         painter->drawLine(r.x(), r.y() + r.height() - 1,
2459                                           r.x() + r.width() - 1,
2460                                           r.y() + r.height() - 1);
2461                         painter->drawLine(r.x() + r.width() - 1, r.y(),
2462                                           r.x() + r.width() - 1,
2463                                           r.y() + r.height() - 1);
2464                     } else {
2465                         bool paintH = true;
2466                         bool paintV = true;
2467 
2468                         switch (toolbar->toolBarArea) {
2469                         case Qt::BottomToolBarArea:
2470                         case Qt::TopToolBarArea:
2471                             paintV = false;
2472                             break;
2473                         case Qt::RightToolBarArea:
2474                         case Qt::LeftToolBarArea:
2475                             paintH = false;
2476                         default:
2477                             break;
2478                         }
2479 
2480                         painter->setPen(use[0]);
2481                         if (paintH) {
2482                             painter->drawLine(r.x(), r.y(),
2483                                               r.x() + r.width() - 1, r.y());
2484                         }
2485                         if (paintV) {
2486                             painter->drawLine(r.x(), r.y(), r.x(),
2487                                               r.y() + r.height()-1);
2488                         }
2489                         painter->setPen(use[dark ? 3 : 4]);
2490                         if (paintH) {
2491                             painter->drawLine(r.x(), r.y() + r.height() - 1,
2492                                               r.x() + r.width() - 1,
2493                                               r.y() + r.height() - 1);
2494                         }
2495                         if (paintV) {
2496                             painter->drawLine(r.x() + r.width() - 1,
2497                                               r.y(), r.x() + r.width() - 1,
2498                                               r.y() + r.height() - 1);
2499                         }
2500                     }
2501                 }
2502                 painter->restore();
2503             }
2504         }
2505         break;
2506     case CE_DockWidgetTitle:
2507         if (auto dwOpt = styleOptCast<QStyleOptionDockWidget>(option)) {
2508             bool verticalTitleBar = dwOpt->verticalTitleBar;
2509             bool isKOffice = qtcCheckType(widget, "KoDockWidgetTitleBar");
2510             QRect fillRect = r;
2511 
2512             // This fixes the look of KOffice's dock widget titlebars...
2513             if (isKOffice)
2514                 fillRect.adjust(-r.x(), -r.y(), 0, 0);
2515 
2516             if (!qtcIsFlat(opts.dwtAppearance)) {
2517                 painter->save();
2518 
2519                 QColor col((opts.dwtSettings & DWT_COLOR_AS_PER_TITLEBAR) ?
2520                            getMdiColors(option,
2521                                         state&State_Active)[ORIGINAL_SHADE] :
2522                            palette.window().color());
2523                 if (opts.round < ROUND_FULL) {
2524                     drawBevelGradient(col, painter, fillRect, !verticalTitleBar,
2525                                       false, opts.dwtAppearance,
2526                                       WIDGET_DOCK_WIDGET_TITLE);
2527                 } else {
2528                     double radius = qtcGetRadius(&opts, fillRect.width(),
2529                                                  fillRect.height(),
2530                                                  WIDGET_OTHER, RADIUS_EXTERNAL);
2531                     int round = ROUNDED_ALL;
2532 
2533                     if (opts.dwtSettings & DWT_ROUND_TOP_ONLY) {
2534                         round = verticalTitleBar ? ROUNDED_LEFT : ROUNDED_TOP;
2535                     }
2536                     painter->setRenderHint(QPainter::Antialiasing, true);
2537                     drawBevelGradient(col, painter, fillRect,
2538                                       buildPath(QRectF(fillRect), WIDGET_OTHER,
2539                                                 round, radius),
2540                                       !verticalTitleBar, false,
2541                                       opts.dwtAppearance,
2542                                       WIDGET_DOCK_WIDGET_TITLE, false);
2543                 }
2544                 painter->restore();
2545             }
2546             if (!dwOpt->title.isEmpty()) {
2547                 QRect titleRect(subElementRect(SE_DockWidgetTitleBarText,
2548                                                option, widget));
2549 
2550                 if (verticalTitleBar) {
2551                     QRect rVert(r);
2552                     QSize s(rVert.size());
2553 
2554                     s.transpose();
2555                     rVert.setSize(s);
2556 
2557                     titleRect = QRect(rVert.left() + r.bottom() -
2558                                       titleRect.bottom(),
2559                                       rVert.top() + titleRect.left() - r.left(),
2560                                       titleRect.height(), titleRect.width());
2561 
2562                     painter->translate(rVert.left(),
2563                                        rVert.top() + rVert.width());
2564                     painter->rotate(-90);
2565                     painter->translate(-rVert.left(), -rVert.top());
2566                 }
2567 #ifdef QTC_QT5_ENABLE_KDE
2568                 if (opts.dwtSettings & DWT_FONT_AS_PER_TITLEBAR) {
2569                     painter->setFont(QFontDatabase::systemFont(QFontDatabase::TitleFont));
2570                 }
2571 #endif
2572                 QFontMetrics fm(painter->fontMetrics());
2573                 QString title(fm.elidedText(dwOpt->title, Qt::ElideRight,
2574                                             titleRect.width(),
2575                                             QPalette::WindowText));
2576                 painter->save();
2577                 getMdiColors(option, state & State_Active);
2578 
2579                 QColor textColor((opts.dwtSettings &
2580                                   DWT_COLOR_AS_PER_TITLEBAR) ?
2581                                  state&State_Active ? m_activeMdiTextColor :
2582                                  m_mdiTextColor :
2583                                  palette.color(QPalette::WindowText));
2584                 QColor shadow(WINDOW_SHADOW_COLOR(opts.titlebarEffect));
2585                 int textOpt(Qt::AlignVCenter); // TODO: dwtPosAsPerTitleBar ?
2586 
2587                 if (opts.dwtSettings & DWT_TEXT_ALIGN_AS_PER_TITLEBAR) {
2588                     switch (opts.titlebarAlignment) {
2589                     case ALIGN_FULL_CENTER:
2590                         if (!verticalTitleBar && !reverse) {
2591                             QFontMetrics fm(painter->fontMetrics());
2592                             int width = fm.boundingRect(title).width();
2593 
2594                             if (((fillRect.width() + width) / 2) <=
2595                                 titleRect.width() + (isKOffice ? r.x() : 0)) {
2596                                 titleRect = fillRect;
2597                                 textOpt |= Qt::AlignHCenter;
2598                             } else {
2599                                 textOpt |= Qt::AlignRight;
2600                             }
2601                             break;
2602                         }
2603                         QTC_FALLTHROUGH();
2604                     case ALIGN_CENTER:
2605                         textOpt |= Qt::AlignHCenter;
2606                         break;
2607                     case ALIGN_RIGHT:
2608                         textOpt |= Qt::AlignRight;
2609                         break;
2610                     default:
2611                     case ALIGN_LEFT:
2612                         textOpt|=Qt::AlignLeft;
2613                         break;
2614                     }
2615                 } else {
2616                     textOpt |= Qt::AlignLeft;
2617                 }
2618 
2619                 if (!styleHint(SH_UnderlineShortcut, dwOpt, widget)) {
2620                     textOpt |= Qt::TextHideMnemonic;
2621                 } else {
2622                     textOpt |= Qt::TextShowMnemonic;
2623                 }
2624 
2625                 if ((opts.dwtSettings & DWT_EFFECT_AS_PER_TITLEBAR) &&
2626                     EFFECT_NONE != opts.titlebarEffect) {
2627                     shadow.setAlphaF(
2628                         WINDOW_TEXT_SHADOW_ALPHA(opts.titlebarEffect));
2629                     painter->setPen(shadow);
2630                     painter->drawText(titleRect.adjusted(1, 1, 1, 1),
2631                                       textOpt, title);
2632 
2633                     if (!(state & State_Active) &&
2634                         DARK_WINDOW_TEXT(textColor)) {
2635                         textColor.setAlpha((textColor.alpha() * 180) >> 8);
2636                     }
2637                 }
2638                 painter->setPen(textColor);
2639                 painter->drawText(titleRect, textOpt, title);
2640                 painter->restore();
2641             }
2642         }
2643         break;
2644     case CE_HeaderEmptyArea: {
2645         auto ho = styleOptCast<QStyleOptionHeader>(option);
2646         bool horiz = (ho ? ho->orientation == Qt::Horizontal :
2647                       state & State_Horizontal);
2648         QStyleOption opt(*option);
2649         const QColor *use = (opts.lvButton ? buttonColors(option) :
2650                              backgroundColors(option));
2651 
2652         opt.state &= ~State_MouseOver;
2653         painter->save();
2654 
2655         drawBevelGradient(getFill(&opt, use), painter, r, horiz, false,
2656                           opts.lvAppearance, WIDGET_LISTVIEW_HEADER);
2657 
2658         painter->setRenderHint(QPainter::Antialiasing, true);
2659         if(opts.lvAppearance == APPEARANCE_RAISED) {
2660             painter->setPen(use[4]);
2661             if (horiz) {
2662                 drawAaLine(painter, r.x(), r.y() + r.height() - 2,
2663                            r.x() + r.width() - 1, r.y() + r.height() - 2);
2664             } else {
2665                 drawAaLine(painter, r.x() + r.width() - 2, r.y(),
2666                            r.x() + r.width() - 2, r.y() + r.height() - 1);
2667             }
2668         }
2669 
2670         painter->setPen(use[QTC_STD_BORDER]);
2671         if (horiz) {
2672             drawAaLine(painter, r.x(), r.y() + r.height() - 1,
2673                        r.x() + r.width() - 1, r.y() + r.height() - 1);
2674         } else if (reverse) {
2675             drawAaLine(painter, r.x(), r.y(), r.x(), r.y() + r.height() - 1);
2676         } else {
2677             drawAaLine(painter, r.x() + r.width() - 1, r.y(),
2678                        r.x() + r.width() - 1, r.y() + r.height() - 1);
2679         }
2680         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
2681         painter->restore();
2682         break;
2683     }
2684     case CE_HeaderSection:
2685         if (auto ho = styleOptCast<QStyleOptionHeader>(option)) {
2686             const QColor *use = (state & State_Enabled && m_sortedLvColors &&
2687                                  QStyleOptionHeader::None != ho->sortIndicator ?
2688                                  m_sortedLvColors : opts.lvButton ?
2689                                  buttonColors(option) :
2690                                  backgroundColors(option));
2691             painter->save();
2692             if (state & (State_Raised | State_Sunken)) {
2693                 bool sunken = (state & (/*State_Down |*/ /*State_On | */
2694                                    State_Sunken));
2695                 QStyleOption opt(*option);
2696                 opt.state &= ~State_On;
2697 
2698                 if (ho->section == -1 && !(state & State_Enabled) && widget &&
2699                     widget->isEnabled()) {
2700                     opt.state |= State_Enabled;
2701                 }
2702                 drawBevelGradient(getFill(&opt, use), painter, r,
2703                                   ho->orientation == Qt::Horizontal, sunken,
2704                                   opts.lvAppearance, WIDGET_LISTVIEW_HEADER);
2705                 painter->setRenderHint(QPainter::Antialiasing, true);
2706                 if(opts.lvAppearance == APPEARANCE_RAISED) {
2707                     painter->setPen(use[4]);
2708                     if (ho->orientation == Qt::Horizontal) {
2709                         drawAaLine(painter, r.x(), r.y() + r.height() - 2,
2710                                    r.x() + r.width() - 1,
2711                                    r.y() + r.height() - 2);
2712                     } else {
2713                         drawAaLine(painter, r.x() + r.width() - 2, r.y(),
2714                                    r.x() + r.width() - 2,
2715                                    r.y() + r.height() - 1);
2716                     }
2717                 }
2718 
2719                 if (ho->orientation == Qt::Horizontal) {
2720                     painter->setPen(use[QTC_STD_BORDER]);
2721                     drawAaLine(painter, r.x(), r.y() + r.height() - 1,
2722                                r.x() + r.width() - 1, r.y() + r.height() - 1);
2723                     if (opts.coloredMouseOver && state & State_MouseOver &&
2724                         state & State_Enabled) {
2725                         drawHighlight(painter, QRect(r.x(),
2726                                                      r.y() + r.height() - 2,
2727                                                      r.width(), 2), true, true);
2728                     }
2729 
2730                     if (noneOf(ho->position, QStyleOptionHeader::End,
2731                                QStyleOptionHeader::OnlyOneSection)) {
2732                         // Draw header separator
2733                         int sep_x = reverse ? r.x() : r.x() + r.width() - 2;
2734                         drawFadedLine(painter, QRect(sep_x, r.y() + 5, 1,
2735                                                      r.height() - 10),
2736                                       use[QTC_STD_BORDER], true, true, false);
2737                         drawFadedLine(painter, QRect(sep_x + 1, r.y() + 5, 1,
2738                                                      r.height() - 10),
2739                                       use[0], true, true, false);
2740                     }
2741                 } else {
2742                     painter->setPen(use[QTC_STD_BORDER]);
2743                     if (reverse) {
2744                         drawAaLine(painter, r.x(), r.y(), r.x(),
2745                                    r.y() + r.height() - 1);
2746                     } else {
2747                         drawAaLine(painter, r.x() + r.width() - 1,
2748                                    r.y(), r.x() + r.width() - 1,
2749                                    r.y() + r.height() - 1);
2750                     }
2751 
2752                     if (noneOf(ho->position, QStyleOptionHeader::End,
2753                                QStyleOptionHeader::OnlyOneSection)) {
2754                         // Draw header separator
2755                         drawFadedLine(painter, QRect(r.x() + 5,
2756                                                      r.y() + r.height() - 2,
2757                                                      r.width() - 10, 1),
2758                                       use[QTC_STD_BORDER], true, true, true);
2759                         drawFadedLine(painter, QRect(r.x() + 5,
2760                                                      r.y() + r.height() - 1,
2761                                                      r.width() - 10, 1),
2762                                       use[0], true, true, true);
2763                     }
2764                     if (opts.coloredMouseOver && state & State_MouseOver &&
2765                         state & State_Enabled) {
2766                         drawHighlight(painter, QRect(r.x(),
2767                                                      r.y() + r.height() - 3,
2768                                                      r.width(), 2), true, true);
2769                     }
2770                 }
2771                 QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
2772             } else if (!qtcIsFlat(opts.lvAppearance) && !reverse &&
2773                        ((State_Enabled | State_Active) == state ||
2774                         State_Enabled == state)) {
2775                 QPolygon top;
2776                 const QColor &col = getFill(option, use);
2777 
2778                 top.setPoints(3, r.x(), r.y(), r.x() + r.width(), r.y(),
2779                               r.x() + r.width(), r.y() + r.height());
2780                 painter->setClipRegion(QRegion(top));
2781                 drawBevelGradient(col, painter, r, true, false,
2782                                   opts.lvAppearance, WIDGET_LISTVIEW_HEADER);
2783                 painter->setClipRegion(QRegion(r).xored(QRegion(top)));
2784                 drawBevelGradient(col, painter, r, false, false,
2785                                   opts.lvAppearance, WIDGET_LISTVIEW_HEADER);
2786             } else {
2787                 painter->fillRect(r, getFill(option, use));
2788             }
2789             painter->restore();
2790         }
2791         break;
2792     case CE_HeaderLabel:
2793         if (auto header = styleOptCast<QStyleOptionHeader>(option)) {
2794             if (!header->icon.isNull()) {
2795                 QPixmap pixmap(getIconPixmap(header->icon,
2796                                              pixelMetric(PM_SmallIconSize),
2797                                              header->state));
2798                 int pixw = pixmap.width();
2799                 QRect aligned(alignedRect(header->direction,
2800                                           QFlag(header->iconAlignment),
2801                                           pixmap.size(), r));
2802                 QRect inter(aligned.intersected(r));
2803 
2804                 painter->drawPixmap(inter.x(), inter.y(), pixmap,
2805                                     inter.x() - aligned.x(),
2806                                     inter.y() - aligned.y(), inter.width(),
2807                                     inter.height());
2808 
2809                 if (Qt::LeftToRight == header->direction) {
2810                     r.setLeft(r.left() + pixw + 2);
2811                 } else {
2812                     r.setRight(r.right() - pixw - 2);
2813                 }
2814             }
2815             drawItemTextWithRole(painter, r, header->textAlignment, palette,
2816                                  state & State_Enabled, header->text,
2817                                  QPalette::ButtonText);
2818         }
2819         break;
2820     case CE_ProgressBarGroove: {
2821         bool doEtch = opts.buttonEffect != EFFECT_NONE && opts.borderProgress;
2822         bool horiz = true;
2823         QColor col;
2824 
2825         if (auto bar = styleOptCast<QStyleOptionProgressBar>(option)) {
2826             horiz = bar->orientation == Qt::Horizontal;
2827         }
2828 
2829         painter->save();
2830 
2831         if (doEtch) {
2832             r.adjust(1, 1, -1, -1);
2833         }
2834 
2835         switch (opts.progressGrooveColor) {
2836         default:
2837         case ECOLOR_BASE:
2838             col = palette.base().color();
2839             break;
2840         case ECOLOR_BACKGROUND:
2841             col = palette.window().color();
2842             break;
2843         case ECOLOR_DARK:
2844             col = m_backgroundCols[2];
2845         }
2846 
2847         drawBevelGradient(col, painter, r, opts.borderProgress ?
2848                           buildPath(r, WIDGET_PBAR_TROUGH, ROUNDED_ALL,
2849                                     qtcGetRadius(&opts, r.width(), r.height(),
2850                                                  WIDGET_PBAR_TROUGH,
2851                                                  RADIUS_EXTERNAL)) :
2852                           QPainterPath(), horiz, false,
2853                           opts.progressGrooveAppearance, WIDGET_PBAR_TROUGH);
2854 
2855         if (doEtch) {
2856             drawEtch(painter, r.adjusted(-1, -1, 1, 1), widget,
2857                      WIDGET_PBAR_TROUGH);
2858         } else if (!opts.borderProgress) {
2859             painter->setPen(m_backgroundCols[QTC_STD_BORDER]);
2860             if (horiz) {
2861                 painter->drawLine(r.topLeft(), r.topRight());
2862                 painter->drawLine(r.bottomLeft(), r.bottomRight());
2863             } else {
2864                 painter->drawLine(r.topLeft(), r.bottomLeft());
2865                 painter->drawLine(r.topRight(), r.bottomRight());
2866             }
2867         }
2868 
2869         if (opts.borderProgress)
2870             drawBorder(painter, r, option, ROUNDED_ALL,
2871                        backgroundColors(option), WIDGET_PBAR_TROUGH,
2872                        qtcIsFlat(opts.progressGrooveAppearance) &&
2873                        ECOLOR_DARK != opts.progressGrooveColor ?
2874                        BORDER_SUNKEN : BORDER_FLAT);
2875         painter->restore();
2876         break;
2877     }
2878     case CE_ProgressBarContents:
2879         if (auto bar = styleOptCast<QStyleOptionProgressBar>(option)) {
2880             bool vertical(false);
2881             bool inverted(false);
2882             bool indeterminate = bar->minimum == 0 && bar->maximum == 0;
2883 
2884             // Get extra style options if version 2
2885             if (auto bar = styleOptCast<QStyleOptionProgressBar>(option)) {
2886                 vertical = bar->orientation == Qt::Vertical;
2887                 inverted = bar->invertedAppearance;
2888             }
2889 
2890             if (!indeterminate && bar->progress == -1)
2891                 break;
2892 
2893             bool reverse = ((!vertical && (bar->direction == Qt::RightToLeft)) ||
2894                             vertical);
2895 
2896             if (inverted)
2897                 reverse = !reverse;
2898 
2899             painter->save();
2900 
2901             if (!m_progressBarAnimateTimer && (opts.animatedProgress || indeterminate)) {
2902                 if (!m_timer.isValid())
2903                     m_timer.start();
2904                 // now we'll need a timer, start it at the regular frequency
2905                 m_progressBarAnimateFps = constProgressBarFps;
2906                 m_progressBarAnimateTimer = const_cast<Style*>(this)->startTimer(1000/m_progressBarAnimateFps);
2907             }
2908 
2909             if (indeterminate) {
2910                 //Busy indicator
2911                 int chunkSize = PROGRESS_CHUNK_WIDTH * 3.4;
2912                 int measure = vertical ? r.height() : r.width();
2913 
2914                 if (chunkSize > measure / 2)
2915                     chunkSize = measure / 2;
2916 
2917                 int step = m_animateStep % ((measure - chunkSize) * 2);
2918                 QStyleOption opt(*option);
2919 
2920                 if (step > (measure - chunkSize))
2921                     step = 2 * (measure - chunkSize) - step;
2922 
2923                 opt.state |= State_Raised | State_Horizontal;
2924                 drawProgress(painter, vertical ? QRect(r.x(), r.y() + step,
2925                                                        r.width(), chunkSize) :
2926                              QRect(r.x() + step, r.y(), chunkSize, r.height()),
2927                              option, vertical);
2928             } else if (r.isValid() && bar->progress > 0) {
2929                 // workaround for bug in QProgressBar
2930                 qint64 progress = qMax(bar->progress, bar->minimum);
2931                 double pg = ((progress - bar->minimum) /
2932                              qtcMax(1.0, double(bar->maximum - bar->minimum)));
2933 
2934                 if (vertical) {
2935                     int height = qtcMin(r.height(), pg * r.height());
2936 
2937                     if (inverted) {
2938                         drawProgress(painter, QRect(r.x(), r.y(), r.width(),
2939                                                     height), option, true);
2940                     } else {
2941                         drawProgress(painter,
2942                                      QRect(r.x(), r.y() + (r.height() - height),
2943                                            r.width(), height), option, true);
2944                     }
2945                 } else {
2946                     int width = qtcMin(r.width(), pg * r.width());
2947 
2948                     if (reverse || inverted) {
2949                         drawProgress(painter, QRect(r.x() + r.width() - width,
2950                                                     r.y(), width, r.height()),
2951                                      option, false, true);
2952                     } else {
2953                         drawProgress(painter, QRect(r.x(), r.y(), width,
2954                                                     r.height()), option);
2955                     }
2956                 }
2957             }
2958             painter->restore();
2959         }
2960         break;
2961     case CE_ProgressBarLabel:
2962         if (auto bar = styleOptCast<QStyleOptionProgressBar>(option)) {
2963             // The busy indicator doesn't draw a label
2964             if (bar->minimum == 0 && bar->maximum == 0)
2965                 return;
2966 
2967             bool vertical = false;
2968             bool inverted = false;
2969             bool bottomToTop = false;
2970 
2971             // Get extra style options if version 2
2972             if (auto bar = styleOptCast<QStyleOptionProgressBar>(option)) {
2973                 vertical = bar->orientation == Qt::Vertical;
2974                 inverted = bar->invertedAppearance;
2975                 bottomToTop = bar->bottomToTop;
2976             }
2977 
2978             painter->save();
2979             painter->setRenderHint(QPainter::Antialiasing, true);
2980 
2981             if (vertical) {
2982                 // flip width and height
2983                 r = QRect(r.left(), r.top(), r.height(), r.width());
2984 
2985                 QTransform m;
2986                 if (bottomToTop) {
2987                     m.translate(0.0, r.width());
2988                     m.rotate(-90);
2989                 } else {
2990                     m.translate(r.height(), 0.0);
2991                     m.rotate(90);
2992                 }
2993                 painter->setTransform(m);
2994             }
2995 
2996             int progressIndicatorPos =
2997                 ((bar->progress - bar->minimum) /
2998                  qMax(1.0, double(bar->maximum - bar->minimum)) * r.width());
2999             bool flip((!vertical &&
3000                        (((bar->direction == Qt::RightToLeft) && !inverted) ||
3001                         ((Qt::LeftToRight==bar->direction) && inverted))) ||
3002                       (vertical && ((!inverted && !bottomToTop) ||
3003                                     (inverted && bottomToTop))));
3004             QRect leftRect;
3005             QRegion rightRect(r);
3006             QPalette::ColorGroup cg =
3007                 (state & State_Enabled || state == State_None ?
3008                  QPalette::Active : QPalette::Current);
3009 
3010             if (flip) {
3011                 int indicatorPos = r.width() - progressIndicatorPos;
3012 
3013                 if (indicatorPos >= 0 && indicatorPos <= r.width()) {
3014                     painter->setPen(palette.brush(cg, QPalette::Base).color());
3015                     leftRect = QRect(r.left(), r.top(), indicatorPos, r.height());
3016                     // rightRect = QRect(r.left() + indicatorPos, r.top(),
3017                     //                   r.width() - indicatorPos, r.height());
3018                 } else if (indicatorPos > r.width()) {
3019                     painter->setPen(palette.brush(cg, QPalette::Text).color());
3020                 } else {
3021                     painter->setPen(
3022                         palette.brush(cg, QPalette::HighlightedText).color());
3023                 }
3024             } else {
3025                 if (progressIndicatorPos >= 0 &&
3026                     progressIndicatorPos <= r.width()) {
3027                     leftRect = QRect(r.left(), r.top(), progressIndicatorPos,
3028                                      r.height());
3029                     // rightRect = QRect(r.left() + progressIndicatorPos, r.top(),
3030                     //                   r.width() - progressIndicatorPos,
3031                     //                   r.height());
3032                 } else if (progressIndicatorPos > r.width()) {
3033                     painter->setPen(
3034                         palette.brush(cg, QPalette::HighlightedText).color());
3035                 } else {
3036                     painter->setPen(palette.brush(cg, QPalette::Text).color());
3037                 }
3038             }
3039 
3040             QString text = bar->fontMetrics.elidedText(bar->text,
3041                                                        Qt::ElideRight,
3042                                                        r.width());
3043             rightRect = rightRect.subtracted(leftRect);
3044             painter->setClipRegion(rightRect);
3045             painter->drawText(r, text,
3046                               QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter |
3047                                           Qt::AlignVCenter));
3048             if (!leftRect.isNull()) {
3049                 painter->setPen(
3050                     palette.brush(cg, flip ? QPalette::Text :
3051                                   QPalette::HighlightedText).color());
3052                 painter->setClipRect(leftRect);
3053                 painter->drawText(
3054                     r, text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter |
3055                                          Qt::AlignVCenter));
3056             }
3057             painter->restore();
3058         }
3059         break;
3060     case CE_MenuBarItem:
3061         if (auto mbi = styleOptCast<QStyleOptionMenuItem>(option)) {
3062             bool down = state & (State_On | State_Sunken);
3063             bool active = (state & State_Enabled &&
3064                            (down || (state & State_Selected &&
3065                                      opts.menubarMouseOver)));
3066             uint alignment = (Qt::AlignCenter | Qt::TextShowMnemonic |
3067                               Qt::TextDontClip | Qt::TextSingleLine);
3068             QPixmap pix = getIconPixmap(mbi->icon,
3069                                         pixelMetric(PM_SmallIconSize),
3070                                         mbi->state);
3071             if (!styleHint(SH_UnderlineShortcut, mbi, widget))
3072                 alignment |= Qt::TextHideMnemonic;
3073 
3074             painter->save();
3075             drawMenuOrToolBarBackground(widget, painter, mbi->menuRect, option);
3076             if (active)
3077                 drawMenuItem(painter, !opts.roundMbTopOnly &&
3078                              !(opts.square & SQUARE_POPUP_MENUS) ?
3079                              r.adjusted(1, 1, -1, -1) : r, option, MENU_BAR,
3080                              (down || theThemedApp == APP_OPENOFFICE) &&
3081                              opts.roundMbTopOnly ? ROUNDED_TOP : ROUNDED_ALL,
3082                              opts.useHighlightForMenu &&
3083                              (opts.colorMenubarMouseOver || down ||
3084                               theThemedApp == APP_OPENOFFICE) ?
3085                              (m_ooMenuCols ? m_ooMenuCols :
3086                               m_highlightCols) : m_backgroundCols);
3087             if (!pix.isNull()) {
3088                 drawItemPixmap(painter, mbi->rect, alignment, pix);
3089             } else {
3090                 const QColor &col =
3091                     (state & State_Enabled ?
3092                      ((opts.colorMenubarMouseOver && active) ||
3093                       (!opts.colorMenubarMouseOver && down)) ?
3094                      opts.customMenuTextColor ?
3095                      opts.customMenuSelTextColor :
3096                      opts.useHighlightForMenu ?
3097                      palette.highlightedText().color() :
3098                      palette.windowText().color() :
3099                      palette.windowText().color() :
3100                      palette.windowText().color());
3101 
3102                 painter->setPen(col);
3103                 painter->drawText(r, alignment, mbi->text);
3104             }
3105             painter->restore();
3106         }
3107         break;
3108     case CE_MenuItem:
3109         if (auto menuItem = styleOptCast<QStyleOptionMenuItem>(option)) {
3110             // TODO check qtquick
3111             bool comboMenu(qobject_cast<const QComboBox*>(widget)),
3112                 reverse(Qt::RightToLeft==menuItem->direction),
3113                 isOO(isOOWidget(widget));
3114             int checkcol(qMax(menuItem->maxIconWidth, 20)),
3115                 stripeWidth(qMax(checkcol, constMenuPixmapWidth)-2);
3116             const QColor *use = popupMenuCols(option);
3117 
3118             QRect rx(r);
3119 
3120             if (isOO) {
3121                 if (opts.borderMenuitems) {
3122                     r.adjust(2, 0, -2, 0);
3123                 } else if (opts.menuitemAppearance == APPEARANCE_FADE) {
3124                     r.adjust(1, 0, -1, 0);
3125                 }
3126             }
3127 
3128             painter->save();
3129 
3130             if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
3131                 bool isMenu = !widget || qobject_cast<const QMenu*>(widget);
3132                 bool doStripe = isMenu && opts.menuStripe && !comboMenu;
3133 
3134                 if (doStripe)
3135                     drawBevelGradient(menuStripeCol(), painter,
3136                                       QRect(reverse ? r.right() - stripeWidth :
3137                                             r.x(), r.y(), stripeWidth,
3138                                             r.height()), false, false,
3139                                       opts.menuStripeAppearance, WIDGET_OTHER);
3140 
3141                 if (!menuItem->text.isEmpty()) {
3142                     int textAlignment;
3143                     QFont font = m_fntHelper->fontStripStyleName(menuItem->font);
3144                     QRect textRect;
3145                     if (opts.buttonStyleMenuSections) {
3146                         QStyleOption opt;
3147                         opt.rect = r.adjusted(2, 2, -3, -2);
3148                         opt.state = State_Raised | State_Enabled | State_Horizontal;
3149                         drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL,
3150                                        getFill(&opt, use), use, true,
3151                                        WIDGET_NO_ETCH_BTN);
3152 
3153                         font.setBold(true);
3154                         painter->setFont(font);
3155                         textAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
3156                         textRect = r;
3157                     } else {
3158                         font.setBold(true);
3159                         font.setUnderline(true);
3160 #ifdef Q_OS_MACOS
3161                         if (QGuiApplication::platformName() == QLatin1String("cocoa")) {
3162                             font.setLetterSpacing(QFont::PercentageSpacing, 95);
3163                         }
3164 #endif
3165                         painter->setFont(font);
3166                         QRect miRect(menuItem->rect.left() + 5 +
3167                                      (!reverse && doStripe ? stripeWidth : 0),
3168                                      menuItem->rect.center().y() - painter->fontMetrics().ascent() / 2 - 5,
3169                                      menuItem->rect.width() -
3170                                      (9 + (doStripe ? stripeWidth : 0)), 1);
3171                         QColor lineCol = use[MENU_SEP_SHADE];
3172                         if (miRect.y() >= rx.height() / 2) {
3173                             drawFadedLine(painter, miRect, lineCol, reverse,
3174                                       !reverse, true);
3175                         }
3176                         textAlignment = Qt::AlignLeft | Qt::AlignBottom;
3177                         textRect = r.adjusted(5, 5, -5, -5);
3178                     }
3179                     drawItemTextWithRole(painter, textRect,
3180                                          textAlignment,
3181                                          palette, state & State_Enabled,
3182                                          menuItem->text, QPalette::Text);
3183                 } else {
3184                     QRect miRect(menuItem->rect.left() + 3 +
3185                                  (!reverse && doStripe ? stripeWidth : 0),
3186                                  menuItem->rect.center().y(),
3187                                  menuItem->rect.width() -
3188                                  (7 + (doStripe ? stripeWidth : 0)), 1);
3189                     drawFadedLine(painter, miRect, use[MENU_SEP_SHADE], true,
3190                                   true, true);
3191                 }
3192 
3193                 if (isOO) {
3194                     painter->setPen(use[QTC_STD_BORDER]);
3195                     painter->drawLine(rx.topLeft(), rx.bottomLeft());
3196                     painter->drawLine(rx.topRight(), rx.bottomRight());
3197                 }
3198                 painter->restore();
3199                 break;
3200             }
3201 
3202             bool selected = state & State_Selected;
3203             bool checkable =
3204                 menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
3205             bool checked = menuItem->checked;
3206             bool enabled = state & State_Enabled;
3207 
3208             // check if the font tick is wider than the current margin
3209             // and adjust if necessary
3210             initFontTickData(menuItem->font, widget);
3211             int dx = 0;
3212             if (menuTickCompensation(opts, checkcol, dx)) {
3213                 r.adjust(-dx, 0, dx, 0);
3214                 checkcol += dx;
3215             }
3216             if (opts.menuStripe && !comboMenu)
3217                 drawBevelGradient(menuStripeCol(), painter,
3218                                   QRect(reverse ? r.right()-stripeWidth : r.x(),
3219                                         r.y(), stripeWidth, r.height()),
3220                                   false, false, opts.menuStripeAppearance,
3221                                   WIDGET_OTHER);
3222 
3223             if (selected && enabled) {
3224                 drawMenuItem(painter, r, option,
3225                              /*comboMenu ? MENU_COMBO : */MENU_POPUP,
3226                              ROUNDED_ALL,
3227                              opts.useHighlightForMenu ?
3228                              (m_ooMenuCols ? m_ooMenuCols :
3229                               m_highlightCols) : use);
3230             }
3231 
3232             if (comboMenu) {
3233                 if (menuItem->icon.isNull()) {
3234                     checkcol = 0;
3235                 } else {
3236                     checkcol = menuItem->maxIconWidth;
3237                 }
3238             } else {
3239                 // Check
3240                 QRect checkRect(r.left() + 3, r.center().y() - 6,
3241                                 opts.crSize, opts.crSize);
3242                 checkRect = visualRect(menuItem->direction, menuItem->rect,
3243                                        checkRect);
3244                 if (checkable) {
3245                     if (!opts.onlyTicksInMenu && (menuItem->checkType &
3246                          QStyleOptionMenuItem::Exclusive) &&
3247                         menuItem->icon.isNull()) {
3248                         QStyleOptionButton button;
3249                         button.rect = checkRect;
3250                         button.state = menuItem->state|STATE_MENU;
3251                         if (checked)
3252                             button.state |= State_On;
3253                         button.palette = palette;
3254                         drawPrimitive(PE_IndicatorRadioButton, &button,
3255                                       painter, widget);
3256                     } else {
3257                         if (menuItem->icon.isNull() || !opts.menuIcons) {
3258                             QStyleOptionButton button;
3259                             button.rect = checkRect;
3260                             button.state = menuItem->state|STATE_MENU;
3261                             if (checked)
3262                                 button.state |= State_On;
3263                             button.palette = palette;
3264                             drawPrimitive(PE_IndicatorMenuCheckMark, &button,
3265                                           painter, widget);
3266                         } else if (checked) {
3267                             int iconSize = qMax(menuItem->maxIconWidth, 20);
3268                             QRect sunkenRect(r.left() + 1,
3269                                              r.top() + (r.height() -
3270                                                         iconSize) / 2,
3271                                              iconSize, iconSize);
3272                             QStyleOption opt(*option);
3273 
3274                             sunkenRect = visualRect(menuItem->direction,
3275                                                     menuItem->rect, sunkenRect);
3276                             opt.state = menuItem->state;
3277                             opt.state |= State_Raised | State_Horizontal | State_On;
3278                             drawLightBevel(painter, sunkenRect, &opt, widget,
3279                                            ROUNDED_ALL,
3280                                            getFill(&opt, m_buttonCols),
3281                                            m_buttonCols);
3282                         }
3283                     }
3284                 }
3285             }
3286 
3287             // Text and icon, ripped from windows style
3288             bool dis = !(state & State_Enabled);
3289             bool act = state & State_Selected;
3290 
3291             if (opts.menuIcons && !menuItem->icon.isNull()) {
3292                 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
3293                 if (act && !dis)
3294                     mode = QIcon::Active;
3295                 QIcon::State state = checked ? QIcon::On : QIcon::Off;
3296 
3297                 int size = pixelMetric(PM_SmallIconSize, option, widget);
3298                 QRect iconRect(menuItem->rect.x(),
3299                                menuItem->rect.y(), checkcol,
3300                                menuItem->rect.height());
3301                 iconRect = centerRect(iconRect, size, size);
3302                 iconRect = visualRect(option->direction, menuItem->rect, iconRect);
3303 
3304                 QPixmap pixmap(getIconPixmap(menuItem->icon, iconRect.size(), mode, state));
3305                 painter->setPen(palette.text().color());
3306                 if (checkable && checked)
3307                     iconRect.adjust(1, 1, 1, 1);
3308                 painter->drawPixmap(iconRect.topLeft(), pixmap);
3309             }
3310 
3311             painter->setPen(dis ? palette.text().color() :
3312                             selected && opts.useHighlightForMenu &&
3313                             !m_ooMenuCols ? palette.highlightedText().color() :
3314                             palette.windowText().color());
3315 
3316             int x;
3317             int y;
3318             int w;
3319             int h;
3320             int tab = menuItem->tabWidth;
3321             menuItem->rect.getRect(&x, &y, &w, &h);
3322             int xm = windowsItemFrame + checkcol + windowsItemHMargin - 2;
3323             int xpos = menuItem->rect.x() + xm;
3324             QRect textRect(xpos, y + windowsItemVMargin,
3325                            opts.menuIcons ?
3326                            (w - xm - windowsRightBorder - tab + 1) :
3327                            (w - ((xm*2) + tab)), h - 2 * windowsItemVMargin);
3328             QRect vTextRect = visualRect(option->direction, menuItem->rect,
3329                                          textRect);
3330             QString s = menuItem->text;
3331 
3332             if (!s.isEmpty()) {
3333                 // draw text
3334                 int t(s.indexOf(QLatin1Char('\t'))),
3335                     textFlags(Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine);
3336 
3337                 if (!styleHint(SH_UnderlineShortcut, menuItem, widget))
3338                     textFlags |= Qt::TextHideMnemonic;
3339                 textFlags |= Qt::AlignLeft;
3340 
3341                 if (t >= 0)
3342                 {
3343                     QRect vShortcutRect(visualRect(option->direction, menuItem->rect,
3344                                                    QRect(textRect.topRight(), QPoint(menuItem->rect.right(), textRect.bottom()))));
3345                     vShortcutRect.adjust(dx, 0, dx, 0);
3346                     painter->drawText(vShortcutRect, textFlags, s.mid(t + 1));
3347                     s = s.left(t);
3348                 }
3349 
3350                 QFont font = m_fntHelper->fontStripStyleName(menuItem->font);
3351 
3352                 if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem)
3353                     font.setBold(true);
3354 
3355                 painter->setFont(font);
3356                 painter->drawText(vTextRect, textFlags, s.left(t));
3357             }
3358 
3359             // Arrow
3360             if (QStyleOptionMenuItem::SubMenu==menuItem->menuItemType) // draw sub menu arrow
3361             {
3362                 int              dim((menuItem->rect.height() - 4) / 2),
3363                     xpos(menuItem->rect.left() + menuItem->rect.width() - 3 - dim);
3364                 PrimitiveElement arrow(Qt::RightToLeft==option->direction ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight);
3365                 QRect            vSubMenuRect(visualRect(option->direction, menuItem->rect,
3366                                                          QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim)));
3367 
3368                 drawArrow(painter, vSubMenuRect, arrow,
3369                           opts.useHighlightForMenu && state&State_Enabled && state&State_Selected && !m_ooMenuCols
3370                           ? palette.highlightedText().color()
3371                           : palette.text().color());
3372             }
3373 
3374             if(isOO)
3375             {
3376                 painter->setPen(use[QTC_STD_BORDER]);
3377                 painter->drawLine(rx.topLeft(), rx.bottomLeft());
3378                 painter->drawLine(rx.topRight(), rx.bottomRight());
3379             }
3380             painter->restore();
3381         }
3382         break;
3383     case CE_MenuHMargin:
3384     case CE_MenuVMargin:
3385     case CE_MenuEmptyArea:
3386         break;
3387     case CE_PushButton:
3388         if (auto btn = styleOptCast<QStyleOptionButton>(option)) {
3389             // For OO.o 3.2 need to fill widget background!
3390             if(isOOWidget(widget))
3391                 painter->fillRect(r, palette.brush(QPalette::Window));
3392             drawControl(CE_PushButtonBevel, btn, painter, widget);
3393 
3394             QStyleOptionButton subopt(*btn);
3395             if (!btn->icon.isNull()
3396                 && !(styleHint(SH_DialogButtonBox_ButtonsHaveIcons, btn, widget) || btn->text.isEmpty())) {
3397                 // remove the icon from our local QStyleOptionButton copy
3398                 subopt.icon = QIcon();
3399             }
3400 
3401             subopt.rect = subElementRect(SE_PushButtonContents, &subopt, widget);
3402             drawControl(CE_PushButtonLabel, &subopt, painter, widget);
3403 
3404             if (state & State_HasFocus &&
3405                 !(state & State_MouseOver && opts.coloredMouseOver != MO_NONE &&
3406                   oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED))) {
3407                 QStyleOptionFocusRect fropt;
3408                 fropt.QStyleOption::operator=(*btn);
3409                 fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
3410                 drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
3411             }
3412         }
3413         break;
3414     case CE_PushButtonBevel:
3415         if (auto btn = styleOptCast<QStyleOptionButton>(option)) {
3416             int dbi(pixelMetric(PM_ButtonDefaultIndicator, btn, widget));
3417 
3418             if (btn->features & QStyleOptionButton::DefaultButton)
3419                 drawPrimitive(PE_FrameDefaultButton, option, painter, widget);
3420             if (btn->features & QStyleOptionButton::AutoDefaultButton)
3421                 r.setCoords(r.left() + dbi, r.top() + dbi, r.right() - dbi, r.bottom() - dbi);
3422             if (!(btn->features & (QStyleOptionButton::Flat |
3423                                    QStyleOptionButton::CommandLinkButton)) ||
3424                 state&(State_Sunken | State_On | State_MouseOver)) {
3425                 QStyleOptionButton tmpBtn(*btn);
3426 
3427                 tmpBtn.rect = r;
3428                 drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget);
3429             }
3430             if (btn->features & QStyleOptionButton::HasMenu)
3431             {
3432                 int   mbi(pixelMetric(PM_MenuButtonIndicator, btn, widget));
3433                 QRect ar(Qt::LeftToRight==btn->direction
3434                          ? btn->rect.right() - (mbi+6)
3435                          : btn->rect.x() + 6,
3436                          ((btn->rect.height() - mbi)/2),
3437                          mbi, mbi);
3438 
3439                 if(option->state &(State_On | State_Sunken))
3440                     ar.adjust(1, 1, 1, 1);
3441 
3442                 drawArrow(painter, ar, PE_IndicatorArrowDown,
3443                           MOArrow(state, palette, QPalette::ButtonText));
3444             }
3445         }
3446         break;
3447     case CE_PushButtonLabel:
3448         if (auto button = styleOptCast<QStyleOptionButton>(option)) {
3449             uint tf(Qt::AlignVCenter | Qt::TextShowMnemonic);
3450 
3451             if (!styleHint(SH_UnderlineShortcut, button, widget))
3452                 tf |= Qt::TextHideMnemonic;
3453 
3454             if (!button->icon.isNull() &&
3455                 (styleHint(SH_DialogButtonBox_ButtonsHaveIcons, button, widget) ||
3456                  button->text.isEmpty())) {
3457                 QIcon::Mode mode(button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
3458 
3459                 if (QIcon::Normal == mode && button->state & State_HasFocus)
3460                     mode = QIcon::Active;
3461 
3462                 QIcon::State state((button->state & State_On) || (button->state & State_Sunken) ?
3463                                    QIcon::On : QIcon::Off);
3464 
3465                 QSize iconSize = button->iconSize;
3466                 int width = iconSize.width();
3467                 int height = iconSize.height();
3468                 int iconSpacing = 4; //### 4 is currently hardcoded in QPushButton::sizeHint()
3469 
3470                 // Center both icon and text
3471                 int xoffset = width;
3472                 if (!button->text.isEmpty())
3473                     xoffset += (button->fontMetrics.boundingRect(r, tf, button->text).width() +
3474                                 iconSpacing);
3475                 QRect iconRect(r.x() + (r.width() - xoffset) / 2,
3476                                r.y() + (r.height() - height) / 2, width, height);
3477 
3478                 tf |= Qt::AlignLeft; // left align, we adjust the text-rect instead
3479 
3480                 if (button->direction == Qt::RightToLeft)
3481                     r.setRight(iconRect.left() - iconSpacing);
3482                 else
3483                     r.setLeft(iconRect.right() + iconSpacing);
3484 
3485                 if (button->state & (State_On|State_Sunken))
3486                     iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
3487                                        pixelMetric(PM_ButtonShiftVertical, option, widget));
3488                 iconRect = visualRect(option->direction, button->rect, iconRect);
3489 
3490                 QPixmap pixmap(getIconPixmap(button->icon, iconRect.size(), mode, state));
3491                 painter->drawPixmap(iconRect, pixmap);
3492             } else {
3493                 tf |= Qt::AlignHCenter;
3494             }
3495 
3496             if (button->state & (State_On|State_Sunken))
3497                 r.translate(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
3498                             pixelMetric(PM_ButtonShiftVertical, option, widget));
3499 
3500             // The following is mainly for DejaVu Sans 11...
3501             if(button->fontMetrics.height()==19 && r.height()==(23+((opts.thin&THIN_BUTTONS) ? 0 : 2)))
3502                 r.translate(0, 1);
3503 
3504             if (button->features & QStyleOptionButton::HasMenu) {
3505                 int mbi(pixelMetric(PM_MenuButtonIndicator, button, widget));
3506 
3507                 if (Qt::LeftToRight == button->direction) {
3508                     r = r.adjusted(0, 0, -mbi, 0);
3509                 } else {
3510                     r = r.adjusted(mbi, 0, 0, 0);
3511                 }
3512             }
3513 
3514             int num(opts.embolden && button->features&QStyleOptionButton::DefaultButton ? 2 : 1);
3515 
3516             for(int i=0; i<num; ++i)
3517                 drawItemTextWithRole(painter, r.adjusted(i, 0, i, 0), tf, palette, (button->state&State_Enabled),
3518                                      button->text, QPalette::ButtonText);
3519         }
3520         break;
3521     case CE_ComboBoxLabel:
3522         if (auto comboBox = styleOptCast<QStyleOptionComboBox>(option)) {
3523             QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget);
3524             bool  sunken=!comboBox->editable && (state&(State_On|State_Sunken));
3525             int   shiftH=sunken ? pixelMetric(PM_ButtonShiftHorizontal, option, widget) : 0,
3526                 shiftV=sunken ? pixelMetric(PM_ButtonShiftVertical, option, widget) : 0;
3527 
3528             painter->save();
3529 
3530             if (!comboBox->currentIcon.isNull())
3531             {
3532                 QPixmap pixmap = getIconPixmap(comboBox->currentIcon, comboBox->iconSize, state);
3533                 QRect   iconRect(editRect);
3534 
3535                 iconRect.setWidth(comboBox->iconSize.width() + 5);
3536                 if(!comboBox->editable)
3537                     iconRect = alignedRect(QApplication::layoutDirection(), Qt::AlignLeft|Qt::AlignVCenter,
3538                                            iconRect.size(), editRect);
3539                 if (comboBox->editable)
3540                 {
3541                     int adjust=opts.etchEntry ? 2 : 1;
3542 
3543                     if(opts.square&SQUARE_ENTRY || opts.round<ROUND_FULL)
3544                         painter->fillRect(iconRect.adjusted(adjust-1, adjust, -(adjust-1), -adjust), palette.brush(QPalette::Base));
3545                     else
3546                     {
3547                         painter->fillRect(iconRect.adjusted(1, adjust, -1, -adjust), palette.brush(QPalette::Base));
3548                         painter->fillRect(iconRect.adjusted(0, adjust+1, 0, -(adjust+1)), palette.brush(QPalette::Base));
3549                     }
3550                 }
3551 
3552                 if (sunken)
3553                     iconRect.translate(shiftH, shiftV);
3554 
3555                 drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
3556 
3557                 if (reverse)
3558                     editRect.translate(-4 - comboBox->iconSize.width(), 0);
3559                 else
3560                     editRect.translate(comboBox->iconSize.width() + 4, 0);
3561             }
3562 
3563             if (!comboBox->currentText.isEmpty() && !comboBox->editable)
3564             {
3565                 if (sunken)
3566                     editRect.translate(shiftH, shiftV);
3567 
3568                 int margin=comboBox->frame && widget && widget->rect().height()<(opts.buttonEffect != EFFECT_NONE ? 22 : 20)  ? 4 : 0;
3569                 editRect.adjust(1, -margin, -1, margin);
3570                 painter->setClipRect(editRect);
3571                 drawItemTextWithRole(painter, editRect, Qt::AlignLeft|Qt::AlignVCenter, palette,
3572                                      state&State_Enabled, comboBox->currentText, QPalette::ButtonText);
3573             }
3574             painter->restore();
3575         }
3576         break;
3577     case CE_MenuBarEmptyArea:
3578     {
3579         painter->save();
3580 
3581         drawMenuOrToolBarBackground(widget, painter, r, option);
3582         if (TB_NONE!=opts.toolbarBorders && widget && widget->parentWidget() &&
3583             (qobject_cast<const QMainWindow *>(widget->parentWidget())))
3584         {
3585             const QColor *use=menuColors(option, m_active);
3586             bool         dark(TB_DARK==opts.toolbarBorders || TB_DARK_ALL==opts.toolbarBorders);
3587 
3588             if(TB_DARK_ALL==opts.toolbarBorders || TB_LIGHT_ALL==opts.toolbarBorders)
3589             {
3590                 painter->setPen(use[0]);
3591                 painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y());
3592                 painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.width()-1);
3593                 painter->setPen(use[dark ? 3 : 4]);
3594                 painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1);
3595                 painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1);
3596             }
3597             else
3598             {
3599                 painter->setPen(use[dark ? 3 : 4]);
3600                 painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1);
3601             }
3602         }
3603         painter->restore();
3604     }
3605     break;
3606     case CE_TabBarTabLabel:
3607         if (auto _tab = styleOptCast<QStyleOptionTab>(option)) {
3608             QStyleOptionTab tab(*_tab);
3609             bool verticalTabs(QTabBar::RoundedEast == tab.shape ||
3610                               QTabBar::RoundedWest == tab.shape ||
3611                               QTabBar::TriangularEast == tab.shape ||
3612                               QTabBar::TriangularWest == tab.shape);
3613             bool toolbarTab = (!opts.toolbarTabs &&
3614                                widget && widget->parentWidget() &&
3615                                qobject_cast<QToolBar*>(widget->parentWidget()));
3616 
3617             if (verticalTabs) {
3618                 painter->save();
3619                 int newX, newY, newRot;
3620                 if (QTabBar::RoundedEast == tab.shape ||
3621                     QTabBar::TriangularEast == tab.shape) {
3622                     newX = r.width();
3623                     newY = r.y();
3624                     newRot = 90;
3625                 } else {
3626                     newX = 0;
3627                     newY = r.y() + r.height();
3628                     newRot = -90;
3629                 }
3630                 r.setRect(0, 0, r.height(), r.width());
3631 
3632                 QTransform m;
3633                 m.translate(newX, newY);
3634                 m.rotate(newRot);
3635                 painter->setTransform(m, true);
3636             }
3637 
3638             int alignment(Qt::AlignVCenter | Qt::TextShowMnemonic |
3639                           (opts.centerTabText ? Qt::AlignHCenter : Qt::AlignLeft));
3640 
3641             if (!styleHint(SH_UnderlineShortcut, option, widget))
3642                 alignment |= Qt::TextHideMnemonic;
3643 
3644             if(toolbarTab)
3645                 tab.state &= ~State_Selected;
3646             r = subElementRect(SE_TabBarTabText, &tab, widget);
3647             if (!tab.icon.isNull()) {
3648                 QSize iconSize(tab.iconSize);
3649                 if (!iconSize.isValid()) {
3650                     int iconExtent(pixelMetric(PM_SmallIconSize));
3651                     iconSize = QSize(iconExtent, iconExtent);
3652                 }
3653 
3654                 QPixmap tabIcon(getIconPixmap(tab.icon, iconSize,
3655                                               state & State_Enabled));
3656                 QSize tabIconSize = tab.icon.actualSize(iconSize,
3657                                                         tab.state & State_Enabled
3658                                                         ? QIcon::Normal
3659                                                         : QIcon::Disabled);
3660 
3661                 int offset = 4,
3662                     left = option->rect.left();
3663                 if (tab.leftButtonSize.isNull() || tab.leftButtonSize.width()<=0) {
3664                     offset += 2;
3665                 } else {
3666                     left += tab.leftButtonSize.width() + 2;
3667                 }
3668                 QRect iconRect = QRect(left + offset,
3669                                        r.center().y() - tabIcon.height() / 2,
3670                                        tabIconSize.width(),
3671                                        tabIconSize.height());
3672                 if (!verticalTabs)
3673                     iconRect = visualRect(option->direction, option->rect,
3674                                           iconRect);
3675                 painter->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
3676             }
3677 
3678             if(!_tab->text.isEmpty()) {
3679                 drawItemTextWithRole(painter, r, alignment, _tab->palette,
3680                                      _tab->state & State_Enabled, _tab->text,
3681                                      !opts.stdSidebarButtons && toolbarTab &&
3682                                      state&State_Selected ?
3683                                      QPalette::HighlightedText :
3684                                      QPalette::WindowText);
3685             }
3686 
3687             if (verticalTabs)
3688                 painter->restore();
3689 
3690             if (tab.state & State_HasFocus) {
3691                 const int constOffset = 1 + pixelMetric(PM_DefaultFrameWidth);
3692 
3693                 int x1 = tab.rect.left();
3694                 int x2 = tab.rect.right() - 1;
3695                 QStyleOptionFocusRect fropt;
3696                 fropt.QStyleOption::operator=(*_tab);
3697                 fropt.rect.setRect(x1 + 1 + constOffset,
3698                                    tab.rect.y() + constOffset,
3699                                    x2 - x1 - 2 * constOffset,
3700                                    tab.rect.height() - 2 * constOffset);
3701 
3702                 fropt.state|=State_Horizontal;
3703                 if(FOCUS_LINE != opts.focus) {
3704                     if(QTabBar::RoundedNorth == tab.shape ||
3705                        QTabBar::TriangularNorth == tab.shape) {
3706                         fropt.rect.adjust(0, 1, 0, 0);
3707                     }
3708                 } else if(TAB_MO_BOTTOM == opts.tabMouseOver &&
3709                           FOCUS_LINE==opts.focus)
3710                     switch(tab.shape) {
3711                     case QTabBar::RoundedNorth:
3712                     case QTabBar::TriangularNorth:
3713                         fropt.rect.adjust(0, 0, 0, 1);
3714                         break;
3715                     case QTabBar::RoundedEast:
3716                     case QTabBar::TriangularEast:
3717                         fropt.rect.adjust(-2, 0, -(fropt.rect.width()+1), 0);
3718                         fropt.state&=~State_Horizontal;
3719                         break;
3720                     case QTabBar::RoundedSouth:
3721                     case QTabBar::TriangularSouth:
3722                         fropt.rect.adjust(0, 0, 0, 1);
3723                         break;
3724                     case QTabBar::RoundedWest:
3725                     case QTabBar::TriangularWest:
3726                         fropt.rect.adjust(0, 0, 2, 0);
3727                         fropt.state&=~State_Horizontal;
3728                     default:
3729                         break;
3730                     }
3731 
3732                 drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
3733             }
3734         }
3735         break;
3736     case CE_TabBarTabShape:
3737         if(!opts.toolbarTabs && widget && widget->parentWidget() && qobject_cast<QToolBar *>(widget->parentWidget()))
3738         {
3739             QStyleOption opt(*option);
3740             if(state&State_Selected)
3741                 opt.state|=State_On;
3742             if(opts.stdSidebarButtons)
3743             {
3744                 if(state&(State_Selected|State_MouseOver))
3745                 {
3746                     opt.state|=STATE_TBAR_BUTTON;
3747                     drawPrimitive(PE_PanelButtonTool, &opt, painter, widget);
3748                 }
3749             }
3750             else
3751                 drawSideBarButton(painter, r, &opt, widget);
3752         }
3753         else if (auto tab = styleOptCast<QStyleOptionTab>(option)) {
3754             bool onlyTab(widget && widget->parentWidget() ?
3755                          qobject_cast<const QTabWidget*>(widget->parentWidget()) ?
3756                          false : true : false),
3757                 selected(state&State_Selected),
3758                 horiz(QTabBar::RoundedNorth==tab->shape || QTabBar::RoundedSouth==tab->shape);
3759             QRect        r2(r);
3760             bool         rtlHorTabs(Qt::RightToLeft==tab->direction && horiz),
3761                 oneTab(QStyleOptionTab::OnlyOneTab==tab->position),
3762                 leftCornerWidget(tab->cornerWidgets&QStyleOptionTab::LeftCornerWidget),
3763                 rightCornerWidget(tab->cornerWidgets&QStyleOptionTab::RightCornerWidget),
3764                 firstTab((tab->position == (Qt::LeftToRight==tab->direction || !horiz ?
3765                                             QStyleOptionTab::Beginning : QStyleOptionTab::End)) || oneTab),
3766                 lastTab((tab->position == (Qt::LeftToRight==tab->direction  || !horiz ?
3767                                            QStyleOptionTab::End : QStyleOptionTab::Beginning)) || oneTab);
3768             int          tabBarAlignment(styleHint(SH_TabBar_Alignment, tab, widget)),
3769                 tabOverlap(oneTab ? 0 : pixelMetric(PM_TabBarTabOverlap, option, widget)),
3770                 moOffset(opts.round == ROUND_NONE || TAB_MO_TOP!=opts.tabMouseOver ? 1 : opts.round),
3771                 highlightOffset(opts.highlightTab && opts.round>ROUND_SLIGHT ? 2 : 1),
3772                 highlightBorder(opts.round>ROUND_FULL ? 4 : 3),
3773                 sizeAdjust(!selected && TAB_MO_GLOW==opts.tabMouseOver ? 1 : 0);
3774             bool leftAligned((!rtlHorTabs && Qt::AlignLeft==tabBarAlignment) ||
3775                              (rtlHorTabs && Qt::AlignRight==tabBarAlignment)),
3776                 rightAligned((!rtlHorTabs && Qt::AlignRight==tabBarAlignment) ||
3777                              (rtlHorTabs && Qt::AlignLeft==tabBarAlignment)),
3778                 docMode(tab->documentMode),
3779                 docFixLeft(!leftCornerWidget && leftAligned && firstTab && (docMode || onlyTab)),
3780                 fixLeft(!onlyTab && !leftCornerWidget && leftAligned && firstTab && !docMode),
3781                 fixRight(!onlyTab && !rightCornerWidget && rightAligned && lastTab && !docMode),
3782                 mouseOver(state&State_Enabled && state&State_MouseOver),
3783                 glowMo(!selected && mouseOver && opts.coloredMouseOver &&
3784                        TAB_MO_GLOW==opts.tabMouseOver),
3785                 thin(opts.thin&THIN_FRAMES),
3786                 drawOuterGlow(glowMo && !thin);
3787             const QColor *use(backgroundColors(option));
3788             QColor       fill(getTabFill(selected, mouseOver, use));
3789             double       radius=qtcGetRadius(&opts, r.width(), r.height(), WIDGET_TAB_TOP, RADIUS_EXTERNAL);
3790             EBorder      borderProfile(selected || opts.borderInactiveTab
3791                                        ? opts.borderTab
3792                                        ? BORDER_LIGHT
3793                                        : BORDER_RAISED
3794                                        : BORDER_FLAT);
3795 
3796             painter->save();
3797 
3798             if(!selected && (100!=opts.bgndOpacity || 100!=opts.dlgOpacity))
3799             {
3800                 QWidget *top=widget ? widget->window() : 0L;
3801                 bool isDialog = top && qtcIsDialog(top);
3802 
3803                 // Note: opacity is divided by 150 to make dark
3804                 // inactive tabs more translucent
3805                 if (isDialog && 100 != opts.dlgOpacity) {
3806                     fill.setAlphaF(opts.dlgOpacity / 150.0);
3807                 } else if (!isDialog && 100 != opts.bgndOpacity) {
3808                     fill.setAlphaF(opts.bgndOpacity / 150.0);
3809                 }
3810             }
3811 
3812             switch(tab->shape) {
3813             case QTabBar::RoundedNorth:
3814             case QTabBar::TriangularNorth:
3815             {
3816                 int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs
3817                     ? ROUNDED_TOP
3818                     : firstTab
3819                     ? ROUNDED_TOPLEFT
3820                     : lastTab
3821                     ? ROUNDED_TOPRIGHT
3822                     : ROUNDED_NONE;
3823                 if(!selected)
3824                     r.adjust(0, 2, 0, -2);
3825 
3826                 if(!firstTab)
3827                     r.adjust(-tabOverlap, 0, 0, 0);
3828                 painter->setClipPath(buildPath(r.adjusted(0, 0, 0, 4), WIDGET_TAB_TOP, round, radius));
3829                 fillTab(painter, r.adjusted(1+sizeAdjust, 1, -(1+sizeAdjust), 0), option, fill, true, WIDGET_TAB_TOP, (docMode || onlyTab));
3830                 // This clipping (for selected) helps with plasma's tabs and nvidia
3831                 if(selected || thin)
3832                     painter->setClipRect(r2.adjusted(-1, 0, 1, -1));
3833                 else
3834                     painter->setClipping(false);
3835                 drawBorder(painter, r.adjusted(sizeAdjust, 0, -sizeAdjust, 4), option, round, glowMo ? m_mouseOverCols : 0L,
3836                            WIDGET_TAB_TOP, borderProfile, false);
3837                 if(drawOuterGlow)
3838                     drawGlow(painter, r.adjusted(0, -1, 0, 5), WIDGET_TAB_TOP);
3839 
3840                 if(selected || thin)
3841                     painter->setClipping(false);
3842 
3843                 if(selected)
3844                 {
3845                     if(!thin)
3846                     {
3847                         painter->setPen(use[0]);
3848 
3849                         // The point drawn below is because of the clipping above...
3850                         if(fixLeft)
3851                             painter->drawPoint(r2.x()+1, r2.y()+r2.height()-1);
3852                         else
3853                             painter->drawLine(r2.left()-1, r2.bottom(), r2.left(), r2.bottom());
3854                         if(!fixRight)
3855                             painter->drawLine(r2.right()-1, r2.bottom(), r2.right(), r2.bottom());
3856                     }
3857 
3858                     if(docFixLeft)
3859                     {
3860                         QColor col(use[QTC_STD_BORDER]);
3861                         col.setAlphaF(0.5);
3862                         painter->setPen(col);
3863                         painter->drawPoint(r2.x(), r2.y()+r2.height()-1);
3864                     }
3865                 }
3866                 else
3867                 {
3868                     int l(fixLeft ? r2.left()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME) ? 2 : 1) : r2.left()-1),
3869                         r(fixRight ? r2.right()-2 : r2.right()+1);
3870                     painter->setPen(use[QTC_STD_BORDER]);
3871                     painter->drawLine(l, r2.bottom()-1, r, r2.bottom()-1);
3872                     if(!thin)
3873                     {
3874                         painter->setPen(use[0]);
3875                         painter->drawLine(l, r2.bottom(), r, r2.bottom());
3876                     }
3877                 }
3878 
3879                 if(selected)
3880                 {
3881                     if(opts.highlightTab)
3882                     {
3883                         QColor col(m_highlightCols[0]);
3884                         painter->setRenderHint(QPainter::Antialiasing, true);
3885                         painter->setPen(col);
3886                         drawAaLine(painter, r.left()+highlightOffset, r.top()+1, r.right()-highlightOffset, r.top()+1);
3887                         col.setAlphaF(0.5);
3888                         painter->setPen(col);
3889                         drawAaLine(painter, r.left()+1, r.top()+2, r.right()-1, r.top()+2);
3890                         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
3891                         painter->setClipRect(QRect(r.x(), r.y(), r.width(), highlightBorder));
3892                         drawBorder(painter, r, option, ROUNDED_ALL, m_highlightCols, WIDGET_TAB_TOP, BORDER_FLAT, false, 3);
3893                     }
3894 
3895                     if(opts.colorSelTab)
3896                         colorTab(painter, r.adjusted(1+sizeAdjust, 1, -(1+sizeAdjust), 0), true, WIDGET_TAB_TOP, round);
3897                 }
3898                 else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver)
3899                     drawHighlight(painter, QRect(r.x()+(firstTab ? moOffset : 1),
3900                                                  r.y()+(TAB_MO_TOP==opts.tabMouseOver ? 0 : r.height()-1),
3901                                                  r.width()-(firstTab || lastTab ? moOffset : 1), 2),
3902                                   true, TAB_MO_TOP==opts.tabMouseOver);
3903                 break;
3904             }
3905             case QTabBar::RoundedSouth:
3906             case QTabBar::TriangularSouth:
3907             {
3908                 int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs
3909                     ? ROUNDED_BOTTOM
3910                     : firstTab
3911                     ? ROUNDED_BOTTOMLEFT
3912                     : lastTab
3913                     ? ROUNDED_BOTTOMRIGHT
3914                     : ROUNDED_NONE;
3915                 if(!selected)
3916                     r.adjust(0, 2, 0, -2);
3917                 if(!firstTab)
3918                     r.adjust(-tabOverlap, 0, 0, 0);
3919 
3920                 painter->setClipPath(buildPath(r.adjusted(0, -4, 0, 0), WIDGET_TAB_BOT, round, radius));
3921                 fillTab(painter, r.adjusted(1+sizeAdjust, 0, -(1+sizeAdjust), -1), option, fill, true, WIDGET_TAB_BOT, (docMode || onlyTab));
3922                 if(thin)
3923                     painter->setClipRect(r2.adjusted(0, 1, 0, 0));
3924                 else
3925                     painter->setClipping(false);
3926                 drawBorder(painter, r.adjusted(sizeAdjust, -4, -sizeAdjust, 0), option, round, glowMo ? m_mouseOverCols : 0L,
3927                            WIDGET_TAB_BOT, borderProfile, false);
3928                 if(thin)
3929                     painter->setClipping(false);
3930                 if(drawOuterGlow)
3931                     drawGlow(painter, r.adjusted(0, -5, 0, 1), WIDGET_TAB_BOT);
3932 
3933                 if(selected)
3934                 {
3935                     if(!thin)
3936                     {
3937                         painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]);
3938                         if(!fixLeft)
3939                             painter->drawPoint(r2.left()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1), r2.top());
3940                         if(!fixRight)
3941                             painter->drawLine(r2.right()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1), r2.top(), r2.right(), r2.top());
3942                     }
3943                     if(docFixLeft)
3944                     {
3945                         QColor col(use[QTC_STD_BORDER]);
3946                         col.setAlphaF(0.5);
3947                         painter->setPen(col);
3948                         painter->drawPoint(r2.x(), r2.y());
3949                     }
3950                 }
3951                 else
3952                 {
3953                     int l(fixLeft ? r2.left()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME)? 2 : 1) : r2.left()-1),
3954                         r(fixRight ? r2.right()-2 : r2.right());
3955                     painter->setPen(use[QTC_STD_BORDER]);
3956                     painter->drawLine(l, r2.top()+1, r, r2.top()+1);
3957                     if(!thin)
3958                     {
3959                         painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]);
3960                         painter->drawLine(l, r2.top(), r, r2.top());
3961                     }
3962                 }
3963 
3964                 if(selected)
3965                 {
3966                     if(opts.highlightTab)
3967                     {
3968                         QColor col(m_highlightCols[0]);
3969                         painter->setRenderHint(QPainter::Antialiasing, true);
3970                         painter->setPen(col);
3971                         drawAaLine(painter, r.left()+highlightOffset, r.bottom()-1, r.right()-highlightOffset, r.bottom()-1);
3972                         col.setAlphaF(0.5);
3973                         painter->setPen(col);
3974                         drawAaLine(painter, r.left()+1, r.bottom()-2, r.right()-1, r.bottom()-2);
3975                         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
3976                         painter->setClipRect(QRect(r.x(), r.y()+r.height()-highlightBorder, r.width(), r.y()+r.height()-1));
3977                         drawBorder(painter, r, option, ROUNDED_ALL, m_highlightCols, WIDGET_TAB_BOT, BORDER_FLAT, false, 3);
3978                     }
3979 
3980                     if(opts.colorSelTab)
3981                         colorTab(painter, r.adjusted(1+sizeAdjust, 0, -(1+sizeAdjust), -1), true, WIDGET_TAB_BOT, round);
3982                 }
3983                 else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver)
3984                     drawHighlight(painter, QRect(r.x()+(firstTab ? moOffset : 1),
3985                                                  r.y()+(TAB_MO_TOP==opts.tabMouseOver ? r.height()-2 : -1),
3986                                                  r.width()-(firstTab || lastTab ? moOffset : 1), 2),
3987                                   true, TAB_MO_TOP!=opts.tabMouseOver);
3988                 break;
3989             }
3990             case QTabBar::RoundedWest:
3991             case QTabBar::TriangularWest:
3992             {
3993                 int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs
3994                     ? ROUNDED_LEFT
3995                     : firstTab
3996                     ? ROUNDED_TOPLEFT
3997                     : lastTab
3998                     ? ROUNDED_BOTTOMLEFT
3999                     : ROUNDED_NONE;
4000                 if(!selected)
4001                     r.adjust(2, 0, -2, 0);
4002 
4003                 if(!firstTab)
4004                     r.adjust(0, -tabOverlap, 0, 0);
4005                 painter->setClipPath(buildPath(r.adjusted(0, 0, 4, 0), WIDGET_TAB_TOP, round, radius));
4006                 fillTab(painter, r.adjusted(1, sizeAdjust, 0, -(1+sizeAdjust)), option, fill, false, WIDGET_TAB_TOP, (docMode || onlyTab));
4007                 if(thin)
4008                     painter->setClipRect(r2.adjusted(0, 0, -1, 0));
4009                 else
4010                     painter->setClipping(false);
4011                 drawBorder(painter, r.adjusted(0, sizeAdjust, 4, -sizeAdjust), option, round, glowMo ? m_mouseOverCols : 0L,
4012                            WIDGET_TAB_TOP, borderProfile, false);
4013                 if(thin)
4014                     painter->setClipping(false);
4015                 if(drawOuterGlow)
4016                     drawGlow(painter, r.adjusted(-1, 0, 5, 0), WIDGET_TAB_TOP);
4017 
4018                 if(selected)
4019                 {
4020                     if(!thin)
4021                     {
4022                         painter->setPen(use[0]);
4023                         if(!firstTab)
4024                             painter->drawPoint(r2.right(), r2.top()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1));
4025                         painter->drawLine(r2.right(), r2.bottom()-1, r2.right(), r2.bottom());
4026                     }
4027                 }
4028                 else
4029                 {
4030                     int t(firstTab ? r2.top()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME)? 2 : 1) : r2.top()-1),
4031                         b(/*lastTab ? r2.bottom()-2 : */ r2.bottom()+1);
4032 
4033                     painter->setPen(use[QTC_STD_BORDER]);
4034                     painter->drawLine(r2.right()-1, t, r2.right()-1, b);
4035                     if(!thin)
4036                     {
4037                         painter->setPen(use[0]);
4038                         painter->drawLine(r2.right(), t, r2.right(), b);
4039                     }
4040                 }
4041 
4042                 if(selected)
4043                 {
4044                     if(opts.highlightTab)
4045                     {
4046                         QColor col(m_highlightCols[0]);
4047                         painter->setRenderHint(QPainter::Antialiasing, true);
4048                         painter->setPen(col);
4049                         drawAaLine(painter, r.left()+1, r.top()+highlightOffset, r.left()+1, r.bottom()-highlightOffset);
4050                         col.setAlphaF(0.5);
4051                         painter->setPen(col);
4052                         drawAaLine(painter, r.left()+2, r.top()+1, r.left()+2, r.bottom()-1);
4053                         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
4054                         painter->setClipRect(QRect(r.x(), r.y(), highlightBorder, r.height()));
4055                         drawBorder(painter, r, option, ROUNDED_ALL, m_highlightCols, WIDGET_TAB_TOP, BORDER_FLAT, false, 3);
4056                     }
4057 
4058                     if(opts.colorSelTab)
4059                         colorTab(painter, r.adjusted(1, sizeAdjust, 0, -(1+sizeAdjust)), false, WIDGET_TAB_TOP, round);
4060                 }
4061                 else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver)
4062                     drawHighlight(painter, QRect(r.x()+(TAB_MO_TOP==opts.tabMouseOver ? 0 : r.width()-1),
4063                                                  r.y()+(firstTab ? moOffset : 1),
4064                                                  2, r.height()-(firstTab || lastTab ? moOffset : 1)),
4065                                   false, TAB_MO_TOP==opts.tabMouseOver);
4066                 break;
4067             }
4068             case QTabBar::RoundedEast:
4069             case QTabBar::TriangularEast:
4070             {
4071                 int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs
4072                     ? ROUNDED_RIGHT
4073                     : firstTab
4074                     ? ROUNDED_TOPRIGHT
4075                     : lastTab
4076                     ? ROUNDED_BOTTOMRIGHT
4077                     : ROUNDED_NONE;
4078                 if(!selected)
4079                     r.adjust(2, 0, -2, 0);
4080 
4081                 if(!firstTab)
4082                     r.adjust(0, -tabOverlap, 0, 0);
4083                 painter->setClipPath(buildPath(r.adjusted(-4, 0, 0, 0), WIDGET_TAB_BOT, round, radius));
4084                 fillTab(painter, r.adjusted(0, sizeAdjust, -1, -(1+sizeAdjust)), option, fill, false, WIDGET_TAB_BOT, (docMode || onlyTab));
4085                 if(thin)
4086                     painter->setClipRect(r2.adjusted(1, 0, 0, 0));
4087                 else
4088                     painter->setClipping(false);
4089                 drawBorder(painter, r.adjusted(-4, sizeAdjust, 0, -sizeAdjust), option, round, glowMo ? m_mouseOverCols : 0L,
4090                            WIDGET_TAB_BOT, borderProfile, false);
4091                 if(thin)
4092                     painter->setClipping(false);
4093                 if(drawOuterGlow)
4094                     drawGlow(painter, r.adjusted(-5, 0, 1, 0), WIDGET_TAB_BOT);
4095 
4096                 if(selected)
4097                 {
4098                     if(!thin)
4099                     {
4100                         painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]);
4101                         if(!firstTab)
4102                             painter->drawPoint(r2.left(), r2.top()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1));
4103                         painter->drawLine(r2.left(), r2.bottom()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1), r2.left(), r2.bottom());
4104                     }
4105                 }
4106                 else
4107                 {
4108                     int t(firstTab ? r2.top()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME)? 2 : 1) : r2.top()-1),
4109                         b(/*lastTab ? r2.bottom()-2 : */ r2.bottom()+1);
4110 
4111                     painter->setPen(use[QTC_STD_BORDER]);
4112                     painter->drawLine(r2.left()+1, t, r2.left()+1, b);
4113                     if(!thin)
4114                     {
4115                         painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]);
4116                         painter->drawLine(r2.left(), t, r2.left(), b);
4117                     }
4118                 }
4119 
4120                 if(selected)
4121                 {
4122                     if(opts.highlightTab)
4123                     {
4124                         QColor col(m_highlightCols[0]);
4125                         painter->setRenderHint(QPainter::Antialiasing, true);
4126                         painter->setPen(col);
4127                         drawAaLine(painter, r.right()-1, r.top()+highlightOffset, r.right()-1, r.bottom()-highlightOffset);
4128                         col.setAlphaF(0.5);
4129                         painter->setPen(col);
4130                         drawAaLine(painter, r.right()-2, r.top()+1, r.right()-2, r.bottom()-1);
4131                         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
4132                         painter->setClipRect(QRect(r.x()+r.width()-highlightBorder, r.y(), r.x()+r.width()-1, r.height()));
4133                         drawBorder(painter, r, option, ROUNDED_ALL, m_highlightCols, WIDGET_TAB_TOP, BORDER_FLAT, false, 3);
4134                     }
4135 
4136                     if(opts.colorSelTab)
4137                         colorTab(painter, r.adjusted(0, sizeAdjust, -1, -(1+sizeAdjust)), false, WIDGET_TAB_BOT, round);
4138                 }
4139                 else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver)
4140                     drawHighlight(painter, QRect(r.x()+(TAB_MO_TOP==opts.tabMouseOver ? r.width()-2 : -1),
4141                                                  r.y()+(firstTab ? moOffset : 1),
4142                                                  2, r.height()-(firstTab || lastTab ? moOffset : 1)),
4143                                   false, TAB_MO_TOP!=opts.tabMouseOver);
4144                 break;
4145             }
4146             }
4147             painter->restore();
4148         }
4149         break;
4150     case CE_ScrollBarAddLine:
4151     case CE_ScrollBarSubLine:
4152     {
4153         QRect            br(r),
4154             ar(r);
4155         const QColor     *use(state&State_Enabled ? m_buttonCols : m_backgroundCols); // buttonColors(option));
4156         bool             reverse(option && Qt::RightToLeft==option->direction);
4157         PrimitiveElement pe=state&State_Horizontal
4158             ? CE_ScrollBarAddLine==element ? (reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight)
4159             : (reverse ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft)
4160             : CE_ScrollBarAddLine==element ? PE_IndicatorArrowDown : PE_IndicatorArrowUp;
4161         int              round=PE_IndicatorArrowRight==pe ? ROUNDED_RIGHT :
4162             PE_IndicatorArrowLeft==pe ? ROUNDED_LEFT :
4163             PE_IndicatorArrowDown==pe ? ROUNDED_BOTTOM :
4164             PE_IndicatorArrowUp==pe ? ROUNDED_TOP : ROUNDED_NONE;
4165 
4166         switch(opts.scrollbarType)
4167         {
4168         default:
4169         case SCROLLBAR_WINDOWS:
4170             break;
4171         case SCROLLBAR_KDE:
4172         case SCROLLBAR_PLATINUM:
4173             if(!reverse && PE_IndicatorArrowLeft==pe && r.x()>3)
4174             {
4175                 round=ROUNDED_NONE;
4176                 br.adjust(0, 0, 1, 0);
4177                 if(opts.flatSbarButtons || !opts.vArrows)
4178                     ar.adjust(1, 0, 1, 0);
4179             }
4180             else if(reverse && PE_IndicatorArrowRight==pe && r.x()>3)
4181             {
4182                 if(SCROLLBAR_PLATINUM==opts.scrollbarType)
4183                 {
4184                     round=ROUNDED_NONE;
4185                     br.adjust(-1, 0, 0, 0);
4186                     if(opts.flatSbarButtons || !opts.vArrows)
4187                         ar.adjust(-1, 0, -1, 0);
4188                 }
4189                 else
4190                 {
4191                     if(r.x()<pixelMetric(PM_ScrollBarExtent, option, widget)+2)
4192                         round=ROUNDED_NONE;
4193                     br.adjust(0, 0, 1, 0);
4194                     if(opts.flatSbarButtons || !opts.vArrows)
4195                         ar.adjust(1, 0, 1, 0);
4196                 }
4197             }
4198             else if(PE_IndicatorArrowUp==pe && r.y()>3)
4199             {
4200                 round=ROUNDED_NONE;
4201                 br.adjust(0, 0, 0, 1);
4202                 if(opts.flatSbarButtons || !opts.vArrows)
4203                     ar.adjust(0, 1, 0, 1);
4204             }
4205             break;
4206         case SCROLLBAR_NEXT:
4207             if(!reverse && PE_IndicatorArrowRight==pe)
4208             {
4209                 round=ROUNDED_NONE;
4210                 br.adjust(-1, 0, 0, 0);
4211                 if(opts.flatSbarButtons || !opts.vArrows)
4212                     ar.adjust(-1, 0, 0, -1);
4213             }
4214             else if(reverse && PE_IndicatorArrowLeft==pe)
4215             {
4216                 round=ROUNDED_NONE;
4217                 br.adjust(0, 0, 1, 0);
4218                 if(opts.flatSbarButtons || !opts.vArrows)
4219                     ar.adjust(-1, 0, 0, 1);
4220             }
4221             else if(PE_IndicatorArrowDown==pe)
4222             {
4223                 round=ROUNDED_NONE;
4224                 br.adjust(0, -1, 0, 0);
4225                 if(opts.flatSbarButtons || !opts.vArrows)
4226                     ar.adjust(0, -1, 0, -1);
4227             }
4228             break;
4229         }
4230 
4231         painter->save();
4232         if(opts.flatSbarButtons && !qtcIsFlat(opts.sbarBgndAppearance) /*&& SCROLLBAR_NONE!=opts.scrollbarType*/)
4233             drawBevelGradientReal(palette.brush(QPalette::Background).color(), painter, r, state&State_Horizontal, false,
4234                                   opts.sbarBgndAppearance, WIDGET_SB_BGND);
4235 
4236         QStyleOption opt(*option);
4237 
4238         opt.state|=State_Raised;
4239 
4240         if (auto slider = styleOptCast<QStyleOptionSlider>(option)) {
4241             if((CE_ScrollBarSubLine==element && slider->sliderValue==slider->minimum) ||
4242                (CE_ScrollBarAddLine==element && slider->sliderValue==slider->maximum))
4243                 opt.state&=~(State_MouseOver|State_Sunken|State_On);
4244 
4245             if(slider->minimum==slider->maximum && opt.state&State_Enabled)
4246                 opt.state^=State_Enabled;
4247         }
4248 
4249         if(opts.flatSbarButtons)
4250             opt.state&=~(State_Sunken|State_On);
4251         else
4252             drawLightBevel(painter, br, &opt, widget, round, getFill(&opt, use), use, true, WIDGET_SB_BUTTON);
4253 
4254         opt.rect = ar;
4255 
4256         if(!(opt.state&State_Enabled))
4257             opt.palette.setCurrentColorGroup(QPalette::Disabled);
4258 
4259         if(opt.palette.text().color()!=opt.palette.buttonText().color()) // The following fixes gwenviews scrollbars...
4260             opt.palette.setColor(QPalette::Text, opt.palette.buttonText().color());
4261 
4262         drawPrimitive(pe, &opt, painter, widget);
4263         painter->restore();
4264         break;
4265     }
4266     case CE_ScrollBarSubPage:
4267     case CE_ScrollBarAddPage:
4268     {
4269         const QColor *use(m_backgroundCols); // backgroundColors(option));
4270         int          borderAdjust(0);
4271 
4272         painter->save();
4273 #ifndef SIMPLE_SCROLLBARS
4274         if (opts.round != ROUND_NONE && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons))
4275             painter->fillRect(r, palette.window().color());
4276 #endif
4277 
4278         switch(opts.scrollbarType)
4279         {
4280         case SCROLLBAR_KDE:
4281         case SCROLLBAR_WINDOWS:
4282             borderAdjust=1;
4283             break;
4284         case SCROLLBAR_PLATINUM:
4285             if(CE_ScrollBarAddPage==element)
4286                 borderAdjust=1;
4287             break;
4288         case SCROLLBAR_NEXT:
4289             if(CE_ScrollBarSubPage==element)
4290                 borderAdjust=1;
4291         default:
4292             break;
4293         }
4294 
4295         if(state&State_Horizontal)
4296         {
4297             if(qtcIsFlat(opts.appearance))
4298                 painter->fillRect(r.x(), r.y()+1, r.width(), r.height()-2, use[2]);
4299             else
4300                 drawBevelGradient(use[2], painter, QRect(r.x(), r.y()+1, r.width(), r.height()-2),
4301                                   true, false, opts.grooveAppearance, WIDGET_TROUGH);
4302 
4303 #ifndef SIMPLE_SCROLLBARS
4304             if (opts.round != ROUND_NONE && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons))
4305             {
4306                 if(CE_ScrollBarAddPage==element)
4307                     drawBorder(painter, r.adjusted(-5, 0, 0, 0), option, ROUNDED_RIGHT, use, WIDGET_TROUGH);
4308                 else
4309                     drawBorder(painter, r.adjusted(0, 0, 5, 0), option, ROUNDED_LEFT, use, WIDGET_TROUGH);
4310             }
4311             else
4312 #endif
4313                 if(CE_ScrollBarAddPage==element)
4314                     drawBorder(painter, r.adjusted(-5, 0, borderAdjust, 0), option, ROUNDED_NONE, use, WIDGET_TROUGH);
4315                 else
4316                     drawBorder(painter, r.adjusted(-borderAdjust, 0, 5, 0), option, ROUNDED_NONE, use, WIDGET_TROUGH);
4317         }
4318         else
4319         {
4320             if(qtcIsFlat(opts.appearance))
4321                 painter->fillRect(r.x()+1, r.y(), r.width()-2, r.height(), use[2]);
4322             else
4323                 drawBevelGradient(use[2], painter, QRect(r.x()+1, r.y(), r.width()-2, r.height()),
4324                                   false, false, opts.grooveAppearance, WIDGET_TROUGH);
4325 
4326 #ifndef SIMPLE_SCROLLBARS
4327             if (opts.round != ROUND_NONE && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons))
4328             {
4329                 if(CE_ScrollBarAddPage==element)
4330                     drawBorder(painter, r.adjusted(0, -5, 0, 0), option, ROUNDED_BOTTOM, use, WIDGET_TROUGH);
4331                 else
4332                     drawBorder(painter, r.adjusted(0, 0, 0, 5), option, ROUNDED_TOP, use, WIDGET_TROUGH);
4333             }
4334             else
4335 #endif
4336                 if(CE_ScrollBarAddPage==element)
4337                     drawBorder(painter, r.adjusted(0, -5, 0, borderAdjust), option, ROUNDED_NONE, use, WIDGET_TROUGH);
4338                 else
4339                     drawBorder(painter, r.adjusted(0, -borderAdjust, 0, 5), option, ROUNDED_NONE, use, WIDGET_TROUGH);
4340         }
4341         painter->restore();
4342         break;
4343     }
4344     case CE_ScrollBarSlider:
4345         painter->save();
4346         drawSbSliderHandle(painter, r, option);
4347         painter->restore();
4348         break;
4349 #ifdef FIX_DISABLED_ICONS
4350         // Taken from QStyle - only required so that we can corectly set the disabled icon!!!
4351     case CE_ToolButtonLabel:
4352         if (auto tb = styleOptCast<QStyleOptionToolButton>(option)) {
4353             int shiftX = 0;
4354             int shiftY = 0;
4355             if (state & (State_Sunken | State_On)) {
4356                 shiftX = pixelMetric(PM_ButtonShiftHorizontal, tb, widget);
4357                 shiftY = pixelMetric(PM_ButtonShiftVertical, tb, widget);
4358             }
4359 
4360             // Arrow type always overrules and is always shown
4361             bool hasArrow = tb->features & QStyleOptionToolButton::Arrow;
4362 
4363             if (((!hasArrow && tb->icon.isNull()) && !tb->text.isEmpty()) ||
4364                 tb->toolButtonStyle == Qt::ToolButtonTextOnly) {
4365                 int alignment = Qt::AlignCenter|Qt::TextShowMnemonic;
4366 
4367                 if (!styleHint(SH_UnderlineShortcut, option, widget))
4368                     alignment |= Qt::TextHideMnemonic;
4369 
4370                 r.translate(shiftX, shiftY);
4371 
4372                 drawItemTextWithRole(painter, r, alignment, palette, state&State_Enabled,
4373                                      tb->text, QPalette::ButtonText);
4374             } else {
4375                 QPixmap pm;
4376                 QSize   iconSize = tb->iconSize;
4377                 QRect   pr = r;
4378 
4379                 if (!tb->icon.isNull()) {
4380                     QIcon::State state = tb->state & State_On ? QIcon::On : QIcon::Off;
4381                     QIcon::Mode mode;
4382                     if (!(tb->state & State_Enabled)) {
4383                         mode = QIcon::Disabled;
4384                     } else if ((state & State_MouseOver) && (state & State_AutoRaise)) {
4385                         mode = QIcon::Active;
4386                     } else {
4387                         mode = QIcon::Normal;
4388                     }
4389 
4390                     if (!iconSize.isValid()) {
4391                         int iconExtent = pixelMetric(PM_ToolBarIconSize);
4392                         iconSize = QSize(iconExtent, iconExtent);
4393                     }
4394 
4395                     if (iconSize.width() > tb->rect.size().width())
4396                         iconSize = QSize(tb->rect.size().width(), tb->rect.size().width());
4397                     if (iconSize.height() > tb->rect.size().height())
4398                         iconSize = QSize(tb->rect.size().height(), tb->rect.size().height());
4399 
4400                     pm = getIconPixmap(tb->icon, iconSize, mode, state);
4401                 }
4402 
4403                 if (Qt::ToolButtonIconOnly!=tb->toolButtonStyle)
4404                 {
4405                     QRect tr = r;
4406                     int   alignment = Qt::TextShowMnemonic;
4407 
4408                     painter->setFont(tb->font);
4409                     if (!styleHint(SH_UnderlineShortcut, option, widget))
4410                         alignment |= Qt::TextHideMnemonic;
4411 
4412                     if (Qt::ToolButtonTextUnderIcon==tb->toolButtonStyle)
4413                     {
4414                         pr.setHeight(iconSize.height() + 6);
4415 
4416                         tr.adjust(0, pr.bottom()-3, 0, 0); // -3);
4417                         pr.translate(shiftX, shiftY);
4418                         if (hasArrow)
4419                             drawTbArrow(this, tb, pr, painter, widget);
4420                         else
4421                             drawItemPixmap(painter, pr, Qt::AlignCenter, pm);
4422                         alignment |= Qt::AlignCenter;
4423                     }
4424                     else
4425                     {
4426                         pr.setWidth(iconSize.width() + 8);
4427                         tr.adjust(pr.right(), 0, 0, 0);
4428                         pr.translate(shiftX, shiftY);
4429                         if (hasArrow)
4430                             drawTbArrow(this, tb, pr, painter, widget);
4431                         else
4432                             drawItemPixmap(painter, QStyle::visualRect(option->direction, r, pr), Qt::AlignCenter, pm);
4433                         alignment |= Qt::AlignLeft | Qt::AlignVCenter;
4434                     }
4435                     tr.translate(shiftX, shiftY);
4436                     drawItemTextWithRole(painter, QStyle::visualRect(option->direction, r, tr), alignment, palette,
4437                                          state & State_Enabled, tb->text, QPalette::ButtonText);
4438                 }
4439                 else
4440                 {
4441                     pr.translate(shiftX, shiftY);
4442 
4443                     if (hasArrow)
4444                         drawTbArrow(this, tb, pr, painter, widget);
4445                     else
4446                     {
4447                         if (!(tb->subControls&SC_ToolButtonMenu) && tb->features&QStyleOptionToolButton::HasMenu &&
4448                             pr.width()>pm.width() && ((pr.width()-pm.width())>LARGE_ARR_WIDTH))
4449                             pr.adjust(-LARGE_ARR_WIDTH, 0, 0, 0);
4450                         drawItemPixmap(painter, pr, Qt::AlignCenter, pm);
4451                     }
4452                 }
4453             }
4454         }
4455         break;
4456     case CE_RadioButtonLabel:
4457     case CE_CheckBoxLabel:
4458         if (auto btn = styleOptCast<QStyleOptionButton>(option)) {
4459             uint    alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
4460             QPixmap pix;
4461             QRect   textRect = r;
4462 
4463             if (!styleHint(SH_UnderlineShortcut, btn, widget))
4464                 alignment |= Qt::TextHideMnemonic;
4465 
4466             if (!btn->icon.isNull())
4467             {
4468                 pix = getIconPixmap(btn->icon, btn->iconSize, btn->state);
4469                 drawItemPixmap(painter, r, alignment, pix);
4470                 if (reverse)
4471                     textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
4472                 else
4473                     textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
4474             }
4475             if (!btn->text.isEmpty())
4476                 drawItemTextWithRole(painter, textRect, alignment | Qt::TextShowMnemonic,
4477                                      palette, state&State_Enabled, btn->text, QPalette::WindowText);
4478         }
4479         break;
4480     case CE_ToolBoxTabLabel:
4481         if (auto tb = styleOptCast<QStyleOptionToolBox>(option)) {
4482             bool    enabled = state & State_Enabled,
4483                 selected = state & State_Selected;
4484             QPixmap pm = getIconPixmap(tb->icon, pixelMetric(QStyle::PM_SmallIconSize, tb, widget) ,state);
4485             QRect   cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget);
4486             QRect   tr, ir;
4487             int     ih = 0;
4488 
4489             if (pm.isNull())
4490             {
4491                 tr = cr;
4492                 tr.adjust(4, 0, -8, 0);
4493             }
4494             else
4495             {
4496                 int iw = pm.width() + 4;
4497                 ih = pm.height();
4498                 ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
4499                 tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
4500             }
4501 
4502             if (selected && styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb, widget))
4503             {
4504                 QFont f = m_fntHelper->fontStripStyleName(painter->font());
4505                 f.setBold(true);
4506                 painter->setFont(f);
4507             }
4508 
4509             QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width());
4510 
4511             if (ih)
4512                 painter->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm);
4513 
4514             int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
4515             if (!styleHint(QStyle::SH_UnderlineShortcut, tb, widget))
4516                 alignment |= Qt::TextHideMnemonic;
4517             drawItemTextWithRole(painter, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText);
4518 
4519             if (!txt.isEmpty() && state&State_HasFocus)
4520             {
4521                 QStyleOptionFocusRect opt;
4522                 opt.rect = tr;
4523                 opt.palette = palette;
4524                 opt.state = QStyle::State_None;
4525                 drawPrimitive(PE_FrameFocusRect, &opt, painter, widget);
4526             }
4527         }
4528         break;
4529 #endif
4530     case CE_RadioButton:
4531     case CE_CheckBox:
4532         if (opts.crHighlight && (r.width()>opts.crSize*2))
4533             if (auto button = styleOptCast<QStyleOptionButton>(option)) {
4534                 QStyleOptionButton copy(*button);
4535 
4536                 copy.rect.adjust(2, 0, -2, 0);
4537 
4538                 if(button->state&State_MouseOver && button->state&State_Enabled)
4539                 {
4540                     QRect highlightRect(subElementRect(CE_RadioButton==element ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect,
4541                                                        option, widget));
4542 
4543                     if(Qt::RightToLeft==button->direction)
4544                         highlightRect.setRight(r.right());
4545                     else
4546                         highlightRect.setX(r.x());
4547                     highlightRect.setWidth(highlightRect.width()+1);
4548 
4549                     if(ROUND_NONE!=opts.round)
4550                     {
4551                         painter->save();
4552                         painter->setRenderHint(QPainter::Antialiasing, true);
4553                         double   radius(qtcGetRadius(&opts, highlightRect.width(), highlightRect.height(),
4554                                                      WIDGET_OTHER, RADIUS_SELECTION));
4555 
4556                         drawBevelGradient(shade(palette.window().color(), TO_FACTOR(opts.crHighlight)),
4557                                           painter, highlightRect,
4558                                           buildPath(QRectF(highlightRect), WIDGET_OTHER, ROUNDED_ALL, radius), true,
4559                                           false, opts.selectionAppearance, WIDGET_SELECTION, false);
4560                         painter->restore();
4561                     }
4562                     else
4563                         drawBevelGradient(shade(palette.window().color(), TO_FACTOR(opts.crHighlight)), painter,
4564                                           highlightRect, true, false, opts.selectionAppearance, WIDGET_SELECTION);
4565                 }
4566                 ParentStyleClass::drawControl(element, &copy, painter, widget);
4567                 break;
4568             }
4569         // Fall through!
4570     default:
4571         ParentStyleClass::drawControl(element, option, painter, widget);
4572     }
4573 }
4574 
4575 void Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
4576 {
4577     prePolish(widget);
4578     QRect               r(option->rect);
4579     const State &state(option->state);
4580     const QPalette      &palette(option->palette);
4581     bool                reverse(Qt::RightToLeft==option->direction);
4582 
4583     switch (control)
4584     {
4585     case CC_Dial:
4586         if (auto slider = styleOptCast<QStyleOptionSlider>(option)) {
4587             r.adjust(1, 1, -1, -1);
4588 
4589             QStyleOptionComplex opt(*option);
4590             bool                mo(state&State_Enabled && state&State_MouseOver);
4591             QRect               outer(r);
4592             int                 sliderWidth = /*qMin(2*r.width()/5, */CIRCULAR_SLIDER_SIZE/*)*/;
4593 #ifdef DIAL_DOT_ON_RING
4594             int                 halfWidth=sliderWidth/2;
4595 #endif
4596 
4597             opt.state|=State_Horizontal;
4598 
4599             // Outer circle...
4600             if (outer.width() > outer.height())
4601             {
4602                 outer.setLeft(outer.x()+(outer.width()-outer.height())/2);
4603                 outer.setWidth(outer.height());
4604             }
4605             else
4606             {
4607                 outer.setTop(outer.y()+(outer.height()-outer.width())/2);
4608                 outer.setHeight(outer.width());
4609             }
4610 
4611             opt.state&=~State_MouseOver;
4612 #ifdef DIAL_DOT_ON_RING
4613             opt.rect=outer.adjusted(halfWidth, halfWidth, -halfWidth, -halfWidth);
4614 #else
4615             opt.rect=outer;
4616 #endif
4617             drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL,
4618                            getFill(&opt, m_backgroundCols), m_backgroundCols,
4619                            true, WIDGET_DIAL);
4620 
4621             // Inner 'dot'
4622             if(mo)
4623                 opt.state|=State_MouseOver;
4624 
4625             // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA.
4626             qreal               angle(0);
4627             if(slider->maximum == slider->minimum)
4628                 angle = M_PI / 2;
4629             else
4630             {
4631                 const qreal fraction(qreal(slider->sliderValue - slider->minimum)/
4632                                      qreal(slider->maximum - slider->minimum));
4633                 if(slider->dialWrapping)
4634                     angle = 1.5*M_PI - fraction*2*M_PI;
4635                 else
4636                     angle = (M_PI*8 - fraction*10*M_PI)/6;
4637             }
4638 
4639             QPoint center = outer.center();
4640 #ifdef DIAL_DOT_ON_RING
4641             const qreal radius=0.5*(outer.width() - sliderWidth);
4642 #else
4643             const qreal radius=0.5*(outer.width() - 2*sliderWidth);
4644 #endif
4645             center += QPoint(radius*cos(angle), -radius*sin(angle));
4646 
4647             opt.rect=QRect(outer.x(), outer.y(), sliderWidth, sliderWidth);
4648             opt.rect.moveCenter(center);
4649 
4650             const QColor *use(buttonColors(option));
4651 
4652             drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL,
4653                            getFill(&opt, use), use, true, WIDGET_RADIO_BUTTON);
4654 
4655             // Draw value...
4656 #ifdef DIAL_DOT_ON_RING
4657             drawItemTextWithRole(painter, outer.adjusted(sliderWidth, sliderWidth, -sliderWidth, -sliderWidth),
4658                                  Qt::AlignCenter, palette, state&State_Enabled,
4659                                  QString::number(slider->sliderValue), QPalette::ButtonText);
4660 #else
4661             int adjust=2*sliderWidth;
4662             drawItemTextWithRole(painter, outer.adjusted(adjust, adjust, -adjust, -adjust),
4663                                  Qt::AlignCenter, palette, state&State_Enabled,
4664                                  QString::number(slider->sliderValue), QPalette::ButtonText);
4665 #endif
4666 
4667             if(state&State_HasFocus)
4668             {
4669                 QStyleOptionFocusRect fr;
4670                 fr.rect = outer.adjusted(-1, -1, 1, 1);
4671                 drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
4672             }
4673         }
4674         break;
4675     case CC_ToolButton:
4676         // For OO.o 3.2 need to fill widget background!
4677         if(isOOWidget(widget))
4678             painter->fillRect(r, palette.brush(QPalette::Window));
4679         if (auto toolbutton = styleOptCast<QStyleOptionToolButton>(option)) {
4680             int widthAdjust(0),
4681                 heightAdjust(0);
4682 
4683             if (widget) {
4684                 if ((opts.dwtSettings & DWT_BUTTONS_AS_PER_TITLEBAR) &&
4685                     (widget->inherits("QDockWidgetTitleButton") ||
4686                      qtcCheckType(getParent(widget),
4687                                   "KoDockWidgetTitleBar"))) {
4688                     ETitleBarButtons btn = TITLEBAR_CLOSE;
4689                     Icon icon = ICN_CLOSE;
4690 
4691                     if (constDwtFloat == widget->objectName()) {
4692                         btn = TITLEBAR_MAX;
4693                         icon = ICN_RESTORE;
4694                     } else if (constDwtClose != widget->objectName() &&
4695                                qtcCheckType(getParent(widget),
4696                                             "KoDockWidgetTitleBar") &&
4697                                qtcCheckType<QDockWidget>(
4698                                    getParent<2>(widget))) {
4699                         QDockWidget *dw = (QDockWidget*)getParent<2>(widget);
4700                         QWidget *koDw = widget->parentWidget();
4701                         int fw = dw->isFloating()
4702                             ? pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, dw)
4703                             : 0;
4704                         QRect geom(widget->geometry());
4705                         QStyleOptionDockWidget dwOpt;
4706                         dwOpt.initFrom(dw);
4707                         dwOpt.rect = QRect(QPoint(fw, fw),
4708                                            QSize(koDw->geometry().width() -
4709                                                  (fw * 2),
4710                                                  koDw->geometry().height() -
4711                                                  (fw * 2)));
4712                         dwOpt.title = dw->windowTitle();
4713                         dwOpt.closable = (dw->features() &
4714                                           QDockWidget::DockWidgetClosable) == QDockWidget::DockWidgetClosable;
4715                         dwOpt.floatable = (dw->features() &
4716                                            QDockWidget::DockWidgetFloatable) ==
4717                             QDockWidget::DockWidgetFloatable;
4718 
4719                         if(dwOpt.closable && subElementRect(QStyle::SE_DockWidgetCloseButton, &dwOpt,
4720                                                             widget->parentWidget()->parentWidget())==geom)
4721                             btn=TITLEBAR_CLOSE, icon=ICN_CLOSE;
4722                         else if(dwOpt.floatable && subElementRect(QStyle::SE_DockWidgetFloatButton, &dwOpt,
4723                                                                   widget->parentWidget()->parentWidget())==geom)
4724                             btn=TITLEBAR_MAX, icon=ICN_RESTORE;
4725                         else
4726                             btn=TITLEBAR_SHADE, icon=dw && dw->widget() && dw->widget()->isVisible()
4727                                 ? ICN_SHADE
4728                                 : ICN_UNSHADE;
4729                     }
4730 
4731                     QColor        shadow(WINDOW_SHADOW_COLOR(opts.titlebarEffect));
4732                     const QColor *bgndCols((opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR)
4733                                            ? getMdiColors(option, state&State_Active)
4734                                            : buttonColors(option)),
4735                         *btnCols((opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR)
4736                                  ? opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR
4737                                  ? buttonColors(option)
4738                                  : getMdiColors(option, state&State_Active)
4739                                  : bgndCols);
4740 
4741                     drawDwtControl(painter, state, r.adjusted(-1, -1, 1, 1), btn,
4742                                    icon, option->palette.color(QPalette::WindowText), btnCols,
4743                                    bgndCols);
4744                     break;
4745                 }
4746                 if(qobject_cast<QTabBar *>(widget->parentWidget()))
4747                 {
4748                     QStyleOptionToolButton btn(*toolbutton);
4749 
4750                     if(Qt::LeftArrow==toolbutton->arrowType || Qt::RightArrow==toolbutton->arrowType)
4751                         btn.rect.adjust(0, 4, 0, -4);
4752                     else
4753                         btn.rect.adjust(4, 0, -4, 0);
4754                     if(!(btn.state&State_Enabled))
4755                         btn.state&=~State_MouseOver;
4756                     drawPrimitive(PE_PanelButtonTool, &btn, painter, widget);
4757                     if(opts.vArrows)
4758                         switch(toolbutton->arrowType)
4759                         {
4760                         case Qt::LeftArrow:
4761                             btn.rect.adjust(-1, 0, -1, 0);
4762                             break;
4763                         case Qt::RightArrow:
4764                             btn.rect.adjust(1, 0, 1, 0);
4765                             break;
4766                         case Qt::UpArrow:
4767                             btn.rect.adjust(0, -1, 0, -1);
4768                             break;
4769                         case Qt::DownArrow:
4770                             btn.rect.adjust(0, 1, 0, 1);
4771                         default:
4772                             break;
4773                         }
4774                     drawTbArrow(this, &btn, btn.rect, painter, widget);
4775                     break;
4776                 }
4777 
4778                 const QToolButton *btn = qobject_cast<const QToolButton *>(widget);
4779 
4780                 if(btn && btn->isDown() && Qt::ToolButtonTextBesideIcon==btn->toolButtonStyle() &&
4781                    widget->parentWidget() && qobject_cast<QMenu*>(widget->parentWidget()))
4782                 {
4783                     painter->save();
4784                     if(opts.menuStripe)
4785                     {
4786                         int stripeWidth(qMax(20, constMenuPixmapWidth));
4787 
4788                         drawBevelGradient(menuStripeCol(),
4789                                           painter, QRect(reverse ? r.right()-stripeWidth : r.x(), r.y(),
4790                                                          stripeWidth, r.height()), false,
4791                                           false, opts.menuStripeAppearance, WIDGET_OTHER);
4792                     }
4793 
4794 #if 0
4795                     // For some reason the MenuTitle has a larger border on the left, so adjust the width by 1 pixel to make this look nicer.
4796                     //drawBorder(painter, r.adjusted(2, 2, -3, -2), option, ROUNDED_ALL, 0L, WIDGET_OTHER, BORDER_SUNKEN);
4797                     QStyleOptionToolButton opt(*toolbutton);
4798                     opt.rect = r.adjusted(2, 2, -3, -2);
4799                     opt.state=State_Raised|State_Enabled|State_Horizontal;
4800                     drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL,
4801                                    getFill(&opt, m_backgroundCols), m_backgroundCols, true, WIDGET_NO_ETCH_BTN);
4802 #else
4803                     if(!opts.menuStripe)
4804                         drawFadedLine(painter, QRect(r.x()+3, r.y()+r.height()-1, r.width()-7, 1),
4805                                       popupMenuCols(option)[MENU_SEP_SHADE], true, true, true);
4806 #endif
4807                     QFont font = m_fntHelper->fontStripStyleName(toolbutton->font);
4808 
4809                     font.setBold(true);
4810                     painter->setFont(font);
4811                     drawItemTextWithRole(painter, r, Qt::AlignHCenter | Qt::AlignVCenter,
4812                                          palette, state&State_Enabled, toolbutton->text, QPalette::Text);
4813                     painter->restore();
4814                     break;
4815                 }
4816 
4817                 // Amarok's toolbars (the one just above the collection list)
4818                 // are much thinner then normal, and QToolBarExtension does not
4819                 // seem to take this into account - so adjust the size here...
4820                 QWidget *parent = getParent(widget);
4821                 if (widget->inherits("QToolBarExtension") && parent) {
4822                     if (r.height() > parent->rect().height()) {
4823                         heightAdjust = (r.height() -
4824                                         parent->rect().height()) + 2;
4825                     }
4826                     if (r.width() > parent->rect().width()) {
4827                         widthAdjust = (r.width() -
4828                                        parent->rect().width()) + 2;
4829                     }
4830                 }
4831             }
4832             QRect button(subControlRect(control, toolbutton, SC_ToolButton, widget)),
4833                 menuarea(subControlRect(control, toolbutton, SC_ToolButtonMenu, widget));
4834             State bflags(toolbutton->state);
4835             bool  etched(opts.buttonEffect != EFFECT_NONE),
4836                 raised=widget && (TBTN_RAISED==opts.tbarBtns || TBTN_JOINED==opts.tbarBtns),
4837                 horizTBar(true);
4838             int   round=ROUNDED_ALL,
4839                 leftAdjust(0), topAdjust(0), rightAdjust(0), bottomAdjust(0);
4840 
4841             if(raised)
4842             {
4843                 const QToolBar *toolbar=getToolBar(widget);
4844 
4845                 if(toolbar)
4846                 {
4847                     if(TBTN_JOINED==opts.tbarBtns)
4848                     {
4849                         horizTBar=Qt::Horizontal==toolbar->orientation();
4850                         adjustToolbarButtons(widget, toolbar, leftAdjust, topAdjust, rightAdjust, bottomAdjust, round);
4851                     }
4852                 }
4853                 else
4854                     raised=false;
4855             }
4856 
4857             if (!(bflags&State_Enabled))
4858                 bflags &= ~(State_MouseOver/* | State_Raised*/);
4859 
4860             if(bflags&State_MouseOver)
4861                 bflags |= State_Raised;
4862             else if(!raised && (bflags&State_AutoRaise))
4863                 bflags &= ~State_Raised;
4864 
4865             if(state&State_AutoRaise || toolbutton->subControls&SC_ToolButtonMenu)
4866                 bflags|=STATE_TBAR_BUTTON;
4867 
4868             State mflags(bflags);
4869 
4870             if (!isOOWidget(widget)) {
4871                 if (state&State_Sunken &&
4872                     !(toolbutton->activeSubControls & SC_ToolButton)) {
4873                     bflags &= ~State_Sunken;
4874                 }
4875             }
4876 
4877             bool         drawMenu=TBTN_JOINED==opts.tbarBtns
4878                 ? mflags & (State_Sunken | State_On)
4879                 : raised || (mflags & (State_Sunken | State_On | State_Raised)),
4880                 drawnBevel=false;
4881             QStyleOption tool(0);
4882             tool.palette = toolbutton->palette;
4883 
4884             if ( raised ||
4885                  (toolbutton->subControls&SC_ToolButton && (bflags & (State_Sunken | State_On | State_Raised))) ||
4886                  (toolbutton->subControls&SC_ToolButtonMenu && drawMenu))
4887             {
4888                 const QColor *use(buttonColors(toolbutton));
4889 
4890                 tool.rect = (toolbutton->subControls&SC_ToolButtonMenu ? button.united(menuarea) : button)
4891                     .adjusted(leftAdjust, topAdjust, rightAdjust, bottomAdjust);
4892                 tool.state = bflags|State_Horizontal;
4893 
4894                 if(raised && TBTN_JOINED==opts.tbarBtns && !horizTBar)
4895                     tool.state &= ~State_Horizontal;
4896 
4897                 tool.rect.adjust(0, 0, -widthAdjust, -heightAdjust);
4898                 if(!(bflags&State_Sunken) && (mflags&State_Sunken))
4899                     tool.state &= ~State_MouseOver;
4900                 drawnBevel=true;
4901                 drawLightBevel(painter, tool.rect, &tool, widget, round, getFill(&tool, use), use, true, WIDGET_TOOLBAR_BUTTON);
4902 
4903                 if(raised && TBTN_JOINED==opts.tbarBtns)
4904                 {
4905                     const int constSpace=4;
4906 
4907                     QRect br(tool.rect.adjusted(-leftAdjust, -topAdjust, -rightAdjust, -bottomAdjust));
4908 
4909                     if(leftAdjust)
4910                         drawFadedLine(painter, QRect(br.x(), br.y()+constSpace, 1, br.height()-(constSpace*2)), use[0], true, true, false);
4911                     if(topAdjust)
4912                         drawFadedLine(painter, QRect(br.x()+constSpace, br.y(), br.width()-(constSpace*2), 1), use[0], true, true, true);
4913                     if(rightAdjust)
4914                         drawFadedLine(painter, QRect(br.x()+br.width()-1, br.y()+constSpace, 1, br.height()-(constSpace*2)),
4915                                       use[QTC_STD_BORDER], true, true, false);
4916                     if(bottomAdjust)
4917                         drawFadedLine(painter, QRect(br.x()+constSpace, br.y()+br.height()-1, br.width()-(constSpace*2), 1),
4918                                       use[QTC_STD_BORDER], true, true, true);
4919                 }
4920             }
4921 
4922             if (toolbutton->subControls&SC_ToolButtonMenu)
4923             {
4924                 if(etched)
4925                 {
4926                     if(reverse)
4927                         menuarea.adjust(1, 1, 0, -1);
4928                     else
4929                         menuarea.adjust(0, 1, -1, -1);
4930                 }
4931 
4932                 tool.state = mflags|State_Horizontal;
4933 
4934                 if(drawMenu)
4935                 {
4936                     const QColor *use(buttonColors(option));
4937                     int          mRound=reverse ? ROUNDED_LEFT : ROUNDED_RIGHT;
4938 
4939                     if(mflags&State_Sunken)
4940                         tool.state&=~State_MouseOver;
4941 
4942                     if(raised && TBTN_JOINED==opts.tbarBtns)
4943                     {
4944                         if(!horizTBar)
4945                             tool.state &= ~State_Horizontal;
4946                         painter->save();
4947                         painter->setClipRect(menuarea, Qt::IntersectClip);
4948                         if((reverse && leftAdjust) || (!reverse && rightAdjust))
4949                             mRound=ROUNDED_NONE;
4950                         if(reverse)
4951                             tool.rect.adjust(1, 0, 0, 0);
4952                         else
4953                             tool.rect.adjust(0, 0, -1, 0);
4954                     }
4955                     else
4956                         tool.rect = menuarea;
4957 
4958                     drawLightBevel(painter, tool.rect, &tool, widget, mRound, getFill(&tool, use), use, true,
4959                                    MO_GLOW==opts.coloredMouseOver ? WIDGET_MENU_BUTTON : WIDGET_NO_ETCH_BTN);
4960                     if(raised && TBTN_JOINED==opts.tbarBtns)
4961                         painter->restore();
4962                 }
4963 
4964                 tool.rect = menuarea;
4965 
4966                 if(mflags&State_Sunken)
4967                     tool.rect.adjust(1, 1, 1, 1);
4968                 drawArrow(painter, tool.rect, PE_IndicatorArrowDown,
4969                           MOArrow(state, palette,
4970                                   toolbutton->activeSubControls &
4971                                   SC_ToolButtonMenu,
4972                                   QPalette::ButtonText));
4973             }
4974 
4975             if ((opts.focus != FOCUS_GLOW || !drawnBevel) &&
4976                 toolbutton->state & State_HasFocus) {
4977                 QStyleOptionFocusRect fr;
4978                 fr.QStyleOption::operator=(*toolbutton);
4979 
4980                 if (oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED)) {
4981                     if (etched) {
4982                         fr.rect.adjust(1, 1, -1, -1);
4983                     }
4984                 } else {
4985                     if (opts.focus == FOCUS_GLOW) {
4986                         fr.rect.adjust(1, 1, -1, -1);
4987                     } else if (etched) {
4988                         fr.rect.adjust(4, 4, -4, -4);
4989                     } else {
4990                         fr.rect.adjust(3, 3, -3, -3);
4991                     }
4992                     if (toolbutton->features &
4993                         QStyleOptionToolButton::MenuButtonPopup) {
4994                         fr.rect.adjust(
4995                             0, 0, -(pixelMetric(QStyle::PM_MenuButtonIndicator,
4996                                                 toolbutton, widget)-1), 0);
4997                     }
4998                 }
4999                 if (!(state & State_MouseOver &&
5000                       oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED) &&
5001                       opts.coloredMouseOver != MO_NONE)) {
5002                     drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
5003                 }
5004             }
5005             QStyleOptionToolButton label = *toolbutton;
5006             int fw = pixelMetric(PM_DefaultFrameWidth, option, widget);
5007             label.rect = button.adjusted(fw, fw, -(fw+widthAdjust), -(fw+heightAdjust));
5008             label.state = bflags;
5009             drawControl(CE_ToolButtonLabel, &label, painter, widget);
5010 
5011             if (!(toolbutton->subControls&SC_ToolButtonMenu) &&
5012                 (toolbutton->features&QStyleOptionToolButton::HasMenu))
5013             {
5014                 QRect arrow(r.right()-(LARGE_ARR_WIDTH+(etched ? 3 : 2)),
5015                             r.bottom()-(LARGE_ARR_HEIGHT+(etched ? 4 : 3)),
5016                             LARGE_ARR_WIDTH, LARGE_ARR_HEIGHT);
5017 
5018                 if(bflags&State_Sunken)
5019                     arrow.adjust(1, 1, 1, 1);
5020 
5021                 drawArrow(painter, arrow, PE_IndicatorArrowDown,
5022                           MOArrow(state, palette, QPalette::ButtonText));
5023             }
5024         }
5025         break;
5026     case CC_GroupBox:
5027         if (auto groupBox = styleOptCast<QStyleOptionGroupBox>(option)) {
5028             // Draw frame
5029             QRect textRect = /*proxy()->*/subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
5030             QRect checkBoxRect = /*proxy()->*/subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
5031             if (groupBox->subControls & QStyle::SC_GroupBoxFrame)
5032             {
5033                 QStyleOptionFrame frame;
5034                 frame.QStyleOption::operator=(*groupBox);
5035                 frame.features = groupBox->features;
5036                 frame.lineWidth = groupBox->lineWidth;
5037                 frame.midLineWidth = groupBox->midLineWidth;
5038                 frame.rect = /*proxy()->*/subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
5039 
5040                 if((groupBox->features & QStyleOptionFrame::Flat) || !(opts.gbLabel&(GB_LBL_INSIDE|GB_LBL_OUTSIDE)))
5041                 {
5042                     painter->save();
5043                     QRegion region(r);
5044                     if (!groupBox->text.isEmpty())
5045                         region -= QRect(groupBox->subControls&QStyle::SC_GroupBoxCheckBox
5046                                         ? checkBoxRect.united(textRect).adjusted(reverse ? 0 : -2, 0, reverse ? 2 : 0, 0)
5047                                         : textRect);
5048                     painter->setClipRegion(region);
5049                 }
5050                 /*proxy()->*/drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
5051                 if((groupBox->features&QStyleOptionFrame::Flat) || !(opts.gbLabel&(GB_LBL_INSIDE|GB_LBL_OUTSIDE)))
5052                     painter->restore();
5053             }
5054 
5055             // Draw title
5056             if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty())
5057             {
5058                 QColor textColor = groupBox->textColor;
5059                 if (textColor.isValid())
5060                     painter->setPen(textColor);
5061                 int alignment = int(groupBox->textAlignment);
5062                 if (!/*proxy()->*/styleHint(QStyle::SH_UnderlineShortcut, option, widget))
5063                     alignment |= Qt::TextHideMnemonic;
5064 
5065                 if(opts.gbLabel&GB_LBL_BOLD)
5066                 {
5067                     QFont font = m_fntHelper->fontStripStyleName(painter->font());
5068 
5069                     font.setBold(true);
5070                     painter->save();
5071                     painter->setFont(font);
5072                 }
5073                 /*proxy()->*/drawItemText(painter, textRect,  Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
5074                                           palette, state & State_Enabled, groupBox->text,
5075                                           textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
5076 
5077                 if(opts.gbLabel&GB_LBL_BOLD)
5078                     painter->restore();
5079 
5080                 if (state & State_HasFocus)
5081                 {
5082                     QStyleOptionFocusRect fropt;
5083                     fropt.QStyleOption::operator=(*groupBox);
5084                     fropt.rect = textRect;
5085                     /*proxy()->*/drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
5086                 }
5087             }
5088 
5089             // Draw checkbox
5090             if (groupBox->subControls & SC_GroupBoxCheckBox)
5091             {
5092                 QStyleOptionButton box;
5093                 box.QStyleOption::operator=(*groupBox);
5094                 box.rect = checkBoxRect;
5095                 /*proxy()->*/drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
5096             }
5097         }
5098         break;
5099     case CC_SpinBox:
5100         if (auto spinBox = styleOptCast<QStyleOptionSpinBox>(option)) {
5101             QRect frame(subControlRect(CC_SpinBox, option, SC_SpinBoxFrame, widget)),
5102                 up(subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget)),
5103                 down(subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget)),
5104                 all(frame.united(up).united(down));
5105             bool  doFrame(spinBox->frame && frame.isValid()),
5106                 sunken(state&State_Sunken),
5107                 enabled(state&State_Enabled),
5108                 mouseOver(state&State_MouseOver),
5109                 upIsActive(SC_SpinBoxUp==spinBox->activeSubControls),
5110                 downIsActive(SC_SpinBoxDown==spinBox->activeSubControls),
5111                 doEtch(opts.buttonEffect != EFFECT_NONE && opts.etchEntry),
5112                 isOO(isOOWidget(widget)),
5113                 oldUnify=opts.unifySpin; // See Krita note below...
5114 
5115             if(!doFrame && isOO && !opts.unifySpin)
5116             {
5117                 doFrame=true;
5118                 frame=all;
5119             }
5120 
5121             if(isOO)
5122                 painter->fillRect(r, palette.brush(QPalette::Window));
5123 
5124             if(up.isValid())
5125             {
5126                 if(reverse)
5127                     frame.adjust(up.width(), 0, 0, 0);
5128                 else
5129                     frame.adjust(0, 0, -up.width(), 0);
5130             }
5131 
5132             if(doEtch)
5133             {
5134                 drawEtch(painter, all, widget, WIDGET_SPIN, false,
5135                          opts.square&SQUARE_ENTRY
5136                          ? opts.unifySpin
5137                          ? ROUNDED_NONE
5138                          : reverse
5139                          ? ROUNDED_LEFT
5140                          : ROUNDED_RIGHT
5141                          : ROUNDED_ALL);
5142                 down.adjust(reverse ? 1 : 0, 0, reverse ? 0 : -1, -1);
5143                 up.adjust(reverse ? 1 : 0, 1, reverse ? 0 : -1, 0);
5144                 frame.adjust(reverse ? 0 : 1, 1, reverse ? -1 : 0, -1);
5145                 all.adjust(1, 1, -1, -1);
5146             }
5147 
5148             // Krita/KOffice uses a progressbar with spin buttons at the end
5149             // ...when drawn, the frame part is not set - so in this case dont draw the background behind the buttons!
5150             if(!isOO && !doFrame)
5151                 opts.unifySpin=true; // So, set this to true to fake the above scenario!
5152             else
5153                 if(opts.unifySpin)
5154                     drawEntryField(painter, all, widget, option, ROUNDED_ALL, true, false);
5155                 else
5156                 {
5157                     if(opts.unifySpinBtns)
5158                     {
5159                         QRect btns=up.united(down);
5160                         const QColor *use(buttonColors(option));
5161                         QStyleOption opt(*option);
5162 
5163                         opt.state&=~(State_Sunken|State_MouseOver);
5164                         opt.state|=State_Horizontal;
5165 
5166                         drawLightBevel(painter, btns, &opt, widget, reverse ?  ROUNDED_LEFT : ROUNDED_RIGHT,
5167                                        getFill(&opt, use), use, true, WIDGET_SPIN);
5168 
5169                         if(state&State_MouseOver && state&State_Enabled && !(state&State_Sunken))
5170                         {
5171                             opt.state|=State_MouseOver;
5172                             painter->save();
5173                             painter->setClipRect(upIsActive ? up : down);
5174                             drawLightBevel(painter, btns, &opt, widget, reverse ?  ROUNDED_LEFT : ROUNDED_RIGHT,
5175                                            getFill(&opt, use), use, true, WIDGET_SPIN);
5176                             painter->restore();
5177                         }
5178                         drawFadedLine(painter, down.adjusted(2, 0, -2, 0), use[BORDER_VAL(state&State_Enabled)], true, true, true);
5179                     }
5180                 }
5181 
5182             if(up.isValid())
5183             {
5184                 QStyleOption opt(*option);
5185 
5186                 up.setHeight(up.height()+1);
5187                 opt.rect=up;
5188                 opt.direction=option->direction;
5189                 opt.state=(enabled && (spinBox->stepEnabled&QAbstractSpinBox::StepUpEnabled ||
5190                                        (QAbstractSpinBox::StepNone==spinBox->stepEnabled && isOO))
5191                            ? State_Enabled : State_None)|
5192                     (upIsActive && sunken ? State_Sunken : State_Raised)|
5193                     (upIsActive && !sunken && mouseOver ? State_MouseOver : State_None)|State_Horizontal;
5194 
5195                 drawPrimitive(QAbstractSpinBox::PlusMinus==spinBox->buttonSymbols ? PE_IndicatorSpinPlus : PE_IndicatorSpinUp,
5196                               &opt, painter, widget);
5197             }
5198 
5199             if(down.isValid())
5200             {
5201                 QStyleOption opt(*option);
5202 
5203                 opt.rect=down;
5204                 opt.state=(enabled && (spinBox->stepEnabled&QAbstractSpinBox::StepDownEnabled ||
5205                                        (QAbstractSpinBox::StepNone==spinBox->stepEnabled && isOO))
5206                            ? State_Enabled : State_None)|
5207                     (downIsActive && sunken ? State_Sunken : State_Raised)|
5208                     (downIsActive && !sunken && mouseOver ? State_MouseOver : State_None)|State_Horizontal;
5209                 opt.direction=option->direction;
5210 
5211                 drawPrimitive(QAbstractSpinBox::PlusMinus==spinBox->buttonSymbols ? PE_IndicatorSpinMinus : PE_IndicatorSpinDown,
5212                               &opt, painter, widget);
5213             }
5214             if(doFrame && !opts.unifySpin)
5215             {
5216                 if(reverse)
5217                     frame.setX(frame.x()-1);
5218                 else
5219                     frame.setWidth(frame.width()+1);
5220                 drawEntryField(painter, frame, widget, option, reverse ? ROUNDED_RIGHT : ROUNDED_LEFT, true, false);
5221             }
5222             opts.unifySpin=oldUnify;
5223         }
5224         break;
5225     case CC_Slider:
5226         if (auto slider = styleOptCast<QStyleOptionSlider>(option)) {
5227             QRect groove(subControlRect(CC_Slider, option,
5228                                         SC_SliderGroove, widget));
5229             QRect handle(subControlRect(CC_Slider, option,
5230                                         SC_SliderHandle, widget));
5231             // QRect ticks(subControlRect(CC_Slider, option,
5232             //                            SC_SliderTickmarks, widget));
5233             bool  horizontal(slider->orientation == Qt::Horizontal),
5234                 ticksAbove(slider->tickPosition & QSlider::TicksAbove),
5235                 ticksBelow(slider->tickPosition & QSlider::TicksBelow);
5236 
5237             //The clickable region is 5 px wider than the visible groove for improved usability
5238 //                 if (groove.isValid())
5239 //                     groove = horizontal ? groove.adjusted(0, 5, 0, -5) : groove.adjusted(5, 0, -5, 0);
5240 
5241             if ((option->subControls&SC_SliderGroove) && groove.isValid())
5242                 drawSliderGroove(painter, groove, handle, slider, widget);
5243 
5244             if ((option->subControls&SC_SliderHandle) && handle.isValid())
5245             {
5246                 QStyleOptionSlider s(*slider);
5247                 if(!(s.activeSubControls & QStyle::SC_SliderHandle))
5248                 {
5249                     s.state &= ~QStyle::State_MouseOver;
5250                     s.state &= ~QStyle::State_Sunken;
5251                 }
5252 
5253                 drawSliderHandle(painter, handle, &s);
5254 
5255                 if (state&State_HasFocus && FOCUS_GLOW!=opts.focus)
5256                 {
5257                     QStyleOptionFocusRect fropt;
5258                     fropt.QStyleOption::operator=(*slider);
5259                     fropt.rect = slider->rect;
5260 
5261                     if(horizontal)
5262                         fropt.rect.adjust(0, 0, 0, -1);
5263                     else
5264                         fropt.rect.adjust(0, 0, -1, 0);
5265 
5266                     drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
5267                 }
5268             }
5269 
5270             if (option->subControls&SC_SliderTickmarks)
5271             {
5272                 QPen oldPen = painter->pen();
5273                 painter->setPen(backgroundColors(option)[QTC_STD_BORDER]);
5274                 int tickSize(pixelMetric(PM_SliderTickmarkOffset, option, widget)),
5275                     available(pixelMetric(PM_SliderSpaceAvailable, slider, widget)),
5276                     interval(slider->tickInterval);
5277                 if (interval <= 0)
5278                 {
5279                     interval = slider->singleStep;
5280                     if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
5281                                                         available)
5282                         - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
5283                                                           0, available) < 3)
5284                         interval = slider->pageStep;
5285                 }
5286                 if (interval <= 0)
5287                     interval = 1;
5288 
5289                 int sliderLength(slider->maximum - slider->minimum + 1),
5290                     nticks(sliderLength / interval); // add one to get the end tickmark
5291                 if (sliderLength % interval > 0)
5292                     nticks++; // round up the number of tick marks
5293 
5294                 int v(slider->minimum),
5295                     len(pixelMetric(PM_SliderLength, slider, widget));
5296 
5297                 while (v <= slider->maximum + 1)
5298                 {
5299                     if (v == slider->maximum + 1 && interval == 1)
5300                         break;
5301 
5302                     int pos(sliderPositionFromValue(slider->minimum, slider->maximum,
5303                                                     qMin(v, slider->maximum), (horizontal
5304                                                                                ? slider->rect.width()
5305                                                                                : slider->rect.height()) - len,
5306                                                     slider->upsideDown) + len / 2);
5307 
5308                     int extra(2); // - ((v == slider->minimum || v == slider->maximum) ? 1 : 0);
5309 
5310                     if (horizontal)
5311                     {
5312                         if (ticksAbove)
5313                             painter->drawLine(QLine(pos, slider->rect.top() + extra,
5314                                                     pos, slider->rect.top() + tickSize));
5315                         if (ticksBelow)
5316                             painter->drawLine(QLine(pos, slider->rect.bottom() - extra,
5317                                                     pos, slider->rect.bottom() - tickSize));
5318                     }
5319                     else
5320                     {
5321                         if (ticksAbove)
5322                             painter->drawLine(QLine(slider->rect.left() + extra, pos,
5323                                                     slider->rect.left() + tickSize, pos));
5324                         if (ticksBelow)
5325                             painter->drawLine(QLine(slider->rect.right() - extra, pos,
5326                                                     slider->rect.right() - tickSize, pos));
5327                     }
5328 
5329                     // in the case where maximum is max int
5330                     int nextInterval = v + interval;
5331                     if (nextInterval < v)
5332                         break;
5333                     v = nextInterval;
5334                 }
5335                 painter->setPen(oldPen);
5336             }
5337         }
5338         break;
5339     case CC_TitleBar:
5340         if (auto titleBar = styleOptCast<QStyleOptionTitleBar>(option)) {
5341             painter->save();
5342 
5343             EAppearance  app=qtcWidgetApp(WIDGET_MDI_WINDOW_TITLE, &opts, option->state&State_Active);
5344             bool         active(state&State_Active),
5345                 kwin(theThemedApp==APP_KWIN || titleBar->titleBarState&QtC_StateKWin);
5346             const QColor *bgndCols(APPEARANCE_NONE==app
5347                                    ? kwin ? backgroundColors(option) : backgroundColors(palette.color(QPalette::Active, QPalette::Window))
5348                                    : kwin ? buttonColors(option) : getMdiColors(titleBar, active)),
5349                 *btnCols(kwin || opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR
5350                          ? buttonColors(option)
5351                          : getMdiColors(titleBar, active)),
5352                 *titleCols(APPEARANCE_NONE==app
5353                            ? bgndCols
5354                            : kwin || !(opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR)
5355                            ? btnCols : getMdiColors(titleBar, active));
5356             QColor       textColor(theThemedApp==APP_KWIN
5357                                    ? option->palette.color(QPalette::WindowText)
5358                                    : active
5359                                    ? m_activeMdiTextColor
5360                                    : m_mdiTextColor),
5361                 iconColor(textColor),
5362                 shadow(WINDOW_SHADOW_COLOR(opts.titlebarEffect));
5363             QStyleOption opt(*option);
5364             QRect        tr(r),
5365                 menuRect(subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget));
5366             ERound       round=(opts.square&SQUARE_WINDOWS && opts.round>ROUND_SLIGHT) ? ROUND_SLIGHT : opts.round;
5367             QColor       borderCol(kwin && option->version==(TBAR_BORDER_VERSION_HACK+2)
5368                                    ? palette.color(QPalette::Active, QPalette::Shadow)
5369                                    : titleCols[kwin && option->version==TBAR_BORDER_VERSION_HACK ? 0 : QTC_STD_BORDER]);
5370 
5371             if(!kwin && widget && BLEND_TITLEBAR && qobject_cast<const QMdiSubWindow *>(widget))
5372             {
5373                 const QWidget *w=nullptr;
5374                 if(qobject_cast<const QMainWindow *>(widget))
5375                     w=widget;
5376                 else if (static_cast<const QMdiSubWindow *>(widget)->widget())
5377                     w=qobject_cast<const QMainWindow *>(static_cast<const QMdiSubWindow *>(widget)->widget());
5378                 if(w)
5379                 {
5380                     const QMenuBar *menuBar=static_cast<const QMainWindow *>(w)->menuBar();
5381 
5382                     if(menuBar)
5383                         tr.adjust(0, 0, 0, menuBar->rect().height());
5384                 }
5385             }
5386 
5387             opt.state=State_Horizontal|State_Enabled|State_Raised|(active ? State_Active : State_None);
5388 
5389 #ifndef QTC_QT5_ENABLE_KDE
5390             QPainterPath path;
5391 #else
5392             QPainterPath path(round < ROUND_SLIGHT ? QPainterPath() :
5393                               buildPath(QRectF(state&QtC_StateKWinNoBorder ?
5394                                                tr : tr.adjusted(1, 1, -1, 0)),
5395                                         WIDGET_MDI_WINDOW_TITLE,
5396                                         state & QtC_StateKWin &&
5397                                         state & QtC_StateKWinTabDrag ?
5398                                         ROUNDED_ALL : ROUNDED_TOP,
5399                                         (round > ROUND_SLIGHT /*&& kwin*/ ?
5400                                          6.0 : 2.0)));
5401 #endif
5402             if (!kwin && !qtcIsCustomBgnd(opts))
5403                 painter->fillRect(tr, borderCol);
5404 
5405             painter->setRenderHint(QPainter::Antialiasing, true);
5406 
5407             if(kwin && (state&QtC_StateKWinFillBgnd))
5408                 drawBevelGradient(titleCols[ORIGINAL_SHADE], painter, tr, path, true, false, APPEARANCE_FLAT, WIDGET_MDI_WINDOW, false);
5409             if((!kwin && !m_isPreview) ||
5410                (APPEARANCE_NONE!=app && (!qtcIsFlat(app) || (titleCols[ORIGINAL_SHADE]!=QApplication::palette().window().color()))))
5411                 drawBevelGradient(titleCols[ORIGINAL_SHADE], painter, tr, path, true, false, app, WIDGET_MDI_WINDOW, false);
5412 
5413             if(!(state&QtC_StateKWinNoBorder))
5414             {
5415                 QColor light(titleCols[0]),
5416                     dark(borderCol);
5417                 bool   addLight=opts.windowBorder&WINDOW_BORDER_ADD_LIGHT_BORDER && (!kwin || qtcGetWindowBorderSize(false).sides>1);
5418 
5419                 if(kwin)
5420                 {
5421                     light.setAlphaF(1.0);
5422                     dark.setAlphaF(1.0);
5423                 }
5424 
5425                 if(addLight)
5426                 {
5427                     painter->setPen(light);
5428                     painter->save();
5429                     painter->setClipRect(r.adjusted(0, 0, -1, -1));
5430                     painter->drawPath(buildPath(r.adjusted(1, 1, 0, 1), WIDGET_MDI_WINDOW_TITLE, ROUNDED_TOP,
5431                                                 round<ROUND_SLIGHT
5432                                                 ? 0
5433                                                 : round>ROUND_SLIGHT /*&& kwin*/
5434                                                 ? 5.0
5435                                                 : 1.0));
5436                     painter->restore();
5437                 }
5438 
5439                 painter->setPen(dark);
5440                 painter->drawPath(buildPath(r, WIDGET_MDI_WINDOW_TITLE, ROUNDED_TOP,
5441                                             round<ROUND_SLIGHT
5442                                             ? 0
5443                                             : round>ROUND_SLIGHT /*&& kwin*/
5444                                             ? 6.0
5445                                             : 2.0));
5446 
5447                 QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
5448 
5449                 if(addLight)
5450                 {
5451                     painter->setPen(light);
5452                     painter->drawPoint(r.x()+1, r.y()+r.height()-1);
5453                 }
5454 
5455                 if (round > ROUND_SLIGHT && opts.round >= ROUND_FULL) {
5456                     if (!(state & QtC_StateKWinCompositing)) {
5457                         painter->setPen(dark);
5458 
5459                         painter->drawLine(r.x()+1, r.y()+4, r.x()+1, r.y()+3);
5460                         painter->drawPoint(r.x()+2, r.y()+2);
5461                         painter->drawLine(r.x()+3, r.y()+1, r.x()+4, r.y()+1);
5462                         painter->drawLine(r.x()+r.width()-2, r.y()+4, r.x()+r.width()-2, r.y()+3);
5463                         painter->drawPoint(r.x()+r.width()-3, r.y()+2);
5464                         painter->drawLine(r.x()+r.width()-4, r.y()+1, r.x()+r.width()-5, r.y()+1);
5465                     }
5466 
5467                     if(addLight &&
5468                        (APPEARANCE_SHINY_GLASS!=(active ? opts.titlebarAppearance : opts.inactiveTitlebarAppearance)))
5469                     {
5470                         painter->setPen(light);
5471                         painter->drawLine(r.x()+2, r.y()+4, r.x()+2, r.y()+3);
5472                         painter->drawLine(r.x()+3, r.y()+2, r.x()+4, r.y()+2);
5473                         painter->drawLine(r.x()+r.width()-4, r.y()+2, r.x()+r.width()-5, r.y()+2);
5474                     }
5475                 }
5476 
5477                 if(opts.windowBorder&WINDOW_BORDER_BLEND_TITLEBAR && (!kwin || !(state&QtC_StateKWinNoBorder)))
5478                 {
5479                     static const int constFadeLen=8;
5480                     QPoint          start(0, r.y()+r.height()-(1+constFadeLen)),
5481                         end(start.x(), start.y()+constFadeLen);
5482                     QLinearGradient grad(start, end);
5483 
5484                     grad.setColorAt(0, dark);
5485                     grad.setColorAt(1, m_backgroundCols[QTC_STD_BORDER]);
5486                     painter->setPen(QPen(QBrush(grad), QPENWIDTH1));
5487                     painter->drawLine(r.x(), start.y(), r.x(), end.y());
5488                     painter->drawLine(r.x()+r.width()-1, start.y(), r.x()+r.width()-1, end.y());
5489 
5490                     if(addLight)
5491                     {
5492                         grad.setColorAt(0, light);
5493                         grad.setColorAt(1, m_backgroundCols[0]);
5494                         painter->setPen(QPen(QBrush(grad), QPENWIDTH1));
5495                         painter->drawLine(r.x()+1, start.y(), r.x()+1, end.y());
5496                     }
5497                 }
5498             }
5499             else
5500                 QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
5501 
5502             if(kwin)
5503             {
5504                 painter->restore();
5505                 break;
5506             }
5507 
5508             int   adjust(0);
5509             QRect captionRect(subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget));
5510 
5511             if(opts.titlebarButtons&TITLEBAR_BUTTON_SUNKEN_BACKGROUND && captionRect!=r)
5512             {
5513                 bool menuIcon=TITLEBAR_ICON_MENU_BUTTON==opts.titlebarIcon,
5514                     menuLeft=menuRect.isValid() && !titleBar->icon.isNull() && menuRect.left()<(r.left()+constWindowMargin+4);
5515                 int  height=r.height()-(1+(2*constWindowMargin));
5516 
5517                 adjust=1;
5518                 if(captionRect.left()>(r.left()+constWindowMargin))
5519                 {
5520                     int width=captionRect.left()-(r.left()+(2*constWindowMargin));
5521 
5522                     if(!(menuIcon && menuLeft) || width>(height+4))
5523                         drawSunkenBevel(painter, QRect(r.left()+constWindowMargin+1, r.top()+constWindowMargin+1, width, height), titleCols[ORIGINAL_SHADE]);
5524                 }
5525                 if(captionRect.right()<(r.right()-constWindowMargin))
5526                 {
5527                     int width=r.right()-(captionRect.right()+(2*constWindowMargin));
5528 
5529                     if(!(menuIcon && !menuLeft) || width>(height+4))
5530                         drawSunkenBevel(painter, QRect(captionRect.right()+constWindowMargin, r.top()+constWindowMargin+1, width, height), titleCols[ORIGINAL_SHADE]);
5531                 }
5532             }
5533 
5534             bool    showIcon=TITLEBAR_ICON_NEXT_TO_TITLE==opts.titlebarIcon && !titleBar->icon.isNull();
5535             int     iconSize=showIcon ? pixelMetric(QStyle::PM_SmallIconSize) : 0,
5536                 iconX=r.x();
5537             QPixmap pixmap;
5538 
5539             if(showIcon)
5540                 pixmap=getIconPixmap(titleBar->icon, iconSize, titleBar->state);
5541 
5542             if(!titleBar->text.isEmpty())
5543             {
5544                 static const int constPad=4;
5545 
5546                 Qt::Alignment alignment((Qt::Alignment)pixelMetric((QStyle::PixelMetric)QtC_TitleAlignment, 0L, 0L));
5547                 bool          alignFull(Qt::AlignHCenter==alignment),
5548                     iconRight((!reverse && alignment&Qt::AlignRight) || (reverse && alignment&Qt::AlignLeft));
5549                 QRect         textRect(alignFull
5550                                        ? QRect(r.x(), captionRect.y(), r.width(), captionRect.height())
5551                                        : captionRect);
5552 
5553 #ifndef QTC_QT5_ENABLE_KDE
5554                 QFont         font = m_fntHelper->fontStripStyleName(painter->font());
5555                 font.setBold(true);
5556                 painter->setFont(font);
5557 #else
5558                 painter->setFont(QFontDatabase::systemFont(QFontDatabase::TitleFont));
5559 #endif
5560 
5561                 QFontMetrics fm(painter->fontMetrics());
5562                 QString str(fm.elidedText(titleBar->text, Qt::ElideRight, textRect.width(), QPalette::WindowText));
5563 
5564                 int           textWidth=alignFull || (showIcon && alignment&Qt::AlignHCenter)
5565                     ? fm.boundingRect(str).width()+(showIcon ? iconSize+constPad : 0) : 0;
5566 
5567                 if(alignFull &&
5568                    ( (captionRect.left()>((textRect.width()-textWidth)>>1)) ||
5569                      (captionRect.right()<((textRect.width()+textWidth)>>1)) ) )
5570                 {
5571                     alignment=Qt::AlignVCenter|Qt::AlignRight;
5572                     textRect=captionRect;
5573                 }
5574 
5575                 if(alignment&Qt::AlignLeft && constWindowMargin==textRect.x())
5576                     textRect.adjust(showIcon ? 4 : 6, 0, 0, 0);
5577 
5578                 if(showIcon)
5579                 {
5580                     if(alignment&Qt::AlignHCenter)
5581                     {
5582                         if(reverse)
5583                         {
5584                             iconX=((textRect.width()-textWidth)/2.0)+0.5+textWidth+iconSize;
5585                             textRect.setX(textRect.x()-(iconSize+constPad));
5586                         }
5587                         else
5588                         {
5589                             iconX=((textRect.width()-textWidth)/2.0)+0.5;
5590                             textRect.setX(iconX+iconSize+constPad);
5591                             alignment=Qt::AlignVCenter|Qt::AlignLeft;
5592                         }
5593                     }
5594                     else if((!reverse && alignment&Qt::AlignLeft) || (reverse && alignment&Qt::AlignRight))
5595                     {
5596                         iconX=textRect.x();
5597                         textRect.setX(textRect.x()+(iconSize+constPad));
5598                     }
5599                     else if((!reverse && alignment&Qt::AlignRight) || (reverse && alignment&Qt::AlignLeft))
5600                     {
5601                         if(iconRight)
5602                         {
5603                             iconX=textRect.x()+textRect.width()-iconSize;
5604                             textRect.setWidth(textRect.width()-(iconSize+constPad));
5605                         }
5606                         else
5607                         {
5608                             iconX=textRect.x()+textRect.width()-textWidth;
5609                             if(iconX<textRect.x())
5610                                 iconX=textRect.x();
5611                         }
5612                     }
5613                 }
5614 
5615                 QTextOption textOpt(alignment|Qt::AlignVCenter);
5616                 textOpt.setWrapMode(QTextOption::NoWrap);
5617 
5618                 if(EFFECT_NONE!=opts.titlebarEffect)
5619                 {
5620                     shadow.setAlphaF(WINDOW_TEXT_SHADOW_ALPHA(opts.titlebarEffect));
5621                     //painter->setPen(shadow);
5622                     painter->setPen(blendColors(WINDOW_SHADOW_COLOR(opts.titlebarEffect), titleCols[ORIGINAL_SHADE],
5623                                                 WINDOW_TEXT_SHADOW_ALPHA(opts.titlebarEffect)));
5624                     painter->drawText(EFFECT_SHADOW==opts.titlebarEffect
5625                                       ? textRect.adjusted(1, 1, 1, 1)
5626                                       : textRect.adjusted(0, 1, 0, 1),
5627                                       str, textOpt);
5628 
5629                     if (!active && DARK_WINDOW_TEXT(textColor))
5630                     {
5631                         //textColor.setAlpha((textColor.alpha() * 180) >> 8);
5632                         textColor=blendColors(textColor, titleCols[ORIGINAL_SHADE], ((255 * 180) >> 8)/256.0);
5633                     }
5634                 }
5635                 painter->setPen(textColor);
5636                 painter->drawText(textRect, str, textOpt);
5637             }
5638 
5639             if(showIcon && iconX>=0)
5640                 painter->drawPixmap(iconX, r.y()+((r.height()-iconSize)/2)+1, pixmap);
5641 
5642             if ((titleBar->subControls&SC_TitleBarMinButton) && (titleBar->titleBarFlags&Qt::WindowMinimizeButtonHint) &&
5643                 !(titleBar->titleBarState&Qt::WindowMinimized))
5644                 drawMdiControl(painter, titleBar, SC_TitleBarMinButton, widget, TITLEBAR_MIN, iconColor, btnCols, bgndCols,
5645                                adjust, active);
5646 
5647             if ((titleBar->subControls&SC_TitleBarMaxButton) && (titleBar->titleBarFlags&Qt::WindowMaximizeButtonHint) &&
5648                 !(titleBar->titleBarState&Qt::WindowMaximized))
5649                 drawMdiControl(painter, titleBar, SC_TitleBarMaxButton, widget, TITLEBAR_MAX, iconColor, btnCols, bgndCols,
5650                                adjust, active);
5651 
5652             if ((titleBar->subControls&SC_TitleBarCloseButton) && (titleBar->titleBarFlags&Qt::WindowSystemMenuHint))
5653                 drawMdiControl(painter, titleBar, SC_TitleBarCloseButton, widget, TITLEBAR_CLOSE, iconColor, btnCols, bgndCols,
5654                                adjust, active);
5655 
5656             if ((titleBar->subControls&SC_TitleBarNormalButton) &&
5657                 (((titleBar->titleBarFlags&Qt::WindowMinimizeButtonHint) &&
5658                   (titleBar->titleBarState&Qt::WindowMinimized)) ||
5659                  ((titleBar->titleBarFlags&Qt::WindowMaximizeButtonHint) &&
5660                   (titleBar->titleBarState&Qt::WindowMaximized))))
5661                 drawMdiControl(painter, titleBar, SC_TitleBarNormalButton, widget, TITLEBAR_MAX, iconColor, btnCols, bgndCols,
5662                                adjust, active);
5663 
5664             if (titleBar->subControls&SC_TitleBarContextHelpButton && (titleBar->titleBarFlags&Qt::WindowContextHelpButtonHint))
5665                 drawMdiControl(painter, titleBar, SC_TitleBarContextHelpButton, widget, TITLEBAR_HELP, iconColor, btnCols, bgndCols,
5666                                adjust, active);
5667 
5668             if (titleBar->subControls&SC_TitleBarShadeButton && (titleBar->titleBarFlags&Qt::WindowShadeButtonHint))
5669                 drawMdiControl(painter, titleBar, SC_TitleBarShadeButton, widget, TITLEBAR_SHADE, iconColor, btnCols, bgndCols,
5670                                adjust, active);
5671 
5672             if (titleBar->subControls&SC_TitleBarUnshadeButton && (titleBar->titleBarFlags&Qt::WindowShadeButtonHint))
5673                 drawMdiControl(painter, titleBar, SC_TitleBarUnshadeButton, widget, TITLEBAR_SHADE, iconColor, btnCols, bgndCols,
5674                                adjust, active);
5675 
5676             if ((titleBar->subControls&SC_TitleBarSysMenu) && (titleBar->titleBarFlags&Qt::WindowSystemMenuHint))
5677             {
5678                 if(TITLEBAR_ICON_MENU_BUTTON==opts.titlebarIcon)
5679                 {
5680                     bool hover((titleBar->activeSubControls&SC_TitleBarSysMenu) && (titleBar->state&State_MouseOver));
5681 
5682                     if(active || hover || !(opts.titlebarButtons&TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW))
5683                     {
5684                         if (menuRect.isValid())
5685                         {
5686                             bool sunken((titleBar->activeSubControls&SC_TitleBarSysMenu) && (titleBar->state&State_Sunken));
5687                             int  offset(sunken ? 1 : 0);
5688 
5689 //                                 if(!(opts.titlebarButtons&TITLEBAR_BUTTON_ROUND))
5690 //                                     drawMdiButton(painter, menuRect, hover, sunken,
5691 //                                                   coloredMdiButtons(state&State_Active, hover)
5692 //                                                     ? m_titleBarButtonsCols[TITLEBAR_MENU] : btnCols);
5693 
5694                             if (!titleBar->icon.isNull())
5695                                 titleBar->icon.paint(painter, menuRect.adjusted(offset, offset, offset, offset));
5696                             else
5697                             {
5698                                 QStyleOption tool(0);
5699 
5700                                 tool.palette = palette;
5701                                 tool.rect = menuRect;
5702                                 painter->save();
5703                                 drawItemPixmap(painter, menuRect.adjusted(offset, offset, offset, offset), Qt::AlignCenter,
5704                                                standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16));
5705                                 painter->restore();
5706                             }
5707                         }
5708                     }
5709                 }
5710                 else
5711                     drawMdiControl(painter, titleBar, SC_TitleBarSysMenu, widget, TITLEBAR_MENU, iconColor, btnCols, bgndCols,
5712                                    adjust, active);
5713 
5714                 if(active && opts.windowBorder&WINDOW_BORDER_SEPARATOR)
5715                 {
5716                     QColor        color(active ? m_activeMdiTextColor : m_mdiTextColor);
5717                     Qt::Alignment align(pixelMetric((QStyle::PixelMetric)QtC_TitleAlignment, 0L, 0L));
5718                     QRect         lr(r.x(), captionRect.y(), r.width(), captionRect.height());
5719 
5720                     lr.adjust(16, lr.height()-2, -16, 0);
5721                     color.setAlphaF(0.5);
5722                     drawFadedLine(painter, lr, color, align&(Qt::AlignHCenter|Qt::AlignRight),
5723                                   align&(Qt::AlignHCenter|Qt::AlignLeft), true);
5724                 }
5725             }
5726 
5727             painter->restore();
5728         }
5729         break;
5730     case CC_ScrollBar:
5731         if (auto scrollbar = styleOptCast<QStyleOptionSlider>(option)) {
5732             bool useThreeButtonScrollBar(SCROLLBAR_KDE==opts.scrollbarType),
5733                 horiz(Qt::Horizontal==scrollbar->orientation),
5734                 maxed(scrollbar->minimum == scrollbar->maximum),
5735                 atMin(maxed || scrollbar->sliderValue==scrollbar->minimum),
5736                 atMax(maxed || scrollbar->sliderValue==scrollbar->maximum)/*,
5737                                                                             inStack(0!=opts.tabBgnd && inStackWidget(widget))*/;
5738             QRect subline(subControlRect(control, option,
5739                                          SC_ScrollBarSubLine, widget));
5740             QRect addline(subControlRect(control, option,
5741                                          SC_ScrollBarAddLine, widget));
5742             QRect subpage(subControlRect(control, option,
5743                                          SC_ScrollBarSubPage, widget));
5744             QRect addpage(subControlRect(control, option,
5745                                          SC_ScrollBarAddPage, widget));
5746             QRect slider(subControlRect(control, option,
5747                                         SC_ScrollBarSlider, widget));
5748             QRect first(subControlRect(control, option,
5749                                        SC_ScrollBarFirst, widget));
5750             QRect last(subControlRect(control, option,
5751                                       SC_ScrollBarLast, widget));
5752             QRect subline2(addline);
5753             // QRect sbRect(scrollbar->rect);
5754             QStyleOptionSlider opt(*scrollbar);
5755 
5756             // For OO.o 3.2 need to fill widget background!
5757             if(isOOWidget(widget))
5758                 painter->fillRect(r, palette.brush(QPalette::Window));
5759 
5760             if(reverse && horiz)
5761             {
5762                 bool tmp(atMin);
5763 
5764                 atMin=atMax;
5765                 atMax=tmp;
5766             }
5767 
5768             if (useThreeButtonScrollBar)
5769             {
5770                 int sbextent(pixelMetric(PM_ScrollBarExtent, scrollbar, widget));
5771 
5772                 if(horiz && reverse)
5773                     subline2=QRect((r.x()+r.width()-1)-sbextent, r.y(), sbextent, sbextent);
5774                 else if (horiz)
5775                     subline2.translate(-addline.width(), 0);
5776                 else
5777                     subline2.translate(0, -addline.height());
5778 
5779                 if (horiz)
5780                     subline.setWidth(sbextent);
5781                 else
5782                     subline.setHeight(sbextent);
5783             }
5784 
5785             // Draw trough...
5786             bool  noButtons(opts.round != ROUND_NONE &&
5787                             (opts.scrollbarType == SCROLLBAR_NONE ||
5788                              opts.flatSbarButtons));
5789             QRect s2(subpage), a2(addpage);
5790 
5791 #ifndef SIMPLE_SCROLLBARS
5792             if(noButtons)
5793             {
5794                 // Increase clipping to allow trough to "bleed" into slider corners...
5795                 a2.adjust(-3, -3, 3, 3);
5796                 s2.adjust(-3, -3, 3, 3);
5797             }
5798 #endif
5799 
5800             painter->save();
5801 
5802             if ((opts.thinSbarGroove || opts.flatSbarButtons) &&
5803                 qtcCheckType(getParent<2>(widget), "QComboBoxListView")) {
5804                 painter->fillRect(r, palette.brush(QPalette::Base));
5805             } else if (opts.thinSbarGroove && theThemedApp == APP_ARORA &&
5806                        qtcCheckType(widget, "WebView")) {
5807                 painter->fillRect(r, m_backgroundCols[ORIGINAL_SHADE]);
5808             }
5809             if (!opts.gtkScrollViews ||
5810                 (opts.flatSbarButtons && !qtcIsFlat(opts.sbarBgndAppearance)))
5811                 drawBevelGradientReal(palette.brush(QPalette::Background).color(), painter, r, horiz, false,
5812                                       opts.sbarBgndAppearance, WIDGET_SB_BGND);
5813 
5814             if(noButtons || opts.flatSbarButtons)
5815             {
5816                 int mod=THIN_SBAR_MOD;
5817                 // Draw complete groove here, as we want to round both ends...
5818                 opt.rect=subpage.united(addpage);
5819                 opt.state=scrollbar->state;
5820                 opt.state&=~(State_MouseOver|State_Sunken|State_On);
5821 
5822                 if(opts.thinSbarGroove && slider.isValid())
5823                 {
5824                     painter->save();
5825                     painter->setClipRegion(QRegion(opt.rect).subtracted(slider.adjusted(1, 1, -1, -1)));
5826                 }
5827                 drawLightBevel(painter, opts.thinSbarGroove
5828                                ? horiz
5829                                ? opt.rect.adjusted(0, mod, 0, -mod)
5830                                : opt.rect.adjusted(mod, 0, -mod, 0)
5831                                : opt.rect, &opt, widget,
5832 #ifndef SIMPLE_SCROLLBARS
5833                                !(opts.square&SQUARE_SB_SLIDER) && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)
5834                                ? ROUNDED_ALL :
5835 #endif
5836                                ROUNDED_NONE,
5837                                m_backgroundCols[2], m_backgroundCols, true,
5838                                opts.thinSbarGroove ? WIDGET_SLIDER_TROUGH : WIDGET_TROUGH);
5839                 if(opts.thinSbarGroove && slider.isValid())
5840                     painter->restore();
5841             }
5842             else
5843             {
5844                 if((option->subControls&SC_ScrollBarSubPage) && subpage.isValid())
5845                 {
5846                     opt.state=scrollbar->state;
5847                     opt.rect = subpage;
5848 //                         if (!(scrollbar->activeSubControls&SC_ScrollBarSubPage))
5849                     opt.state &= ~(State_Sunken|State_MouseOver|State_On);
5850                     drawControl(CE_ScrollBarSubPage, &opt, painter, widget);
5851                 }
5852 
5853                 if((option->subControls&SC_ScrollBarAddPage) && addpage.isValid())
5854                 {
5855                     opt.state=scrollbar->state;
5856                     opt.rect = addpage;
5857 //                         if (!(scrollbar->activeSubControls&SC_ScrollBarAddPage))
5858                     opt.state &= ~(State_Sunken|State_MouseOver|State_On);
5859                     drawControl(CE_ScrollBarAddPage, &opt, painter, widget);
5860                 }
5861             }
5862 
5863             if((option->subControls&SC_ScrollBarSubLine) && subline.isValid())
5864             {
5865                 opt.rect=subline;
5866                 opt.state=scrollbar->state/*|(inStack ? NO_BGND_BUTTON : State_None)*/;
5867                 if(maxed || atMin)
5868                     opt.state&=~State_Enabled;
5869                 if (!(scrollbar->activeSubControls&SC_ScrollBarSubLine) ||
5870                     (useThreeButtonScrollBar && m_sbWidget && m_sbWidget==widget))
5871                     opt.state &= ~(State_Sunken | State_MouseOver);
5872 
5873                 drawControl(CE_ScrollBarSubLine, &opt, painter, widget);
5874 
5875                 if (useThreeButtonScrollBar && subline2.isValid())
5876                 {
5877                     opt.rect=subline2;
5878                     opt.state=scrollbar->state/*|(inStack ? NO_BGND_BUTTON : State_None)*/;
5879                     if(maxed || atMin)
5880                         opt.state&=~State_Enabled;
5881                     if ((!(scrollbar->activeSubControls&SC_ScrollBarSubLine)) || (m_sbWidget && m_sbWidget!=widget))
5882                         opt.state &= ~(State_Sunken | State_MouseOver);
5883 
5884                     drawControl(CE_ScrollBarSubLine, &opt, painter, widget);
5885                 }
5886             }
5887 
5888             if((option->subControls&SC_ScrollBarAddLine) && addline.isValid())
5889             {
5890                 opt.rect=addline;
5891                 opt.state=scrollbar->state/*|(inStack ? NO_BGND_BUTTON : State_None)*/;
5892                 if(maxed || atMax)
5893                     opt.state&=~State_Enabled;
5894                 if (!(scrollbar->activeSubControls&SC_ScrollBarAddLine))
5895                     opt.state &= ~(State_Sunken | State_MouseOver);
5896                 drawControl(CE_ScrollBarAddLine, &opt, painter, widget);
5897             }
5898 
5899             if((option->subControls&SC_ScrollBarFirst) && first.isValid())
5900             {
5901                 opt.rect=first;
5902                 opt.state=scrollbar->state;
5903                 if (!(scrollbar->activeSubControls&SC_ScrollBarFirst))
5904                     opt.state &= ~(State_Sunken | State_MouseOver);
5905                 drawControl(CE_ScrollBarFirst, &opt, painter, widget);
5906             }
5907 
5908             if((option->subControls&SC_ScrollBarLast) && last.isValid())
5909             {
5910                 opt.rect=last;
5911                 opt.state=scrollbar->state;
5912                 if (!(scrollbar->activeSubControls&SC_ScrollBarLast))
5913                     opt.state &= ~(State_Sunken | State_MouseOver);
5914                 drawControl(CE_ScrollBarLast, &opt, painter, widget);
5915             }
5916 
5917             if(((option->subControls&SC_ScrollBarSlider) || noButtons) && slider.isValid())
5918             {
5919                 // If "SC_ScrollBarSlider" wasn't specified, then we only want to draw the portion
5920                 // of the slider that overlaps with the trough. So, once again set the clipping
5921                 // region...
5922 
5923                 // NO! Seeems to mess things up with Arora, su just dsiable all clipping when drawing
5924                 // the slider...
5925                 painter->setClipping(false);
5926 #ifdef INCREASE_SB_SLIDER
5927                 if(!opts.flatSbarButtons)
5928                 {
5929                     if(atMax)
5930                         switch(opts.scrollbarType)
5931                         {
5932                         case SCROLLBAR_KDE:
5933                         case SCROLLBAR_WINDOWS:
5934                         case SCROLLBAR_PLATINUM:
5935                             if(horiz)
5936                                 slider.adjust(0, 0, 1, 0);
5937                             else
5938                                 slider.adjust(0, 0, 0, 1);
5939                         default:
5940                             break;
5941                         }
5942                     if(atMin)
5943                         switch(opts.scrollbarType)
5944                         {
5945                         case SCROLLBAR_KDE:
5946                         case SCROLLBAR_WINDOWS:
5947                         case SCROLLBAR_NEXT:
5948                             if(horiz)
5949                                 slider.adjust(-1, 0, 0, 0);
5950                             else
5951                                 slider.adjust(0, -1, 0, 0);
5952                         default:
5953                             break;
5954                         }
5955                 }
5956 #endif
5957                 opt.rect=slider;
5958                 opt.state=scrollbar->state;
5959                 if (!(scrollbar->activeSubControls&SC_ScrollBarSlider))
5960                     opt.state &= ~(State_Sunken | State_MouseOver);
5961                 drawControl(CE_ScrollBarSlider, &opt, painter, widget);
5962 
5963                 // ### perhaps this should not be able to accept focus if maxedOut?
5964                 if(state&State_HasFocus)
5965                 {
5966                     opt.state=scrollbar->state;
5967                     opt.rect=QRect(slider.x()+2, slider.y()+2, slider.width()-5, slider.height()-5);
5968                     drawPrimitive(PE_FrameFocusRect, &opt, painter, widget);
5969                 }
5970             }
5971             painter->restore();
5972         }
5973         break;
5974     case CC_ComboBox:
5975         if (auto comboBox = styleOptCast<QStyleOptionComboBox>(option)) {
5976             painter->save();
5977 
5978             QRect frame(subControlRect(CC_ComboBox, option,
5979                                        SC_ComboBoxFrame, widget));
5980             QRect arrow(subControlRect(CC_ComboBox, option,
5981                                        SC_ComboBoxArrow, widget));
5982             QRect field(subControlRect(CC_ComboBox, option,
5983                                        SC_ComboBoxEditField, widget));
5984             const QColor *use = buttonColors(option);
5985             bool sunken = state & State_On;
5986             bool glowOverFocus =
5987                 (state & State_MouseOver &&
5988                  oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED) &&
5989                  opts.coloredMouseOver == MO_GLOW &&
5990                  opts.buttonEffect != EFFECT_NONE && !sunken &&
5991                  !comboBox->editable && state & State_Enabled &&
5992                  state & State_HasFocus);
5993             bool doEffect = (opts.buttonEffect != EFFECT_NONE &&
5994                              (!comboBox->editable || opts.etchEntry));
5995             bool isOO = isOOWidget(widget);
5996             bool isOO31 = isOO;
5997 
5998             if (isOO) {
5999                 // This (hopefull) checks is we're OO.o 3.2 -
6000                 // in which case no adjustment is required...
6001                 const QImage *img = getImage(painter);
6002 
6003                 isOO31 = !img || img->rect() != r;
6004 
6005                 if (isOO31) {
6006                     frame.adjust(0, 0, 0, -2);
6007                     arrow.adjust(0, 0, 0, -2);
6008                     field.adjust(0, 0, 0, -2);
6009                 } else {
6010                     arrow.adjust(1, 0, 0, 0);
6011                 }
6012             }
6013 
6014             // painter->fillRect(r, Qt::transparent);
6015             if (doEffect) {
6016                 bool glowFocus(state&State_HasFocus && state&State_Enabled && USE_GLOW_FOCUS(state&State_MouseOver));
6017 
6018                 if (!glowOverFocus && !(opts.thin & THIN_FRAMES) && !sunken &&
6019                     opts.coloredMouseOver == MO_GLOW &&
6020                     (((oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED) ||
6021                        glowFocus) && state & State_HasFocus) ||
6022                      state & State_MouseOver) &&
6023                     state & State_Enabled && !comboBox->editable) {
6024                     drawGlow(painter, r,
6025                              oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED) &&
6026                              state & State_HasFocus ? WIDGET_DEF_BUTTON :
6027                              WIDGET_COMBO, glowFocus ? m_focusCols : 0L);
6028                 } else {
6029                     drawEtch(painter, r, widget, WIDGET_COMBO,
6030                              !comboBox->editable &&
6031                              opts.buttonEffect == EFFECT_SHADOW && !sunken,
6032                              comboBox->editable && opts.square & SQUARE_ENTRY ?
6033                              opts.unifyCombo ? ROUNDED_NONE : reverse ?
6034                              ROUNDED_LEFT : ROUNDED_RIGHT : ROUNDED_ALL);
6035                 }
6036                 frame.adjust(1, 1, -1, -1);
6037             }
6038 
6039             if(/*comboBox->frame &&*/ frame.isValid() && (!comboBox->editable || !opts.unifyCombo))
6040             {
6041                 const QColor *cols=m_comboBtnCols && comboBox->editable && state&State_Enabled ? m_comboBtnCols : use;
6042 
6043                 QStyleOption frameOpt(*option);
6044 
6045                 if (comboBox->editable && !(comboBox->activeSubControls&SC_ComboBoxArrow))
6046                     frameOpt.state &= ~(State_Sunken | State_MouseOver);
6047 
6048                 if(!sunken)
6049                     frameOpt.state|=State_Raised;
6050 
6051                 //if(opts.coloredMouseOver && frameOpt.state&State_MouseOver && comboBox->editable && !sunken)
6052                 //    frame.adjust(reverse ? 0 : 1, 0, reverse ? 1 : 0, 0);
6053 
6054                 drawLightBevel(painter, frame, &frameOpt, widget,
6055                                comboBox->editable ? (reverse ? ROUNDED_LEFT : ROUNDED_RIGHT) : ROUNDED_ALL,
6056                                getFill(&frameOpt, cols, false,
6057                                        (SHADE_DARKEN==opts.comboBtn || (SHADE_NONE!=opts.comboBtn &&
6058                                                                         !(state&State_Enabled))) &&
6059                                        comboBox->editable),
6060                                cols, true, comboBox->editable ? WIDGET_COMBO_BUTTON : WIDGET_COMBO);
6061             }
6062 
6063             if(/*controls&SC_ComboBoxEditField &&*/ field.isValid())
6064             {
6065                 if(comboBox->editable)
6066                 {
6067                     if(opts.unifyCombo)
6068                     {
6069                         field=r;
6070                         if(doEffect)
6071                             field.adjust(1, 1, -1, -1);
6072                         if(isOO31)
6073                             field.adjust(0, 0, 0, -2);
6074                     }
6075                     else if(doEffect)
6076                         field.adjust(reverse ? -4 : -3, -1, reverse ? 3 : 4, 1);
6077                     else
6078                         field.adjust(reverse ? -4 : -2, -1, reverse ? 2 : 4, 1);
6079                     drawEntryField(painter, field, widget, option, opts.unifyCombo ? ROUNDED_ALL : reverse ? ROUNDED_RIGHT : ROUNDED_LEFT,
6080                                    true, false);
6081                 }
6082                 else if(opts.comboSplitter && !(SHADE_DARKEN==opts.comboBtn || m_comboBtnCols))
6083                 {
6084                     drawFadedLine(painter, QRect(reverse ? arrow.right()+1 : arrow.x()-1, arrow.top()+2,
6085                                                  1, arrow.height()-4),
6086                                   use[BORDER_VAL(state&State_Enabled)], true, true, false);
6087                     if(!sunken)
6088                         drawFadedLine(painter, QRect(reverse ? arrow.right()+2 : arrow.x(), arrow.top()+2,
6089                                                      1, arrow.height()-4),
6090                                       use[0], true, true, false);
6091                 }
6092             }
6093 
6094             if(/*controls&SC_ComboBoxArrow && */arrow.isValid())
6095             {
6096                 bool mouseOver=comboBox->editable && !(comboBox->activeSubControls&SC_ComboBoxArrow)
6097                     ? false : (state&State_MouseOver ? true : false);
6098 
6099                 if(!comboBox->editable && (SHADE_DARKEN==opts.comboBtn || m_comboBtnCols))
6100                 {
6101                     if(!comboBox->editable && isOO && !isOO31)
6102                         arrow.adjust(reverse ? 0 : 1, 0, reverse ? -1 : 0, 0);
6103 
6104                     QStyleOption frameOpt(*option);
6105                     QRect        btn(arrow.x(), frame.y(), arrow.width()+1, frame.height());
6106                     const QColor *cols=SHADE_DARKEN==opts.comboBtn || !(state&State_Enabled) ? use : m_comboBtnCols;
6107                     if(!sunken)
6108                         frameOpt.state|=State_Raised;
6109                     painter->save();
6110                     painter->setClipRect(btn, Qt::IntersectClip);
6111                     drawLightBevel(painter, opts.comboSplitter
6112                                    ? btn.adjusted(reverse ? -2 : 0, 0, reverse ? 2 : 1, 0)
6113                                    : btn.adjusted(reverse ? -3 : -2, 0, reverse ? 2 : 1, 0),
6114                                    &frameOpt, widget, reverse ? ROUNDED_LEFT : ROUNDED_RIGHT,
6115                                    getFill(&frameOpt, cols, false,
6116                                            SHADE_DARKEN==opts.comboBtn || (SHADE_NONE!=opts.comboBtn &&
6117                                                                            !(state&State_Enabled))),
6118                                    cols, true, WIDGET_COMBO);
6119                     painter->restore();
6120                 }
6121 
6122                 if(sunken && (!comboBox->editable || !opts.unifyCombo))
6123                     arrow.adjust(1, 1, 1, 1);
6124 
6125                 const QColor &arrowColor = MOArrow(state, palette, mouseOver,
6126                                                    QPalette::ButtonText);
6127                 if(comboBox->editable || !(opts.gtkComboMenus && opts.doubleGtkComboArrow))
6128                     drawArrow(painter, arrow, PE_IndicatorArrowDown, arrowColor, false);
6129                 else
6130                 {
6131                     int middle=arrow.y()+(arrow.height()>>1),
6132                         gap=(opts.vArrows ? 2 : 1);
6133 
6134                     QRect ar=QRect(arrow.x(), middle-(LARGE_ARR_HEIGHT+gap), arrow.width(), LARGE_ARR_HEIGHT);
6135                     drawArrow(painter, ar, PE_IndicatorArrowUp, arrowColor, false);
6136                     ar=QRect(arrow.x(), middle+gap, arrow.width(), LARGE_ARR_HEIGHT);
6137                     drawArrow(painter, ar, PE_IndicatorArrowDown, arrowColor, false);
6138                 }
6139             }
6140 
6141             if(state&State_Enabled && state&State_HasFocus &&
6142                /*state&State_KeyboardFocusChange &&*/ !comboBox->editable && FOCUS_GLOW!=opts.focus)
6143             {
6144                 QStyleOptionFocusRect focus;
6145                 bool listViewCombo = (comboBox->frame && widget &&
6146                                       widget->rect().height() <
6147                                       (opts.buttonEffect != EFFECT_NONE ?
6148                                        22 : 20));
6149 
6150                 if (oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED)) {
6151                     focus.rect = frame;
6152                 } else if (opts.comboSplitter) {
6153                     focus.rect = (reverse ? field.adjusted(0, -1, 1, 1) :
6154                                   field.adjusted(-1, -1, 0, 1));
6155 
6156                     if(listViewCombo)
6157                         focus.rect.adjust(0, -2, 0, 2);
6158                 }
6159                 else if(listViewCombo)
6160                     focus.rect=frame.adjusted(1, 1, -1, -1);
6161                 else
6162                     focus.rect=frame.adjusted(3, 3, -3, -3);
6163 
6164                 // Draw glow over top of filled focus
6165                 if(glowOverFocus && !(opts.thin&THIN_FRAMES))
6166                     drawGlow(painter, frame.adjusted(-1, -1, 1, 1), WIDGET_COMBO);
6167                 else
6168                     drawPrimitive(PE_FrameFocusRect, &focus, painter, widget);
6169             }
6170             painter->restore();
6171         }
6172         break;
6173     default:
6174         ParentStyleClass::drawComplexControl(control, option, painter, widget);
6175         break;
6176     }
6177 }
6178 
6179 void
6180 Style::drawItemText(QPainter *painter, const QRect &rect, int flags,
6181                     const QPalette &pal, bool enabled, const QString &text,
6182                     QPalette::ColorRole textRole) const
6183 {
6184     if (textRole == QPalette::ButtonText && !opts.stdSidebarButtons) {
6185         const QAbstractButton *button = getButton(nullptr, painter);
6186         if (button && isMultiTabBarTab(button) && button->isChecked()) {
6187             QPalette p(pal);
6188             if (m_inactiveChangeSelectionColor &&
6189                 p.currentColorGroup() == QPalette::Inactive) {
6190                 p.setCurrentColorGroup(QPalette::Active);
6191             }
6192             ParentStyleClass::drawItemText(painter, rect, flags, p, enabled,
6193                                        text, QPalette::HighlightedText);
6194             return;
6195         }
6196     }
6197 
6198     ParentStyleClass::drawItemText(painter, rect, flags, pal,
6199                                enabled, text, textRole);
6200 }
6201 
6202 QSize Style::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
6203 {
6204     prePolish(widget);
6205     QSize newSize(ParentStyleClass::sizeFromContents(type, option, size, widget));
6206 
6207     switch (type)
6208     {
6209     case CT_TabBarTab:
6210         newSize+=QSize(1, 1);
6211         break;
6212     case CT_Splitter:
6213     {
6214         int sw=pixelMetric(PM_SplitterWidth, 0L, 0L);
6215         return QSize(sw, sw);
6216     }
6217     case CT_PushButton:
6218     {
6219         newSize=size;
6220         newSize.setWidth(newSize.width()+(ROUND_MAX==opts.round ? 12 : 8));
6221 
6222         if (auto btn = styleOptCast<QStyleOptionButton>(option)) {
6223             if (!opts.stdBtnSizes) {
6224                 // Cant rely on AutoDefaultButton
6225                 //   - as VirtualBox does not set this!!!
6226                 bool allowIcon = styleHint(SH_DialogButtonBox_ButtonsHaveIcons, btn, widget) || btn->text.isEmpty();
6227                 if (allowIcon && (qtcCheckType<QDialogButtonBox>(getParent(widget)) ||
6228                     qtcCheckType(getParent(widget), "KFileWidget"))) {
6229                     int iconHeight = (btn->icon.isNull() ?
6230                                       btn->iconSize.height() : 16);
6231                     if (size.height() < iconHeight + 2) {
6232                         newSize.setHeight(iconHeight + 2);
6233                     }
6234                 }
6235             }
6236 
6237             int margin = (pixelMetric(PM_ButtonMargin, btn, widget)+
6238                           (pixelMetric(PM_DefaultFrameWidth, btn, widget) * 2))-MAX_ROUND_BTN_PAD;
6239 
6240             newSize+=QSize(margin, margin);
6241 
6242             if (btn->features&QStyleOptionButton::HasMenu)
6243                 newSize+=QSize(4, 0);
6244 
6245             if (!btn->text.isEmpty() && "..."!=btn->text && newSize.width() < 80)
6246                 newSize.setWidth(80);
6247 
6248             newSize.rheight() += ((1 - newSize.rheight()) & 1);
6249         }
6250         break;
6251     }
6252 //         case CT_RadioButton:
6253 //             ++newSize.rheight();
6254 //             ++newSize.rwidth();
6255 //             break;
6256     case CT_RadioButton:
6257     case CT_CheckBox:
6258         if (auto btn = styleOptCast<QStyleOptionButton>(option)) {
6259             bool isRadio = CT_RadioButton==type;
6260             int  w = /*proxy()->*/pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth : PM_IndicatorWidth, btn, widget),
6261                 h = /*proxy()->*/pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight : PM_IndicatorHeight, btn, widget),
6262                 margins = 0;
6263 
6264             newSize=size;
6265             // we add 4 pixels for label margins
6266             if (btn->icon.isNull() || !btn->text.isEmpty())
6267                 margins = 0+/*proxy()->*/pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, option, widget)+
6268                     (opts.crHighlight ? 4 : 0);
6269 
6270             newSize += QSize(w + margins, 4);
6271             newSize.setHeight(qMax(newSize.height(), h));
6272         }
6273         break;
6274     case CT_ScrollBar:
6275         if (auto scrollBar = styleOptCast<QStyleOptionSlider>(option)) {
6276             int scrollBarExtent =
6277                 pixelMetric(PM_ScrollBarExtent, option, widget);
6278             // See https://github.com/QtCurve/qtcurve-qt4/issues/7
6279             // and https://bugs.kde.org/show_bug.cgi?id=317690.
6280             int scrollBarLen =
6281                 (qtcMax(scrollBarExtent, 13) *
6282                  qtcScrollbarButtonNumSize(opts.scrollbarType) +
6283                  pixelMetric(PM_ScrollBarSliderMin, option, widget));
6284 
6285             if (scrollBar->orientation == Qt::Horizontal) {
6286                 newSize = QSize(scrollBarLen, scrollBarExtent);
6287             } else {
6288                 newSize = QSize(scrollBarExtent, scrollBarLen);
6289             }
6290         }
6291         break;
6292     case CT_LineEdit:
6293         if (auto f = styleOptCast<QStyleOptionFrame>(option)) {
6294             newSize = size + QSize(2 * f->lineWidth, 2 * f->lineWidth);
6295         }
6296         break;
6297     case CT_SpinBox:
6298         if(!opts.unifySpin)
6299             newSize.rheight() -= ((1 - newSize.rheight()) & 1);
6300         break;
6301     case CT_ToolButton:
6302     {
6303         newSize = QSize(size.width()+8, size.height()+8);
6304         // -- from kstyle & oxygen --
6305         // We want to avoid super-skiny buttons, for things like "up" when icons + text
6306         // For this, we would like to make width >= height.
6307         // However, once we get here, QToolButton may have already put in the menu area
6308         // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things
6309         // up, and add it back in. So much for class-independent rendering...
6310         int menuAreaWidth(0);
6311 
6312         if (auto tbOpt = styleOptCast<QStyleOptionToolButton>(option)) {
6313             // Make Kate/KWrite's option toolbuton have the same size as the next/prev buttons...
6314             if (widget && !getToolBar(widget) && !tbOpt->text.isEmpty() &&
6315                 tbOpt->features & QStyleOptionToolButton::MenuButtonPopup) {
6316                 QStyleOptionButton btn;
6317 
6318                 btn.init(widget);
6319                 btn.text = tbOpt->text;
6320                 btn.icon = tbOpt->icon;
6321                 btn.iconSize = tbOpt->iconSize;
6322                 btn.features = ((tbOpt->features &
6323                                 QStyleOptionToolButton::MenuButtonPopup) ?
6324                                 QStyleOptionButton::HasMenu :
6325                                 QStyleOptionButton::None);
6326                 return sizeFromContents(CT_PushButton, &btn, size, widget);
6327             }
6328 
6329             if (!tbOpt->icon.isNull() && !tbOpt->text.isEmpty() && Qt::ToolButtonTextUnderIcon==tbOpt->toolButtonStyle)
6330                 newSize.setHeight(newSize.height()-4);
6331 
6332             if (tbOpt->features & QStyleOptionToolButton::MenuButtonPopup)
6333                 menuAreaWidth = pixelMetric(QStyle::PM_MenuButtonIndicator,
6334                                             option, widget);
6335             else if (tbOpt->features & QStyleOptionToolButton::HasMenu)
6336                 switch(tbOpt->toolButtonStyle)
6337                 {
6338                 case Qt::ToolButtonIconOnly:
6339                     newSize.setWidth(newSize.width()+LARGE_ARR_WIDTH+2);
6340                     break;
6341                 case Qt::ToolButtonTextBesideIcon:
6342                     newSize.setWidth(newSize.width()+3);
6343                     break;
6344                 case Qt::ToolButtonTextOnly:
6345                     newSize.setWidth(newSize.width()+8);
6346                     break;
6347                 case Qt::ToolButtonTextUnderIcon:
6348                     newSize.setWidth(newSize.width()+8);
6349                     break;
6350                 default:
6351                     break;
6352                 }
6353         }
6354 
6355         newSize.setWidth(newSize.width() - menuAreaWidth);
6356         if (newSize.width() < newSize.height())
6357             newSize.setWidth(newSize.height());
6358         newSize.setWidth(newSize.width() + menuAreaWidth);
6359 
6360         break;
6361     }
6362     case CT_ComboBox: {
6363         newSize = size;
6364         newSize.setWidth(newSize.width() + 4);
6365 
6366         auto combo = styleOptCast<QStyleOptionComboBox>(option);
6367         int  margin = (pixelMetric(PM_ButtonMargin, option, widget)+
6368                        (pixelMetric(PM_DefaultFrameWidth, option, widget) * 2))-MAX_ROUND_BTN_PAD,
6369             textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1),
6370             // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
6371             other = qMax(opts.buttonEffect != EFFECT_NONE ? 20 : 18,
6372                          2 * textMargins +
6373                          pixelMetric(QStyle::PM_ScrollBarExtent,
6374                                      option, widget));
6375         bool editable=combo ? combo->editable : false;
6376         newSize+=QSize(margin+other, margin-2);
6377         newSize.rheight() += ((1 - newSize.rheight()) & 1);
6378 
6379         if (!opts.etchEntry && opts.buttonEffect != EFFECT_NONE && editable)
6380             newSize.rheight()-=2;
6381         // KWord's zoom combo clips 'Fit Page Width' without the following...
6382         if(editable)
6383             newSize.rwidth()+=6;
6384         break;
6385     }
6386     case CT_MenuItem:
6387         if (auto mi = styleOptCast<QStyleOptionMenuItem>(option)) {
6388             initFontTickData(mi->font, widget);
6389             // Taken from QWindowStyle...
6390             int w = size.width();
6391 
6392             if (QStyleOptionMenuItem::Separator==mi->menuItemType) {
6393                 newSize = QSize(10, windowsSepHeight);
6394             } else {
6395                 if (mi->icon.isNull()) {
6396                     newSize.setHeight(newSize.height() - 2);
6397                     w -= 6;
6398                 } else {
6399                     int iconExtent = pixelMetric(PM_SmallIconSize, option, widget);
6400                     newSize.setHeight(qMax(newSize.height(),
6401                                         mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
6402                                         + 2 * windowsItemFrame));
6403                 }
6404                 int dx;
6405                 if (menuTickCompensation(opts, 20, dx)) {
6406                     w += dx;
6407                 }
6408             }
6409             int maxpmw = mi->maxIconWidth,
6410                 tabSpacing = 20;
6411 
6412             if (!opts.buttonStyleMenuSections && QStyleOptionMenuItem::Separator == mi->menuItemType && !mi->text.isEmpty())
6413             {
6414                 QFont fontBold = m_fntHelper->fontStripStyleName(mi->font);
6415                 fontBold.setBold(true);
6416                 QFontMetrics fmBold(fontBold);
6417                 // _set_ w, it will have been initialised to something inappropriately small
6418                 w = horizontalAdvance(fmBold, mi->text);
6419             }
6420             else if (mi->text.contains(QLatin1Char('\t')))
6421                 w += tabSpacing;
6422             else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
6423                 w += 2 * windowsArrowHMargin;
6424             else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem)
6425             {
6426                 // adjust the font and add the difference in size.
6427                 // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
6428                 QFont fontBold = m_fntHelper->fontStripStyleName(mi->font);
6429                 QFontMetrics fm(fontBold);
6430                 fontBold.setBold(true);
6431                 QFontMetrics fmBold(fontBold);
6432                 w += horizontalAdvance(fmBold, mi->text) - horizontalAdvance(fm, mi->text);
6433             }
6434 
6435             if (QStyleOptionMenuItem::Separator != mi->menuItemType || opts.buttonStyleMenuSections)
6436             {
6437                 int checkcol = qMax<int>(maxpmw, windowsCheckMarkWidth); // Windows always shows a check column
6438                 w += checkcol + windowsRightBorder;
6439             }
6440             else
6441             {
6442                 w += 5;
6443             }
6444             w += 10;
6445             newSize.setWidth(w);
6446             // ....
6447 
6448             int h(newSize.height()-8); // Fix mainly for Qt4.4
6449 
6450             if (QStyleOptionMenuItem::Separator==mi->menuItemType && mi->text.isEmpty())
6451                 h = 7;
6452             else
6453             {
6454                 h = qMax(h, mi->fontMetrics.height());
6455                 if (!mi->icon.isNull())
6456                     h = qMax(h, mi->icon.pixmap(pixelMetric(PM_SmallIconSize), QIcon::Normal).height());
6457 
6458                 if (h < 18)
6459                     h = 18;
6460                 h+=((opts.thin&THIN_MENU_ITEMS) ? 2 : 4);
6461 
6462                 if(QStyleOptionMenuItem::Separator==mi->menuItemType)
6463                     h+=4;
6464             }
6465 
6466             newSize.setHeight(h);
6467             // Gtk2's icon->text spacing is 2 pixels smaller - so adjust here...
6468             newSize.setWidth(newSize.width()-2);
6469         }
6470         break;
6471     case CT_MenuBarItem:
6472         if (!size.isEmpty())
6473             newSize = size + QSize((windowsItemHMargin * 4) + 2,
6474                                    windowsItemVMargin + 1);
6475         break;
6476     default:
6477         break;
6478     }
6479 
6480     return newSize;
6481 }
6482 
6483 QRect Style::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
6484 {
6485     prePolish(widget);
6486     QRect rect;
6487     switch (element) {
6488     case SE_SliderFocusRect:
6489     case SE_ToolBoxTabContents:
6490         return visualRect(option->direction, option->rect, option->rect);
6491     case SE_DockWidgetTitleBarText: {
6492         auto dwopt = styleOptCast<QStyleOptionDockWidget>(option);
6493         bool verticalTitleBar = dwopt ? dwopt->verticalTitleBar : false;
6494         int m = pixelMetric(PM_DockWidgetTitleMargin, option, widget);
6495 
6496         rect = ParentStyleClass::subElementRect(element, option, widget);
6497 
6498         if (verticalTitleBar)
6499             rect.adjust(0, 0, 0, -m);
6500         else if (Qt::LeftToRight==option->direction )
6501             rect.adjust(m, 0, 0, 0);
6502         else
6503             rect.adjust(0, 0, -m, 0);
6504         return rect;
6505     }
6506     case SE_TabBarTabLeftButton:
6507         return ParentStyleClass::subElementRect(element, option, widget).translated(-2, -1);
6508     case SE_TabBarTabRightButton:
6509         return ParentStyleClass::subElementRect(element, option, widget).translated(2, -1);
6510     case SE_TabBarTabText:
6511         if (auto _tab = styleOptCast<QStyleOptionTab>(option)) {
6512             QStyleOptionTab tab(*_tab);
6513             bool verticalTabs = QTabBar::RoundedEast == tab.shape ||
6514                 QTabBar::RoundedWest == tab.shape ||
6515                 QTabBar::TriangularEast == tab.shape ||
6516                 QTabBar::TriangularWest == tab.shape;
6517 
6518             rect=tab.rect;
6519             if (verticalTabs)
6520                 rect.setRect(0, 0, rect.height(), rect.width());
6521             int verticalShift = pixelMetric(QStyle::PM_TabBarTabShiftVertical,
6522                                             _tab, widget);
6523             int horizontalShift = pixelMetric(QStyle::PM_TabBarTabShiftHorizontal,
6524                                               _tab, widget);
6525             if (tab.shape == QTabBar::RoundedSouth ||
6526                 tab.shape == QTabBar::TriangularSouth)
6527                 verticalShift = -verticalShift;
6528             rect.adjust(0, 0, horizontalShift, verticalShift);
6529             bool selected = tab.state & State_Selected;
6530             if (selected) {
6531                 rect.setBottom(rect.bottom() - verticalShift);
6532                 rect.setRight(rect.right() - horizontalShift);
6533             }
6534 
6535             // left widget
6536             if(opts.centerTabText) {
6537                 if (!tab.leftButtonSize.isEmpty())  // left widget
6538                     rect.setLeft(rect.left() + constTabPad +
6539                                  (verticalTabs ? tab.leftButtonSize.height() :
6540                                   tab.leftButtonSize.width()));
6541                 if (!tab.rightButtonSize.isEmpty()) // right widget
6542                     rect.setRight(rect.right() - constTabPad -
6543                                   (verticalTabs ? tab.rightButtonSize.height() :
6544                                    tab.rightButtonSize.width()));
6545             } else {
6546                 if (tab.leftButtonSize.isNull()) {
6547                     rect.setLeft(rect.left()+constTabPad);
6548                 } else if(tab.leftButtonSize.width()>0) {
6549                     rect.setLeft(rect.left() + constTabPad + 2 +
6550                                  (verticalTabs ? tab.leftButtonSize.height() :
6551                                   tab.leftButtonSize.width()));
6552                 } else if(tab.icon.isNull()) {
6553                     rect.setLeft(rect.left() + constTabPad);
6554                 } else {
6555                     rect.setLeft(rect.left() + 2);
6556                 }
6557             }
6558 
6559             // icon
6560             if (!tab.icon.isNull()) {
6561                 QSize iconSize = tab.iconSize;
6562                 if (!iconSize.isValid()) {
6563                     int iconExtent = pixelMetric(PM_SmallIconSize);
6564                     iconSize = QSize(iconExtent, iconExtent);
6565                 }
6566                 QSize tabIconSize = tab.icon.actualSize(iconSize,
6567                                                         (tab.state &
6568                                                          State_Enabled) ?
6569                                                         QIcon::Normal :
6570                                                         QIcon::Disabled);
6571                 int offset = 4;
6572 
6573                 if (!opts.centerTabText && tab.leftButtonSize.isNull())
6574                     offset += 2;
6575 
6576                 QRect iconRect = QRect(rect.left() + offset, rect.center().y() - tabIconSize.height() / 2,
6577                                        tabIconSize.width(), tabIconSize .height());
6578                 if (!verticalTabs)
6579                     iconRect = visualRect(option->direction, option->rect, iconRect);
6580                 rect.setLeft(rect.left() + tabIconSize.width() + offset + 2);
6581             }
6582 
6583             // right widget
6584             if (!opts.centerTabText && !tab.rightButtonSize.isNull() &&
6585                 tab.rightButtonSize.width() > 0) {
6586                 rect.setRight(rect.right() - constTabPad - 2 -
6587                               (verticalTabs ? tab.rightButtonSize.height() :
6588                                tab.rightButtonSize.width()));
6589             } else {
6590                 rect.setRight(rect.right() - constTabPad);
6591             }
6592 
6593             if (!verticalTabs)
6594                 rect = visualRect(option->direction, option->rect, rect);
6595             return rect;
6596         }
6597         break;
6598     case SE_RadioButtonIndicator:
6599         rect = visualRect(option->direction, option->rect,
6600                           ParentStyleClass::subElementRect(element, option, widget)).adjusted(0, 0, 1, 1);
6601         break;
6602     case SE_ProgressBarContents:
6603         return (opts.fillProgress ? opts.buttonEffect != EFFECT_NONE &&
6604                 opts.borderProgress ? option->rect.adjusted(1, 1, -1, -1) :
6605                 option->rect : opts.buttonEffect != EFFECT_NONE &&
6606                 opts.borderProgress ? option->rect.adjusted(3, 3, -3, -3) :
6607                 option->rect.adjusted(2, 2, -2, -2));
6608     case SE_ProgressBarGroove:
6609     case SE_ProgressBarLabel:
6610         return option->rect;
6611     case SE_GroupBoxLayoutItem:
6612         rect = option->rect;
6613 //             if (auto groupBoxOpt = styleOptCast<QStyleOptionGroupBox>(option))
6614 //                 if (groupBoxOpt->subControls & (SC_GroupBoxCheckBox | SC_GroupBoxLabel))
6615 //                     rect.setTop(rect.top() + 2);    // eat the top margin a little bit
6616         break;
6617     case SE_PushButtonFocusRect:
6618         if (oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED)) {
6619             rect = subElementRect(SE_PushButtonContents, option, widget);
6620             if (opts.buttonEffect != EFFECT_NONE) {
6621                 rect.adjust(-1, -1, 1, 1);
6622             } else {
6623                 rect.adjust(-2, -2, 2, 2);
6624             }
6625         } else {
6626             rect = ParentStyleClass::subElementRect(element, option, widget);
6627             if (opts.buttonEffect != EFFECT_NONE) {
6628                 rect.adjust(1, 1, -1, -1);
6629             }
6630         }
6631         return rect;
6632     default:
6633         return ParentStyleClass::subElementRect(element, option, widget);
6634     }
6635 
6636     return visualRect(option->direction, option->rect, rect);
6637 }
6638 
6639 QRect Style::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const
6640 {
6641     prePolish(widget);
6642     QRect r(option->rect);
6643     bool  reverse(Qt::RightToLeft==option->direction);
6644 
6645     switch (control) {
6646     case CC_ComboBox:
6647         if (auto comboBox = styleOptCast<QStyleOptionComboBox>(option)) {
6648             bool ed = comboBox->editable;
6649             bool doEtch = ((!ed || opts.etchEntry) &&
6650                            opts.buttonEffect != EFFECT_NONE);
6651             int  x(r.x()),
6652                 y(r.y()),
6653                 w(r.width()),
6654                 h(r.height());
6655 
6656             switch (subControl)
6657             {
6658             case SC_ComboBoxFrame:
6659                 if(ed)
6660                 {
6661                     int btnWidth(doEtch ? 22 : 20);
6662 
6663                     r=QRect(x+w-btnWidth, y, btnWidth, h);
6664                 }
6665                 break;
6666             case SC_ComboBoxArrow:
6667             {
6668                 int bmarg(comboBox->frame ? 2 : 0);
6669 
6670                 r.setRect(x + w - bmarg - (doEtch ? 17 : 16), y + bmarg, 16, h - 2*bmarg);
6671                 if(ed && opts.unifyCombo)
6672                     r.adjust(-1, 0, 0, 0);
6673                 break;
6674             }
6675             case SC_ComboBoxEditField:
6676             {
6677                 int margin(comboBox->frame ? 3 : 0);
6678 
6679                 r.setRect(x + margin+(opts.unifyCombo ? 0 : 2), y + margin,
6680                           w - 2 * margin - (opts.unifyCombo ? 15 : 23), h - 2 * margin);
6681                 if(doEtch)
6682                     r.adjust(ed ? 0 : 1, 1, ed ? 0 : -1, -1);
6683                 if(ed)
6684                     r.adjust(-1, -2, 1, 2);
6685                 break;
6686             }
6687             case SC_ComboBoxListBoxPopup:
6688             default:
6689                 break;
6690             }
6691             return visualRect(comboBox->direction, comboBox->rect, r);
6692         }
6693         break;
6694     case CC_SpinBox:
6695         if (auto spinbox = styleOptCast<QStyleOptionSpinBox>(option)) {
6696             QSize bs;
6697             int fw = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
6698 
6699             bs.setHeight(r.height() >> 1);
6700             if (bs.height() < 8)
6701                 bs.setHeight(8);
6702             bs.setWidth(opts.buttonEffect != EFFECT_NONE && opts.etchEntry ?
6703                         16 : 15);
6704             bs = bs.expandedTo(QApplication::globalStrut());
6705 
6706             int y = 0;
6707             int x = reverse ? (0 + fw) : (r.width() - bs.width() - fw + r.x());
6708 
6709             switch (subControl) {
6710             case SC_SpinBoxUp:
6711                 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
6712                     return QRect();
6713                 r = QRect(x, y, bs.width(), bs.height());
6714                 break;
6715             case SC_SpinBoxDown:
6716                 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
6717                     return QRect();
6718                 r = QRect(x, y + bs.height(), bs.width(),
6719                           bs.height() + (bs.height() * 2 == r.height() ? 0 : 1));
6720                 break;
6721             case SC_SpinBoxEditField: {
6722                 int pad = opts.round > ROUND_FULL ? 2 : 0;
6723                 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
6724                     r = QRect(fw, fw, (x - fw * 2) - pad, r.height() - 2 * fw);
6725                 }
6726                 else {
6727                     r = QRect(fw + (reverse ? bs.width() : 0), fw,
6728                               (x - fw * 2) - pad, r.height() - 2 * fw);
6729                 }
6730                 break;
6731             }
6732             case SC_SpinBoxFrame:
6733             default:
6734                 break;
6735             }
6736             return visualRect(spinbox->direction, spinbox->rect, r);
6737         }
6738         break;
6739     case CC_ScrollBar:
6740         if (auto scrollBar = styleOptCast<QStyleOptionSlider>(option)) {
6741             // Taken from kstyle.cpp (KDE 3) , and modified so as to allow
6742             // for no scrollbar butttons...
6743             bool  threeButtonScrollBar(SCROLLBAR_KDE==opts.scrollbarType),
6744                 platinumScrollBar(SCROLLBAR_PLATINUM==opts.scrollbarType),
6745                 nextScrollBar(SCROLLBAR_NEXT==opts.scrollbarType),
6746                 noButtons(SCROLLBAR_NONE==opts.scrollbarType);
6747             QRect ret;
6748             bool  horizontal(Qt::Horizontal==scrollBar->orientation);
6749             int   sbextent(pixelMetric(PM_ScrollBarExtent, scrollBar, widget)),
6750                 sliderMaxLength(((scrollBar->orientation == Qt::Horizontal) ?
6751                                  scrollBar->rect.width() : scrollBar->rect.height()) - (sbextent * qtcScrollbarButtonNum(opts.scrollbarType))),
6752                 sliderMinLength(pixelMetric(PM_ScrollBarSliderMin, scrollBar, widget)),
6753                 sliderLength;
6754 
6755             if (scrollBar->maximum != scrollBar->minimum)
6756             {
6757                 uint valueRange = scrollBar->maximum - scrollBar->minimum;
6758                 sliderLength = (scrollBar->pageStep * sliderMaxLength) / (valueRange + scrollBar->pageStep);
6759 
6760                 if (sliderLength < sliderMinLength || (!isOOWidget(widget) && valueRange > INT_MAX / 2))
6761                     sliderLength = sliderMinLength;
6762                 if (sliderLength > sliderMaxLength)
6763                     sliderLength = sliderMaxLength;
6764             }
6765             else
6766                 sliderLength = sliderMaxLength;
6767 
6768             int sliderstart(sliderPositionFromValue(scrollBar->minimum,
6769                                                     scrollBar->maximum,
6770                                                     scrollBar->sliderPosition,
6771                                                     sliderMaxLength - sliderLength,
6772                                                     scrollBar->upsideDown));
6773 
6774             switch(opts.scrollbarType)
6775             {
6776             case SCROLLBAR_KDE:
6777             case SCROLLBAR_WINDOWS:
6778                 sliderstart+=sbextent;
6779                 break;
6780             case SCROLLBAR_NEXT:
6781                 sliderstart+=sbextent*2;
6782             default:
6783                 break;
6784             }
6785 
6786             // Subcontrols
6787             switch(subControl)
6788             {
6789             case SC_ScrollBarSubLine:
6790                 if(noButtons)
6791                     return QRect();
6792 
6793                 // top/left button
6794                 if (platinumScrollBar)
6795                     if (horizontal)
6796                         ret.setRect(scrollBar->rect.width() - 2 * sbextent, 0, sbextent, sbextent);
6797                     else
6798                         ret.setRect(0, scrollBar->rect.height() - 2 * sbextent, sbextent, sbextent);
6799                 else if(threeButtonScrollBar)
6800                     if (horizontal)
6801                         ret.setRect(0, 0, scrollBar->rect.width() - sbextent +1, sbextent);
6802                     else
6803                         ret.setRect(0, 0, sbextent, scrollBar->rect.height() - sbextent +1);
6804                 else
6805                     ret.setRect(0, 0, sbextent, sbextent);
6806                 break;
6807             case SB_SUB2:
6808                 if(threeButtonScrollBar)
6809                     if (horizontal)
6810                         if(reverse)
6811                             ret.setRect(sbextent, 0, sbextent, sbextent);
6812                         else
6813                             ret.setRect(scrollBar->rect.width() - 2 * sbextent, 0, sbextent, sbextent);
6814                     else
6815                         ret.setRect(0, scrollBar->rect.height() - 2 * sbextent, sbextent, sbextent);
6816                 else
6817                     return QRect();
6818                 break;
6819             case SC_ScrollBarAddLine:
6820                 if(noButtons)
6821                     return QRect();
6822 
6823                 // bottom/right button
6824                 if (nextScrollBar)
6825                     if (horizontal)
6826                         ret.setRect(sbextent, 0, sbextent, sbextent);
6827                     else
6828                         ret.setRect(0, sbextent, sbextent, sbextent);
6829                 else
6830                     if (horizontal)
6831                         ret.setRect(scrollBar->rect.width() - sbextent, 0, sbextent, sbextent);
6832                     else
6833                         ret.setRect(0, scrollBar->rect.height() - sbextent, sbextent, sbextent);
6834                 break;
6835             case SC_ScrollBarSubPage:
6836                 // between top/left button and slider
6837                 if (platinumScrollBar)
6838                     if (horizontal)
6839                         ret.setRect(0, 0, sliderstart, sbextent);
6840                     else
6841                         ret.setRect(0, 0, sbextent, sliderstart);
6842                 else if (nextScrollBar)
6843                     if (horizontal)
6844                         ret.setRect(sbextent*2, 0, sliderstart-2*sbextent, sbextent);
6845                     else
6846                         ret.setRect(0, sbextent*2, sbextent, sliderstart-2*sbextent);
6847                 else
6848                     if (horizontal)
6849                         ret.setRect(noButtons ? 0 : sbextent, 0,
6850                                     noButtons ? sliderstart
6851                                     : (sliderstart - sbextent), sbextent);
6852                     else
6853                         ret.setRect(0, noButtons ? 0 : sbextent, sbextent,
6854                                     noButtons ? sliderstart : (sliderstart - sbextent));
6855                 break;
6856             case SC_ScrollBarAddPage:
6857             {
6858                 // between bottom/right button and slider
6859                 int fudge;
6860 
6861                 if (platinumScrollBar)
6862                     fudge = 0;
6863                 else if (nextScrollBar)
6864                     fudge = 2*sbextent;
6865                 else if(noButtons)
6866                     fudge = 0;
6867                 else
6868                     fudge = sbextent;
6869 
6870                 if (horizontal)
6871                     ret.setRect(sliderstart + sliderLength, 0,
6872                                 sliderMaxLength - sliderstart - sliderLength + fudge, sbextent);
6873                 else
6874                     ret.setRect(0, sliderstart + sliderLength, sbextent,
6875                                 sliderMaxLength - sliderstart - sliderLength + fudge);
6876                 break;
6877             }
6878             case SC_ScrollBarGroove:
6879                 if(noButtons)
6880                 {
6881                     if (horizontal)
6882                         ret=QRect(0, 0, scrollBar->rect.width(), scrollBar->rect.height());
6883                     else
6884                         ret=QRect(0, 0, scrollBar->rect.width(), scrollBar->rect.height());
6885                 }
6886                 else
6887                 {
6888                     int multi = threeButtonScrollBar ? 3 : 2,
6889                         fudge;
6890 
6891                     if (platinumScrollBar)
6892                         fudge = 0;
6893                     else if (nextScrollBar)
6894                         fudge = 2*sbextent;
6895                     else
6896                         fudge = sbextent;
6897 
6898                     if (horizontal)
6899                         ret=QRect(fudge, 0, scrollBar->rect.width() - sbextent * multi, scrollBar->rect.height());
6900                     else
6901                         ret=QRect(0, fudge, scrollBar->rect.width(), scrollBar->rect.height() - sbextent * multi);
6902                 }
6903                 break;
6904             case SC_ScrollBarSlider:
6905                 if (horizontal)
6906                     ret=QRect(sliderstart, 0, sliderLength, sbextent);
6907                 else
6908                     ret=QRect(0, sliderstart, sbextent, sliderLength);
6909                 break;
6910             default:
6911                 ret = ParentStyleClass::subControlRect(control, option, subControl, widget);
6912                 break;
6913             }
6914             return visualRect(scrollBar->direction/*Qt::LeftToRight*/, scrollBar->rect, ret);
6915         }
6916         break;
6917     case CC_Slider:
6918         if (auto slider = styleOptCast<QStyleOptionSlider>(option)) {
6919             if (SLIDER_TRIANGULAR == opts.sliderStyle) {
6920                 int tickSize(pixelMetric(PM_SliderTickmarkOffset, option, widget)),
6921                     mod=MO_GLOW==opts.coloredMouseOver && opts.buttonEffect != EFFECT_NONE ? 2 : 0;
6922                 QRect rect(ParentStyleClass::subControlRect(control, option, subControl, widget));
6923 
6924                 switch (subControl) {
6925                 case SC_SliderHandle:
6926                     if (slider->orientation == Qt::Horizontal) {
6927                         rect.setWidth(11 + mod);
6928                         rect.setHeight(15 + mod);
6929                         int centerY = r.center().y() - rect.height() / 2;
6930                         if (slider->tickPosition & QSlider::TicksAbove) {
6931                             centerY += tickSize;
6932                         }
6933                         if (slider->tickPosition & QSlider::TicksBelow) {
6934                             centerY -= tickSize - 1;
6935                         }
6936                         rect.moveTop(centerY);
6937                     } else {
6938                         rect.setWidth(15 + mod);
6939                         rect.setHeight(11 + mod);
6940                         int centerX = r.center().x() - rect.width() / 2;
6941                         if (slider->tickPosition & QSlider::TicksAbove) {
6942                             centerX += tickSize;
6943                         }
6944                         if (slider->tickPosition & QSlider::TicksBelow) {
6945                             centerX -= tickSize - 1;
6946                         }
6947                         rect.moveLeft(centerX);
6948                     }
6949                     break;
6950                 case SC_SliderGroove: {
6951                     QPoint grooveCenter = r.center();
6952 
6953                     if (Qt::Horizontal == slider->orientation) {
6954                         rect.setHeight(13);
6955                         --grooveCenter.ry();
6956                         if (slider->tickPosition & QSlider::TicksAbove) {
6957                             grooveCenter.ry() += tickSize + 2;
6958                         }
6959                         if (slider->tickPosition & QSlider::TicksBelow) {
6960                             grooveCenter.ry() -= tickSize - 1;
6961                         }
6962                     } else {
6963                         rect.setWidth(13);
6964                         --grooveCenter.rx();
6965                         if (slider->tickPosition & QSlider::TicksAbove) {
6966                             grooveCenter.rx() += tickSize + 2;
6967                         }
6968                         if (slider->tickPosition & QSlider::TicksBelow) {
6969                             grooveCenter.rx() -= tickSize - 1;
6970                         }
6971                     }
6972                     rect.moveCenter(grooveCenter);
6973                     break;
6974                 }
6975                 default:
6976                     break;
6977                 }
6978                 return rect;
6979             } else {
6980                 bool horizontal = Qt::Horizontal == slider->orientation;
6981                 int thickness = pixelMetric(PM_SliderControlThickness,
6982                                             slider, widget);
6983                 int tickOffset = (slider->tickPosition & QSlider::TicksAbove ||
6984                                   slider->tickPosition & QSlider::TicksBelow ?
6985                                   pixelMetric(PM_SliderTickmarkOffset, slider,
6986                                               widget) :
6987                                   ((horizontal ? r.height() :
6988                                     r.width()) - thickness) / 2);
6989 
6990                 switch (subControl) {
6991                 case SC_SliderHandle: {
6992                     int len = pixelMetric(PM_SliderLength, slider, widget);
6993                     int sliderPos =
6994                         sliderPositionFromValue(slider->minimum, slider->maximum,
6995                                                 slider->sliderPosition,
6996                                                 (horizontal ? r.width() :
6997                                                  r.height()) - len,
6998                                                 slider->upsideDown);
6999 
7000                     if (horizontal) {
7001                         r.setRect(r.x() + sliderPos, r.y() + tickOffset,
7002                                   len, thickness);
7003                     } else {
7004                         r.setRect(r.x() + tickOffset, r.y() + sliderPos,
7005                                   thickness, len);
7006                     }
7007                     break;
7008                 }
7009                 case SC_SliderGroove:
7010                     if (horizontal) {
7011                         r.setRect(r.x(), r.y() + tickOffset,
7012                                   r.width(), thickness);
7013                     } else {
7014                         r.setRect(r.x() + tickOffset, r.y(),
7015                                   thickness, r.height());
7016                     }
7017                     break;
7018                 default:
7019                     break;
7020                 }
7021                 return visualRect(slider->direction, r, r);
7022             }
7023         }
7024         break;
7025     case CC_GroupBox:
7026         if (oneOf(subControl, SC_GroupBoxCheckBox, SC_GroupBoxLabel))
7027             if (auto groupBox = styleOptCast<QStyleOptionGroupBox>(option)) {
7028                 QFont font = m_fntHelper->fontStripStyleName(widget ? widget->font() : QApplication::font());
7029                 font.setBold(opts.gbLabel & GB_LBL_BOLD);
7030                 QFontMetrics fontMetrics(font);
7031                 int h = fontMetrics.height();
7032                 int tw = fontMetrics.size(Qt::TextShowMnemonic,
7033                                           groupBox->text +
7034                                           QLatin1Char(' ')).width();
7035                 int marg = ((groupBox->features & QStyleOptionFrame::Flat) ||
7036                             qtcNoFrame(opts.groupBox) ||
7037                             opts.gbLabel & GB_LBL_OUTSIDE ? 0 :
7038                             opts.gbLabel & GB_LBL_INSIDE ? 2 : 6);
7039                 int indicatorWidth = pixelMetric(PM_IndicatorWidth,
7040                                                  option, widget);
7041                 int indicatorSpace = pixelMetric(PM_CheckBoxLabelSpacing,
7042                                                  option, widget) - 1;
7043                 bool hasCheckBox(groupBox->subControls & QStyle::SC_GroupBoxCheckBox);
7044                 int checkBoxSize(hasCheckBox ? (indicatorWidth + indicatorSpace) : 0),
7045                     checkAdjust(qtcNoFrame(opts.groupBox) ||
7046                                 opts.gbLabel & GB_LBL_OUTSIDE ? 0 : 2);
7047 
7048                 if(0==checkAdjust)
7049                     checkBoxSize-=2;
7050 
7051                 r.adjust(marg, 0, -marg, 0);
7052                 if(!qtcNoFrame(opts.groupBox) && opts.gbLabel & GB_LBL_INSIDE)
7053                     r.adjust(0, 2, 0, 2);
7054                 r.setHeight(h);
7055 
7056                 // Adjusted rect for label + indicatorWidth + indicatorSpace
7057                 Qt::Alignment align = groupBox->textAlignment;
7058                 if (opts.gbLabel & GB_LBL_CENTRED) {
7059                     align &= ~(Qt::AlignLeft | Qt::AlignRight);
7060                     align |= Qt::AlignHCenter;
7061                 }
7062                 r = alignedRect(groupBox->direction, align,
7063                                 QSize(tw + checkBoxSize, h), r);
7064 
7065                 // Adjust totalRect if checkbox is set
7066                 if (hasCheckBox) {
7067                     if (SC_GroupBoxCheckBox == subControl) {
7068                         // Adjust for check box
7069                         int indicatorHeight(pixelMetric(PM_IndicatorHeight, option, widget)),
7070                             top(r.top() + (fontMetrics.height() - indicatorHeight) / 2);
7071 
7072                         r.setRect(reverse ? (r.right() - indicatorWidth) : r.left()+checkAdjust, top, indicatorWidth, indicatorHeight);
7073                     } else {
7074                         // Adjust for label
7075                         r.setRect(reverse ? r.left() :
7076                                   (r.left() + checkBoxSize), r.top(),
7077                                   r.width() - checkBoxSize, r.height());
7078                     }
7079                 }
7080                 return r;
7081             }
7082         break;
7083     case CC_TitleBar:
7084         if (auto tb = styleOptCast<QStyleOptionTitleBar>(option)) {
7085             bool isMinimized(tb->titleBarState&Qt::WindowMinimized),
7086                 isMaximized(tb->titleBarState&Qt::WindowMaximized);
7087 
7088             if( (isMaximized && SC_TitleBarMaxButton==subControl) ||
7089                 (isMinimized && SC_TitleBarMinButton==subControl) ||
7090                 (isMinimized && SC_TitleBarShadeButton==subControl) ||
7091                 (!isMinimized && SC_TitleBarUnshadeButton==subControl))
7092                 return QRect();
7093 
7094             readMdiPositions();
7095 
7096             const int controlSize(tb->rect.height() - constWindowMargin *2);
7097             int sc = (subControl == SC_TitleBarUnshadeButton ?
7098                       SC_TitleBarShadeButton :
7099                       subControl == SC_TitleBarNormalButton ?
7100                       isMaximized ? SC_TitleBarMaxButton :
7101                       SC_TitleBarMinButton : subControl);
7102             int pos = 0;
7103             int totalLeft = 0;
7104             int totalRight = 0;
7105             bool rhs = false;
7106             bool found = false;
7107 
7108             for (int hint: const_(m_mdiButtons[0])) {
7109                 if (hint == SC_TitleBarCloseButton ||
7110                     hint == WINDOWTITLE_SPACER ||
7111                     tb->titleBarFlags & toHint(hint)) {
7112                     totalLeft += (hint == WINDOWTITLE_SPACER ?
7113                                   controlSize / 2 : controlSize);
7114                     if (hint == sc) {
7115                         found = true;
7116                     } else if (!found) {
7117                         pos += (hint == WINDOWTITLE_SPACER ?
7118                                 controlSize / 2 : controlSize);
7119                     }
7120                 }
7121             }
7122             if (!found) {
7123                 pos = 0;
7124                 rhs = true;
7125             }
7126 
7127             for (int hint: const_(m_mdiButtons[1])) {
7128                 if (hint == SC_TitleBarCloseButton ||
7129                     hint == WINDOWTITLE_SPACER ||
7130                     tb->titleBarFlags & toHint(hint)) {
7131                     if (hint != WINDOWTITLE_SPACER || totalRight) {
7132                         totalRight += (hint == WINDOWTITLE_SPACER ?
7133                                        controlSize / 2 : controlSize);
7134                     }
7135                     if (rhs) {
7136                         if (hint == sc) {
7137                             pos += controlSize;
7138                             found = true;
7139                         } else if (found) {
7140                             pos += (hint == WINDOWTITLE_SPACER ?
7141                                     controlSize / 2 : controlSize);
7142                         }
7143                     }
7144                 }
7145             }
7146 
7147             totalLeft += constWindowMargin * (totalLeft ? 2 : 1);
7148             totalRight += constWindowMargin * (totalRight ? 2 : 1);
7149 
7150             if (subControl == SC_TitleBarLabel) {
7151                 r.adjust(totalLeft, 0, -totalRight, 0);
7152             } else if (!found) {
7153                 return QRect();
7154             } else if (rhs) {
7155                 r.setRect(r.right() - (pos + constWindowMargin),
7156                           r.top() + constWindowMargin,
7157                           controlSize, controlSize);
7158             } else {
7159                 r.setRect(r.left() + constWindowMargin + pos,
7160                           r.top() + constWindowMargin,
7161                           controlSize, controlSize);
7162             }
7163             if (r.height() % 2 == 0)
7164                 r.adjust(0, 0, 1, 1);
7165             return visualRect(tb->direction, tb->rect, r);
7166         }
7167     default:
7168         break;
7169     }
7170     return ParentStyleClass::subControlRect(control, option, subControl, widget);
7171 }
7172 
7173 QStyle::SubControl
7174 Style::hitTestComplexControl(ComplexControl control,
7175                              const QStyleOptionComplex *option,
7176                              const QPoint &pos, const QWidget *widget) const
7177 {
7178     prePolish(widget);
7179     m_sbWidget = nullptr;
7180     switch (control) {
7181     case CC_ScrollBar:
7182         if (auto scrollBar = styleOptCast<QStyleOptionSlider>(option)) {
7183             if (subControlRect(control, scrollBar,
7184                                SC_ScrollBarSlider, widget).contains(pos)) {
7185                 return SC_ScrollBarSlider;
7186             }
7187             if (subControlRect(control, scrollBar,
7188                                SC_ScrollBarAddLine, widget).contains(pos)) {
7189                 return SC_ScrollBarAddLine;
7190             }
7191             if (subControlRect(control, scrollBar,
7192                                SC_ScrollBarSubPage, widget).contains(pos)) {
7193                 return SC_ScrollBarSubPage;
7194             }
7195             if (subControlRect(control, scrollBar,
7196                                SC_ScrollBarAddPage, widget).contains(pos)) {
7197                 return SC_ScrollBarAddPage;
7198             }
7199             if (subControlRect(control, scrollBar,
7200                                SC_ScrollBarSubLine, widget).contains(pos)) {
7201                 if (opts.scrollbarType == SCROLLBAR_KDE &&
7202                     subControlRect(control, scrollBar,
7203                                    SB_SUB2, widget).contains(pos)) {
7204                     m_sbWidget = widget;
7205                 }
7206                 return SC_ScrollBarSubLine;
7207             }
7208         }
7209     default:
7210         break;
7211     }
7212     return ParentStyleClass::hitTestComplexControl(control, option,  pos, widget);
7213 }
7214 
7215 }