1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qwindowsstyle_p.h"
41 #include "qwindowsstyle_p_p.h"
42 
43 #if QT_CONFIG(style_windows) || defined(QT_PLUGIN)
44 
45 #include "qapplication.h"
46 #include "qbitmap.h"
47 #include "qdrawutil.h" // for now
48 #include "qevent.h"
49 #if QT_CONFIG(menu)
50 #include "qmenu.h"
51 #endif
52 #if QT_CONFIG(menubar)
53 #include "qmenubar.h"
54 #include <private/qmenubar_p.h>
55 #endif
56 #include "qpaintengine.h"
57 #include "qpainter.h"
58 #if QT_CONFIG(rubberband)
59 #include "qrubberband.h"
60 #endif
61 #include "qstyleoption.h"
62 #if QT_CONFIG(tabbar)
63 #include "qtabbar.h"
64 #endif
65 #include "qwidget.h"
66 #include "qdebug.h"
67 #if QT_CONFIG(mainwindow)
68 #include "qmainwindow.h"
69 #endif
70 #include "qfile.h"
71 #include "qtextstream.h"
72 #include "qpixmapcache.h"
73 #if QT_CONFIG(wizard)
74 #include "qwizard.h"
75 #endif
76 #if QT_CONFIG(listview)
77 #include "qlistview.h"
78 #endif
79 #include <private/qmath_p.h>
80 #include <qmath.h>
81 #include <QtGui/qpainterpath.h>
82 #include <QtGui/qscreen.h>
83 #include <QtGui/qwindow.h>
84 #include <qpa/qplatformtheme.h>
85 #include <qpa/qplatformscreen.h>
86 #include <private/qguiapplication_p.h>
87 #include <private/qhighdpiscaling_p.h>
88 #include <qpa/qplatformnativeinterface.h>
89 #include <private/qwidget_p.h>
90 
91 #include <private/qstylehelper_p.h>
92 #if QT_CONFIG(animation)
93 #include <private/qstyleanimation_p.h>
94 #endif
95 
96 #include <algorithm>
97 
98 QT_BEGIN_NAMESPACE
99 
100 #if defined(Q_OS_WIN)
101 
102 QT_BEGIN_INCLUDE_NAMESPACE
103 #include "qt_windows.h"
104 QT_END_INCLUDE_NAMESPACE
105 #  ifndef COLOR_GRADIENTACTIVECAPTION
106 #    define COLOR_GRADIENTACTIVECAPTION     27
107 #  endif
108 #  ifndef COLOR_GRADIENTINACTIVECAPTION
109 #    define COLOR_GRADIENTINACTIVECAPTION   28
110 #  endif
111 
112 Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &);
113 #endif //Q_OS_WIN
114 
115 QT_BEGIN_INCLUDE_NAMESPACE
116 #include <limits.h>
117 QT_END_INCLUDE_NAMESPACE
118 
119 enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
120 
121 /*
122     \internal
123 */
124 
125 QWindowsStylePrivate::QWindowsStylePrivate() = default;
126 
appDevicePixelRatio()127 qreal QWindowsStylePrivate::appDevicePixelRatio()
128 {
129     return qApp->devicePixelRatio();
130 }
131 
isDarkMode()132 bool QWindowsStylePrivate::isDarkMode()
133 {
134     bool result = false;
135 #ifdef Q_OS_WIN
136     // Windows only: Return whether dark mode style support is desired and
137     // dark mode is in effect.
138     if (auto ni = QGuiApplication::platformNativeInterface()) {
139         const QVariant darkModeStyleP = ni->property("darkModeStyle");
140         result = darkModeStyleP.type() == QVariant::Bool
141                  && darkModeStyleP.value<bool>()
142                  && ni->property("darkMode").value<bool>();
143     }
144 #endif
145     return result;
146 }
147 
148 // Returns \c true if the toplevel parent of \a widget has seen the Alt-key
hasSeenAlt(const QWidget * widget) const149 bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const
150 {
151     widget = widget->window();
152     return seenAlt.contains(widget);
153 }
154 
155 /*!
156     \reimp
157 */
eventFilter(QObject * o,QEvent * e)158 bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
159 {
160     // Records Alt- and Focus events
161     if (!o->isWidgetType())
162         return QObject::eventFilter(o, e);
163 
164     QWidget *widget = qobject_cast<QWidget*>(o);
165     Q_D(QWindowsStyle);
166     switch(e->type()) {
167     case QEvent::KeyPress:
168         if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) {
169             widget = widget->window();
170 
171             // Alt has been pressed - find all widgets that care
172             QList<QWidget *> l = widget->findChildren<QWidget *>();
173             auto ignorable = [](QWidget *w) {
174                 return w->isWindow() || !w->isVisible()
175                         || w->style()->styleHint(SH_UnderlineShortcut, nullptr, w);
176             };
177             l.erase(std::remove_if(l.begin(), l.end(), ignorable), l.end());
178             // Update states before repainting
179             d->seenAlt.append(widget);
180             d->alt_down = true;
181 
182             // Repaint all relevant widgets
183             for (int pos = 0; pos < l.size(); ++pos)
184                 l.at(pos)->update();
185         }
186         break;
187     case QEvent::KeyRelease:
188         if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) {
189             widget = widget->window();
190 
191             // Update state and repaint the menu bars.
192             d->alt_down = false;
193 #if QT_CONFIG(menubar)
194             QList<QMenuBar *> l = widget->findChildren<QMenuBar *>();
195             for (int i = 0; i < l.size(); ++i)
196                 l.at(i)->update();
197 #endif
198         }
199         break;
200     case QEvent::Close:
201         // Reset widget when closing
202         d->seenAlt.removeAll(widget);
203         d->seenAlt.removeAll(widget->window());
204         break;
205     default:
206         break;
207     }
208     return QCommonStyle::eventFilter(o, e);
209 }
210 
211 /*!
212     \class QWindowsStyle
213     \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel.
214 
215     \ingroup appearance
216     \inmodule QtWidgets
217     \internal
218 
219     This style is Qt's default GUI style on Windows.
220 
221     \image qwindowsstyle.png
222     \sa QWindowsVistaStyle, QMacStyle, QFusionStyle
223 */
224 
225 /*!
226     Constructs a QWindowsStyle object.
227 */
QWindowsStyle()228 QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate)
229 {
230 }
231 
232 /*!
233     \internal
234 
235     Constructs a QWindowsStyle object.
236 */
QWindowsStyle(QWindowsStylePrivate & dd)237 QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd)
238 {
239 }
240 
241 
242 /*! Destroys the QWindowsStyle object. */
~QWindowsStyle()243 QWindowsStyle::~QWindowsStyle()
244 {
245 }
246 
247 #ifdef Q_OS_WIN
colorref2qrgb(COLORREF col)248 static inline QRgb colorref2qrgb(COLORREF col)
249 {
250     return qRgb(GetRValue(col), GetGValue(col), GetBValue(col));
251 }
252 #endif
253 
254 /*! \reimp */
polish(QApplication * app)255 void QWindowsStyle::polish(QApplication *app)
256 {
257     QCommonStyle::polish(app);
258     QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
259     // We only need the overhead when shortcuts are sometimes hidden
260     if (!proxy()->styleHint(SH_UnderlineShortcut, nullptr) && app)
261         app->installEventFilter(this);
262 
263     const auto &palette = QGuiApplication::palette();
264     d->activeGradientCaptionColor = palette.highlight().color();
265     d->activeCaptionColor = d->activeGradientCaptionColor;
266     d->inactiveGradientCaptionColor = palette.dark().color();
267     d->inactiveCaptionColor = d->inactiveGradientCaptionColor;
268     d->inactiveCaptionText = palette.window().color();
269 
270 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors
271     if(app->desktopSettingsAware()){
272         DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
273         DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
274         DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION);
275         DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
276         DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
277         d->activeCaptionColor = colorref2qrgb(activeCaption);
278         d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption);
279         d->inactiveCaptionColor = colorref2qrgb(inactiveCaption);
280         d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption);
281         d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText);
282     }
283 #endif
284 }
285 
286 /*! \reimp */
unpolish(QApplication * app)287 void QWindowsStyle::unpolish(QApplication *app)
288 {
289     QCommonStyle::unpolish(app);
290     app->removeEventFilter(this);
291 }
292 
293 /*! \reimp */
polish(QWidget * widget)294 void QWindowsStyle::polish(QWidget *widget)
295 {
296     QCommonStyle::polish(widget);
297 }
298 
299 /*! \reimp */
unpolish(QWidget * widget)300 void QWindowsStyle::unpolish(QWidget *widget)
301 {
302     QCommonStyle::unpolish(widget);
303 }
304 
305 /*!
306   \reimp
307 */
polish(QPalette & pal)308 void QWindowsStyle::polish(QPalette &pal)
309 {
310     QCommonStyle::polish(pal);
311 }
312 
pixelMetricFromSystemDp(QStyle::PixelMetric pm,const QStyleOption *,const QWidget * widget)313 int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget)
314 {
315 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
316     switch (pm) {
317     case QStyle::PM_DockWidgetFrameWidth:
318         return GetSystemMetrics(SM_CXFRAME);
319 
320     case QStyle::PM_TitleBarHeight:
321         if (widget && (widget->windowType() == Qt::Tool)) {
322             // MS always use one less than they say
323             return GetSystemMetrics(SM_CYSMCAPTION) - 1;
324         }
325         return GetSystemMetrics(SM_CYCAPTION) - 1;
326 
327     case QStyle::PM_ScrollBarExtent:
328         {
329             NONCLIENTMETRICS ncm;
330             ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
331             if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
332                 return qMax(ncm.iScrollHeight, ncm.iScrollWidth);
333         }
334         break;
335 
336     case  QStyle::PM_MdiSubWindowFrameWidth:
337         return GetSystemMetrics(SM_CYFRAME);
338 
339     default:
340         break;
341     }
342 #else // Q_OS_WIN && !Q_OS_WINRT
343     Q_UNUSED(pm);
344     Q_UNUSED(widget);
345 #endif
346     return QWindowsStylePrivate::InvalidMetric;
347 }
348 
fixedPixelMetric(QStyle::PixelMetric pm)349 int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
350 {
351     switch (pm) {
352     case QStyle::PM_ToolBarItemSpacing:
353         return 0;
354     case QStyle::PM_ButtonDefaultIndicator:
355     case QStyle::PM_ButtonShiftHorizontal:
356     case QStyle::PM_ButtonShiftVertical:
357     case QStyle::PM_MenuHMargin:
358     case QStyle::PM_MenuVMargin:
359     case QStyle::PM_ToolBarItemMargin:
360         return 1;
361     case QStyle::PM_DockWidgetSeparatorExtent:
362         return 4;
363 #if QT_CONFIG(tabbar)
364     case QStyle::PM_TabBarTabShiftHorizontal:
365         return 0;
366     case QStyle::PM_TabBarTabShiftVertical:
367         return 2;
368 #endif
369 
370 #if QT_CONFIG(slider)
371     case QStyle::PM_SliderLength:
372         return 11;
373 #endif // QT_CONFIG(slider)
374 
375 #if QT_CONFIG(menu)
376     case QStyle::PM_MenuBarHMargin:
377     case QStyle::PM_MenuBarVMargin:
378     case QStyle::PM_MenuBarPanelWidth:
379         return 0;
380     case QStyle::PM_SmallIconSize:
381         return 16;
382     case QStyle::PM_LargeIconSize:
383         return 32;
384     case QStyle::PM_DockWidgetTitleMargin:
385         return 2;
386     case QStyle::PM_DockWidgetTitleBarButtonMargin:
387     case QStyle::PM_DockWidgetFrameWidth:
388         return 4;
389 
390 #endif // QT_CONFIG(menu)
391     case QStyle::PM_ToolBarHandleExtent:
392         return 10;
393     default:
394         break;
395     }
396     return QWindowsStylePrivate::InvalidMetric;
397 }
398 
screenOf(const QWidget * w)399 static QScreen *screenOf(const QWidget *w)
400 {
401     if (w) {
402         if (auto screen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen())
403             return screen;
404     }
405     return QGuiApplication::primaryScreen();
406 }
407 
408 // Calculate the overall scale factor to obtain Qt Device Independent
409 // Pixels from a native Windows size. Divide by devicePixelRatio
410 // and account for secondary screens with differing logical DPI.
nativeMetricScaleFactor(const QWidget * widget)411 qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget)
412 {
413     qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget);
414     if (QGuiApplicationPrivate::screen_list.size() > 1) {
415         const QScreen *primaryScreen = QGuiApplication::primaryScreen();
416         const QScreen *screen = screenOf(widget);
417         if (screen != primaryScreen) {
418             const qreal primaryLogicalDpi = primaryScreen->handle()->logicalDpi().first;
419             const qreal logicalDpi = screen->handle()->logicalDpi().first;
420             if (!qFuzzyCompare(primaryLogicalDpi, logicalDpi))
421                 result *= logicalDpi / primaryLogicalDpi;
422         }
423     }
424     return result;
425 }
426 
427 /*!
428   \reimp
429 */
pixelMetric(PixelMetric pm,const QStyleOption * opt,const QWidget * widget) const430 int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
431 {
432     int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget);
433     if (ret != QWindowsStylePrivate::InvalidMetric)
434         return qRound(qreal(ret) * QWindowsStylePrivate::nativeMetricScaleFactor(widget));
435 
436     ret = QWindowsStylePrivate::fixedPixelMetric(pm);
437     if (ret != QWindowsStylePrivate::InvalidMetric)
438         return int(QStyleHelper::dpiScaled(ret, opt));
439 
440     ret = 0;
441 
442     switch (pm) {
443     case PM_MaximumDragDistance:
444         ret = QCommonStyle::pixelMetric(PM_MaximumDragDistance);
445         if (ret == -1)
446             ret = 60;
447         break;
448 
449 #if QT_CONFIG(slider)
450         // Returns the number of pixels to use for the business part of the
451         // slider (i.e., the non-tickmark portion). The remaining space is shared
452         // equally between the tickmark regions.
453     case PM_SliderControlThickness:
454         if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
455             int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
456             int ticks = sl->tickPosition;
457             int n = 0;
458             if (ticks & QSlider::TicksAbove)
459                 ++n;
460             if (ticks & QSlider::TicksBelow)
461                 ++n;
462             if (!n) {
463                 ret = space;
464                 break;
465             }
466 
467             int thick = 6;        // Magic constant to get 5 + 16 + 5
468             if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
469                 thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;
470 
471             space -= thick;
472             if (space > 0)
473                 thick += (space * 2) / (n + 2);
474             ret = thick;
475         }
476         break;
477 #endif // QT_CONFIG(slider)
478 
479     case PM_IconViewIconSize:
480         ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
481         break;
482 
483     case PM_SplitterWidth:
484         ret = qMax(int(QStyleHelper::dpiScaled(4, opt)), QApplication::globalStrut().width());
485         break;
486 
487     default:
488         ret = QCommonStyle::pixelMetric(pm, opt, widget);
489         break;
490     }
491 
492     return ret;
493 }
494 
495 /*!
496  \reimp
497  */
standardPixmap(StandardPixmap standardPixmap,const QStyleOption * opt,const QWidget * widget) const498 QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
499                                       const QWidget *widget) const
500 {
501 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
502     QPixmap desktopIcon;
503     switch(standardPixmap) {
504     case SP_DriveCDIcon:
505     case SP_DriveDVDIcon:
506     case SP_DriveNetIcon:
507     case SP_DriveHDIcon:
508     case SP_DriveFDIcon:
509     case SP_FileIcon:
510     case SP_FileLinkIcon:
511     case SP_DirLinkIcon:
512     case SP_DirClosedIcon:
513     case SP_DesktopIcon:
514     case SP_ComputerIcon:
515     case SP_DirOpenIcon:
516     case SP_FileDialogNewFolder:
517     case SP_DirHomeIcon:
518     case SP_TrashIcon:
519     case SP_VistaShield:
520         if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
521             QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap);
522             desktopIcon = theme->standardPixmap(sp, QSizeF(16, 16));
523         }
524         break;
525     case SP_MessageBoxInformation:
526     case SP_MessageBoxWarning:
527     case SP_MessageBoxCritical:
528     case SP_MessageBoxQuestion:
529         if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
530             QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap);
531             desktopIcon = theme->standardPixmap(sp, QSizeF());
532         }
533         break;
534     default:
535         break;
536     }
537     if (!desktopIcon.isNull()) {
538         return desktopIcon;
539     }
540 #endif // Q_OS_WIN && !Q_OS_WINRT
541     return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
542 }
543 
544 /*! \reimp */
styleHint(StyleHint hint,const QStyleOption * opt,const QWidget * widget,QStyleHintReturn * returnData) const545 int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
546                              QStyleHintReturn *returnData) const
547 {
548     int ret = 0;
549 
550     switch (hint) {
551     case SH_EtchDisabledText:
552         ret = d_func()->isDarkMode() ? 0 : 1;
553         break;
554     case SH_Slider_SnapToValue:
555     case SH_PrintDialog_RightAlignButtons:
556     case SH_FontDialog_SelectAssociatedText:
557     case SH_Menu_AllowActiveAndDisabled:
558     case SH_MenuBar_AltKeyNavigation:
559     case SH_MenuBar_MouseTracking:
560     case SH_Menu_MouseTracking:
561     case SH_ComboBox_ListMouseTracking:
562     case SH_Slider_StopMouseOverSlider:
563     case SH_MainWindow_SpaceBelowMenuBar:
564         ret = 1;
565 
566         break;
567     case SH_ItemView_ShowDecorationSelected:
568 #if QT_CONFIG(listview)
569         if (qobject_cast<const QListView*>(widget))
570             ret = 1;
571 #endif
572         break;
573     case SH_ItemView_ChangeHighlightOnFocus:
574         ret = 1;
575         break;
576     case SH_ToolBox_SelectedPageTitleBold:
577         ret = 0;
578         break;
579 
580 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Option not used on WinRT -> common style
581     case SH_UnderlineShortcut:
582     {
583         ret = 1;
584         BOOL cues = false;
585         SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
586         ret = int(cues);
587         // Do nothing if we always paint underlines
588         Q_D(const QWindowsStyle);
589         if (!ret && widget && d) {
590 #if QT_CONFIG(menubar)
591             const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget);
592             if (!menuBar && qobject_cast<const QMenu *>(widget)) {
593                 QWidget *w = QApplication::activeWindow();
594                 if (w && w != widget)
595                     menuBar = w->findChild<QMenuBar *>();
596             }
597             // If we paint a menu bar draw underlines if is in the keyboardState
598             if (menuBar) {
599                 if (menuBar->d_func()->keyboardState || d->altDown())
600                     ret = 1;
601                 // Otherwise draw underlines if the toplevel widget has seen an alt-press
602             } else
603 #endif // QT_CONFIG(menubar)
604             if (d->hasSeenAlt(widget)) {
605                 ret = 1;
606             }
607         }
608 #ifndef QT_NO_ACCESSIBILITY
609         if (!ret && opt && opt->type == QStyleOption::SO_MenuItem
610             && QStyleHelper::isInstanceOf(opt->styleObject, QAccessible::MenuItem)
611             && opt->styleObject->property("_q_showUnderlined").toBool())
612             ret = 1;
613 #endif // QT_NO_ACCESSIBILITY
614         break;
615     }
616 #endif // Q_OS_WIN && !Q_OS_WINRT
617     case SH_Menu_SubMenuSloppyCloseTimeout:
618     case SH_Menu_SubMenuPopupDelay: {
619 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
620         DWORD delay;
621         if (SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0))
622             ret = delay;
623         else
624 #endif // Q_OS_WIN && !Q_OS_WINRT
625             ret = 400;
626         break;
627     }
628 #if QT_CONFIG(rubberband)
629     case SH_RubberBand_Mask:
630         if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
631             ret = 0;
632             if (rbOpt->shape == QRubberBand::Rectangle) {
633                 ret = true;
634                 if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
635                     mask->region = opt->rect;
636                     int size = 1;
637                     if (widget && widget->isWindow())
638                         size = 4;
639                     mask->region -= opt->rect.adjusted(size, size, -size, -size);
640                 }
641             }
642         }
643         break;
644 #endif // QT_CONFIG(rubberband)
645 #if QT_CONFIG(wizard)
646     case SH_WizardStyle:
647         ret = QWizard::ModernStyle;
648         break;
649 #endif
650     case SH_ItemView_ArrowKeysNavigateIntoChildren:
651         ret = true;
652         break;
653     case SH_DialogButtonBox_ButtonsHaveIcons:
654         ret = 0;
655         break;
656     default:
657         ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
658         break;
659     }
660     return ret;
661 }
662 
663 /*! \reimp */
drawPrimitive(PrimitiveElement pe,const QStyleOption * opt,QPainter * p,const QWidget * w) const664 void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
665                                   const QWidget *w) const
666 {
667     // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox
668     bool doRestore = false;
669 
670     switch (pe) {
671 #if QT_CONFIG(toolbar)
672   case PE_IndicatorToolBarSeparator:
673         {
674             QRect rect = opt->rect;
675             const int margin = 2;
676             QPen oldPen = p->pen();
677             if(opt->state & State_Horizontal){
678                 const int offset = rect.width()/2;
679                 p->setPen(QPen(opt->palette.dark().color()));
680                 p->drawLine(rect.bottomLeft().x() + offset,
681                             rect.bottomLeft().y() - margin,
682                             rect.topLeft().x() + offset,
683                             rect.topLeft().y() + margin);
684                 p->setPen(QPen(opt->palette.light().color()));
685                 p->drawLine(rect.bottomLeft().x() + offset + 1,
686                             rect.bottomLeft().y() - margin,
687                             rect.topLeft().x() + offset + 1,
688                             rect.topLeft().y() + margin);
689             }
690             else{ //Draw vertical separator
691                 const int offset = rect.height()/2;
692                 p->setPen(QPen(opt->palette.dark().color()));
693                 p->drawLine(rect.topLeft().x() + margin ,
694                             rect.topLeft().y() + offset,
695                             rect.topRight().x() - margin,
696                             rect.topRight().y() + offset);
697                 p->setPen(QPen(opt->palette.light().color()));
698                 p->drawLine(rect.topLeft().x() + margin ,
699                             rect.topLeft().y() + offset + 1,
700                             rect.topRight().x() - margin,
701                             rect.topRight().y() + offset + 1);
702             }
703             p->setPen(oldPen);
704         }
705         break;
706     case PE_IndicatorToolBarHandle:
707         p->save();
708         p->translate(opt->rect.x(), opt->rect.y());
709         if (opt->state & State_Horizontal) {
710             int x = opt->rect.width() / 2 - 4;
711             if (opt->direction == Qt::RightToLeft)
712                 x -= 2;
713             if (opt->rect.height() > 4) {
714                 qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
715                                 opt->palette, false, 1, nullptr);
716                 qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
717                                 opt->palette, false, 1, nullptr);
718             }
719         } else {
720             if (opt->rect.width() > 4) {
721                 int y = opt->rect.height() / 2 - 4;
722                 qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
723                                 opt->palette, false, 1, nullptr);
724                 qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
725                                 opt->palette, false, 1, nullptr);
726             }
727         }
728         p->restore();
729         break;
730 
731 #endif // QT_CONFIG(toolbar)
732     case PE_FrameButtonTool:
733     case PE_PanelButtonTool: {
734         QPen oldPen = p->pen();
735 #if QT_CONFIG(dockwidget)
736         if (w && w->inherits("QDockWidgetTitleButton")) {
737            if (const QWidget *dw = w->parentWidget())
738                 if (dw->isWindow()){
739                     qDrawWinButton(p, opt->rect.adjusted(1, 1, 0, 0), opt->palette, opt->state & (State_Sunken | State_On),
740                            &opt->palette.button());
741 
742                     return;
743                 }
744         }
745 #endif // QT_CONFIG(dockwidget)
746         QBrush fill;
747         bool stippled;
748         bool panel = (pe == PE_PanelButtonTool);
749         if ((!(opt->state & State_Sunken ))
750             && (!(opt->state & State_Enabled)
751                 || !(opt->state & State_MouseOver && opt->state & State_AutoRaise))
752             && (opt->state & State_On)) {
753             fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
754             stippled = true;
755         } else {
756             fill = opt->palette.brush(QPalette::Button);
757             stippled = false;
758         }
759 
760         if (opt->state & (State_Raised | State_Sunken | State_On)) {
761             if (opt->state & State_AutoRaise) {
762                 if(opt->state & (State_Enabled | State_Sunken | State_On)){
763                     if (panel)
764                         qDrawShadePanel(p, opt->rect, opt->palette,
765                                         opt->state & (State_Sunken | State_On), 1, &fill);
766                     else
767                         qDrawShadeRect(p, opt->rect, opt->palette,
768                                        opt->state & (State_Sunken | State_On), 1);
769                 }
770                 if (stippled) {
771                     p->setPen(opt->palette.button().color());
772                     p->drawRect(opt->rect.adjusted(1,1,-2,-2));
773                 }
774             } else {
775                 qDrawWinButton(p, opt->rect, opt->palette,
776                                opt->state & (State_Sunken | State_On), panel ? &fill : nullptr);
777             }
778         } else {
779             p->fillRect(opt->rect, fill);
780         }
781         p->setPen(oldPen);
782         break; }
783     case PE_PanelButtonCommand:
784         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
785             QBrush fill;
786             State flags = opt->state;
787             QPalette pal = opt->palette;
788             QRect r = opt->rect;
789             if (! (flags & State_Sunken) && (flags & State_On))
790                 fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
791             else
792                 fill = pal.brush(QPalette::Button);
793 
794             if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
795                 p->setPen(pal.dark().color());
796                 p->setBrush(fill);
797                 p->drawRect(r.adjusted(0, 0, -1, -1));
798             } else if (flags & (State_Raised | State_On | State_Sunken)) {
799                 qDrawWinButton(p, r, pal, flags & (State_Sunken | State_On),
800                                &fill);
801             } else {
802                 p->fillRect(r, fill);
803             }
804         }
805         break;
806     case PE_FrameDefaultButton: {
807         QPen oldPen = p->pen();
808         p->setPen(QPen(opt->palette.shadow().color(), 0));
809         QRectF rect = opt->rect;
810         const qreal dpi = QStyleHelper::dpi(opt);
811         const qreal topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi);
812         const qreal bottomRightAdjustment = QStyleHelper::dpiScaled(-1.5, dpi);
813         rect.adjust(topLevelAdjustment, topLevelAdjustment,
814                     bottomRightAdjustment, bottomRightAdjustment);
815         p->drawRect(rect);
816         p->setPen(oldPen);
817         break;
818     }
819     case PE_IndicatorCheckBox: {
820         QBrush fill;
821         if (opt->state & State_NoChange)
822             fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern);
823         else if (opt->state & State_Sunken)
824             fill = opt->palette.button();
825         else if (opt->state & State_Enabled)
826             fill = opt->palette.base();
827         else
828             fill = opt->palette.window();
829         p->save();
830         doRestore = true;
831         qDrawWinPanel(p, opt->rect, opt->palette, true, &fill);
832         if (opt->state & State_NoChange)
833             p->setPen(opt->palette.dark().color());
834         else
835             p->setPen(opt->palette.text().color());
836         }
837         Q_FALLTHROUGH();
838     case PE_IndicatorItemViewItemCheck:
839         if (!doRestore) {
840             p->save();
841             doRestore = true;
842         }
843 #if QT_CONFIG(itemviews)
844         if (pe == PE_IndicatorItemViewItemCheck) {
845             const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
846             p->setPen(itemViewOpt
847                       && itemViewOpt->showDecorationSelected
848                       && opt->state & State_Selected
849                         ? opt->palette.highlightedText().color()
850                         : opt->palette.text().color());
851             if (opt->state & State_NoChange)
852                 p->setBrush(opt->palette.brush(QPalette::Button));
853             p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, opt->rect.width() - 2, opt->rect.height() - 2);
854         }
855 #endif // QT_CONFIG(itemviews)
856         if (!(opt->state & State_Off)) {
857             QPointF  points[6];
858             qreal scaleh = opt->rect.width() / 12.0;
859             qreal scalev = opt->rect.height() / 12.0;
860             points[0] = { opt->rect.x() + 3.5 * scaleh, opt->rect.y() + 5.5 * scalev };
861             points[1] = { points[0].x(),                points[0].y() + 2 * scalev };
862             points[2] = { points[1].x() + 2 * scaleh,   points[1].y() + 2 * scalev };
863             points[3] = { points[2].x() + 4 * scaleh,   points[2].y() - 4 * scalev };
864             points[4] = { points[3].x(),                points[3].y() - 2 * scalev };
865             points[5] = { points[4].x() - 4 * scaleh,   points[4].y() + 4 * scalev };
866             p->setPen(QPen(opt->palette.text().color(), 0));
867             p->setBrush(opt->palette.text().color());
868             p->drawPolygon(points, 6);
869         }
870         if (doRestore)
871             p->restore();
872         break;
873     case PE_FrameFocusRect:
874         if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
875             //### check for d->alt_down
876             if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(SH_UnderlineShortcut, opt))
877                 return;
878             QRect r = opt->rect;
879             p->save();
880             p->setBackgroundMode(Qt::TransparentMode);
881             QColor bg_col = fropt->backgroundColor;
882             if (!bg_col.isValid())
883                 bg_col = p->background().color();
884             // Create an "XOR" color.
885             QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
886                               (bg_col.green() ^ 0xff) & 0xff,
887                               (bg_col.blue() ^ 0xff) & 0xff);
888             p->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
889             p->setBrushOrigin(r.topLeft());
890             p->setPen(Qt::NoPen);
891             p->drawRect(r.left(), r.top(), r.width(), 1);    // Top
892             p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom
893             p->drawRect(r.left(), r.top(), 1, r.height());   // Left
894             p->drawRect(r.right(), r.top(), 1, r.height());  // Right
895             p->restore();
896         }
897         break;
898     case PE_IndicatorRadioButton:
899         {
900             QRect r = opt->rect;
901             p->save();
902             p->setRenderHint(QPainter::Antialiasing, true);
903 
904             QPointF circleCenter = r.center() + QPoint(1, 1);
905             qreal radius = (r.width() + (r.width() + 1) % 2) / 2.0 - 1;
906 
907             QPainterPath path1;
908             path1.addEllipse(circleCenter, radius, radius);
909             radius *= 0.85;
910             QPainterPath path2;
911             path2.addEllipse(circleCenter, radius, radius);
912             radius *= 0.85;
913             QPainterPath path3;
914             path3.addEllipse(circleCenter, radius, radius);
915             radius *= 0.5;
916             QPainterPath path4;
917             path4.addEllipse(circleCenter, radius, radius);
918 
919             QPolygon topLeftPol, bottomRightPol;
920             topLeftPol.setPoints(3, r.x(), r.y(), r.x(), r.y() + r.height(), r.x() + r.width(), r.y());
921             bottomRightPol.setPoints(3, r.x(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y());
922 
923             p->setClipRegion(QRegion(topLeftPol));
924             p->setPen(opt->palette.dark().color());
925             p->setBrush(opt->palette.dark().color());
926             p->drawPath(path1);
927             p->setPen(opt->palette.shadow().color());
928             p->setBrush(opt->palette.shadow().color());
929             p->drawPath(path2);
930 
931             p->setClipRegion(QRegion(bottomRightPol));
932             p->setPen(opt->palette.light().color());
933             p->setBrush(opt->palette.light().color());
934             p->drawPath(path1);
935             p->setPen(opt->palette.midlight().color());
936             p->setBrush(opt->palette.midlight().color());
937             p->drawPath(path2);
938 
939             QColor fillColor = ((opt->state & State_Sunken) || !(opt->state & State_Enabled)) ?
940                                 opt->palette.button().color() : opt->palette.base().color();
941 
942             p->setClipping(false);
943             p->setPen(fillColor);
944             p->setBrush(fillColor);
945             p->drawPath(path3);
946 
947             if (opt->state & State_On) {
948                 p->setPen(opt->palette.text().color());
949                 p->setBrush(opt->palette.text());
950                 p->drawPath(path4);
951             }
952             p->restore();
953             break;
954         }
955 #ifndef QT_NO_FRAME
956     case PE_Frame:
957     case PE_FrameMenu:
958         if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
959             if (frame->lineWidth == 2 || pe == PE_Frame) {
960                 QPalette popupPal = frame->palette;
961                 if (pe == PE_FrameMenu) {
962                     popupPal.setColor(QPalette::Light, frame->palette.window().color());
963                     popupPal.setColor(QPalette::Midlight, frame->palette.light().color());
964                 }
965                 if (pe == PE_Frame && (frame->state & State_Raised))
966                     qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken);
967                 else if (pe == PE_Frame && (frame->state & State_Sunken))
968                 {
969                     popupPal.setColor(QPalette::Midlight, frame->palette.window().color());
970                     qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
971                 }
972                 else
973                     qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
974             } else {
975                 QCommonStyle::drawPrimitive(pe, opt, p, w);
976             }
977         } else {
978             QPalette popupPal = opt->palette;
979             popupPal.setColor(QPalette::Light, opt->palette.window().color());
980             popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
981             qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
982         }
983         break;
984 #endif // QT_NO_FRAME
985     case PE_FrameButtonBevel:
986     case PE_PanelButtonBevel: {
987         QBrush fill;
988         bool panel = pe != PE_FrameButtonBevel;
989         p->setBrushOrigin(opt->rect.topLeft());
990         if (!(opt->state & State_Sunken) && (opt->state & State_On))
991             fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
992         else
993             fill = opt->palette.brush(QPalette::Button);
994 
995         if (opt->state & (State_Raised | State_On | State_Sunken)) {
996             qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
997                            panel ? &fill : nullptr);
998         } else {
999             if (panel)
1000                 p->fillRect(opt->rect, fill);
1001             else
1002                 p->drawRect(opt->rect);
1003         }
1004         break; }
1005     case PE_FrameWindow: {
1006          QPalette popupPal = opt->palette;
1007          popupPal.setColor(QPalette::Light, opt->palette.window().color());
1008          popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
1009          qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
1010         break; }
1011 #if QT_CONFIG(dockwidget)
1012     case PE_IndicatorDockWidgetResizeHandle:
1013         break;
1014     case PE_FrameDockWidget:
1015         if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
1016             proxy()->drawPrimitive(QStyle::PE_FrameWindow, opt, p, w);
1017         }
1018     break;
1019 #endif // QT_CONFIG(dockwidget)
1020 
1021     case PE_FrameStatusBarItem:
1022         qDrawShadePanel(p, opt->rect, opt->palette, true, 1, nullptr);
1023         break;
1024 
1025     case PE_IndicatorProgressChunk:
1026         {
1027             bool vertical = false, inverted = false;
1028             if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1029                 vertical = pb->orientation == Qt::Vertical;
1030                 inverted = pb->invertedAppearance;
1031             }
1032 
1033             int space = 2;
1034             int chunksize = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, w) - space;
1035             if (!vertical) {
1036                 if (opt->rect.width() <= chunksize)
1037                     space = 0;
1038 
1039                 if (inverted)
1040                     p->fillRect(opt->rect.x() + space, opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
1041                             opt->palette.brush(QPalette::Highlight));
1042                 else
1043                     p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
1044                                 opt->palette.brush(QPalette::Highlight));
1045             } else {
1046                 if (opt->rect.height() <= chunksize)
1047                     space = 0;
1048 
1049                 if (inverted)
1050                     p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height() - space,
1051                             opt->palette.brush(QPalette::Highlight));
1052                 else
1053                     p->fillRect(opt->rect.x(), opt->rect.y() + space, opt->rect.width(), opt->rect.height() - space,
1054                                 opt->palette.brush(QPalette::Highlight));
1055             }
1056         }
1057         break;
1058 
1059     case PE_FrameTabWidget: {
1060         qDrawWinButton(p, opt->rect, opt->palette, false, nullptr);
1061         break;
1062     }
1063     default:
1064         QCommonStyle::drawPrimitive(pe, opt, p, w);
1065     }
1066 }
1067 
1068 /*! \reimp */
drawControl(ControlElement ce,const QStyleOption * opt,QPainter * p,const QWidget * widget) const1069 void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
1070                                 const QWidget *widget) const
1071 {
1072     switch (ce) {
1073 #if QT_CONFIG(rubberband)
1074     case CE_RubberBand:
1075         if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
1076             // ### workaround for slow general painter path
1077             QPixmap tiledPixmap(16, 16);
1078             QPainter pixmapPainter(&tiledPixmap);
1079             pixmapPainter.setPen(Qt::NoPen);
1080             pixmapPainter.setBrush(Qt::Dense4Pattern);
1081             pixmapPainter.setBackground(Qt::white);
1082             pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
1083             pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
1084             pixmapPainter.end();
1085             tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
1086             p->save();
1087             QRect r = opt->rect;
1088             QStyleHintReturnMask mask;
1089             if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
1090                 p->setClipRegion(mask.region);
1091             p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
1092             p->restore();
1093             return;
1094         }
1095         break;
1096 #endif // QT_CONFIG(rubberband)
1097 
1098 #if QT_CONFIG(menu) && QT_CONFIG(mainwindow)
1099     case CE_MenuBarEmptyArea:
1100         if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
1101             p->fillRect(opt->rect, opt->palette.button());
1102             QPen oldPen = p->pen();
1103             p->setPen(QPen(opt->palette.dark().color()));
1104             p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
1105             p->setPen(oldPen);
1106         }
1107         break;
1108 #endif
1109 #if QT_CONFIG(menu)
1110     case CE_MenuItem:
1111         if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1112             int x, y, w, h;
1113             menuitem->rect.getRect(&x, &y, &w, &h);
1114             int tab = menuitem->tabWidth;
1115             bool dis = !(menuitem->state & State_Enabled);
1116             bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
1117                             ? menuitem->checked : false;
1118             bool act = menuitem->state & State_Selected;
1119 
1120             // windows always has a check column, regardless whether we have an icon or not
1121             int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
1122 
1123             QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
1124             p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill);
1125 
1126             if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
1127                 int yoff = y-1 + h / 2;
1128                 p->setPen(menuitem->palette.dark().color());
1129                 p->drawLine(x + 2, yoff, x + w - 4, yoff);
1130                 p->setPen(menuitem->palette.light().color());
1131                 p->drawLine(x + 2, yoff + 1, x + w - 4, yoff + 1);
1132                 return;
1133             }
1134 
1135             QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
1136             if (!menuitem->icon.isNull() && checked) {
1137                 if (act) {
1138                     qDrawShadePanel(p, vCheckRect,
1139                                     menuitem->palette, true, 1,
1140                                     &menuitem->palette.brush(QPalette::Button));
1141                 } else {
1142                     QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
1143                     qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &fill);
1144                 }
1145             } else if (!act) {
1146                 p->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button));
1147             }
1148 
1149             // On Windows Style, if we have a checkable item and an icon we
1150             // draw the icon recessed to indicate an item is checked. If we
1151             // have no icon, we draw a checkmark instead.
1152             if (!menuitem->icon.isNull()) {
1153                 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1154                 if (act && !dis)
1155                     mode = QIcon::Active;
1156                 QPixmap pixmap;
1157                 if (checked)
1158                     pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
1159                 else
1160                     pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode);
1161                 const int pixw = pixmap.width() / pixmap.devicePixelRatio();
1162                 const int pixh = pixmap.height() / pixmap.devicePixelRatio();
1163                 QRect pmr(0, 0, pixw, pixh);
1164                 pmr.moveCenter(vCheckRect.center());
1165                 p->setPen(menuitem->palette.text().color());
1166                 p->drawPixmap(pmr.topLeft(), pixmap);
1167             } else if (checked) {
1168                 QStyleOptionMenuItem newMi = *menuitem;
1169                 newMi.state = State_None;
1170                 if (!dis)
1171                     newMi.state |= State_Enabled;
1172                 if (act)
1173                     newMi.state |= State_On;
1174                 newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
1175                                                                               menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
1176                                                                               checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
1177                                                                               menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
1178                 proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
1179             }
1180             p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
1181 
1182             QColor discol;
1183             if (dis) {
1184                 discol = menuitem->palette.text().color();
1185                 p->setPen(discol);
1186             }
1187 
1188             int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
1189             int xpos = menuitem->rect.x() + xm;
1190             QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
1191                            w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
1192             QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
1193             QStringRef s(&menuitem->text);
1194             if (!s.isEmpty()) {                     // draw text
1195                 p->save();
1196                 int t = s.indexOf(QLatin1Char('\t'));
1197                 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1198                 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1199                     text_flags |= Qt::TextHideMnemonic;
1200                 text_flags |= Qt::AlignLeft;
1201                 if (t >= 0) {
1202                     QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
1203                         QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1204                     const QString textToDraw = s.mid(t + 1).toString();
1205                     if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
1206                         p->setPen(menuitem->palette.light().color());
1207                         p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1208                         p->setPen(discol);
1209                     }
1210                     p->drawText(vShortcutRect, text_flags, textToDraw);
1211                     s = s.left(t);
1212                 }
1213                 QFont font = menuitem->font;
1214                 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1215                     font.setBold(true);
1216                 p->setFont(font);
1217                 const QString textToDraw = s.left(t).toString();
1218                 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
1219                     p->setPen(menuitem->palette.light().color());
1220                     p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
1221                     p->setPen(discol);
1222                 }
1223                 p->drawText(vTextRect, text_flags, textToDraw);
1224                 p->restore();
1225             }
1226             if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1227                 int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
1228                 PrimitiveElement arrow;
1229                 arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1230                 xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
1231                 QRect  vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
1232                 QStyleOptionMenuItem newMI = *menuitem;
1233                 newMI.rect = vSubMenuRect;
1234                 newMI.state = dis ? State_None : State_Enabled;
1235                 if (act)
1236                     newMI.palette.setColor(QPalette::ButtonText,
1237                                            newMI.palette.highlightedText().color());
1238                 proxy()->drawPrimitive(arrow, &newMI, p, widget);
1239             }
1240 
1241         }
1242         break;
1243 #endif // QT_CONFIG(menu)
1244 #if QT_CONFIG(menubar)
1245     case CE_MenuBarItem:
1246         if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1247             bool active = mbi->state & State_Selected;
1248             bool hasFocus = mbi->state & State_HasFocus;
1249             bool down = mbi->state & State_Sunken;
1250             QStyleOptionMenuItem newMbi = *mbi;
1251             p->fillRect(mbi->rect, mbi->palette.brush(QPalette::Button));
1252             if (active || hasFocus) {
1253                 QBrush b = mbi->palette.brush(QPalette::Button);
1254                 if (active && down)
1255                     p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1));
1256                 if (active && hasFocus)
1257                     qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(),
1258                                    mbi->rect.height(), mbi->palette, active && down, 1, 0, &b);
1259                 if (active && down) {
1260                     newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget),
1261                                        proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget));
1262                     p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1));
1263                 }
1264             }
1265             QCommonStyle::drawControl(ce, &newMbi, p, widget);
1266         }
1267         break;
1268 #endif // QT_CONFIG(menubar)
1269 #if QT_CONFIG(tabbar)
1270     case CE_TabBarTabShape:
1271         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1272             bool rtlHorTabs = (tab->direction == Qt::RightToLeft
1273                                && (tab->shape == QTabBar::RoundedNorth
1274                                    || tab->shape == QTabBar::RoundedSouth));
1275             bool selected = tab->state & State_Selected;
1276             bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
1277                             || (rtlHorTabs
1278                                 && tab->position == QStyleOptionTab::Beginning));
1279             bool firstTab = ((!rtlHorTabs
1280                                && tab->position == QStyleOptionTab::Beginning)
1281                              || (rtlHorTabs
1282                                  && tab->position == QStyleOptionTab::End));
1283             bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1284             bool previousSelected =
1285                 ((!rtlHorTabs
1286                   && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
1287                 || (rtlHorTabs
1288                     && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
1289             bool nextSelected =
1290                 ((!rtlHorTabs
1291                   && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
1292                  || (rtlHorTabs
1293                      && tab->selectedPosition
1294                             == QStyleOptionTab::PreviousIsSelected));
1295             int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget);
1296             bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
1297                                 || (rtlHorTabs
1298                                     && tabBarAlignment == Qt::AlignRight);
1299 
1300             bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
1301                                  || (rtlHorTabs
1302                                          && tabBarAlignment == Qt::AlignLeft);
1303 
1304             QColor light = tab->palette.light().color();
1305             QColor dark = tab->palette.dark().color();
1306             QColor shadow = tab->palette.shadow().color();
1307             int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
1308             if (selected)
1309                 borderThinkness /= 2;
1310             QRect r2(opt->rect);
1311             int x1 = r2.left();
1312             int x2 = r2.right();
1313             int y1 = r2.top();
1314             int y2 = r2.bottom();
1315             switch (tab->shape) {
1316             default:
1317                 QCommonStyle::drawControl(ce, tab, p, widget);
1318                 break;
1319             case QTabBar::RoundedNorth: {
1320                 if (!selected) {
1321                     y1 += 2;
1322                     x1 += onlyOne || firstTab ? borderThinkness : 0;
1323                     x2 -= onlyOne || lastTab ? borderThinkness : 0;
1324                 }
1325 
1326                 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window());
1327 
1328                 // Delete border
1329                 if (selected) {
1330                     p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window());
1331                     p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window());
1332                 }
1333                 // Left
1334                 if (firstTab || selected || onlyOne || !previousSelected) {
1335                     p->setPen(light);
1336                     p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1337                     p->drawPoint(x1 + 1, y1 + 1);
1338                 }
1339                 // Top
1340                 {
1341                     int beg = x1 + (previousSelected ? 0 : 2);
1342                     int end = x2 - (nextSelected ? 0 : 2);
1343                     p->setPen(light);
1344                     p->drawLine(beg, y1, end, y1);
1345                 }
1346                 // Right
1347                 if (lastTab || selected || onlyOne || !nextSelected) {
1348                     p->setPen(shadow);
1349                     p->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1350                     p->drawPoint(x2 - 1, y1 + 1);
1351                     p->setPen(dark);
1352                     p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1353                 }
1354                 break; }
1355             case QTabBar::RoundedSouth: {
1356                 if (!selected) {
1357                     y2 -= 2;
1358                     x1 += firstTab ? borderThinkness : 0;
1359                     x2 -= lastTab ? borderThinkness : 0;
1360                 }
1361 
1362                 p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1363 
1364                 // Delete border
1365                 if (selected) {
1366                     p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window());
1367                     p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window());
1368                 }
1369                 // Left
1370                 if (firstTab || selected || onlyOne || !previousSelected) {
1371                     p->setPen(light);
1372                     p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
1373                     p->drawPoint(x1 + 1, y2 - 1);
1374                 }
1375                 // Bottom
1376                 {
1377                     int beg = x1 + (previousSelected ? 0 : 2);
1378                     int end = x2 - (nextSelected ? 0 : 2);
1379                     p->setPen(shadow);
1380                     p->drawLine(beg, y2, end, y2);
1381                     p->setPen(dark);
1382                     p->drawLine(beg, y2 - 1, end, y2 - 1);
1383                 }
1384                 // Right
1385                 if (lastTab || selected || onlyOne || !nextSelected) {
1386                     p->setPen(shadow);
1387                     p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1388                     p->drawPoint(x2 - 1, y2 - 1);
1389                     p->setPen(dark);
1390                     p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
1391                 }
1392                 break; }
1393             case QTabBar::RoundedWest: {
1394                 if (!selected) {
1395                     x1 += 2;
1396                     y1 += firstTab ? borderThinkness : 0;
1397                     y2 -= lastTab ? borderThinkness : 0;
1398                 }
1399 
1400                 p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window());
1401 
1402                 // Delete border
1403                 if (selected) {
1404                     p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window());
1405                     p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window());
1406                 }
1407                 // Top
1408                 if (firstTab || selected || onlyOne || !previousSelected) {
1409                     p->setPen(light);
1410                     p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
1411                     p->drawPoint(x1 + 1, y1 + 1);
1412                 }
1413                 // Left
1414                 {
1415                     int beg = y1 + (previousSelected ? 0 : 2);
1416                     int end = y2 - (nextSelected ? 0 : 2);
1417                     p->setPen(light);
1418                     p->drawLine(x1, beg, x1, end);
1419                 }
1420                 // Bottom
1421                 if (lastTab || selected || onlyOne || !nextSelected) {
1422                     p->setPen(shadow);
1423                     p->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1424                     p->drawPoint(x1 + 2, y2 - 1);
1425                     p->setPen(dark);
1426                     p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
1427                     p->drawPoint(x1 + 1, y2 - 1);
1428                     p->drawPoint(x1 + 2, y2);
1429                 }
1430                 break; }
1431             case QTabBar::RoundedEast: {
1432                 if (!selected) {
1433                     x2 -= 2;
1434                     y1 += firstTab ? borderThinkness : 0;
1435                     y2 -= lastTab ? borderThinkness : 0;
1436                 }
1437 
1438                 p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
1439 
1440                 // Delete border
1441                 if (selected) {
1442                     p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window());
1443                     p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window());
1444                 }
1445                 // Top
1446                 if (firstTab || selected || onlyOne || !previousSelected) {
1447                     p->setPen(light);
1448                     p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
1449                     p->drawPoint(x2 - 1, y1 + 1);
1450                 }
1451                 // Right
1452                 {
1453                     int beg = y1 + (previousSelected ? 0 : 2);
1454                     int end = y2 - (nextSelected ? 0 : 2);
1455                     p->setPen(shadow);
1456                     p->drawLine(x2, beg, x2, end);
1457                     p->setPen(dark);
1458                     p->drawLine(x2 - 1, beg, x2 - 1, end);
1459                 }
1460                 // Bottom
1461                 if (lastTab || selected || onlyOne || !nextSelected) {
1462                     p->setPen(shadow);
1463                     p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
1464                     p->drawPoint(x2 - 1, y2 - 1);
1465                     p->setPen(dark);
1466                     p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
1467                 }
1468                 break; }
1469             }
1470         }
1471         break;
1472 #endif // QT_CONFIG(tabbar)
1473     case CE_ToolBoxTabShape:
1474         qDrawShadePanel(p, opt->rect, opt->palette,
1475                         opt->state & (State_Sunken | State_On), 1,
1476                         &opt->palette.brush(QPalette::Button));
1477         break;
1478 #if QT_CONFIG(splitter)
1479     case CE_Splitter:
1480         p->eraseRect(opt->rect);
1481         break;
1482 #endif // QT_CONFIG(splitter)
1483 #if QT_CONFIG(scrollbar)
1484     case CE_ScrollBarSubLine:
1485     case CE_ScrollBarAddLine: {
1486         if ((opt->state & State_Sunken)) {
1487             p->setPen(opt->palette.dark().color());
1488             p->setBrush(opt->palette.brush(QPalette::Button));
1489             p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
1490         } else {
1491             QStyleOption buttonOpt = *opt;
1492             if (!(buttonOpt.state & State_Sunken))
1493                 buttonOpt.state |= State_Raised;
1494             QPalette pal(opt->palette);
1495             pal.setColor(QPalette::Button, opt->palette.light().color());
1496             pal.setColor(QPalette::Light, opt->palette.button().color());
1497             qDrawWinButton(p, opt->rect, pal, opt->state & (State_Sunken | State_On),
1498                            &opt->palette.brush(QPalette::Button));
1499         }
1500         PrimitiveElement arrow;
1501         if (opt->state & State_Horizontal) {
1502             if (ce == CE_ScrollBarAddLine)
1503                 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
1504             else
1505                 arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1506         } else {
1507             if (ce == CE_ScrollBarAddLine)
1508                 arrow = PE_IndicatorArrowDown;
1509             else
1510                 arrow = PE_IndicatorArrowUp;
1511         }
1512         QStyleOption arrowOpt = *opt;
1513         arrowOpt.rect = opt->rect.adjusted(4, 4, -4, -4);
1514         proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
1515         break; }
1516     case CE_ScrollBarAddPage:
1517     case CE_ScrollBarSubPage: {
1518             QBrush br;
1519             QBrush bg = p->background();
1520             Qt::BGMode bg_mode = p->backgroundMode();
1521             p->setPen(Qt::NoPen);
1522             p->setBackgroundMode(Qt::OpaqueMode);
1523 
1524             if (opt->state & State_Sunken) {
1525                 br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
1526                 p->setBackground(opt->palette.dark().color());
1527                 p->setBrush(br);
1528             } else {
1529                 const QBrush paletteBrush = opt->palette.brush(QPalette::Light);
1530                 if (paletteBrush.style() == Qt::TexturePattern) {
1531                     if (qHasPixmapTexture(paletteBrush))
1532                         br = QBrush(paletteBrush.texture());
1533                     else
1534                         br = QBrush(paletteBrush.textureImage());
1535                 } else
1536                     br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1537                 p->setBackground(opt->palette.window().color());
1538                 p->setBrush(br);
1539             }
1540             p->drawRect(opt->rect);
1541             p->setBackground(bg);
1542             p->setBackgroundMode(bg_mode);
1543             break; }
1544     case CE_ScrollBarSlider:
1545         if (!(opt->state & State_Enabled)) {
1546             QBrush br;
1547             const QBrush paletteBrush = opt->palette.brush(QPalette::Light);
1548             if (paletteBrush.style() == Qt::TexturePattern) {
1549                 if (qHasPixmapTexture(paletteBrush))
1550                     br = QBrush(paletteBrush.texture());
1551                 else
1552                     br = QBrush(paletteBrush.textureImage());
1553             } else
1554                 br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1555             p->setPen(Qt::NoPen);
1556             p->setBrush(br);
1557             p->setBackgroundMode(Qt::OpaqueMode);
1558             p->drawRect(opt->rect);
1559         } else {
1560             QStyleOptionButton buttonOpt;
1561             buttonOpt.QStyleOption::operator=(*opt);
1562             buttonOpt.state = State_Enabled | State_Raised;
1563 
1564             QPalette pal(opt->palette);
1565             pal.setColor(QPalette::Button, opt->palette.light().color());
1566             pal.setColor(QPalette::Light, opt->palette.button().color());
1567             qDrawWinButton(p, opt->rect, pal, false, &opt->palette.brush(QPalette::Button));
1568         }
1569         break;
1570 #endif // QT_CONFIG(scrollbar)
1571     case CE_HeaderSection: {
1572         QBrush fill;
1573         if (opt->state & State_On)
1574             fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
1575         else
1576             fill = opt->palette.brush(QPalette::Button);
1577 
1578         if (opt->state & (State_Raised | State_Sunken)) {
1579             qDrawWinButton(p, opt->rect, opt->palette, opt->state & State_Sunken, &fill);
1580         } else {
1581             p->fillRect(opt->rect, fill);
1582         }
1583         break; }
1584 #if QT_CONFIG(toolbar)
1585     case CE_ToolBar:
1586         if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
1587             // Reserve the beveled appearance only for mainwindow toolbars
1588             if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget())))
1589                 break;
1590 
1591             QRect rect = opt->rect;
1592             bool paintLeftBorder = true;
1593             bool paintRightBorder = true;
1594             bool paintBottomBorder = true;
1595 
1596             switch (toolbar->toolBarArea){
1597             case Qt::BottomToolBarArea :
1598                 switch(toolbar->positionOfLine){
1599                 case QStyleOptionToolBar::Beginning:
1600                 case QStyleOptionToolBar::OnlyOne:
1601                     paintBottomBorder = false;
1602                     break;
1603                 default:
1604                     break;
1605                 }
1606                 Q_FALLTHROUGH(); // It continues in the end of the next case
1607             case Qt::TopToolBarArea :
1608                 switch(toolbar->positionWithinLine){
1609                 case QStyleOptionToolBar::Beginning:
1610                     paintLeftBorder = false;
1611                     break;
1612                 case QStyleOptionToolBar::End:
1613                     paintRightBorder = false;
1614                     break;
1615                 case QStyleOptionToolBar::OnlyOne:
1616                     paintRightBorder = false;
1617                     paintLeftBorder = false;
1618                     break;
1619                 default:
1620                     break;
1621                 }
1622                 if(opt->direction == Qt::RightToLeft){ //reverse layout changes the order of Beginning/end
1623                     bool tmp = paintLeftBorder;
1624                     paintRightBorder=paintLeftBorder;
1625                     paintLeftBorder=tmp;
1626                 }
1627                 break;
1628             case Qt::RightToolBarArea :
1629                 switch (toolbar->positionOfLine){
1630                 case QStyleOptionToolBar::Beginning:
1631                 case QStyleOptionToolBar::OnlyOne:
1632                     paintRightBorder = false;
1633                     break;
1634                 default:
1635                     break;
1636                 }
1637                 break;
1638             case Qt::LeftToolBarArea :
1639                 switch (toolbar->positionOfLine){
1640                 case QStyleOptionToolBar::Beginning:
1641                 case QStyleOptionToolBar::OnlyOne:
1642                     paintLeftBorder = false;
1643                     break;
1644                 default:
1645                     break;
1646                 }
1647                 break;
1648             default:
1649                 break;
1650             }
1651 
1652 
1653             //draw top border
1654             p->setPen(QPen(opt->palette.light().color()));
1655             p->drawLine(rect.topLeft().x(),
1656                         rect.topLeft().y(),
1657                         rect.topRight().x(),
1658                         rect.topRight().y());
1659 
1660             if (paintLeftBorder){
1661                 p->setPen(QPen(opt->palette.light().color()));
1662                 p->drawLine(rect.topLeft().x(),
1663                             rect.topLeft().y(),
1664                             rect.bottomLeft().x(),
1665                             rect.bottomLeft().y());
1666             }
1667 
1668             if (paintRightBorder){
1669                 p->setPen(QPen(opt->palette.dark().color()));
1670                 p->drawLine(rect.topRight().x(),
1671                             rect.topRight().y(),
1672                             rect.bottomRight().x(),
1673                             rect.bottomRight().y());
1674             }
1675 
1676             if (paintBottomBorder){
1677                 p->setPen(QPen(opt->palette.dark().color()));
1678                 p->drawLine(rect.bottomLeft().x(),
1679                             rect.bottomLeft().y(),
1680                             rect.bottomRight().x(),
1681                             rect.bottomRight().y());
1682             }
1683         }
1684         break;
1685 
1686 
1687 #endif // QT_CONFIG(toolbar)
1688 
1689     case CE_ProgressBarContents:
1690         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1691             QRect rect = pb->rect;
1692             if (!rect.isValid())
1693                 return;
1694 
1695             const bool vertical = pb->orientation == Qt::Vertical;
1696             const bool inverted = pb->invertedAppearance;
1697 
1698             QTransform m;
1699             if (vertical) {
1700                 rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
1701                 m.rotate(90);
1702                 m.translate(0, -(rect.height() + rect.y()*2));
1703             }
1704             QPalette pal2 = pb->palette;
1705             // Correct the highlight color if it is the same as the background
1706             if (pal2.highlight() == pal2.window())
1707                 pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
1708                                                                      QPalette::Highlight));
1709             bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1710             if (inverted)
1711                 reverse = !reverse;
1712             int w = rect.width();
1713             Q_D(const QWindowsStyle);
1714             if (pb->minimum == 0 && pb->maximum == 0) {
1715                 const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
1716                 QStyleOptionProgressBar pbBits = *pb;
1717                 Q_ASSERT(unit_width >0);
1718 
1719                 pbBits.rect = rect;
1720                 pbBits.palette = pal2;
1721 
1722                 int step = 0;
1723                 int chunkCount = w / unit_width + 1;
1724 #if QT_CONFIG(animation)
1725                 if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject)))
1726                     step = (animation->animationStep() / 3) % chunkCount;
1727                 else
1728                     d->startAnimation(new QProgressStyleAnimation(d->animationFps, opt->styleObject));
1729 #else
1730                 Q_UNUSED(d);
1731 #endif
1732                 int chunksInRow = 5;
1733                 int myY = pbBits.rect.y();
1734                 int myHeight = pbBits.rect.height();
1735                 int chunksToDraw = chunksInRow;
1736 
1737                 if(step > chunkCount - 5)chunksToDraw = (chunkCount - step);
1738                 p->save();
1739                 p->setClipRect(m.mapRect(QRectF(rect)).toRect());
1740 
1741                 int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width  : rect.left() + unit_width * step;
1742                 int x = 0;
1743 
1744                 for (int i = 0; i < chunksToDraw ; ++i) {
1745                     pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
1746                     pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1747                     proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1748                     x += reverse ? -unit_width : unit_width;
1749                 }
1750                 //Draw wrap-around chunks
1751                 if( step > chunkCount-5){
1752                     x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ;
1753                     x = 0;
1754                     int chunksToDraw = step - (chunkCount - chunksInRow);
1755                     for (int i = 0; i < chunksToDraw ; ++i) {
1756                         pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
1757                         pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1758                         proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1759                         x += reverse ? -unit_width : unit_width;
1760                     }
1761                 }
1762                 p->restore(); //restore state
1763             }
1764             else {
1765 #if QT_CONFIG(animation)
1766                 d->stopAnimation(opt->styleObject);
1767 #endif
1768                 QCommonStyle::drawControl(ce, opt, p, widget);
1769             }
1770         }
1771         break;
1772 
1773 #if QT_CONFIG(dockwidget)
1774     case CE_DockWidgetTitle:
1775 
1776         if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
1777             Q_D(const QWindowsStyle);
1778 
1779             const bool verticalTitleBar = dwOpt->verticalTitleBar;
1780 
1781             QRect rect = dwOpt->rect;
1782             QRect r = rect;
1783 
1784             if (verticalTitleBar) {
1785                 r = r.transposed();
1786 
1787                 p->save();
1788                 p->translate(r.left(), r.top() + r.width());
1789                 p->rotate(-90);
1790                 p->translate(-r.left(), -r.top());
1791             }
1792 
1793             bool floating = false;
1794             bool active = dwOpt->state & State_Active;
1795             QColor inactiveCaptionTextColor = d->inactiveCaptionText;
1796             if (dwOpt->movable) {
1797                 QColor left, right;
1798 
1799                 //Titlebar gradient
1800                 if (opt->state & QStyle::State_Window) {
1801                     floating = true;
1802                     if (active) {
1803                         left = d->activeCaptionColor;
1804                         right = d->activeGradientCaptionColor;
1805                     } else {
1806                         left = d->inactiveCaptionColor;
1807                         right = d->inactiveGradientCaptionColor;
1808                     }
1809                     QBrush fillBrush(left);
1810                     if (left != right) {
1811                         QPoint p1(r.x(), r.top() + r.height()/2);
1812                         QPoint p2(rect.right(), r.top() + r.height()/2);
1813                         QLinearGradient lg(p1, p2);
1814                         lg.setColorAt(0, left);
1815                         lg.setColorAt(1, right);
1816                         fillBrush = lg;
1817                     }
1818                     p->fillRect(r.adjusted(0, 0, 0, -3), fillBrush);
1819                 }
1820             }
1821             if (!dwOpt->title.isEmpty()) {
1822                 QFont oldFont = p->font();
1823                 if (floating) {
1824                     QFont font = oldFont;
1825                     font.setBold(true);
1826                     p->setFont(font);
1827                 }
1828                 QPalette palette = dwOpt->palette;
1829                 palette.setColor(QPalette::Window, inactiveCaptionTextColor);
1830                 QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, widget);
1831                 if (verticalTitleBar) {
1832                     titleRect = QRect(r.left() + rect.bottom()
1833                                         - titleRect.bottom(),
1834                                     r.top() + titleRect.left() - rect.left(),
1835                                     titleRect.height(), titleRect.width());
1836                 }
1837                 proxy()->drawItemText(p, titleRect,
1838                             Qt::AlignLeft | Qt::AlignVCenter, palette,
1839                             dwOpt->state & State_Enabled, dwOpt->title,
1840                             floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
1841                 p->setFont(oldFont);
1842             }
1843             if (verticalTitleBar)
1844                 p->restore();
1845         }
1846         return;
1847 #endif // QT_CONFIG(dockwidget)
1848 #if QT_CONFIG(combobox)
1849     case CE_ComboBoxLabel:
1850         if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
1851             if (cb->state & State_HasFocus) {
1852                 p->setPen(cb->palette.highlightedText().color());
1853                 p->setBackground(cb->palette.highlight());
1854             } else {
1855                 p->setPen(cb->palette.text().color());
1856                 p->setBackground(cb->palette.window());
1857             }
1858         }
1859         QCommonStyle::drawControl(ce, opt, p, widget);
1860         break;
1861 #endif // QT_CONFIG(combobox)
1862     default:
1863         QCommonStyle::drawControl(ce, opt, p, widget);
1864     }
1865 }
1866 
1867 /*! \reimp */
subElementRect(SubElement sr,const QStyleOption * opt,const QWidget * w) const1868 QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
1869 {
1870     QRect r;
1871     switch (sr) {
1872     case SE_SliderFocusRect:
1873     case SE_ToolBoxTabContents:
1874         r = visualRect(opt->direction, opt->rect, opt->rect);
1875         break;
1876     case SE_DockWidgetTitleBarText: {
1877         r = QCommonStyle::subElementRect(sr, opt, w);
1878         const QStyleOptionDockWidget *dwOpt
1879             = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
1880         const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
1881         int m = proxy()->pixelMetric(PM_DockWidgetTitleMargin, opt, w);
1882         if (verticalTitleBar) {
1883             r.adjust(0, 0, 0, -m);
1884         } else {
1885             if (opt->direction == Qt::LeftToRight)
1886                 r.adjust(m, 0, 0, 0);
1887             else
1888                 r.adjust(0, 0, -m, 0);
1889         }
1890         break;
1891     }
1892     case SE_ProgressBarContents:
1893         r = QCommonStyle::subElementRect(SE_ProgressBarGroove, opt, w);
1894         r.adjust(3, 3, -3, -3);
1895         break;
1896     default:
1897         r = QCommonStyle::subElementRect(sr, opt, w);
1898     }
1899     return r;
1900 }
1901 
1902 
1903 /*! \reimp */
drawComplexControl(ComplexControl cc,const QStyleOptionComplex * opt,QPainter * p,const QWidget * widget) const1904 void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
1905                                        QPainter *p, const QWidget *widget) const
1906 {
1907     switch (cc) {
1908 #if QT_CONFIG(slider)
1909     case CC_Slider:
1910         if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1911             int thickness  = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
1912             int len        = proxy()->pixelMetric(PM_SliderLength, slider, widget);
1913             int ticks = slider->tickPosition;
1914             QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
1915             QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
1916 
1917             if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
1918                 int mid = thickness / 2;
1919 
1920                 if (ticks & QSlider::TicksAbove)
1921                     mid += len / 8;
1922                 if (ticks & QSlider::TicksBelow)
1923                     mid -= len / 8;
1924 
1925                 p->setPen(slider->palette.shadow().color());
1926                 if (slider->orientation == Qt::Horizontal) {
1927                     qDrawWinPanel(p, groove.x(), groove.y() + mid - 2,
1928                                    groove.width(), 4, slider->palette, true);
1929                     p->drawLine(groove.x() + 1, groove.y() + mid - 1,
1930                                 groove.x() + groove.width() - 3, groove.y() + mid - 1);
1931                 } else {
1932                     qDrawWinPanel(p, groove.x() + mid - 2, groove.y(),
1933                                   4, groove.height(), slider->palette, true);
1934                     p->drawLine(groove.x() + mid - 1, groove.y() + 1,
1935                                 groove.x() + mid - 1, groove.y() + groove.height() - 3);
1936                 }
1937             }
1938 
1939             if (slider->subControls & SC_SliderTickmarks) {
1940                 QStyleOptionSlider tmpSlider = *slider;
1941                 tmpSlider.subControls = SC_SliderTickmarks;
1942                 QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
1943             }
1944 
1945             if (slider->subControls & SC_SliderHandle) {
1946                 // 4444440
1947                 // 4333310
1948                 // 4322210
1949                 // 4322210
1950                 // 4322210
1951                 // 4322210
1952                 // *43210*
1953                 // **410**
1954                 // ***0***
1955                 const QColor c0 = slider->palette.shadow().color();
1956                 const QColor c1 = slider->palette.dark().color();
1957                 // const QColor c2 = g.button();
1958                 const QColor c3 = slider->palette.midlight().color();
1959                 const QColor c4 = slider->palette.light().color();
1960                 QBrush handleBrush;
1961 
1962                 if (slider->state & State_Enabled) {
1963                     handleBrush = slider->palette.color(QPalette::Button);
1964                 } else {
1965                     handleBrush = QBrush(slider->palette.color(QPalette::Button),
1966                                          Qt::Dense4Pattern);
1967                 }
1968 
1969 
1970                 int x = handle.x(), y = handle.y(),
1971                    wi = handle.width(), he = handle.height();
1972 
1973                 int x1 = x;
1974                 int x2 = x+wi-1;
1975                 int y1 = y;
1976                 int y2 = y+he-1;
1977 
1978                 Qt::Orientation orient = slider->orientation;
1979                 bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
1980                 bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
1981 
1982                 if (slider->state & State_HasFocus) {
1983                     QStyleOptionFocusRect fropt;
1984                     fropt.QStyleOption::operator=(*slider);
1985                     fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
1986                     proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1987                 }
1988 
1989                 if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
1990                     Qt::BGMode oldMode = p->backgroundMode();
1991                     p->setBackgroundMode(Qt::OpaqueMode);
1992                     qDrawWinButton(p, QRect(x, y, wi, he), slider->palette, false,
1993                                    &handleBrush);
1994                     p->setBackgroundMode(oldMode);
1995                     return;
1996                 }
1997 
1998                 QSliderDirection dir;
1999 
2000                 if (orient == Qt::Horizontal)
2001                     if (tickAbove)
2002                         dir = SlUp;
2003                     else
2004                         dir = SlDown;
2005                 else
2006                     if (tickAbove)
2007                         dir = SlLeft;
2008                     else
2009                         dir = SlRight;
2010 
2011                 QPolygon a;
2012 
2013                 int d = 0;
2014                 switch (dir) {
2015                 case SlUp:
2016                     y1 = y1 + wi/2;
2017                     d =  (wi + 1) / 2 - 1;
2018                     a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d);
2019                     break;
2020                 case SlDown:
2021                     y2 = y2 - wi/2;
2022                     d =  (wi + 1) / 2 - 1;
2023                     a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1);
2024                     break;
2025                 case SlLeft:
2026                     d =  (he + 1) / 2 - 1;
2027                     x1 = x1 + he/2;
2028                     a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1);
2029                     break;
2030                 case SlRight:
2031                     d =  (he + 1) / 2 - 1;
2032                     x2 = x2 - he/2;
2033                     a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1);
2034                     break;
2035                 }
2036 
2037                 QBrush oldBrush = p->brush();
2038                 bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
2039                 p->setPen(Qt::NoPen);
2040                 p->setBrush(handleBrush);
2041                 p->setRenderHint(QPainter::Qt4CompatiblePainting);
2042                 Qt::BGMode oldMode = p->backgroundMode();
2043                 p->setBackgroundMode(Qt::OpaqueMode);
2044                 p->drawRect(x1, y1, x2-x1+1, y2-y1+1);
2045                 p->drawPolygon(a);
2046                 p->setBrush(oldBrush);
2047                 p->setBackgroundMode(oldMode);
2048 
2049                 if (dir != SlUp) {
2050                     p->setPen(c4);
2051                     p->drawLine(x1, y1, x2, y1);
2052                     p->setPen(c3);
2053                     p->drawLine(x1, y1+1, x2, y1+1);
2054                 }
2055                 if (dir != SlLeft) {
2056                     p->setPen(c3);
2057                     p->drawLine(x1+1, y1+1, x1+1, y2);
2058                     p->setPen(c4);
2059                     p->drawLine(x1, y1, x1, y2);
2060                 }
2061                 if (dir != SlRight) {
2062                     p->setPen(c0);
2063                     p->drawLine(x2, y1, x2, y2);
2064                     p->setPen(c1);
2065                     p->drawLine(x2-1, y1+1, x2-1, y2-1);
2066                 }
2067                 if (dir != SlDown) {
2068                     p->setPen(c0);
2069                     p->drawLine(x1, y2, x2, y2);
2070                     p->setPen(c1);
2071                     p->drawLine(x1+1, y2-1, x2-1, y2-1);
2072                 }
2073 
2074                 switch (dir) {
2075                 case SlUp:
2076                     p->setPen(c4);
2077                     p->drawLine(x1, y1, x1+d, y1-d);
2078                     p->setPen(c0);
2079                     d = wi - d - 1;
2080                     p->drawLine(x2, y1, x2-d, y1-d);
2081                     d--;
2082                     p->setPen(c3);
2083                     p->drawLine(x1+1, y1, x1+1+d, y1-d);
2084                     p->setPen(c1);
2085                     p->drawLine(x2-1, y1, x2-1-d, y1-d);
2086                     break;
2087                 case SlDown:
2088                     p->setPen(c4);
2089                     p->drawLine(x1, y2, x1+d, y2+d);
2090                     p->setPen(c0);
2091                     d = wi - d - 1;
2092                     p->drawLine(x2, y2, x2-d, y2+d);
2093                     d--;
2094                     p->setPen(c3);
2095                     p->drawLine(x1+1, y2, x1+1+d, y2+d);
2096                     p->setPen(c1);
2097                     p->drawLine(x2-1, y2, x2-1-d, y2+d);
2098                     break;
2099                 case SlLeft:
2100                     p->setPen(c4);
2101                     p->drawLine(x1, y1, x1-d, y1+d);
2102                     p->setPen(c0);
2103                     d = he - d - 1;
2104                     p->drawLine(x1, y2, x1-d, y2-d);
2105                     d--;
2106                     p->setPen(c3);
2107                     p->drawLine(x1, y1+1, x1-d, y1+1+d);
2108                     p->setPen(c1);
2109                     p->drawLine(x1, y2-1, x1-d, y2-1-d);
2110                     break;
2111                 case SlRight:
2112                     p->setPen(c4);
2113                     p->drawLine(x2, y1, x2+d, y1+d);
2114                     p->setPen(c0);
2115                     d = he - d - 1;
2116                     p->drawLine(x2, y2, x2+d, y2-d);
2117                     d--;
2118                     p->setPen(c3);
2119                     p->drawLine(x2, y1+1, x2+d, y1+1+d);
2120                     p->setPen(c1);
2121                     p->drawLine(x2, y2-1, x2+d, y2-1-d);
2122                     break;
2123                 }
2124                 p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
2125             }
2126         }
2127         break;
2128 #endif // QT_CONFIG(slider)
2129 #if QT_CONFIG(scrollbar)
2130     case CC_ScrollBar:
2131         if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2132             QStyleOptionSlider newScrollbar = *scrollbar;
2133             if (scrollbar->minimum == scrollbar->maximum)
2134                 newScrollbar.state &= ~State_Enabled; //do not draw the slider.
2135             QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
2136         }
2137         break;
2138 #endif // QT_CONFIG(scrollbar)
2139 #if QT_CONFIG(combobox)
2140     case CC_ComboBox:
2141         if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2142             QBrush editBrush = cmb->palette.brush(QPalette::Button);
2143             if ((cmb->subControls & SC_ComboBoxFrame)) {
2144                 if (cmb->frame) {
2145                     QPalette shadePal = opt->palette;
2146                     shadePal.setColor(QPalette::Midlight, shadePal.button().color());
2147                     qDrawWinPanel(p, opt->rect, shadePal, true, &editBrush);
2148                 }
2149                 else {
2150                     p->fillRect(opt->rect, editBrush);
2151                 }
2152             }
2153             if (cmb->subControls & SC_ComboBoxArrow) {
2154                 State flags = State_None;
2155 
2156                 QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
2157                 bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow
2158                                    && cmb->state & State_Sunken;
2159                 if (sunkenArrow) {
2160                     p->setPen(cmb->palette.dark().color());
2161                     p->setBrush(cmb->palette.brush(QPalette::Button));
2162                     p->drawRect(ar.adjusted(0,0,-1,-1));
2163                 } else {
2164                     // Make qDrawWinButton use the right colors for drawing the shade of the button
2165                     QPalette pal(cmb->palette);
2166                     pal.setColor(QPalette::Button, cmb->palette.light().color());
2167                     pal.setColor(QPalette::Light, cmb->palette.button().color());
2168                     qDrawWinButton(p, ar, pal, false,
2169                                    &cmb->palette.brush(QPalette::Button));
2170                 }
2171 
2172                 ar.adjust(2, 2, -2, -2);
2173                 if (opt->state & State_Enabled)
2174                     flags |= State_Enabled;
2175                 if (opt->state & State_HasFocus)
2176                     flags |= State_HasFocus;
2177 
2178                 if (sunkenArrow)
2179                     flags |= State_Sunken;
2180                 QStyleOption arrowOpt = *cmb;
2181                 arrowOpt.rect = ar.adjusted(1, 1, -1, -1);
2182                 arrowOpt.state = flags;
2183                 proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
2184             }
2185 
2186             if (cmb->subControls & SC_ComboBoxEditField) {
2187                 QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
2188                 if (cmb->state & State_HasFocus && !cmb->editable)
2189                     p->fillRect(re.x(), re.y(), re.width(), re.height(),
2190                                 cmb->palette.brush(QPalette::Highlight));
2191 
2192                 if (cmb->state & State_HasFocus) {
2193                     p->setPen(cmb->palette.highlightedText().color());
2194                     p->setBackground(cmb->palette.highlight());
2195 
2196                 } else {
2197                     p->setPen(cmb->palette.text().color());
2198                     p->setBackground(cmb->palette.window());
2199                 }
2200 
2201                 if (cmb->state & State_HasFocus && !cmb->editable) {
2202                     QStyleOptionFocusRect focus;
2203                     focus.QStyleOption::operator=(*cmb);
2204                     focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget);
2205                     focus.state |= State_FocusAtBorder;
2206                     focus.backgroundColor = cmb->palette.highlight().color();
2207                     proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
2208                 }
2209             }
2210         }
2211         break;
2212 #endif // QT_CONFIG(combobox)
2213 #if QT_CONFIG(spinbox)
2214     case CC_SpinBox:
2215         if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
2216             QStyleOptionSpinBox copy = *sb;
2217             PrimitiveElement pe;
2218             bool enabled = opt->state & State_Enabled;
2219             if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
2220                 QBrush editBrush = sb->palette.brush(QPalette::Base);
2221                 QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
2222                 QPalette shadePal = sb->palette;
2223                 shadePal.setColor(QPalette::Midlight, shadePal.button().color());
2224                 qDrawWinPanel(p, r, shadePal, true, &editBrush);
2225             }
2226 
2227             QPalette shadePal(opt->palette);
2228             shadePal.setColor(QPalette::Button, opt->palette.light().color());
2229             shadePal.setColor(QPalette::Light, opt->palette.button().color());
2230 
2231             if (sb->subControls & SC_SpinBoxUp) {
2232                 copy.subControls = SC_SpinBoxUp;
2233                 QPalette pal2 = sb->palette;
2234                 if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
2235                     pal2.setCurrentColorGroup(QPalette::Disabled);
2236                     copy.state &= ~State_Enabled;
2237                 }
2238 
2239                 copy.palette = pal2;
2240 
2241                 if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
2242                     copy.state |= State_On;
2243                     copy.state |= State_Sunken;
2244                 } else {
2245                     copy.state |= State_Raised;
2246                     copy.state &= ~State_Sunken;
2247                 }
2248                 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
2249                                                                        : PE_IndicatorSpinUp);
2250 
2251                 copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
2252                 qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
2253                                 &copy.palette.brush(QPalette::Button));
2254                 copy.rect.adjust(4, 1, -5, -1);
2255                 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
2256                     && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
2257                 {
2258                     QStyleOptionSpinBox lightCopy = copy;
2259                     lightCopy.rect.adjust(1, 1, 1, 1);
2260                     lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
2261                     proxy()->drawPrimitive(pe, &lightCopy, p, widget);
2262                 }
2263                 proxy()->drawPrimitive(pe, &copy, p, widget);
2264             }
2265 
2266             if (sb->subControls & SC_SpinBoxDown) {
2267                 copy.subControls = SC_SpinBoxDown;
2268                 copy.state = sb->state;
2269                 QPalette pal2 = sb->palette;
2270                 if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
2271                     pal2.setCurrentColorGroup(QPalette::Disabled);
2272                     copy.state &= ~State_Enabled;
2273                 }
2274                 copy.palette = pal2;
2275 
2276                 if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
2277                     copy.state |= State_On;
2278                     copy.state |= State_Sunken;
2279                 } else {
2280                     copy.state |= State_Raised;
2281                     copy.state &= ~State_Sunken;
2282                 }
2283                 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
2284                                                                        : PE_IndicatorSpinDown);
2285 
2286                 copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
2287                 qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
2288                                 &copy.palette.brush(QPalette::Button));
2289                 copy.rect.adjust(4, 0, -5, -1);
2290                 if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
2291                     && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
2292                 {
2293                     QStyleOptionSpinBox lightCopy = copy;
2294                     lightCopy.rect.adjust(1, 1, 1, 1);
2295                     lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
2296                     proxy()->drawPrimitive(pe, &lightCopy, p, widget);
2297                 }
2298                 proxy()->drawPrimitive(pe, &copy, p, widget);
2299             }
2300         }
2301         break;
2302 #endif // QT_CONFIG(spinbox)
2303 
2304     default:
2305         QCommonStyle::drawComplexControl(cc, opt, p, widget);
2306     }
2307 }
2308 
2309 /*! \reimp */
sizeFromContents(ContentsType ct,const QStyleOption * opt,const QSize & csz,const QWidget * widget) const2310 QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
2311                                       const QSize &csz, const QWidget *widget) const
2312 {
2313     QSize sz(csz);
2314     switch (ct) {
2315     case CT_PushButton:
2316         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2317             sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
2318             int w = sz.width(),
2319                 h = sz.height();
2320             int defwidth = 0;
2321             if (btn->features & QStyleOptionButton::AutoDefaultButton)
2322                 defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2323             const qreal dpi = QStyleHelper::dpi(opt);
2324             int minwidth = int(QStyleHelper::dpiScaled(75, dpi));
2325             int minheight = int(QStyleHelper::dpiScaled(23, dpi));
2326 
2327 #ifndef QT_QWS_SMALL_PUSHBUTTON
2328             if (w < minwidth + defwidth && !btn->text.isEmpty())
2329                 w = minwidth + defwidth;
2330             if (h < minheight + defwidth)
2331                 h = minheight + defwidth;
2332 #endif
2333             sz = QSize(w, h);
2334         }
2335         break;
2336 #if QT_CONFIG(menu)
2337     case CT_MenuItem:
2338         if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
2339             int w = sz.width();
2340             sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
2341 
2342             if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
2343                 sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
2344             }
2345             else if (mi->icon.isNull()) {
2346                 sz.setHeight(sz.height() - 2);
2347                 w -= 6;
2348             }
2349 
2350             if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) {
2351                 int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
2352                 sz.setHeight(qMax(sz.height(),
2353                                   mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
2354                                   + 2 * QWindowsStylePrivate::windowsItemFrame));
2355             }
2356             int maxpmw = mi->maxIconWidth;
2357             int tabSpacing = 20;
2358             if (mi->text.contains(QLatin1Char('\t')))
2359                 w += tabSpacing;
2360             else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
2361                 w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
2362             else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
2363                 // adjust the font and add the difference in size.
2364                 // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
2365                 QFontMetrics fm(mi->font);
2366                 QFont fontBold = mi->font;
2367                 fontBold.setBold(true);
2368                 QFontMetrics fmBold(fontBold);
2369                 w += fmBold.horizontalAdvance(mi->text) - fm.horizontalAdvance(mi->text);
2370             }
2371 
2372             int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
2373             w += checkcol;
2374             w += int(QWindowsStylePrivate::windowsRightBorder) + 10;
2375             sz.setWidth(w);
2376         }
2377         break;
2378 #endif // QT_CONFIG(menu)
2379 #if QT_CONFIG(menubar)
2380     case CT_MenuBarItem:
2381         if (!sz.isEmpty())
2382             sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
2383         break;
2384 #endif
2385     case CT_ToolButton:
2386         if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
2387             return sz += QSize(7, 6);
2388         Q_FALLTHROUGH();
2389 
2390     default:
2391         sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
2392     }
2393     return sz;
2394 }
2395 
2396 /*!
2397     \reimp
2398 */
standardIcon(StandardPixmap standardIcon,const QStyleOption * option,const QWidget * widget) const2399 QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
2400                                   const QWidget *widget) const
2401 {
2402     return QCommonStyle::standardIcon(standardIcon, option, widget);
2403 }
2404 
2405 
2406 
2407 QT_END_NAMESPACE
2408 
2409 #include "moc_qwindowsstyle_p.cpp"
2410 
2411 #endif // style_windows
2412