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

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_p.h"
0024 #include <qtcurve-utils/qtprops.h>
0025 
0026 #include <QMdiSubWindow>
0027 #include <QTreeView>
0028 #include <QSpinBox>
0029 #include <QComboBox>
0030 #include <QMainWindow>
0031 #include <QListView>
0032 #include <QPixmapCache>
0033 #include <QDockWidget>
0034 #include <QGroupBox>
0035 #include <QDial>
0036 #include <QCheckBox>
0037 #include <QRadioButton>
0038 #include <QToolBar>
0039 #include <QMenuBar>
0040 
0041 #include "shadowhelper.h"
0042 #include "utils.h"
0043 #include <common/config_file.h>
0044 
0045 #ifdef QTC_QT5_ENABLE_KDE
0046 #include <KWidgetsAddons/KTitleWidget>
0047 #endif
0048 
0049 namespace QtCurve {
0050 
0051 static inline void setPainterPen(QPainter *p, const QColor &col, const qreal width=1.0)
0052 {
0053     p->setPen(QPen(col, width));
0054 }
0055 
0056 bool
0057 Style::drawPrimitiveIndicatorTabClose(PrimitiveElement,
0058                                       const QStyleOption*option,
0059                                       QPainter *painter,
0060                                       const QWidget*) const
0061 {
0062 #ifdef QTC_QT5_ENABLE_KDE
0063     int size = pixelMetric(QStyle::PM_SmallIconSize);
0064     State state = option->state;
0065     QIcon::Mode mode = (state & State_Enabled ? state & State_Raised ?
0066                         QIcon::Active : QIcon::Normal : QIcon::Disabled);
0067     if (!(state & State_Raised) && !(state & State_Sunken) &&
0068         !(state & State_Selected)) {
0069         mode = QIcon::Disabled;
0070     }
0071     drawItemPixmap(painter, option->rect, Qt::AlignCenter,
0072                    QIcon::fromTheme(QStringLiteral("dialog-close")).pixmap(size, mode,
0073                                                 state & State_Sunken ?
0074                                                 QIcon::On : QIcon::Off));
0075     return true;
0076 #else
0077     QTC_UNUSED(option);
0078     QTC_UNUSED(painter);
0079     return false;
0080 #endif
0081 }
0082 
0083 bool
0084 Style::drawPrimitiveWidget(PrimitiveElement,
0085                            const QStyleOption *option,
0086                            QPainter *painter,
0087                            const QWidget *widget) const
0088 {
0089     bool isDialog = qtcIsDialog(widget);
0090     bool isSubWindow = (widget && qobject_cast<const QMdiSubWindow*>(widget));
0091     if (widget && (widget->testAttribute(Qt::WA_NoSystemBackground) ||
0092                    !widget->testAttribute(Qt::WA_StyledBackground) ||
0093                    !(isDialog || qtcIsWindow(widget) || isSubWindow))) {
0094         // A few widgets (e.g. QDesignerWidget and Gammaray::OverlayWidget)
0095         // calls this function but we don't want to draw background for them.
0096         // Filter the ones we don't want to draw here.
0097         // TODO?: QtQuick2
0098         return true;
0099     }
0100     // TODO handle QtQuick2 better once there is update from upstream
0101     // The following is copied from Style::drawBackground in order to handle
0102     // widget == NULL, it should probably be merged back at some point.
0103     if (!isSubWindow) {
0104         painter->setCompositionMode(QPainter::CompositionMode_Source);
0105     }
0106     bool previewMdi = m_isPreview && isSubWindow;
0107     const QWidget *window = widget;
0108     if (!m_isPreview && widget) {
0109         window = widget->window();
0110     }
0111     int opacity = isDialog ? opts.dlgOpacity : opts.bgndOpacity;
0112     // Check if we are drawing on a 32-bits window, Note that we don't need
0113     // this check for QMdiSubWindow since we don't draw through the window.
0114     if (opacity != 100 &&
0115         !(isSubWindow || (widget && Utils::hasAlphaChannel(window)))) {
0116         opacity = 100;
0117     }
0118     if (widget) {
0119         QtcQWidgetProps(widget)->opacity = opacity;
0120     }
0121     QRect bgndRect = option->rect;
0122     painter->setClipRegion(option->rect, Qt::IntersectClip);
0123 
0124     if (!previewMdi) {
0125         WindowBorders borders = qtcGetWindowBorderSize(false);
0126         bgndRect.adjust(-borders.sides, -borders.titleHeight,
0127                         borders.sides, borders.bottom);
0128     } else {
0129         bgndRect.adjust(0, -pixelMetric(PM_TitleBarHeight, 0, widget), 0, 0);
0130     }
0131     drawBackground(painter, option->palette.window().color(), bgndRect,
0132                    opacity, isDialog ? BGND_DIALOG : BGND_WINDOW,
0133                    opts.bgndAppearance);
0134     // FIXME, workaround only, the non transparent part of the image will have
0135     // a different overall opacity.
0136     painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
0137     drawBackgroundImage(painter, true, opts.bgndImage.type == IMG_FILE &&
0138                         opts.bgndImage.onBorder ? bgndRect : option->rect);
0139     return true;
0140 }
0141 
0142 bool
0143 Style::drawPrimitivePanelScrollAreaCorner(PrimitiveElement,
0144                                           const QStyleOption *option,
0145                                           QPainter *painter,
0146                                           const QWidget *widget) const
0147 {
0148     // disable painting of PE_PanelScrollAreaCorner
0149     // the default implementation fills the rect with the window background
0150     // color which does not work for windows that have gradients.
0151     // ...but need to for WebView!!!
0152     if (!opts.gtkScrollViews || !qtcIsCustomBgnd(opts) ||
0153         (widget && widget->inherits("WebView"))) {
0154         painter->fillRect(option->rect,
0155                           option->palette.brush(QPalette::Window));
0156     }
0157     return true;
0158 }
0159 
0160 bool
0161 Style::drawPrimitiveIndicatorBranch(PrimitiveElement,
0162                                     const QStyleOption *option,
0163                                     QPainter *painter,
0164                                     const QWidget *widget) const
0165 {
0166     bool reverse = option->direction == Qt::RightToLeft;
0167     const QRect &r = option->rect;
0168     const QPalette &palette = option->palette;
0169     State state = option->state;
0170     int middleH = (r.x() + r.width() / 2) - 1;
0171     int middleV = r.y() + r.height() / 2;
0172     int beforeV = middleV;
0173     int afterH = middleH;
0174 #if 0
0175     int beforeH = middleH;
0176 #endif
0177     int afterV = middleV;
0178     if (state & State_Children) {
0179         QRect ar(r.x() + (r.width() - LV_SIZE - 4) / 2,
0180                  r.y() + (r.height() - LV_SIZE - 4) / 2,
0181                  LV_SIZE + 4, LV_SIZE + 4);
0182         if (opts.lvLines) {
0183             beforeV = ar.y() - 1;
0184             afterH = ar.x() + LV_SIZE + 4;
0185             afterV = ar.y() + LV_SIZE + 4;
0186 #if 0
0187             beforeH = ar.x();
0188             int lo = opts.round != ROUND_NONE ? 2 : 0;
0189 
0190             painter->setPen(palette.mid().color());
0191             painter->drawLine(ar.x() + lo, ar.y(), ar.x() + ar.width() - 1 - lo,
0192                               ar.y());
0193             painter->drawLine(ar.x() + lo, ar.y() + ar.height() - 1,
0194                               ar.x() + ar.width() - 1 - lo,
0195                               ar.y() + ar.height() - 1);
0196             painter->drawLine(ar.x(), ar.y() + lo, ar.x(),
0197                               ar.y() + ar.height() - 1 - lo);
0198             painter->drawLine(ar.x() + ar.width() - 1, ar.y() + lo,
0199                               ar.x() + ar.width() - 1,
0200                               ar.y() + ar.height() - 1 - lo);
0201             if (opts.round != ROUND_NONE) {
0202                 painter->drawPoint(ar.x() + 1, ar.y() + 1);
0203                 painter->drawPoint(ar.x() + 1, ar.y() + ar.height() - 2);
0204                 painter->drawPoint(ar.x() + ar.width() - 2, ar.y() + 1);
0205                 painter->drawPoint(ar.x() + ar.width() - 2,
0206                                    ar.y() + ar.height() - 2);
0207 
0208                 QColor col(palette.mid().color());
0209                 col.setAlphaF(0.5);
0210                 painter->setPen(col);
0211                 painter->drawLine(ar.x() + 1, ar.y() + 1, ar.x() + 2, ar.y());
0212                 painter->drawLine(ar.x() + ar.width() - 2, ar.y(),
0213                                   ar.x() + ar.width() - 1, ar.y() + 1);
0214                 painter->drawLine(ar.x() + 1, ar.y() + ar.height() - 2,
0215                                   ar.x() + 2, ar.y() + ar.height() - 1);
0216                 painter->drawLine(ar.x() + ar.width() - 2,
0217                                   ar.y() + ar.height() - 1,
0218                                   ar.x() + ar.width() - 1,
0219                                   ar.y() + ar.height() - 2);
0220             }
0221 #endif
0222         }
0223         drawArrow(painter, ar, state & State_Open ? PE_IndicatorArrowDown :
0224                   reverse ? PE_IndicatorArrowLeft :
0225                   PE_IndicatorArrowRight,
0226                   MOArrow(state, palette, QPalette::ButtonText));
0227     }
0228     const int constStep = (opts.lvLines ? 0 :
0229                            widget && qobject_cast<const QTreeView*>(widget) ?
0230                            ((QTreeView*)widget)->indentation() : 20);
0231 
0232     if (opts.lvLines) {
0233         painter->setPen(palette.mid().color());
0234         if (state & State_Item) {
0235             if (reverse) {
0236                 painter->drawLine(r.left(), middleV, afterH, middleV);
0237             } else {
0238 #if 0
0239                 if (opts.lvLines == LV_NEW) {
0240                     if (state & State_Children) {
0241                         painter->drawLine(middleH - constStep, middleV,
0242                                           r.right() - constStep, middleV);
0243                     } else {
0244                         drawFadedLine(painter,
0245                                       QRect(middleH - constStep, middleV,
0246                                             r.right() - (middleH - constStep),
0247                                             middleV), palette.mid().color(),
0248                                       false, true, true);
0249                     }
0250                 } else {
0251 #endif
0252                     painter->drawLine(afterH, middleV, r.right(), middleV);
0253 #if 0
0254                 }
0255 #endif
0256             }
0257         }
0258         if (state & State_Sibling && afterV < r.bottom()) {
0259             painter->drawLine(middleH - constStep, afterV,
0260                               middleH - constStep, r.bottom());
0261         }
0262         if (state & (State_Open | State_Children | State_Item |
0263                      State_Sibling) && beforeV > r.y()) {
0264             painter->drawLine(middleH - constStep, r.y(),
0265                               middleH - constStep, beforeV);
0266         }
0267     }
0268     return true;
0269 }
0270 
0271 bool
0272 Style::drawPrimitiveIndicatorViewItemCheck(PrimitiveElement,
0273                                            const QStyleOption *option,
0274                                            QPainter *painter,
0275                                            const QWidget *widget) const
0276 {
0277     QStyleOption opt = *option;
0278     opt.state &= ~State_MouseOver;
0279     opt.state |= STATE_VIEW;
0280     drawPrimitive(PE_IndicatorCheckBox, &opt, painter, widget);
0281     return true;
0282 }
0283 
0284 bool
0285 Style::drawPrimitiveIndicatorHeaderArrow(PrimitiveElement,
0286                                          const QStyleOption *option,
0287                                          QPainter *painter,
0288                                          const QWidget*) const
0289 {
0290     State state = option->state;
0291     const QPalette &palette = option->palette;
0292     if (auto header = styleOptCast<QStyleOptionHeader>(option)) {
0293         drawArrow(painter, option->rect,
0294                   header->sortIndicator & QStyleOptionHeader::SortUp ?
0295                   PE_IndicatorArrowUp : PE_IndicatorArrowDown,
0296                   MOArrow(state, palette, QPalette::ButtonText));
0297     }
0298     return true;
0299 }
0300 
0301 bool
0302 Style::drawPrimitiveIndicatorArrow(PrimitiveElement element,
0303                                    const QStyleOption *option,
0304                                    QPainter *painter,
0305                                    const QWidget *widget) const
0306 {
0307     State state = option->state;
0308     const QPalette &palette = option->palette;
0309     if (state == State_None) {
0310         state |= State_Enabled;
0311     }
0312     if (state == (State_Enabled | QtC_StateKWin)) {
0313         drawArrow(painter, option->rect, element, Qt::color1, false, true);
0314     } else {
0315         QRect r = option->rect;
0316         QColor col = MOArrow(state, palette, QPalette::Text);
0317         if (state & (State_Sunken | State_On) &&
0318             !(widget &&
0319               ((opts.unifySpin && qobject_cast<const QSpinBox*>(widget)) ||
0320                (opts.unifyCombo && qobject_cast<const QComboBox*>(widget) &&
0321                 static_cast<const QComboBox*>(widget)->isEditable())))) {
0322             r.adjust(1, 1, 1, 1);
0323         }
0324         if (col.alpha() < 255 && element == PE_IndicatorArrowRight &&
0325             widget && widget->inherits("KUrlButton")) {
0326             col = blendColors(col, palette.window().color(), col.alphaF());
0327         }
0328         drawArrow(painter, r, element, col, false, false);
0329     }
0330     return true;
0331 }
0332 
0333 bool
0334 Style::drawPrimitiveIndicatorSpin(PrimitiveElement element,
0335                                   const QStyleOption *option,
0336                                   QPainter *painter,
0337                                   const QWidget *widget) const
0338 {
0339     const QRect &r = option->rect;
0340     const QPalette &palette = option->palette;
0341     State state = option->state;
0342     QRect sr = r;
0343     const QColor *use = buttonColors(option);
0344     const QColor &col = MOArrow(state, palette, QPalette::ButtonText);
0345     bool down = oneOf(element, PE_IndicatorSpinDown, PE_IndicatorSpinMinus);
0346     bool reverse = option->direction == Qt::RightToLeft;
0347 
0348     if ((!opts.unifySpinBtns || state & State_Sunken) && !opts.unifySpin) {
0349         drawLightBevel(painter, sr, option, widget, down ? reverse ?
0350                        ROUNDED_BOTTOMLEFT : ROUNDED_BOTTOMRIGHT : reverse ?
0351                        ROUNDED_TOPLEFT : ROUNDED_TOPRIGHT,
0352                        getFill(option, use), use, true, WIDGET_SPIN);
0353     }
0354     if (oneOf(element, PE_IndicatorSpinUp, PE_IndicatorSpinDown)) {
0355         sr.setY(sr.y() + (down ? -2 : 1));
0356         if (opts.unifySpin) {
0357             sr.adjust(reverse ? 1 : -1, 0, reverse ? 1 : -1, 0);
0358             if (!opts.vArrows) {
0359                 sr.setY(sr.y() + (down ? -2 : 2));
0360             }
0361         } else if (state & State_Sunken) {
0362             sr.adjust(1, 1, 1, 1);
0363         }
0364         drawArrow(painter, sr, element == PE_IndicatorSpinUp ?
0365                   PE_IndicatorArrowUp : PE_IndicatorArrowDown,
0366                   col, !opts.unifySpin);
0367     } else {
0368         int l = qMin(r.width() - 6, r.height() - 6);
0369         QPoint c(r.x() + r.width() / 2, r.y() + r.height() / 2);
0370         l /= 2;
0371         if (l % 2 != 0) {
0372             --l;
0373         }
0374         if (state & State_Sunken && !opts.unifySpin) {
0375             c += QPoint(1, 1);
0376         }
0377         painter->setPen(col);
0378         painter->drawLine(c.x() - l, c.y(), c.x() + l, c.y());
0379         if (!down) {
0380             painter->drawLine(c.x(), c.y() - l, c.x(), c.y() + l);
0381         }
0382     }
0383     return true;
0384 }
0385 
0386 bool
0387 Style::drawPrimitiveIndicatorToolBarSeparator(PrimitiveElement,
0388                                               const QStyleOption *option,
0389                                               QPainter *painter,
0390                                               const QWidget*) const
0391 {
0392     const QRect &r = option->rect;
0393     State state = option->state;
0394     switch (opts.toolbarSeparators) {
0395     case LINE_NONE:
0396         break;
0397     case LINE_FLAT:
0398     case LINE_SUNKEN:
0399         if (r.width() < r.height()) {
0400             int x = r.x() + (r.width() - 2) / 2;
0401             drawFadedLine(painter, QRect(x, r.y() + TOOLBAR_SEP_GAP, 1,
0402                                          r.height() - TOOLBAR_SEP_GAP * 2),
0403                           m_backgroundCols[opts.toolbarSeparators ==
0404                                             LINE_SUNKEN ? 3 : 4],
0405                           true, true, false);
0406 
0407             if (opts.toolbarSeparators == LINE_SUNKEN) {
0408                 drawFadedLine(painter, QRect(x + 1, r.y() + 6, 1,
0409                                              r.height() - 12),
0410                               m_backgroundCols[0], true, true, false);
0411             }
0412         } else {
0413             int y = r.y() + (r.height() - 2) / 2;
0414             drawFadedLine(painter, QRect(r.x() + TOOLBAR_SEP_GAP, y,
0415                                          r.width() - TOOLBAR_SEP_GAP * 2, 1),
0416                           m_backgroundCols[opts.toolbarSeparators ==
0417                                             LINE_SUNKEN ? 3 : 4],
0418                           true, true, true);
0419             if (opts.toolbarSeparators == LINE_SUNKEN) {
0420                 drawFadedLine(painter,
0421                               QRect(r.x() + TOOLBAR_SEP_GAP, y + 1,
0422                                     r.width() - TOOLBAR_SEP_GAP * 2, 1),
0423                               m_backgroundCols[0], true, true, true);
0424             }
0425         }
0426         break;
0427     default:
0428     case LINE_DOTS:
0429         drawDots(painter, r, !(state & State_Horizontal), 1, 5,
0430                  m_backgroundCols, 0, 5);
0431     }
0432     return true;
0433 }
0434 
0435 bool
0436 Style::drawPrimitiveFrameGroupBox(PrimitiveElement,
0437                                   const QStyleOption *option,
0438                                   QPainter *painter,
0439                                   const QWidget *widget) const
0440 {
0441     if (opts.groupBox == FRAME_NONE) {
0442         return true;
0443     }
0444     if (auto _frame = styleOptCast<QStyleOptionFrame>(option)) {
0445         bool reverse = option->direction == Qt::RightToLeft;
0446         QStyleOptionFrame frame(*_frame);
0447         if (frame.features & QStyleOptionFrame::Flat ||
0448             opts.groupBox == FRAME_LINE) {
0449             const QRect &r = option->rect;
0450             drawFadedLine(painter, QRect(r.x(), r.y(), r.width(), 1),
0451                           backgroundColors(option)[QTC_STD_BORDER],
0452                           opts.gbLabel & GB_LBL_CENTRED || reverse,
0453                           opts.gbLabel & GB_LBL_CENTRED || !reverse, true);
0454         } else {
0455             QRect r = option->rect;
0456             if (opts.gbLabel & GB_LBL_OUTSIDE) {
0457                 r.adjust(0, 2, 0, 0);
0458             }
0459             if (oneOf(opts.groupBox, FRAME_SHADED, FRAME_FADED)) {
0460                 int round = (opts.square & SQUARE_FRAME ?
0461                              ROUNDED_NONE : ROUNDED_ALL);
0462                 QPainterPath path =
0463                     buildPath(r, WIDGET_FRAME, round,
0464                               round == ROUNDED_ALL ?
0465                               qtcGetRadius(&opts, r.width(), r.height(),
0466                                            WIDGET_FRAME,
0467                                            RADIUS_EXTERNAL) : 0.0);
0468                 painter->save();
0469                 painter->setClipping(false);
0470                 if (opts.gbFactor != 0) {
0471                     QColor col = opts.gbFactor < 0 ? Qt::black : Qt::white;
0472 
0473                     col.setAlphaF(TO_ALPHA(opts.gbFactor));
0474                     if (opts.groupBox == FRAME_SHADED) {
0475                         painter->fillPath(path, col);
0476                     } else {
0477                         QLinearGradient grad(r.topLeft(), r.bottomLeft());
0478                         grad.setColorAt(0, col);
0479                         col.setAlphaF(0.0);
0480                         grad.setColorAt(1, col);
0481                         painter->fillPath(path, grad);
0482                     }
0483                 }
0484 
0485                 if (!(opts.gbLabel & (GB_LBL_INSIDE | GB_LBL_OUTSIDE))) {
0486                     painter->restore();
0487                 }
0488                 if (opts.groupBox == FRAME_SHADED) {
0489                     drawBorder(painter, r, option, round,
0490                                backgroundColors(option), WIDGET_FRAME,
0491                                /* state & State_Raised && opts.gbFactor < 0 ?
0492                                   BORDER_RAISED : */BORDER_SUNKEN);
0493                 } else {
0494                     QColor col = backgroundColors(option)[QTC_STD_BORDER];
0495                     QLinearGradient grad(r.topLeft(), r.bottomLeft());
0496                     col.setAlphaF(1.0);
0497                     grad.setColorAt(0, col);
0498                     col.setAlphaF(0.0);
0499                     grad.setColorAt(1, col);
0500                     painter->setRenderHint(QPainter::Antialiasing, true);
0501                     painter->setPen(QPen(QBrush(grad), QPENWIDTH1));
0502                     painter->drawPath(path);
0503                 }
0504                 if (opts.gbLabel & (GB_LBL_INSIDE | GB_LBL_OUTSIDE)) {
0505                     painter->restore();
0506                 }
0507             } else {
0508                 frame.state &= ~(State_Sunken | State_HasFocus);
0509                 frame.rect = r;
0510                 drawPrimitive(PE_Frame, &frame, painter, widget);
0511             }
0512         }
0513     }
0514     return true;
0515 }
0516 
0517 bool
0518 Style::drawPrimitiveFrame(PrimitiveElement,
0519                           const QStyleOption *option, QPainter *painter,
0520                           const QWidget *widget) const
0521 {
0522     QRect r = option->rect;
0523     const QPalette &palette(option->palette);
0524     State state = option->state;
0525 
0526     // Dont draw OO.o status bar frames...
0527     if (isOOWidget(widget) && r.height() < 22) {
0528         return true;
0529     }
0530     if (widget && qtcCheckKDEType(widget->parent(), KTitleWidget)) {
0531         return true;
0532     } else if (widget && qtcCheckType<QComboBox>(widget->parent())) {
0533         if (opts.gtkComboMenus &&
0534             !((QComboBox*)(widget->parent()))->isEditable()) {
0535             drawPrimitive(PE_FrameMenu, option, painter, widget);
0536         } else if (opts.square & SQUARE_POPUP_MENUS) {
0537             const QColor *use = (theThemedApp == APP_KRUNNER ?
0538                                  m_backgroundCols : backgroundColors(option));
0539             painter->setPen(use[QTC_STD_BORDER]);
0540             drawRect(painter, r);
0541             painter->setPen(palette.base().color());
0542             drawRect(painter, r.adjusted(1, 1, -1, -1));
0543         }
0544     } else {
0545         auto fo = styleOptCast<QStyleOptionFrame>(option);
0546         if (theThemedApp == APP_K3B &&
0547             !(state & (State_Sunken | State_Raised)) &&
0548             fo && fo->lineWidth == 1) {
0549             painter->setPen(backgroundColors(option)[QTC_STD_BORDER]);
0550             drawRect(painter, r);
0551         } else if (oneOf(state, QtC_StateKWin,
0552                          QtC_StateKWin | State_Active) && fo &&
0553                    fo->lineWidth == 1 && fo->midLineWidth == 1) {
0554             QColor border;
0555             if (fo->version == TBAR_BORDER_VERSION_HACK + 2) {
0556                 border = palette.color(QPalette::Active, QPalette::Shadow);
0557             } else {
0558                 const QColor *borderCols =
0559                     (opts.windowBorder & WINDOW_BORDER_COLOR_TITLEBAR_ONLY ?
0560                      backgroundColors(palette.color(QPalette::Active,
0561                                                     QPalette::Window)) :
0562                      theThemedApp == APP_KWIN ? buttonColors(option) :
0563                      getMdiColors(option, state & State_Active));
0564                 border = borderCols[fo->version == TBAR_BORDER_VERSION_HACK ?
0565                                     0 : QTC_STD_BORDER];
0566             }
0567             border.setAlphaF(1.0);
0568             QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
0569             painter->setPen(border);
0570             drawRect(painter, r);
0571         } else {
0572             bool kateView = isKateView(widget);
0573             bool kontactPreview = !kateView && isKontactPreviewPane(widget);
0574             bool sv = (isOOWidget(widget) ||
0575                        qobject_cast<const QAbstractScrollArea*>(widget) ||
0576                        ((opts.square & SQUARE_SCROLLVIEW) &&
0577                         (kateView || kontactPreview)));
0578             bool squareSv = (sv && ((opts.square & SQUARE_SCROLLVIEW) ||
0579                                     (widget && widget->isWindow())));
0580             bool inQAbstractItemView =
0581                 (widget && widget->parentWidget() &&
0582                  isInQAbstractItemView(widget->parentWidget()));
0583 
0584             if (sv && (opts.etchEntry || squareSv || isOOWidget(widget))) {
0585                 QtcQWidgetProps props(widget);
0586                 // For some reason, in KPackageKit, the KTextBrower when
0587                 // polished is not in the scrollview, but is when painted.
0588                 // So check here if it should not be etched.
0589                 // Also, see not in getLowerEtchCol()
0590                 if (opts.buttonEffect != EFFECT_NONE &&
0591                     !USE_CUSTOM_ALPHAS(opts) && widget &&
0592                     widget->parentWidget() && !props->noEtch &&
0593                     inQAbstractItemView) {
0594                     props->noEtch = true;
0595                 }
0596                 // If we are set to have sunken scrollviews, then the frame
0597                 // width is set to 3. ...but it we are a scrollview within
0598                 // a scrollview, then we dont draw sunken, therefore
0599                 // need to draw inner border...
0600                 bool doEtch = (opts.buttonEffect != EFFECT_NONE &&
0601                                opts.etchEntry);
0602                 bool noEtchW = (doEtch && !USE_CUSTOM_ALPHAS(opts) &&
0603                                 props->noEtch);
0604                 if (doEtch && noEtchW) {
0605                     painter->setPen(palette.brush(QPalette::Base).color());
0606                     drawRect(painter, r.adjusted(2, 2, -2, -2));
0607                 }
0608                 if (!opts.highlightScrollViews && fo) {
0609                     QStyleOptionFrame opt(*fo);
0610                     opt.state &= ~State_HasFocus;
0611                     drawEntryField(painter, r, widget, &opt,
0612                                    squareSv ? ROUNDED_NONE : ROUNDED_ALL,
0613                                    false, doEtch && !noEtchW,
0614                                    WIDGET_SCROLLVIEW);
0615                 } else {
0616                     drawEntryField(painter, r, widget, option,
0617                                    squareSv ? ROUNDED_NONE : ROUNDED_ALL, false,
0618                                    doEtch && !noEtchW, WIDGET_SCROLLVIEW);
0619                 }
0620             }
0621             // K3b's Disk usage status bar, etc...
0622             // else if (APP_K3B == theThemedApp && widget &&
0623             //          widget->inherits("K3b::FillStatusDisplay"))
0624             else if (fo && fo->lineWidth > 0) {
0625                 bool kwinTab = (theThemedApp == APP_KWIN && widget &&
0626                                 !widget->parentWidget() &&
0627                                 !strcmp(widget->metaObject()->className(),
0628                                         "KWin::TabBox"));
0629                 QStyleOption opt = *option;
0630                 if (kwinTab) {
0631                     r.adjust(-1, -1, 1, 1);
0632                 }
0633                 if (!opts.highlightScrollViews) {
0634                     opt.state &= ~State_HasFocus;
0635                 }
0636                 if (opts.round && qtcIsFlatBgnd(opts.bgndAppearance) &&
0637                     opts.bgndOpacity == 100 && widget &&
0638                     widget->parentWidget() && !inQAbstractItemView // &&
0639                     // widget->palette().window().color() !=
0640                     // widget->parentWidget()->palette().window().color()
0641                     ) {
0642                     painter->setPen(widget->parentWidget()->palette()
0643                                     .window().color());
0644                     painter->drawRect(r);
0645                     painter->drawRect(r.adjusted(1, 1, -1, -1));
0646                 }
0647                 if (sv || kateView || kontactPreview) {
0648                     painter->setRenderHint(QPainter::Antialiasing, true);
0649                     painter->setPen(
0650                         option->palette.brush(
0651                             opts.thin & THIN_FRAMES &&
0652                             !(opts.square & SQUARE_SCROLLVIEW) ?
0653                             QPalette::Window : QPalette::Base).color());
0654                     painter->drawPath(
0655                         buildPath(r.adjusted(1, 1, -1, -1),
0656                                   WIDGET_SCROLLVIEW, ROUNDED_ALL,
0657                                   qtcGetRadius(&opts, r.width() - 2,
0658                                                r.height() - 2,
0659                                                WIDGET_SCROLLVIEW,
0660                                                RADIUS_INTERNAL)));
0661                     QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
0662                 }
0663                 drawBorder(painter, r, &opt,
0664                            opts.round ? getFrameRound(widget) : ROUND_NONE,
0665                            backgroundColors(option),
0666                            sv || kateView || kontactPreview ?
0667                            WIDGET_SCROLLVIEW : WIDGET_FRAME,
0668                            state & State_Sunken || state & State_HasFocus ?
0669                            BORDER_SUNKEN : state & State_Raised ? BORDER_RAISED :
0670                            BORDER_FLAT);
0671             }
0672         }
0673     }
0674     return true;
0675 }
0676 
0677 bool
0678 Style::drawPrimitivePanelMenuBar(PrimitiveElement,
0679                                  const QStyleOption *option,
0680                                  QPainter *painter,
0681                                  const QWidget *widget) const
0682 {
0683     const QRect &r = option->rect;
0684     if (widget && widget->parentWidget() &&
0685         qobject_cast<const QMainWindow*>(widget->parentWidget())) {
0686         drawMenuOrToolBarBackground(widget, painter, r, option);
0687         if (opts.toolbarBorders != TB_NONE) {
0688             const QColor *use = (m_active ? m_menubarCols :
0689                                  backgroundColors(option));
0690             bool dark = oneOf(opts.toolbarBorders, TB_DARK, TB_DARK_ALL);
0691             if (oneOf(opts.toolbarBorders, TB_DARK_ALL, TB_LIGHT_ALL)) {
0692                 painter->setPen(use[0]);
0693                 painter->drawLine(r.x(), r.y(), r.x() + r.width() - 1, r.y());
0694                 painter->drawLine(r.x(), r.y(), r.x(), r.y() + r.height() - 1);
0695                 painter->setPen(use[dark ? 3 : 4]);
0696                 painter->drawLine(r.x(), r.y() + r.height() - 1,
0697                                   r.x() + r.width() - 1,
0698                                   r.y() + r.height() - 1);
0699                 painter->drawLine(r.x() + r.width() - 1, r.y(),
0700                                   r.x() + r.width() - 1,
0701                                   r.y() + r.height() - 1);
0702             } else {
0703                 painter->setPen(use[dark ? 3 : 4]);
0704                 painter->drawLine(r.x(), r.y() + r.height() - 1,
0705                                   r.x() + r.width() - 1,
0706                                   r.y() + r.height() - 1);
0707             }
0708         }
0709     }
0710     return true;
0711 }
0712 
0713 bool
0714 Style::drawPrimitivePanelTipLabel(PrimitiveElement,
0715                                   const QStyleOption *option,
0716                                   QPainter *painter,
0717                                   const QWidget *widget) const
0718 {
0719     const QRect &r = option->rect;
0720     const QPalette &palette(option->palette);
0721     bool haveAlpha = Utils::hasAlphaChannel(widget);
0722     bool rounded = !(opts.square & SQUARE_TOOLTIPS);
0723     QPainterPath path =
0724         (rounded ? buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL,
0725                              opts.round >= ROUND_FULL ? 5.0 : 2.5) :
0726          QPainterPath());
0727     QColor col = palette.toolTipBase().color();
0728 
0729     if (widget && widget->window()) {
0730         m_shadowHelper->registerWidget(widget->window());
0731     }
0732     if (rounded) {
0733         painter->setRenderHint(QPainter::Antialiasing, true);
0734     }
0735     if (haveAlpha) {
0736         col.setAlphaF(0.875);
0737     }
0738     drawBevelGradient(col, painter, r, path, true, false,
0739                       opts.tooltipAppearance, WIDGET_TOOLTIP, !haveAlpha);
0740     if (qtcIsFlat(opts.tooltipAppearance)) {
0741         painter->setPen(QPen(palette.toolTipText(), 0));
0742         drawRect(painter, r);
0743     }
0744     return true;
0745 }
0746 
0747 bool
0748 Style::drawPrimitiveQtcBackground(PrimitiveElement,
0749                                   const QStyleOption *option,
0750                                   QPainter *painter,
0751                                   const QWidget*) const
0752 {
0753     const QRect &r = option->rect;
0754     const QPalette &palette(option->palette);
0755     State state = option->state;
0756     if (auto bgnd = styleOptCast<BgndOption>(option)) {
0757         if (state & QtC_StateKWin) {
0758             QColor col(palette.brush(QPalette::Window).color());
0759             int opacity(col.alphaF() * 100);
0760             col.setAlphaF(1.0);
0761             drawBackground(painter, col, r, opacity, BGND_WINDOW,
0762                            bgnd->app, bgnd->path);
0763             // APPEARANCE_RAISED is used to signal flat background,
0764             // but have background image!
0765             if (bgnd->app != APPEARANCE_FLAT) {
0766                 painter->setClipRect(bgnd->rect, Qt::IntersectClip);
0767                 drawBackgroundImage(painter, true,
0768                                     (opts.bgndImage.type == IMG_FILE &&
0769                                      opts.bgndImage.onBorder) ? bgnd->rect :
0770                                     bgnd->widgetRect);
0771             }
0772         }
0773     }
0774     return true;
0775 }
0776 
0777 bool
0778 Style::drawPrimitivePanelItemViewItem(PrimitiveElement,
0779                                       const QStyleOption *option,
0780                                       QPainter *painter,
0781                                       const QWidget *widget) const
0782 {
0783     auto opt = styleOptCast<QStyleOptionViewItem>(option);
0784     auto view = qobject_cast<const QAbstractItemView*>(widget);
0785     QRect r = option->rect;
0786     const QPalette &palette(option->palette);
0787     State state = option->state;
0788     bool reverse = option->direction == Qt::RightToLeft;
0789     bool hover = (state & State_MouseOver && state & State_Enabled &&
0790                   (!view ||
0791                    view->selectionMode() != QAbstractItemView::NoSelection));
0792     bool hasCustomBackground = (opt->backgroundBrush.style() != Qt::NoBrush &&
0793                                 !(option->state & State_Selected));
0794     bool hasSolidBackground =
0795         (!hasCustomBackground ||
0796          opt->backgroundBrush.style() == Qt::SolidPattern);
0797     if (!hover && !(state & State_Selected) && !hasCustomBackground &&
0798         !(opt->features & QStyleOptionViewItem::Alternate)) {
0799         return true;
0800     }
0801     QPalette::ColorGroup cg(state & State_Enabled ? state & State_Active ?
0802                             QPalette::Normal : QPalette::Inactive :
0803                             QPalette::Disabled);
0804     if (opt && (opt->features & QStyleOptionViewItem::Alternate)) {
0805         painter->fillRect(r, option->palette.brush(cg,
0806                                                    QPalette::AlternateBase));
0807     }
0808     if (!hover && !(state & State_Selected) && !hasCustomBackground) {
0809         return true;
0810     }
0811     if (hasCustomBackground) {
0812         painter->save();
0813         painter->setBrushOrigin(r.topLeft());
0814         painter->fillRect(r, opt->backgroundBrush);
0815         painter->restore();
0816     }
0817     if (state & State_Selected || hover) {
0818         if (!widget) {
0819             widget = getWidget(painter);
0820             if (widget) {
0821                 widget = widget->parentWidget();
0822             }
0823         }
0824         QColor color = (hasCustomBackground && hasSolidBackground ?
0825                         opt->backgroundBrush.color() :
0826                         palette.color(cg, QPalette::Highlight));
0827         bool square = ((opts.square & SQUARE_LISTVIEW_SELECTION) &&
0828                        ((widget && !widget->inherits("KFilePlacesView") &&
0829                          (qobject_cast<const QTreeView*>(widget) ||
0830                           (qobject_cast<const QListView*>(widget) &&
0831                            ((const QListView*)widget)->viewMode() !=
0832                            QListView::IconMode)))));
0833         bool modAlpha = (!(state & State_Active) &&
0834                          m_inactiveChangeSelectionColor);
0835         if (hover && !hasCustomBackground) {
0836             if (!(state & State_Selected)) {
0837                 color.setAlphaF(theThemedApp == APP_PLASMA && !widget ?
0838                                 0.5 * (modAlpha ? 0.75 : 1.0) : 0.20);
0839             } else {
0840                 color = color.lighter(110);
0841                 if (modAlpha) {
0842                     color.setAlphaF(INACTIVE_SEL_ALPHA);
0843                 }
0844             }
0845         } else if (modAlpha) {
0846             color.setAlphaF(color.alphaF() * INACTIVE_SEL_ALPHA);
0847         }
0848         if (square) {
0849             drawBevelGradient(color, painter, r, true, false,
0850                               opts.selectionAppearance, WIDGET_SELECTION);
0851         } else {
0852             QPixmap pix;
0853             QString key = QStringLiteral("qtc-sel-%1-%2")
0854                 .arg(r.height(), 0, 16)
0855                 .arg(color.rgba(), 0, 16);
0856             if (!m_usePixmapCache || !QPixmapCache::find(key, &pix)) {
0857                 pix = QPixmap(QSize(24, r.height()));
0858                 pix.fill(Qt::transparent);
0859                 QPainter pixPainter(&pix);
0860                 QRect border(0, 0, pix.width(), pix.height());
0861                 double radius(qtcGetRadius(&opts, r.width(), r.height(),
0862                                            WIDGET_OTHER, RADIUS_SELECTION));
0863                 pixPainter.setRenderHint(QPainter::Antialiasing, true);
0864                 drawBevelGradient(color, &pixPainter, border,
0865                                   buildPath(QRectF(border), WIDGET_OTHER,
0866                                             ROUNDED_ALL, radius), true,
0867                                   false, opts.selectionAppearance,
0868                                   WIDGET_SELECTION, false);
0869                 if (opts.borderSelection) {
0870                     pixPainter.setBrush(Qt::NoBrush);
0871                     pixPainter.setPen(color);
0872                     pixPainter.drawPath(buildPath(border, WIDGET_SELECTION,
0873                                                   ROUNDED_ALL, radius));
0874                 }
0875                 pixPainter.end();
0876                 if (m_usePixmapCache) {
0877                     QPixmapCache::insert(key, pix);
0878                 }
0879             }
0880             bool roundedLeft = false;
0881             bool roundedRight = false;
0882             if (opt) {
0883                 roundedLeft = (opt->viewItemPosition ==
0884                                QStyleOptionViewItem::Beginning);
0885                 roundedRight = (opt->viewItemPosition ==
0886                                 QStyleOptionViewItem::End);
0887                 if (oneOf(opt->viewItemPosition,
0888                           QStyleOptionViewItem::OnlyOne,
0889                           QStyleOptionViewItem::Invalid) ||
0890                     (view && (view->selectionBehavior() !=
0891                               QAbstractItemView::SelectRows))) {
0892                     roundedLeft = roundedRight = true;
0893                 }
0894             }
0895             int size = (roundedLeft && roundedRight ?
0896                         qMin(8, r.width() / 2) : 8);
0897             if (!reverse ? roundedLeft : roundedRight) {
0898                 painter->drawPixmap(r.topLeft(), pix.copy(0, 0, size,
0899                                                           r.height()));
0900                 r.adjust(size, 0, 0, 0);
0901             }
0902             if (!reverse ? roundedRight : roundedLeft) {
0903                 painter->drawPixmap(r.right() - size + 1, r.top(),
0904                                     pix.copy(24 - size, 0, size, r.height()));
0905                 r.adjust(0, 0, -size, 0);
0906             }
0907             if (r.isValid()) {
0908                 painter->drawTiledPixmap(r, pix.copy(7, 0, 8, r.height()));
0909             }
0910         }
0911     }
0912     return true;
0913 }
0914 
0915 bool
0916 Style::drawPrimitiveFrameTabWidget(PrimitiveElement,
0917                                    const QStyleOption *option,
0918                                    QPainter *painter,
0919                                    const QWidget *widget) const
0920 {
0921     const QRect &r = option->rect;
0922     bool reverse = option->direction == Qt::RightToLeft;
0923     int round = opts.square & SQUARE_TAB_FRAME ? ROUNDED_NONE : ROUNDED_ALL;
0924 
0925     if (auto twf = styleOptCast<QStyleOptionTabWidgetFrame>(option)) {
0926         if ((opts.round || opts.tabBgnd == 0) &&
0927             widget && qobject_cast<const QTabWidget*>(widget)) {
0928             struct QtcTabWidget: public QTabWidget {
0929                 bool
0930                 tabsVisible() const
0931                 {
0932                     return tabBar() && tabBar()->isVisible();
0933                 }
0934                 QRect
0935                 currentTabRect() const
0936                 {
0937                     return tabBar()->tabRect(tabBar()->currentIndex());
0938                 }
0939             };
0940             const QTabWidget *tw = (const QTabWidget*)widget;
0941             if (tw->count() > 0 &&
0942                 ((const QtcTabWidget*)widget)->tabsVisible()) {
0943                 if (!reverse && opts.tabBgnd == 0) {
0944                     // Does not work for reverse :-(
0945                     QRect tabRect =
0946                         ((const QtcTabWidget*)widget)->currentTabRect();
0947                     int adjust = (opts.tabMouseOver == TAB_MO_GLOW &&
0948                                   !(opts.thin & THIN_FRAMES) ? 2 : 1);
0949                     switch (tw->tabPosition()) {
0950                     case QTabWidget::South:
0951                         tabRect = QRect(tabRect.x() + adjust,
0952                                         r.y() + r.height() - 2,
0953                                         tabRect.width() - 2 * adjust, 4);
0954                         break;
0955                     case QTabWidget::North: {
0956                         int leftAdjust =
0957                             qtcMax(twf->leftCornerWidgetSize.width(), 0);
0958                         tabRect.adjust(leftAdjust + adjust, 0,
0959                                        leftAdjust - adjust, 2);
0960                         break;
0961                     }
0962                     case QTabWidget::West:
0963                         tabRect.adjust(0, adjust, 2, -adjust);
0964                         break;
0965                     case QTabWidget::East:
0966                         tabRect = QRect(r.x() + r.width() - 2,
0967                                         tabRect.y() + adjust, 4,
0968                                         tabRect.height() - 2 * adjust);
0969                         break;
0970                     }
0971                     painter->setClipRegion(QRegion(r).subtracted(tabRect),
0972                                            Qt::IntersectClip);
0973                 }
0974                 if (!(opts.square & SQUARE_TAB_FRAME) &&
0975                     tw->currentIndex() == 0) {
0976                     bool reverse = twf->direction == Qt::RightToLeft;
0977                     switch (tw->tabPosition()) {
0978                     case QTabWidget::North:
0979                         if (reverse && twf->rightCornerWidgetSize.isEmpty()) {
0980                             round -= CORNER_TR;
0981                         } else if (!reverse &&
0982                                    twf->leftCornerWidgetSize.isEmpty()) {
0983                             round -= CORNER_TL;
0984                         }
0985                         break;
0986                     case QTabWidget::South:
0987                         if (reverse && twf->rightCornerWidgetSize.isEmpty()) {
0988                             round -= CORNER_BR;
0989                         } else if (!reverse &&
0990                                    twf->leftCornerWidgetSize.isEmpty()) {
0991                             round -= CORNER_BL;
0992                         }
0993                         break;
0994                     case QTabWidget::West:
0995                         round -= CORNER_TL;
0996                         break;
0997                     case QTabWidget::East:
0998                         round -= CORNER_TR;
0999                         break;
1000                     }
1001                 }
1002             }
1003         }
1004     }
1005 
1006     QStyleOption opt(*option);
1007     const QColor *use = backgroundColors(option);
1008 
1009     opt.state |= State_Enabled;
1010     if (opts.tabBgnd != 0) {
1011         QColor bgnd(shade(use[ORIGINAL_SHADE], TO_FACTOR(opts.tabBgnd)));
1012         painter->fillRect(r.adjusted(0, 1, 0, -1), bgnd);
1013         painter->fillRect(r.adjusted(1, 0, -1, 0), bgnd);
1014     }
1015     drawBorder(painter, r, &opt, round, use, WIDGET_TAB_FRAME,
1016                opts.borderTab ? BORDER_LIGHT : BORDER_RAISED, false);
1017     return true;
1018 }
1019 
1020 bool
1021 Style::drawPrimitiveFrameWindow(PrimitiveElement,
1022                                 const QStyleOption *option,
1023                                 QPainter *painter,
1024                                 const QWidget*) const
1025 {
1026     const QRect &r = option->rect;
1027     State state = option->state;
1028     const QPalette &palette(option->palette);
1029     bool colTbarOnly = opts.windowBorder & WINDOW_BORDER_COLOR_TITLEBAR_ONLY;
1030     bool fillBgnd = (!(state & QtC_StateKWin) && !m_isPreview &&
1031                      !qtcIsFlatBgnd(opts.bgndAppearance));
1032     const QColor *bgndCols =
1033         (colTbarOnly || fillBgnd ?
1034          backgroundColors(palette.color(QPalette::Active,
1035                                         QPalette::Window)) : 0L);
1036     const QColor *borderCols = (colTbarOnly ? bgndCols :
1037                                 theThemedApp == APP_KWIN ?
1038                                 buttonColors(option) :
1039                                 getMdiColors(option, state & State_Active));
1040     QColor light = borderCols[0];
1041     QColor dark = (option->version == TBAR_BORDER_VERSION_HACK + 2 ?
1042                    palette.color(QPalette::Active, QPalette::Shadow) :
1043                    borderCols[option &&
1044                               option->version == TBAR_BORDER_VERSION_HACK ?
1045                               0 : QTC_STD_BORDER]);
1046     bool isKWin = (theThemedApp == APP_KWIN || (state & QtC_StateKWin));
1047     bool addLight = (opts.windowBorder & WINDOW_BORDER_ADD_LIGHT_BORDER &&
1048                      (!isKWin || qtcGetWindowBorderSize(false).sides > 1));
1049     light.setAlphaF(1.0);
1050     dark.setAlphaF(1.0);
1051     if (fillBgnd) {
1052         painter->fillRect(r, bgndCols[ORIGINAL_SHADE]);
1053     }
1054     if (opts.round < ROUND_SLIGHT || !isKWin ||
1055         (state & QtC_StateKWinNotFull && state & QtC_StateKWin)) {
1056         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
1057         if (addLight) {
1058             painter->setPen(light);
1059             painter->drawLine(r.x() + 1, r.y(), r.x() + 1,
1060                               r.y() + r.height() - 1);
1061         }
1062         painter->setPen(dark);
1063         drawRect(painter, r);
1064     } else {
1065         if (addLight) {
1066             QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
1067             painter->setPen(light);
1068             painter->drawLine(r.x() + 1, r.y(), r.x() + 1,
1069                               r.y() + r.height() -
1070                               (1 + (opts.round > ROUND_SLIGHT &&
1071                                     state & QtC_StateKWin ? 3 : 1)));
1072         }
1073         painter->setRenderHint(QPainter::Antialiasing, true);
1074         painter->setPen(dark);
1075         painter->drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL,
1076                                     opts.round > ROUND_SLIGHT &&
1077                                     state & QtC_StateKWin ? 6.0 : 2.0));
1078         if (opts.round >= ROUND_FULL && !(state & QtC_StateKWinCompositing)) {
1079             QColor col(opts.windowBorder & WINDOW_BORDER_COLOR_TITLEBAR_ONLY ?
1080                        backgroundColors(option)[QTC_STD_BORDER] :
1081                        buttonColors(option)[QTC_STD_BORDER]);
1082             QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
1083             painter->setPen(col);
1084             painter->drawPoint(r.x() + 2, r.y() + r.height() - 3);
1085             painter->drawPoint(r.x() + r.width() - 3, r.y() + r.height() - 3);
1086             painter->drawLine(r.x() + 1, r.y() + r.height() - 5,
1087                               r.x() + 1, r.y() + r.height() - 4);
1088             painter->drawLine(r.x() + 3, r.y() + r.height() - 2,
1089                               r.x() + 4, r.y() + r.height() - 2);
1090             painter->drawLine(r.x() + r.width() - 2, r.y() + r.height() - 5,
1091                               r.x() + r.width() - 2, r.y() + r.height() - 4);
1092             painter->drawLine(r.x() + r.width() - 4, r.y() + r.height() - 2,
1093                               r.x() + r.width() - 5, r.y() + r.height() - 2);
1094         }
1095     }
1096     return true;
1097 }
1098 
1099 bool
1100 Style::drawPrimitiveButton(PrimitiveElement element, const QStyleOption *option,
1101                            QPainter *painter, const QWidget *widget) const
1102 {
1103     const QRect &r = option->rect;
1104     State state = option->state;
1105     if (state & STATE_DWT_BUTTON &&
1106         (opts.dwtSettings & DWT_BUTTONS_AS_PER_TITLEBAR)) {
1107         return true;
1108     }
1109     bool doEtch = opts.buttonEffect != EFFECT_NONE;
1110 
1111     // This fixes the "Sign in" button at mail.lycos.co.uk
1112     // ...basically if KHTML gices us a fully transparent background colour,
1113     // then dont paint the button.
1114     if (option->palette.button().color().alpha() == 0) {
1115         if (state & State_MouseOver && state & State_Enabled &&
1116             opts.coloredMouseOver == MO_GLOW && doEtch &&
1117             !(opts.thin & THIN_FRAMES)) {
1118             drawGlow(painter, r, WIDGET_STD_BUTTON);
1119         }
1120         return true;
1121     }
1122     if (!widget) {
1123         widget = getWidget(painter);
1124     }
1125     const QColor *use = buttonColors(option);
1126     bool isDefault = false;
1127     bool isFlat = false;
1128     bool isKWin = (theThemedApp == APP_KWIN || (state & QtC_StateKWin));
1129     bool isDown = state & State_Sunken || state & State_On;
1130     bool isOnListView = (!isKWin && widget &&
1131                          qobject_cast<const QAbstractItemView*>(widget));
1132     QStyleOption opt(*option);
1133     if (element == PE_PanelButtonBevel) {
1134         opt.state |= State_Enabled;
1135     }
1136     if (auto button = styleOptCast<QStyleOptionButton>(option)) {
1137         isDefault = ((button->features & QStyleOptionButton::DefaultButton) &&
1138                      (button->state & State_Enabled));
1139         isFlat = button->features & QStyleOptionButton::Flat;
1140     }
1141     if (!(opt.state & State_Enabled)) {
1142         opt.state &= ~State_MouseOver;
1143     }
1144     // For some reason with OO.o not all buttons are set as raised!
1145     if (!(opt.state & State_AutoRaise)) {
1146         opt.state |= State_Raised;
1147     }
1148 
1149     isDefault = (isDefault ||
1150                  (doEtch && oneOf(opts.focus, FOCUS_FULL, FOCUS_FILLED) &&
1151                   opts.coloredMouseOver == MO_GLOW &&
1152                   opt.state & State_HasFocus && opt.state & State_Enabled));
1153     if (isFlat && !isDown && !(opt.state & State_MouseOver)) {
1154         return true;
1155     }
1156 
1157     if (isOnListView) {
1158         opt.state |= State_Horizontal | State_Raised;
1159     }
1160     if (isDefault && state & State_Enabled &&
1161         oneOf(opts.defBtnIndicator, IND_TINT, IND_SELECTED)) {
1162         use = m_defBtnCols;
1163     } else if (state & STATE_DWT_BUTTON && widget &&
1164                opts.titlebarButtons & TITLEBAR_BUTTON_COLOR &&
1165                coloredMdiButtons(state & State_Active,
1166                                  state & State_MouseOver) &&
1167                !(opts.titlebarButtons & TITLEBAR_BUTTON_COLOR_SYMBOL)) {
1168         if (constDwtClose == widget->objectName()) {
1169             use = m_titleBarButtonsCols[TITLEBAR_CLOSE];
1170         } else if (constDwtFloat == widget->objectName()) {
1171             use = m_titleBarButtonsCols[TITLEBAR_MAX];
1172         } else if (qtcCheckType<QDockWidget>(getParent<2>(widget)) &&
1173                    widget->parentWidget()->inherits("KoDockWidgetTitleBar")) {
1174             QDockWidget *dw = (QDockWidget*)getParent<2>(widget);
1175             QWidget *koDw = widget->parentWidget();
1176             int fw = (dw->isFloating() ?
1177                       pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, dw) : 0);
1178             QRect geom = widget->geometry();
1179             QStyleOptionDockWidget dwOpt;
1180             dwOpt.initFrom(dw);
1181             dwOpt.rect = QRect(QPoint(fw, fw),
1182                                QSize(koDw->geometry().width() - (fw * 2),
1183                                      koDw->geometry().height() - (fw * 2)));
1184             dwOpt.title = dw->windowTitle();
1185             dwOpt.closable = ((dw->features() &
1186                                QDockWidget::DockWidgetClosable) ==
1187                               QDockWidget::DockWidgetClosable);
1188             dwOpt.floatable = ((dw->features() &
1189                                 QDockWidget::DockWidgetFloatable) ==
1190                                QDockWidget::DockWidgetFloatable);
1191             if (dwOpt.closable &&
1192                 subElementRect(QStyle::SE_DockWidgetCloseButton, &dwOpt,
1193                                getParent<2>(widget)) == geom) {
1194                 use = m_titleBarButtonsCols[TITLEBAR_CLOSE];
1195             } else if (dwOpt.floatable &&
1196                        subElementRect(QStyle::SE_DockWidgetFloatButton, &dwOpt,
1197                                       getParent<2>(widget)) == geom) {
1198                 use = m_titleBarButtonsCols[TITLEBAR_MAX];
1199             } else {
1200                 use = m_titleBarButtonsCols[TITLEBAR_SHADE];
1201             }
1202         }
1203     }
1204     if (isKWin) {
1205         opt.state |= STATE_KWIN_BUTTON;
1206     }
1207     bool coloredDef = (isDefault && state & State_Enabled &&
1208                        opts.defBtnIndicator == IND_COLORED);
1209     if (widget && qobject_cast<const QAbstractButton*>(widget) &&
1210         static_cast<const QAbstractButton*>(widget)->isCheckable()) {
1211         opt.state |= STATE_TOGGLE_BUTTON;
1212     }
1213 
1214     drawLightBevel(painter, r, &opt, widget, ROUNDED_ALL,
1215                    coloredDef ? m_defBtnCols[MO_DEF_BTN] :
1216                    getFill(&opt, use, false,
1217                            isDefault && state & State_Enabled &&
1218                            opts.defBtnIndicator == IND_DARKEN),
1219                    coloredDef ? m_defBtnCols : use, true,
1220                    isKWin || state & STATE_DWT_BUTTON ?
1221                    WIDGET_MDI_WINDOW_BUTTON :
1222                    isOnListView ? WIDGET_NO_ETCH_BTN :
1223                    isDefault && state & State_Enabled ?
1224                    WIDGET_DEF_BUTTON :
1225                    state & STATE_TBAR_BUTTON ? WIDGET_TOOLBAR_BUTTON :
1226                    WIDGET_STD_BUTTON);
1227 
1228     if (isDefault && state & State_Enabled) {
1229         switch (opts.defBtnIndicator) {
1230         case IND_CORNER: {
1231             QPainterPath path;
1232             int offset = isDown ? 5 : 4;
1233             int etchOffset = doEtch ? 1 : 0;
1234             double xd = r.x() + 0.5;
1235             double yd = r.y() + 0.5;
1236             const QColor *cols = m_focusCols;
1237 
1238             path.moveTo(xd + offset + etchOffset, yd + offset + etchOffset);
1239             path.lineTo(xd + offset + 6 + etchOffset, yd + offset + etchOffset);
1240             path.lineTo(xd + offset + etchOffset, yd + offset + 6 + etchOffset);
1241             path.lineTo(xd + offset + etchOffset, yd + offset + etchOffset);
1242             painter->setBrush(cols[isDown ? 0 : 4]);
1243             setPainterPen(painter, cols[isDown ? 0 : 4], QPENWIDTH1);
1244             painter->setRenderHint(QPainter::Antialiasing, true);
1245             painter->drawPath(path);
1246             QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
1247             break;
1248         }
1249         case IND_COLORED: {
1250             int offset = COLORED_BORDER_SIZE + (doEtch ? 1 : 0);
1251             drawBevelGradient(getFill(&opt, use), painter,
1252                               r.adjusted(offset, offset, -offset, -offset),
1253                               true, state & (State_On | State_Sunken),
1254                               opts.appearance, WIDGET_STD_BUTTON);
1255         }
1256         default:
1257             break;
1258         }
1259     }
1260     return true;
1261 }
1262 
1263 bool
1264 Style::drawPrimitivePanelMenu(PrimitiveElement, const QStyleOption *option,
1265                               QPainter *painter, const QWidget *w) const
1266 {
1267     QRect r = option->rect;
1268     double radius = opts.round >= ROUND_FULL ? 5.0 : 2.5;
1269 
1270     const QColor *use;
1271     const QColor *bgCols;
1272     QColor altCols[TOTAL_SHADES+1];
1273     if (theThemedApp==APP_KWIN && w
1274             && w->palette().color(QPalette::Active, QPalette::Background)
1275                 != QApplication::palette().color(QPalette::Active, QPalette::Background)) {
1276 //         qWarning() << "drawPrimitivePanelMenu: widget" << w << "bgCol" << w->palette().color(QPalette::Active, QPalette::Background)
1277 //             << "differs from app bgCol" << QApplication::palette().color(QPalette::Active, QPalette::Background);
1278         shadeColors(w->palette().color(QPalette::Active, QPalette::Background), altCols);
1279         bgCols = use = altCols;
1280     } else {
1281         use = popupMenuCols(option);
1282         bgCols = popupMenuCols();
1283     }
1284 
1285     painter->setClipRegion(r);
1286     painter->setCompositionMode(QPainter::CompositionMode_Source);
1287     if (!opts.popupBorder) {
1288         painter->setRenderHint(QPainter::Antialiasing, true);
1289         painter->setPen(use[ORIGINAL_SHADE]);
1290         painter->drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, radius));
1291         QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
1292     }
1293     if (!(opts.square & SQUARE_POPUP_MENUS)) {
1294         painter->setClipRegion(windowMask(r, opts.round > ROUND_SLIGHT),
1295                                Qt::IntersectClip);
1296     }
1297 
1298     // In case the gradient uses alpha, we need to fill with the background
1299     // colour - this makes it consistent with Gtk.
1300     if (opts.menuBgndOpacity == 100) {
1301         painter->fillRect(r, option->palette.brush(QPalette::Background));
1302     }
1303     drawBackground(painter, bgCols[ORIGINAL_SHADE], r,
1304                    opts.menuBgndOpacity, BGND_MENU, opts.menuBgndAppearance);
1305     // FIXME, workaround only, the non transparent part of the image will have
1306     // a different overall opacity.
1307     painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
1308     drawBackgroundImage(painter, false, r);
1309     // TODO: draw border in other functions.
1310     if (opts.popupBorder) {
1311         EGradientBorder border =
1312             qtcGetGradient(opts.menuBgndAppearance, &opts)->border;
1313         painter->setClipping(false);
1314         painter->setPen(use[QTC_STD_BORDER]);
1315         if (opts.square & SQUARE_POPUP_MENUS) {
1316             drawRect(painter, r);
1317         } else {
1318             painter->setRenderHint(QPainter::Antialiasing, true);
1319             painter->drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, radius));
1320         }
1321         if (qtcUseBorder(border) &&
1322             opts.menuBgndAppearance != APPEARANCE_FLAT) {
1323             QRect ri(r.adjusted(1, 1, -1, -1));
1324             painter->setPen(use[0]);
1325             if (border == GB_LIGHT) {
1326                 if (opts.square & SQUARE_POPUP_MENUS) {
1327                     drawRect(painter, ri);
1328                 } else {
1329                     painter->drawPath(buildPath(ri, WIDGET_OTHER, ROUNDED_ALL,
1330                                                 radius - 1.0));
1331                 }
1332             } else if (opts.square & SQUARE_POPUP_MENUS) {
1333                 if (border != GB_3D) {
1334                     painter->drawLine(ri.x(), ri.y(), ri.x() + ri.width() - 1,
1335                                       ri.y());
1336                     painter->drawLine(ri.x(), ri.y(), ri.x(),
1337                                       ri.y() + ri.height() - 1);
1338                 }
1339                 painter->setPen(use[FRAME_DARK_SHADOW]);
1340                 painter->drawLine(ri.x(), ri.y() + ri.height() - 1,
1341                                   ri.x() + ri.width() - 1,
1342                                   ri.y() + ri.height() - 1);
1343                 painter->drawLine(ri.x() + ri.width() - 1, ri.y(),
1344                                   ri.x() + ri.width() - 1,
1345                                   ri.y() + ri.height() - 1);
1346             } else {
1347                 QPainterPath tl;
1348                 QPainterPath br;
1349                 buildSplitPath(ri, ROUNDED_ALL, radius - 1.0, tl, br);
1350                 if (border != GB_3D) {
1351                     painter->drawPath(tl);
1352                 }
1353                 painter->setPen(use[FRAME_DARK_SHADOW]);
1354                 painter->drawPath(br);
1355             }
1356         }
1357     }
1358     return true;
1359 }
1360 
1361 bool
1362 Style::drawPrimitiveFrameFocusRect(PrimitiveElement, const QStyleOption *option,
1363                                    QPainter *painter,
1364                                    const QWidget *widget) const
1365 {
1366     const QRect &r = option->rect;
1367     State state = option->state;
1368     const QPalette &palette(option->palette);
1369 
1370     if (FOCUS_NONE==opts.focus)
1371         return true;
1372 
1373     if (auto focusFrame = styleOptCast<QStyleOptionFocusRect>(option)) {
1374         if (!(focusFrame->state & State_KeyboardFocusChange) ||
1375             (widget && widget->inherits("QComboBoxListView"))) {
1376             return true;
1377         }
1378         if (widget && opts.focus == FOCUS_GLOW) {
1379             if (qobject_cast<const QAbstractButton*>(widget)) {
1380                 if (!qobject_cast<const QToolButton*>(widget) ||
1381                     !static_cast<const QToolButton*>(widget)->autoRaise()) {
1382                     return true;
1383                 }
1384             } else if (qobject_cast<const QComboBox*>(widget) ||
1385                        qobject_cast<const QGroupBox*>(widget) ||
1386                        qobject_cast<const QDial*>(widget)) {
1387                 return true;
1388             }
1389         }
1390         QRect r2(r);
1391         if (widget && (qobject_cast<const QCheckBox*>(widget) ||
1392                        qobject_cast<const QRadioButton*>(widget)) &&
1393             ((QAbstractButton*)widget)->text().isEmpty() &&
1394             r.height() <= widget->rect().height() - 2 &&
1395             r.width() <= widget->rect().width() - 2 &&
1396             r.x() >= 1 && r.y() >= 1) {
1397             int adjust = qMin(qMin(abs(widget->rect().x() - r.x()), 2),
1398                               abs(widget->rect().y() - r.y()));
1399             r2.adjust(-adjust, -adjust, adjust, adjust);
1400         }
1401 
1402         if (widget && qobject_cast<const QGroupBox*>(widget)) {
1403             r2.adjust(0, 2, 0, 0);
1404         }
1405         if (opts.focus == FOCUS_STANDARD) {
1406             // Taken from QWindowsStyle...
1407             painter->setBackgroundMode(Qt::TransparentMode);
1408             QColor bgCol(focusFrame->backgroundColor);
1409             if (!bgCol.isValid()) {
1410                 bgCol = painter->background().color();
1411             }
1412             // Create an "XOR" color.
1413             QColor patternCol((bgCol.red() ^ 0xff) & 0xff,
1414                               (bgCol.green() ^ 0xff) & 0xff,
1415                               (bgCol.blue() ^ 0xff) & 0xff);
1416             painter->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
1417             painter->setBrushOrigin(r.topLeft());
1418             painter->setPen(Qt::NoPen);
1419             painter->drawRect(r.left(), r.top(), r.width(), 1);    // Top
1420             painter->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom
1421             painter->drawRect(r.left(), r.top(), 1, r.height());   // Left
1422             painter->drawRect(r.right(), r.top(), 1, r.height());  // Right
1423         } else {
1424             // Figuring out in what beast we are painting...
1425             bool view(state & State_Item ||
1426                       ((widget &&
1427                         qobject_cast<const QAbstractScrollArea*>(widget)) ||
1428                        (widget && widget->parent() &&
1429                         qobject_cast<const QAbstractScrollArea*>(
1430                             widget->parent()))));
1431             if (!view && !widget) {
1432                 // Try to determine if we are in a KPageView...
1433                 const QWidget *wid = getWidget(painter);
1434                 if (wid && wid->parentWidget()) {
1435                     if (wid->parentWidget()->inherits(
1436                             "KDEPrivate::KPageListView")) {
1437                         r2.adjust(2, 2, -2, -2);
1438                         view = true;
1439                     } else if (theThemedApp == APP_KONTACT &&
1440                                (wid->parentWidget()->inherits(
1441                                     "KMail::MainFolderView") ||
1442                                 wid->parentWidget()->inherits(
1443                                     "MessageList::Core::View"))) {
1444                         view = true;
1445                     }
1446                 }
1447             }
1448             QColor c(view && state & State_Selected ?
1449                      palette.highlightedText().color() :
1450                      m_focusCols[FOCUS_SHADE(state & State_Selected)]);
1451 
1452             if (oneOf(opts.focus, FOCUS_LINE, FOCUS_GLOW)) {
1453                 if (!(state & State_Horizontal) && widget &&
1454                     qobject_cast<const QTabBar*>(widget)) {
1455                     drawFadedLine(painter, QRect(r2.x() + r2.width() - 1,
1456                                                  r2.y(), 1, r2.height()),
1457                                   c, true, true, false);
1458                 } else {
1459                     drawFadedLine(painter,
1460                                   QRect(r2.x(), r2.y() + r2.height() -
1461                                         (view ? 3 : 1), r2.width(), 1),
1462                                   c, true, true, true);
1463                 }
1464             } else {
1465                 painter->setPen(c);
1466                 if (opts.focus == FOCUS_FILLED) {
1467                     c.setAlphaF(FOCUS_ALPHA);
1468                     painter->setBrush(c);
1469                 }
1470                 if (opts.round != ROUND_NONE) {
1471                     bool square((opts.square & SQUARE_LISTVIEW_SELECTION) &&
1472                                 (((widget &&
1473                                    !widget->inherits("KFilePlacesView") &&
1474                                    (qobject_cast<const QTreeView*>(widget) ||
1475                                     (qobject_cast<const QListView*>(widget) &&
1476                                      ((const QListView*)widget)->viewMode() !=
1477                                      QListView::IconMode)))) ||
1478                                  (!widget && view)));
1479                     painter->setRenderHint(QPainter::Antialiasing, true);
1480                     painter->drawPath(
1481                         buildPath(r2, WIDGET_SELECTION, ROUNDED_ALL,
1482                                   square ? SLIGHT_INNER_RADIUS :
1483                                   qtcGetRadius(&opts, r2.width(),
1484                                                r2.height(), WIDGET_OTHER,
1485                                                oneOf(opts.focus, FOCUS_FULL,
1486                                                      FOCUS_FILLED) ?
1487                                                RADIUS_EXTERNAL :
1488                                                RADIUS_SELECTION)));
1489                 } else {
1490                     drawRect(painter, r2);
1491                 }
1492             }
1493         }
1494     }
1495     return true;
1496 }
1497 
1498 bool
1499 Style::drawPrimitiveIndicatorToolBarHandle(PrimitiveElement,
1500                                            const QStyleOption *option,
1501                                            QPainter *painter,
1502                                            const QWidget*) const
1503 {
1504     drawHandleMarkers(painter, option->rect, option, true, opts.handles);
1505     return true;
1506 }
1507 
1508 bool
1509 Style::drawPrimitiveIndicatorRadioButton(PrimitiveElement,
1510                                          const QStyleOption *option,
1511                                          QPainter *painter,
1512                                          const QWidget *widget) const
1513 {
1514     const QRect &r = option->rect;
1515     State state = option->state;
1516     const QPalette &palette(option->palette);
1517     bool isOO = isOOWidget(widget);
1518     // TODO: WTF???
1519     bool selectedOOMenu = (isOO && oneOf(r, QRect(0, 0, 15, 15),
1520                                          QRect(0, 0, 14, 15)) &&
1521                            // OO.o 3.2 =14x15?
1522                            oneOf(state, State_Sunken | State_Enabled,
1523                                  State_Sunken | State_Enabled |
1524                                  State_Selected));
1525 
1526     if (isOO) {
1527         painter->fillRect(r, palette.brush(QPalette::Background));
1528     }
1529     if (selectedOOMenu) {
1530         drawPrimitive(PE_IndicatorCheckBox, option, painter, widget);
1531     } else {
1532         bool menu = state & STATE_MENU;
1533         int x = r.x();
1534         int y = r.y();
1535         if (opts.crButton) {
1536             const QColor *use = checkRadioColors(option);
1537             QStyleOption opt(*option);
1538             bool doEtch = opts.buttonEffect != EFFECT_NONE;
1539             QRect rect(r.x(), r.y(), opts.crSize + (doEtch ? 2 : 0),
1540                        opts.crSize + (doEtch ? 2 : 0));
1541 
1542             if (opts.crSize != CR_SMALL_SIZE && menu) {
1543                 rect.adjust(0, -1, 0, -1);
1544                 y++;
1545             }
1546             if (isOO && r == QRect(0, 0, opts.crSize, opts.crSize)) {
1547                 rect.adjust(-1, -1, -1, -1);
1548                 --x;
1549                 --y;
1550             }
1551             if (menu || selectedOOMenu) {
1552                 opt.state &= ~(State_MouseOver | State_Sunken);
1553             }
1554             opt.state &= ~State_On;
1555             opt.state |= State_Raised;
1556             opt.rect = rect;
1557 
1558             if (doEtch) {
1559                 x++;
1560                 y++;
1561             }
1562             if (opts.crSize != CR_SMALL_SIZE && menu) {
1563                 y -= 2;
1564             }
1565             painter->setRenderHint(QPainter::Antialiasing, true);
1566             drawLightBevel(painter, rect, &opt, widget, ROUNDED_ALL,
1567                            getFill(&opt, use, true, false), use, true,
1568                            WIDGET_RADIO_BUTTON);
1569         } else {
1570             bool sunken = !menu && !selectedOOMenu && (state & State_Sunken);
1571             bool doEtch = (!menu && r.width() >= opts.crSize + 2 &&
1572                            r.height() >= opts.crSize + 2 &&
1573                            opts.buttonEffect != EFFECT_NONE);
1574             bool mo = (!sunken && state & State_MouseOver &&
1575                        state & State_Enabled);
1576             bool glow = doEtch && opts.coloredMouseOver == MO_GLOW && mo;
1577             bool coloredMo = (opts.coloredMouseOver != MO_NONE && !glow &&
1578                               mo && !sunken);
1579             bool lightBorder = DRAW_LIGHT_BORDER(false, WIDGET_TROUGH,
1580                                                  APPEARANCE_INVERTED);
1581             bool doneShadow = false;
1582             QRect rect = doEtch ? r.adjusted(1, 1, -1, -1) : r;
1583             const QColor *bc = sunken ? 0L : borderColors(option, 0L);
1584             const QColor *btn = checkRadioColors(option);
1585             const QColor *use = bc ? bc : btn;
1586             if (doEtch) {
1587                 x++;
1588                 y++;
1589             }
1590             const QColor &bgnd(state & State_Enabled && !sunken ?
1591                                opts.coloredMouseOver == MO_NONE &&
1592                                !opts.crHighlight && mo ?
1593                                use[CR_MO_FILL] :
1594                                palette.base().color() :
1595                                palette.window().color());
1596             QPainterPath path;
1597 
1598             path.addEllipse(QRectF(rect).adjusted(0.5, 0.5, -1.0, -1.0));
1599             drawBevelGradient(bgnd, painter, rect.adjusted(1, 1, -1, -1),
1600                               path, true, false, APPEARANCE_INVERTED,
1601                               WIDGET_TROUGH);
1602             painter->setRenderHint(QPainter::Antialiasing, true);
1603             if (coloredMo) {
1604                 painter->setBrush(Qt::NoBrush);
1605                 setPainterPen(painter, use[CR_MO_FILL], QPENWIDTH1);
1606                 painter->drawArc(QRectF(x + 1, y + 1, opts.crSize - 2,
1607                                         opts.crSize - 2), 0, 360 * 16);
1608                 painter->drawArc(QRectF(x + 2, y + 2, opts.crSize - 4,
1609                                         opts.crSize - 4), 0, 360 * 16);
1610             }
1611             painter->setBrush(Qt::NoBrush);
1612             if (!doneShadow && doEtch &&
1613                 (glow || opts.buttonEffect != EFFECT_NONE || sunken)) {
1614                 QColor topCol = glow ? m_mouseOverCols[GLOW_MO] : Qt::black;
1615                 if (!glow) {
1616                     topCol.setAlphaF(ETCH_RADIO_TOP_ALPHA);
1617                 }
1618                 setPainterPen(painter, topCol, QPENWIDTH1);
1619                 painter->drawArc(QRectF(x - 0.5, y - 0.5, opts.crSize + 1,
1620                                         opts.crSize + 1), 45 * 16, 180 * 16);
1621                 if (!glow) {
1622                     painter->setPen(getLowerEtchCol(widget));
1623                 }
1624                 painter->drawArc(QRectF(x - 0.5, y - 0.5, opts.crSize + 1,
1625                                         opts.crSize + 1), 225 * 16, 180 * 16);
1626             }
1627             setPainterPen(painter, use[BORDER_VAL(state & State_Enabled)], QPENWIDTH1);
1628             painter->drawArc(QRectF(x + 0.25, y + 0.25, opts.crSize - 0.5,
1629                                     opts.crSize - 0.5), 0, 360 * 16);
1630             if (!coloredMo) {
1631                 setPainterPen(painter, btn[state & State_MouseOver ? 3 : 4], QPENWIDTH1);
1632                 painter->drawArc(QRectF(x + 0.75, y + 0.75, opts.crSize - 1.5,
1633                                         opts.crSize - 1.5),
1634                                  lightBorder ? 0 : 45 * 16,
1635                                  lightBorder ? 360 * 16 : 180 * 16);
1636             }
1637         }
1638         if (state & State_On || selectedOOMenu) {
1639             QPainterPath path;
1640             double radius = opts.smallRadio ? 2.75 : 3.75;
1641             double offset = opts.crSize / 2.0 - radius;
1642             path.addEllipse(QRectF(x + offset, y + offset,
1643                                    radius * 2.0, radius * 2.0));
1644             painter->setRenderHint(QPainter::Antialiasing, true);
1645             painter->fillPath(path, checkRadioCol(option));
1646         }
1647     }
1648     return true;
1649 }
1650 
1651 bool
1652 Style::drawPrimitiveIndicatorCheckBox(PrimitiveElement element,
1653                                       const QStyleOption *option,
1654                                       QPainter *painter,
1655                                       const QWidget *widget) const
1656 {
1657     const QRect &r = option->rect;
1658     State state = option->state;
1659     const QPalette &palette(option->palette);
1660     bool menu = state & STATE_MENU;
1661     bool view = state & STATE_VIEW;
1662     bool doEtch = (opts.buttonEffect != EFFECT_NONE &&
1663                    (opts.crButton ||
1664                     (PE_IndicatorMenuCheckMark != element && !menu &&
1665                      r.width() >= opts.crSize + 2 &&
1666                      r.height() >= opts.crSize + 2)));
1667     bool isOO = isOOWidget(widget);
1668     bool selectedOOMenu = (isOO && oneOf(r, QRect(0, 0, 15, 15),
1669                                          QRect(0, 0, 14, 15)) &&
1670                            // OO.o 3.2 =14x15?
1671                            oneOf(state, State_Sunken | State_Enabled,
1672                                  State_Sunken | State_Enabled |
1673                                  State_Selected));
1674     int crSize = opts.crSize + (doEtch ? 2 : 0);
1675     QRect rect(r.x(), r.y() + (view ? -1 : 0), crSize, crSize);
1676     // render checkable menu items with only a tick if so requested
1677     bool onlyTicksInMenu = menu && opts.onlyTicksInMenu;
1678 
1679     // For OO.o 3.2 need to fill widget background!
1680     if (isOO) {
1681         painter->fillRect(r, palette.brush(QPalette::Window));
1682     }
1683 
1684     if (selectedOOMenu) {
1685         if (r == QRect(0, 0, 14, 15)) { // OO.o 3.2 =14x15?
1686             rect.adjust(-1, -1, -1, -1);
1687         }
1688         setPainterPen(painter, option ? option->palette.text().color() :
1689                         QApplication::palette().text().color(), QPENWIDTH1);
1690         drawRect(painter, r);
1691         // LibreOffice its 15x15 - and arrow is not centred, so adjust this...
1692         if (r == QRect(0, 0, 15, 15)) {
1693             rect.adjust(-1, -1, -1, -1);
1694         }
1695     } else if (!onlyTicksInMenu) {
1696         // don't do this when rendering a regular menu so we get just a tick
1697         if (isOO && r == QRect(0, 0, opts.crSize, opts.crSize)) {
1698             rect.adjust(0, -1, 0, -1);
1699         }
1700 
1701         if (opts.crSize != CR_SMALL_SIZE) {
1702             if (menu) {
1703                 rect.adjust(0, -1, 0, -1);
1704             } else if (r.height() > crSize) {
1705                 // Can only adjust position if there is space!
1706                 // ...when used in a listview, usually there is no space.
1707                 rect.adjust(0, 1, 0, 1);
1708             }
1709         }
1710 
1711         if (opts.crButton) {
1712             const QColor *use(checkRadioColors(option));
1713             QStyleOption opt(*option);
1714             if (menu || selectedOOMenu) {
1715                 opt.state &= ~(State_MouseOver | State_Sunken);
1716             }
1717             opt.state &= ~State_On;
1718             opt.state |= State_Raised;
1719             opt.rect = rect;
1720             painter->setRenderHint(QPainter::Antialiasing, true);
1721             drawLightBevel(painter, rect, &opt, widget, ROUNDED_ALL,
1722                            getFill(&opt, use, true, false),
1723                            use, true, WIDGET_CHECKBOX);
1724         } else {
1725             bool sunken = !menu && !selectedOOMenu && (state & State_Sunken);
1726             bool mo = (!sunken && state & State_MouseOver &&
1727                        state & State_Enabled);
1728             bool glow = doEtch && opts.coloredMouseOver == MO_GLOW && mo;
1729             const QColor *bc = sunken ? 0L : borderColors(option, 0L);
1730             const QColor *btn = checkRadioColors(option);
1731             const QColor *use = bc ? bc : btn;
1732             const QColor &bgnd(state & State_Enabled && !sunken ?
1733                                opts.coloredMouseOver == MO_NONE &&
1734                                !opts.crHighlight && mo ? use[CR_MO_FILL] :
1735                                palette.base().color() :
1736                                palette.window().color());
1737             bool lightBorder = DRAW_LIGHT_BORDER(false, WIDGET_TROUGH,
1738                                                  APPEARANCE_INVERTED);
1739             rect = QRect(doEtch ? rect.adjusted(1, 1, -1, -1) : rect);
1740             if (qtcIsFlat(opts.appearance)) {
1741                 painter->fillRect(rect.adjusted(1, 1, -1, -1), bgnd);
1742             } else {
1743                 drawBevelGradient(bgnd, painter, rect.adjusted(1, 1, -1, -1),
1744                                   true, false, APPEARANCE_INVERTED,
1745                                   WIDGET_TROUGH);
1746             }
1747 
1748             if (opts.coloredMouseOver != MO_NONE && !glow && mo) {
1749                 painter->setRenderHint(QPainter::Antialiasing, true);
1750                 setPainterPen(painter, use[CR_MO_FILL], QPENWIDTH1);
1751                 drawAaRect(painter, rect.adjusted(1, 1, -1, -1));
1752                 QPAINTER_RENDERHINT_AA_MAYBE_OFF(painter);
1753             } else {
1754                 setPainterPen(painter, midColor(state & State_Enabled ?
1755                                          palette.base().color() :
1756                                          palette.window().color(), use[3]), QPENWIDTH1);
1757                 if (lightBorder) {
1758                     drawRect(painter, rect.adjusted(1, 1, -1, -1));
1759                 } else {
1760                     painter->drawLine(rect.x() + 1, rect.y() + 1,
1761                                       rect.x() + 1,
1762                                       rect.y() + rect.height() - 2);
1763                     painter->drawLine(rect.x() + 1, rect.y() + 1,
1764                                       rect.x() + rect.width() - 2,
1765                                       rect.y() + 1);
1766                 }
1767             }
1768 
1769             painter->setRenderHint(QPainter::Antialiasing, true);
1770             if (doEtch && !view) {
1771                 if (glow && !(opts.thin & THIN_FRAMES)) {
1772                     drawGlow(painter, r, WIDGET_CHECKBOX);
1773                 } else {
1774                     drawEtch(painter, r, widget, WIDGET_CHECKBOX,
1775                              opts.buttonEffect == EFFECT_SHADOW &&
1776                              opts.crButton ? !sunken : false);
1777                 }
1778             }
1779             drawBorder(painter, rect, option, ROUNDED_ALL, use,
1780                        WIDGET_CHECKBOX);
1781             painter->setRenderHint(QPainter::Antialiasing, QPAINTER_ANTIALIAS_MAYBE_ON);
1782         }
1783     }
1784     if (state & State_On || selectedOOMenu) {
1785         if (onlyTicksInMenu) {
1786             // only tickmarks (= without the box) in menu; adjust its horizontal position
1787             // the normal, hardcoded margin is 20 (pixels). If that's too small, compensate,
1788             // using a hand-tuned ad-hoc recipe tested over point size range 8 - 32 pt
1789             if (opts.fontTickWidth > 20){
1790                 int dx = (opts.fontTickWidth - 20) + 2;
1791                 rect.adjust(dx, -dx, 2 * dx + 1, dx);
1792             } else if (opts.fontTickWidth > 11){
1793                 int dx = (opts.fontTickWidth - 11) / 2;
1794                 rect.adjust(dx + 1, -dx, dx + 1, dx);
1795             } else {
1796                 rect.adjust(6, 0, 0, 0);
1797             }
1798             QFont font(opts.tickFont);
1799             painter->save();
1800             painter->setFont(font);
1801             // render the tickmark using the Unicode "Check Mark" symbol (✓)
1802             drawItemTextWithRole(painter, rect, Qt::AlignHCenter|Qt::AlignVCenter, palette, true,
1803                              opts.menuTick, QPalette::Text);
1804             painter->restore();
1805         } else {
1806             QPixmap *pix = getPixmap(checkRadioCol(option), PIX_CHECK, 1.0);
1807 
1808             painter->drawPixmap(rect.center().x() - pix->width() / 2,
1809                                 rect.center().y() - pix->height() / 2, *pix);
1810         }
1811     } else if (state & State_NoChange) {
1812         // tri-state
1813         int x(rect.center().x()), y(rect.center().y());
1814 
1815         setPainterPen(painter, checkRadioCol(option), QPENWIDTH1);
1816         painter->drawLine(x - 3, y, x + 3, y);
1817         painter->drawLine(x - 3, y + 1, x + 3, y + 1);
1818     }
1819     return true;
1820 }
1821 
1822 bool
1823 Style::drawPrimitiveFrameLineEdit(PrimitiveElement, const QStyleOption *option,
1824                                   QPainter *painter,
1825                                   const QWidget *widget) const
1826 {
1827     const QRect &r = option->rect;
1828     State state = option->state;
1829     const QPalette &palette(option->palette);
1830     if (auto lineEdit = styleOptCast<QStyleOptionFrame>(option)) {
1831         if ((lineEdit->lineWidth > 0 || isOOWidget(widget)) &&
1832             !(widget &&
1833               (qobject_cast<const QComboBox*>(widget->parentWidget()) ||
1834                qobject_cast<const QAbstractSpinBox*>(
1835                    widget->parentWidget())))) {
1836             QStyleOptionFrame opt(*lineEdit);
1837             if (opt.state & State_Enabled && state & State_ReadOnly) {
1838                 opt.state ^= State_Enabled;
1839             }
1840             if (opts.buttonEffect != EFFECT_NONE && opts.etchEntry &&
1841                 theThemedApp == APP_ARORA && widget && widget->parentWidget() &&
1842                 strcmp(widget->metaObject()->className(), "LocationBar") == 0) {
1843                 const QToolBar *tb = getToolBar(widget->parentWidget());
1844                 if (tb) {
1845                     QRect r2(r);
1846                     struct TB: public QToolBar {
1847                         void
1848                         initOpt(QStyleOptionToolBar *opt)
1849                         {
1850                             initStyleOption(opt);
1851                         }
1852                     };
1853                     QStyleOptionToolBar opt;
1854                     ((TB*)tb)->initOpt(&opt);
1855                     painter->save();
1856                     // Only need to adjust coords if toolbar has a gradient...
1857                     if (!qtcIsFlat(opts.toolbarAppearance)) {
1858                         r2.setY(-widget->mapTo((QWidget*)tb,
1859                                                QPoint(r.x(), r.y())).y());
1860                         r2.setHeight(tb->rect().height());
1861                     }
1862                     painter->setClipRegion(
1863                         QRegion(r2).subtracted(QRegion(r2.adjusted(2, 2,
1864                                                                    -2, -2))));
1865                     drawMenuOrToolBarBackground(widget, painter, r2, &opt,
1866                                                 false, true);
1867                     painter->restore();
1868                 }
1869             }
1870             bool isOO = isOOWidget(widget);
1871             QRect rect(r);
1872             int round = ROUNDED_ALL;
1873             if (isOO) {
1874                 // This (hopefull) checks is we're OO.o 3.2 - in which case
1875                 // no adjustment is required...
1876                 const QImage *img = getImage(painter);
1877                 if (!img || img->rect() != r) {
1878                     // OO.o 3.1?
1879                     rect.adjust(1, 2, -1, -2);
1880                 } else {
1881                     round = ROUNDED_NONE;
1882                     painter->fillRect(r, palette.brush(QPalette::Window));
1883                     rect.adjust(1, 1, -1, -1);
1884                 }
1885             }
1886             drawEntryField(painter, rect, widget, &opt, round, isOO,
1887                            !isOO && opts.buttonEffect != EFFECT_NONE);
1888         }
1889     }
1890     return true;
1891 }
1892 
1893 bool
1894 Style::drawPrimitivePanelLineEdit(PrimitiveElement,
1895                                   const QStyleOption *option, QPainter *painter,
1896                                   const QWidget *widget) const
1897 {
1898     const QRect &r = option->rect;
1899     const QPalette &palette(option->palette);
1900     if (auto panel = styleOptCast<QStyleOptionFrame>(option)) {
1901         if (panel->lineWidth > 0) {
1902             QRect r2 = r.adjusted(1, 1, -1,
1903                                   opts.buttonEffect != EFFECT_NONE ? -2 : -1);
1904             painter->fillPath(buildPath(r2, WIDGET_ENTRY, ROUNDED_ALL,
1905                                         qtcGetRadius(&opts, r2.width(),
1906                                                      r2.height(), WIDGET_ENTRY,
1907                                                      RADIUS_INTERNAL)),
1908                               palette.brush(QPalette::Base));
1909             drawPrimitive(PE_FrameLineEdit, option, painter, widget);
1910         } else {
1911             painter->fillRect(r.adjusted(2, 2, -2, -2),
1912                               palette.brush(QPalette::Base));
1913         }
1914     }
1915     return true;
1916 }
1917 
1918 bool
1919 Style::drawPrimitiveIndicatorDockWidgetResizeHandle(
1920     PrimitiveElement, const QStyleOption *option, QPainter *painter,
1921     const QWidget *widget) const
1922 {
1923     State state = option->state;
1924     QStyleOption dockWidgetHandle = *option;
1925     bool horizontal = state & State_Horizontal;
1926     if (horizontal) {
1927         dockWidgetHandle.state &= ~State_Horizontal;
1928     } else {
1929         dockWidgetHandle.state |= State_Horizontal;
1930     }
1931     drawControl(CE_Splitter, &dockWidgetHandle, painter, widget);
1932     return true;
1933 }
1934 
1935 bool
1936 Style::drawPrimitiveButtonTool(PrimitiveElement element,
1937                                const QStyleOption *option, QPainter *painter,
1938                                const QWidget *widget) const
1939 {
1940     State state = option->state;
1941     const QRect &r = option->rect;
1942     if (oneOf(element, PE_FrameButtonTool, PE_PanelButtonTool)) {
1943         if (isMultiTabBarTab(getButton(widget, painter))) {
1944             if (!opts.stdSidebarButtons) {
1945                 drawSideBarButton(painter, r, option, widget);
1946             } else if ((state & State_Enabled) ||
1947                        !(state & State_AutoRaise)) {
1948                 QStyleOption opt(*option);
1949                 opt.state |= STATE_TBAR_BUTTON;
1950                 drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
1951             }
1952             return true;
1953         }
1954     }
1955     bool dwt = widget && widget->inherits("QDockWidgetTitleButton");
1956     bool koDwt = (!dwt && widget && widget->parentWidget() &&
1957                   widget->parentWidget()->inherits("KoDockWidgetTitleBar"));
1958     if (((state & State_Enabled) || !(state & State_AutoRaise)) &&
1959         (!widget || !(dwt || koDwt) || (state & State_MouseOver))) {
1960         QStyleOption opt(*option);
1961         if (dwt || koDwt) {
1962             opt.state |= STATE_DWT_BUTTON;
1963         }
1964         drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
1965     }
1966     return true;
1967 }
1968 
1969 bool
1970 Style::drawPrimitiveFrameDockWidget(PrimitiveElement,
1971                                     const QStyleOption *option,
1972                                     QPainter *painter,
1973                                     const QWidget*) const
1974 {
1975     const QRect &r = option->rect;
1976     const QColor *use = backgroundColors(option);
1977     painter->setPen(use[0]);
1978     painter->drawLine(r.x(), r.y(), r.x() + r.width() - 1, r.y());
1979     painter->drawLine(r.x(), r.y(), r.x(), r.y() + r.height() - 1);
1980     painter->setPen(use[opts.appearance == APPEARANCE_FLAT ? ORIGINAL_SHADE :
1981                         QTC_STD_BORDER]);
1982     painter->drawLine(r.x(), r.y() + r.height() - 1, r.x() + r.width() - 1,
1983                       r.y() + r.height() - 1);
1984     painter->drawLine(r.x() + r.width() - 1, r.y(), r.x() + r.width() - 1,
1985                       r.y() + r.height() - 1);
1986     return true;
1987 }
1988 
1989 bool
1990 Style::drawPrimitiveFrameStatusBarOrMenu(PrimitiveElement element,
1991                                          const QStyleOption *option,
1992                                          QPainter *painter,
1993                                          const QWidget *widget) const
1994 {
1995     if (element == PE_FrameStatusBar && !opts.drawStatusBarFrames) {
1996         return true;
1997     }
1998     QRect r = option->rect;
1999     if ((opts.square & SQUARE_POPUP_MENUS) &&
2000         (qtcIsFlatBgnd(opts.menuBgndAppearance) ||
2001          (opts.gtkComboMenus && widget && widget->parent() &&
2002           qobject_cast<const QComboBox*>(widget->parent())))) {
2003         const QColor *use = popupMenuCols(option);
2004         EGradientBorder border =
2005             qtcGetGradient(opts.menuBgndAppearance, &opts)->border;
2006         painter->setPen(use[QTC_STD_BORDER]);
2007         drawRect(painter, r);
2008 
2009         if (qtcUseBorder(border) &&
2010             opts.menuBgndAppearance != APPEARANCE_FLAT) {
2011             painter->setPen(use[0]);
2012             if (border == GB_LIGHT) {
2013                 drawRect(painter, r.adjusted(1, 1, -1, -1));
2014             } else {
2015                 if (border != GB_3D) {
2016                     painter->drawLine(r.x() + 1, r.y() + 1,
2017                                       r.x() + r.width() - 2, r.y() + 1);
2018                     painter->drawLine(r.x() + 1, r.y() + 1, r.x() + 1,
2019                                       r.y() + r.height() - 2);
2020                 }
2021                 painter->setPen(use[FRAME_DARK_SHADOW]);
2022                 painter->drawLine(r.x() + 1, r.y() + r.height() - 2,
2023                                   r.x() + r.width() - 2,
2024                                   r.y() + r.height() - 2);
2025                 painter->drawLine(r.x() + r.width() - 2, r.y() + 1,
2026                                   r.x() + r.width() - 2,
2027                                   r.y() + r.height() - 2);
2028             }
2029         }
2030     }
2031     return true;
2032 }
2033 
2034 bool
2035 Style::drawPrimitiveFrameTabBarBase(PrimitiveElement,
2036                                     const QStyleOption *option,
2037                                     QPainter *painter,
2038                                     const QWidget *widget) const
2039 {
2040     bool reverse = option->direction == Qt::RightToLeft;
2041     if (auto tbb = styleOptCast<QStyleOptionTabBarBase>(option)) {
2042         if (noneOf(tbb->shape, QTabBar::RoundedNorth, QTabBar::RoundedWest,
2043                    QTabBar::RoundedSouth, QTabBar::RoundedEast)) {
2044             return false;
2045         } else {
2046             static const int constSidePad = 16 * 2;
2047             const QColor *use(backgroundColors(option));
2048             QRegion region(tbb->rect);
2049             QLine topLine(tbb->rect.bottomLeft() - QPoint(0, 1),
2050                           tbb->rect.bottomRight() - QPoint(0, 1));
2051             QLine bottomLine(tbb->rect.bottomLeft(), tbb->rect.bottomRight());
2052             bool horiz = oneOf(tbb->shape, QTabBar::RoundedNorth,
2053                                QTabBar::RoundedSouth);
2054             double size = horiz ? tbb->rect.width() : tbb->rect.height();
2055             double tabRectSize = (horiz ? tbb->tabBarRect.width() :
2056                                   tbb->tabBarRect.height());
2057             double tabFadeSize = (tabRectSize + constSidePad > size ? 0.0 :
2058                                   1.0 - (tabRectSize + constSidePad) / size);
2059             double minFadeSize = 1.0 - (size - constSidePad) / size;
2060             double fadeSizeStart = minFadeSize;
2061             double fadeSizeEnd = (tabFadeSize < minFadeSize ? minFadeSize :
2062                                   (tabFadeSize > FADE_SIZE ? FADE_SIZE :
2063                                    tabFadeSize));
2064             if (reverse && horiz) {
2065                 fadeSizeStart = fadeSizeEnd;
2066                 fadeSizeEnd = minFadeSize;
2067             }
2068             region -= tbb->tabBarRect;
2069             painter->setClipRegion(region);
2070             bool fadeState = true;
2071             bool fadeEnd = true;
2072             // Dont fade start/end of tabbar in KDevelop's menubar
2073             if (theThemedApp == APP_KDEVELOP &&
2074                 qtcCheckType<QMenuBar>(getParent<2>(widget)) &&
2075                 qobject_cast<const QTabBar*>(widget)) {
2076                 fadeState = fadeEnd = false;
2077             }
2078             drawFadedLine(painter, QRect(topLine.p1(), topLine.p2()),
2079                           tbb->shape == QTabBar::RoundedSouth &&
2080                           opts.appearance == APPEARANCE_FLAT ?
2081                           option->palette.window().color() :
2082                           use[tbb->shape == QTabBar::RoundedNorth ?
2083                               QTC_STD_BORDER :
2084                               (opts.borderTab ? 0 : FRAME_DARK_SHADOW)],
2085                           fadeState, fadeEnd, horiz,
2086                           fadeSizeStart, fadeSizeEnd);
2087             if (!(opts.thin & THIN_FRAMES)) {
2088                 drawFadedLine(painter, QRect(bottomLine.p1(), bottomLine.p2()),
2089                               use[tbb->shape == QTabBar::RoundedNorth ?
2090                                   0 : QTC_STD_BORDER],
2091                               fadeState, fadeEnd, horiz, fadeSizeStart,
2092                               fadeSizeEnd);
2093             }
2094         }
2095     }
2096     return true;
2097 }
2098 }