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