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