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 }