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 "qcommonstyle.h"
41 #include "qcommonstyle_p.h"
42
43 #include <qfile.h>
44 #if QT_CONFIG(itemviews)
45 #include <qabstractitemview.h>
46 #endif
47 #include <qapplication.h>
48 #include <private/qguiapplication_p.h>
49 #include <qpa/qplatformtheme.h>
50 #include <qbitmap.h>
51 #include <qcache.h>
52 #if QT_CONFIG(dockwidget)
53 #include <qdockwidget.h>
54 #endif
55 #include <qdrawutil.h>
56 #if QT_CONFIG(dialogbuttonbox)
57 #include <qdialogbuttonbox.h>
58 #endif
59 #if QT_CONFIG(formlayout)
60 #include <qformlayout.h>
61 #else
62 #include <qlayout.h>
63 #endif
64 #if QT_CONFIG(groupbox)
65 #include <qgroupbox.h>
66 #endif
67 #include <qmath.h>
68 #if QT_CONFIG(menu)
69 #include <qmenu.h>
70 #endif
71 #include <qpainter.h>
72 #include <qpaintengine.h>
73 #include <qpainterpath.h>
74 #if QT_CONFIG(slider)
75 #include <qslider.h>
76 #endif
77 #include <qstyleoption.h>
78 #if QT_CONFIG(tabbar)
79 #include <qtabbar.h>
80 #endif
81 #if QT_CONFIG(tabwidget)
82 #include <qtabwidget.h>
83 #endif
84 #if QT_CONFIG(toolbar)
85 #include <qtoolbar.h>
86 #endif
87 #if QT_CONFIG(toolbutton)
88 #include <qtoolbutton.h>
89 #endif
90 #if QT_CONFIG(rubberband)
91 #include <qrubberband.h>
92 #endif
93 #if QT_CONFIG(treeview)
94 #include "qtreeview.h"
95 #endif
96 #include <private/qcommonstylepixmaps_p.h>
97 #include <private/qmath_p.h>
98 #include <qdebug.h>
99 #include <qtextformat.h>
100 #if QT_CONFIG(wizard)
101 #include <qwizard.h>
102 #endif
103 #if QT_CONFIG(filedialog)
104 #include <qsidebar_p.h>
105 #endif
106 #include <qfileinfo.h>
107 #include <qdir.h>
108 #if QT_CONFIG(settings)
109 #include <qsettings.h>
110 #endif
111 #include <qvariant.h>
112 #include <qpixmapcache.h>
113 #if QT_CONFIG(animation)
114 #include <private/qstyleanimation_p.h>
115 #endif
116
117 #include <limits.h>
118
119 #include <private/qtextengine_p.h>
120 #include <private/qstylehelper_p.h>
121
122 QT_BEGIN_NAMESPACE
123
qt_getWindow(const QWidget * widget)124 static QWindow *qt_getWindow(const QWidget *widget)
125 {
126 return widget ? widget->window()->windowHandle() : nullptr;
127 }
128
129 /*!
130 \class QCommonStyle
131 \brief The QCommonStyle class encapsulates the common Look and Feel of a GUI.
132
133 \ingroup appearance
134 \inmodule QtWidgets
135
136 This abstract class implements some of the widget's look and feel
137 that is common to all GUI styles provided and shipped as part of
138 Qt.
139
140 Since QCommonStyle inherits QStyle, all of its functions are fully documented
141 in the QStyle documentation.
142 \omit
143 , although the
144 extra functions that QCommonStyle provides, e.g.
145 drawComplexControl(), drawControl(), drawPrimitive(),
146 hitTestComplexControl(), subControlRect(), sizeFromContents(), and
147 subElementRect() are documented here.
148 \endomit
149
150 \sa QStyle, QProxyStyle
151 */
152
153 /*!
154 Constructs a QCommonStyle.
155 */
QCommonStyle()156 QCommonStyle::QCommonStyle()
157 : QStyle(*new QCommonStylePrivate)
158 { }
159
160 /*! \internal
161 */
QCommonStyle(QCommonStylePrivate & dd)162 QCommonStyle::QCommonStyle(QCommonStylePrivate &dd)
163 : QStyle(dd)
164 { }
165
166 /*!
167 Destroys the style.
168 */
~QCommonStyle()169 QCommonStyle::~QCommonStyle()
170 { }
171
172
173 /*!
174 \reimp
175 */
drawPrimitive(PrimitiveElement pe,const QStyleOption * opt,QPainter * p,const QWidget * widget) const176 void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
177 const QWidget *widget) const
178 {
179 Q_D(const QCommonStyle);
180 switch (pe) {
181 case PE_FrameButtonBevel:
182 case PE_FrameButtonTool:
183 qDrawShadeRect(p, opt->rect, opt->palette,
184 opt->state & (State_Sunken | State_On), 1, 0);
185 break;
186 case PE_PanelButtonCommand:
187 case PE_PanelButtonBevel:
188 case PE_PanelButtonTool:
189 case PE_IndicatorButtonDropDown:
190 qDrawShadePanel(p, opt->rect, opt->palette,
191 opt->state & (State_Sunken | State_On), 1,
192 &opt->palette.brush(QPalette::Button));
193 break;
194 case PE_IndicatorItemViewItemCheck:
195 proxy()->drawPrimitive(PE_IndicatorCheckBox, opt, p, widget);
196 break;
197 case PE_IndicatorCheckBox:
198 if (opt->state & State_NoChange) {
199 p->setPen(opt->palette.windowText().color());
200 p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
201 p->drawRect(opt->rect);
202 p->drawLine(opt->rect.topLeft(), opt->rect.bottomRight());
203 } else {
204 qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(),
205 opt->palette, opt->state & (State_Sunken | State_On), 1,
206 &opt->palette.brush(QPalette::Button));
207 }
208 break;
209 case PE_IndicatorRadioButton: {
210 QRect ir = opt->rect;
211 p->setPen(opt->palette.dark().color());
212 p->drawArc(opt->rect, 0, 5760);
213 if (opt->state & (State_Sunken | State_On)) {
214 ir.adjust(2, 2, -2, -2);
215 p->setBrush(opt->palette.windowText());
216 bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
217 p->setRenderHint(QPainter::Qt4CompatiblePainting);
218 p->drawEllipse(ir);
219 p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
220 }
221 break; }
222 case PE_FrameFocusRect:
223 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
224 QColor bg = fropt->backgroundColor;
225 QPen oldPen = p->pen();
226 if (bg.isValid()) {
227 int h, s, v;
228 bg.getHsv(&h, &s, &v);
229 if (v >= 128)
230 p->setPen(Qt::black);
231 else
232 p->setPen(Qt::white);
233 } else {
234 p->setPen(opt->palette.windowText().color());
235 }
236 QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
237 p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive
238 p->setPen(oldPen);
239 }
240 break;
241 case PE_IndicatorMenuCheckMark: {
242 const int markW = opt->rect.width() > 7 ? 7 : opt->rect.width();
243 const int markH = markW;
244 int posX = opt->rect.x() + (opt->rect.width() - markW)/2 + 1;
245 int posY = opt->rect.y() + (opt->rect.height() - markH)/2;
246
247 QVector<QLineF> a;
248 a.reserve(markH);
249
250 int i, xx, yy;
251 xx = posX;
252 yy = 3 + posY;
253 for (i = 0; i < markW/2; ++i) {
254 a << QLineF(xx, yy, xx, yy + 2);
255 ++xx;
256 ++yy;
257 }
258 yy -= 2;
259 for (; i < markH; ++i) {
260 a << QLineF(xx, yy, xx, yy + 2);
261 ++xx;
262 --yy;
263 }
264 if (!(opt->state & State_Enabled) && !(opt->state & State_On)) {
265 p->save();
266 p->translate(1, 1);
267 p->setPen(opt->palette.light().color());
268 p->drawLines(a);
269 p->restore();
270 }
271 p->setPen((opt->state & State_On) ? opt->palette.highlightedText().color() : opt->palette.text().color());
272 p->drawLines(a);
273 break; }
274 case PE_Frame:
275 case PE_FrameMenu:
276 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
277 if (pe == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) {
278 qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
279 frame->lineWidth);
280 } else {
281 qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth);
282 }
283 }
284 break;
285 #if QT_CONFIG(toolbar)
286 case PE_PanelMenuBar:
287 if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
288 break;
289 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)){
290 qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth,
291 &frame->palette.brush(QPalette::Button));
292
293 }
294 else if (const QStyleOptionToolBar *frame = qstyleoption_cast<const QStyleOptionToolBar *>(opt)){
295 qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth,
296 &frame->palette.brush(QPalette::Button));
297 }
298
299 break;
300 case PE_PanelMenu:
301 break;
302 case PE_PanelToolBar:
303 break;
304 #endif // QT_CONFIG(toolbar)
305 #if QT_CONFIG(progressbar)
306 case PE_IndicatorProgressChunk:
307 {
308 bool vertical = false;
309 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt))
310 vertical = pb->orientation == Qt::Vertical;
311 if (!vertical) {
312 p->fillRect(opt->rect.x(), opt->rect.y() + 3, opt->rect.width() -2, opt->rect.height() - 6,
313 opt->palette.brush(QPalette::Highlight));
314 } else {
315 p->fillRect(opt->rect.x() + 2, opt->rect.y(), opt->rect.width() -6, opt->rect.height() - 2,
316 opt->palette.brush(QPalette::Highlight));
317 }
318 }
319 break;
320 #endif // QT_CONFIG(progressbar)
321 case PE_IndicatorBranch: {
322 static const int decoration_size = 9;
323 int mid_h = opt->rect.x() + opt->rect.width() / 2;
324 int mid_v = opt->rect.y() + opt->rect.height() / 2;
325 int bef_h = mid_h;
326 int bef_v = mid_v;
327 int aft_h = mid_h;
328 int aft_v = mid_v;
329 if (opt->state & State_Children) {
330 int delta = decoration_size / 2;
331 bef_h -= delta;
332 bef_v -= delta;
333 aft_h += delta;
334 aft_v += delta;
335 p->drawLine(bef_h + 2, bef_v + 4, bef_h + 6, bef_v + 4);
336 if (!(opt->state & State_Open))
337 p->drawLine(bef_h + 4, bef_v + 2, bef_h + 4, bef_v + 6);
338 QPen oldPen = p->pen();
339 p->setPen(opt->palette.dark().color());
340 p->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1);
341 p->setPen(oldPen);
342 }
343 QBrush brush(opt->palette.dark().color(), Qt::Dense4Pattern);
344 if (opt->state & State_Item) {
345 if (opt->direction == Qt::RightToLeft)
346 p->fillRect(opt->rect.left(), mid_v, bef_h - opt->rect.left(), 1, brush);
347 else
348 p->fillRect(aft_h, mid_v, opt->rect.right() - aft_h + 1, 1, brush);
349 }
350 if (opt->state & State_Sibling)
351 p->fillRect(mid_h, aft_v, 1, opt->rect.bottom() - aft_v + 1, brush);
352 if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
353 p->fillRect(mid_h, opt->rect.y(), 1, bef_v - opt->rect.y(), brush);
354 break; }
355 case PE_FrameStatusBarItem:
356 qDrawShadeRect(p, opt->rect, opt->palette, true, 1, 0, nullptr);
357 break;
358 case PE_IndicatorHeaderArrow:
359 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
360 QPen oldPen = p->pen();
361 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
362 p->setPen(QPen(opt->palette.light(), 0));
363 p->drawLine(opt->rect.x() + opt->rect.width(), opt->rect.y(),
364 opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height());
365 p->setPen(QPen(opt->palette.dark(), 0));
366 const QPoint points[] = {
367 QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height()),
368 QPoint(opt->rect.x(), opt->rect.y()),
369 QPoint(opt->rect.x() + opt->rect.width(), opt->rect.y()),
370 };
371 p->drawPolyline(points, sizeof points / sizeof *points);
372 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
373 p->setPen(QPen(opt->palette.light(), 0));
374 const QPoint points[] = {
375 QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height()),
376 QPoint(opt->rect.x() + opt->rect.width(), opt->rect.y() + opt->rect.height()),
377 QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y()),
378 };
379 p->drawPolyline(points, sizeof points / sizeof *points);
380 p->setPen(QPen(opt->palette.dark(), 0));
381 p->drawLine(opt->rect.x(), opt->rect.y() + opt->rect.height(),
382 opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
383 }
384 p->setPen(oldPen);
385 }
386 break;
387 #if QT_CONFIG(tabbar)
388 case PE_FrameTabBarBase:
389 if (const QStyleOptionTabBarBase *tbb
390 = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) {
391 p->save();
392 switch (tbb->shape) {
393 case QTabBar::RoundedNorth:
394 case QTabBar::TriangularNorth:
395 p->setPen(QPen(tbb->palette.light(), 0));
396 p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
397 break;
398 case QTabBar::RoundedWest:
399 case QTabBar::TriangularWest:
400 p->setPen(QPen(tbb->palette.light(), 0));
401 p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
402 break;
403 case QTabBar::RoundedSouth:
404 case QTabBar::TriangularSouth:
405 p->setPen(QPen(tbb->palette.shadow(), 0));
406 p->drawLine(tbb->rect.left(), tbb->rect.bottom(),
407 tbb->rect.right(), tbb->rect.bottom());
408 p->setPen(QPen(tbb->palette.dark(), 0));
409 p->drawLine(tbb->rect.left(), tbb->rect.bottom() - 1,
410 tbb->rect.right() - 1, tbb->rect.bottom() - 1);
411 break;
412 case QTabBar::RoundedEast:
413 case QTabBar::TriangularEast:
414 p->setPen(QPen(tbb->palette.dark(), 0));
415 p->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
416 break;
417 }
418 p->restore();
419 }
420 break;
421 case PE_IndicatorTabClose: {
422 if (d->tabBarcloseButtonIcon.isNull()) {
423 d->tabBarcloseButtonIcon.addPixmap(QPixmap(
424 QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-16.png")),
425 QIcon::Normal, QIcon::Off);
426 d->tabBarcloseButtonIcon.addPixmap(QPixmap(
427 QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-down-16.png")),
428 QIcon::Normal, QIcon::On);
429 d->tabBarcloseButtonIcon.addPixmap(QPixmap(
430 QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-hover-16.png")),
431 QIcon::Active, QIcon::Off);
432 }
433
434 const int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize, opt);
435 QIcon::Mode mode = opt->state & State_Enabled ?
436 (opt->state & State_Raised ? QIcon::Active : QIcon::Normal)
437 : QIcon::Disabled;
438 if (!(opt->state & State_Raised)
439 && !(opt->state & State_Sunken)
440 && !(opt->state & QStyle::State_Selected))
441 mode = QIcon::Disabled;
442
443 QIcon::State state = opt->state & State_Sunken ? QIcon::On : QIcon::Off;
444 QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(qt_getWindow(widget), QSize(size, size), mode, state);
445 proxy()->drawItemPixmap(p, opt->rect, Qt::AlignCenter, pixmap);
446 break;
447 }
448 #else
449 Q_UNUSED(d);
450 #endif // QT_CONFIG(tabbar)
451 case PE_FrameTabWidget:
452 case PE_FrameWindow:
453 qDrawWinPanel(p, opt->rect, opt->palette, false, nullptr);
454 break;
455 case PE_FrameLineEdit:
456 proxy()->drawPrimitive(PE_Frame, opt, p, widget);
457 break;
458 #if QT_CONFIG(groupbox)
459 case PE_FrameGroupBox:
460 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
461 if (frame->features & QStyleOptionFrame::Flat) {
462 QRect fr = frame->rect;
463 QPoint p1(fr.x(), fr.y() + 1);
464 QPoint p2(fr.x() + fr.width(), p1.y());
465 qDrawShadeLine(p, p1, p2, frame->palette, true,
466 frame->lineWidth, frame->midLineWidth);
467 } else {
468 qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(),
469 frame->rect.height(), frame->palette, true,
470 frame->lineWidth, frame->midLineWidth);
471 }
472 }
473 break;
474 #endif // QT_CONFIG(groupbox)
475 #if QT_CONFIG(dockwidget)
476 case PE_FrameDockWidget:
477 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
478 int lw = frame->lineWidth;
479 if (lw <= 0)
480 lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, opt);
481
482 qDrawShadePanel(p, frame->rect, frame->palette, false, lw);
483 }
484 break;
485 #endif // QT_CONFIG(dockwidget)
486 #if QT_CONFIG(toolbar)
487 case PE_IndicatorToolBarHandle:
488 p->save();
489 p->translate(opt->rect.x(), opt->rect.y());
490 if (opt->state & State_Horizontal) {
491 int x = opt->rect.width() / 3;
492 if (opt->direction == Qt::RightToLeft)
493 x -= 2;
494 if (opt->rect.height() > 4) {
495 qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
496 opt->palette, false, 1, nullptr);
497 qDrawShadePanel(p, x+3, 2, 3, opt->rect.height() - 4,
498 opt->palette, false, 1, nullptr);
499 }
500 } else {
501 if (opt->rect.width() > 4) {
502 int y = opt->rect.height() / 3;
503 qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
504 opt->palette, false, 1, nullptr);
505 qDrawShadePanel(p, 2, y+3, opt->rect.width() - 4, 3,
506 opt->palette, false, 1, nullptr);
507 }
508 }
509 p->restore();
510 break;
511 case PE_IndicatorToolBarSeparator:
512 {
513 QPoint p1, p2;
514 if (opt->state & State_Horizontal) {
515 p1 = QPoint(opt->rect.width()/2, 0);
516 p2 = QPoint(p1.x(), opt->rect.height());
517 } else {
518 p1 = QPoint(0, opt->rect.height()/2);
519 p2 = QPoint(opt->rect.width(), p1.y());
520 }
521 qDrawShadeLine(p, p1, p2, opt->palette, 1, 1, 0);
522 break;
523 }
524 #endif // QT_CONFIG(toolbar)
525 #if QT_CONFIG(spinbox)
526 case PE_IndicatorSpinPlus:
527 case PE_IndicatorSpinMinus: {
528 QRect r = opt->rect;
529 int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
530 QRect br = r.adjusted(fw, fw, -fw, -fw);
531
532 int offset = (opt->state & State_Sunken) ? 1 : 0;
533 int step = (br.width() + 4) / 5;
534 p->fillRect(br.x() + offset, br.y() + offset +br.height() / 2 - step / 2,
535 br.width(), step,
536 opt->palette.buttonText());
537 if (pe == PE_IndicatorSpinPlus)
538 p->fillRect(br.x() + br.width() / 2 - step / 2 + offset, br.y() + offset,
539 step, br.height(),
540 opt->palette.buttonText());
541
542 break; }
543 case PE_IndicatorSpinUp:
544 case PE_IndicatorSpinDown: {
545 QRect r = opt->rect;
546 int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
547 // QRect br = r.adjusted(fw, fw, -fw, -fw);
548 int x = r.x(), y = r.y(), w = r.width(), h = r.height();
549 int sw = w-4;
550 if (sw < 3)
551 break;
552 else if (!(sw & 1))
553 sw--;
554 sw -= (sw / 7) * 2; // Empty border
555 int sh = sw/2 + 2; // Must have empty row at foot of arrow
556
557 int sx = x + w / 2 - sw / 2;
558 int sy = y + h / 2 - sh / 2;
559
560 if (pe == PE_IndicatorSpinUp && fw)
561 --sy;
562
563 int bsx = 0;
564 int bsy = 0;
565 if (opt->state & State_Sunken) {
566 bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
567 bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
568 }
569 p->save();
570 p->translate(sx + bsx, sy + bsy);
571 p->setPen(opt->palette.buttonText().color());
572 p->setBrush(opt->palette.buttonText());
573 p->setRenderHint(QPainter::Qt4CompatiblePainting);
574 if (pe == PE_IndicatorSpinDown) {
575 const QPoint points[] = { QPoint(0, 1), QPoint(sw-1, 1), QPoint(sh-2, sh-1) };
576 p->drawPolygon(points, sizeof points / sizeof *points);
577 } else {
578 const QPoint points[] = { QPoint(0, sh-1), QPoint(sw-1, sh-1), QPoint(sh-2, 1) };
579 p->drawPolygon(points, sizeof points / sizeof *points);
580 }
581 p->restore();
582 break; }
583 #endif // QT_CONFIG(spinbox)
584 case PE_PanelTipLabel: {
585 const QBrush brush(opt->palette.toolTipBase());
586 qDrawPlainRect(p, opt->rect, opt->palette.toolTipText().color(), 1, &brush);
587 break;
588 }
589 #if QT_CONFIG(tabbar)
590 case PE_IndicatorTabTear:
591 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
592 bool rtl = tab->direction == Qt::RightToLeft;
593 const bool horizontal = tab->rect.height() > tab->rect.width();
594 const int margin = 4;
595 QPainterPath path;
596
597 if (horizontal) {
598 QRect rect = tab->rect.adjusted(rtl ? margin : 0, 0, rtl ? 1 : -margin, 0);
599 rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
600 rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
601
602 path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
603 int count = 4;
604 for (int jags = 1; jags <= count; ++jags, rtl = !rtl)
605 path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
606 } else {
607 QRect rect = tab->rect.adjusted(0, 0, 0, -margin);
608 rect.setLeft(rect.left() + ((tab->state & State_Selected) ? 1 : 3));
609 rect.setRight(rect.right() - ((tab->state & State_Selected) ? 0 : 2));
610
611 path.moveTo(QPoint(rect.left(), rect.top()));
612 int count = 4;
613 for (int jags = 1; jags <= count; ++jags, rtl = !rtl)
614 path.lineTo(QPoint(rect.left() + jags * rect.width()/count, rtl ? rect.top() : rect.bottom()));
615 }
616
617 p->setPen(QPen(tab->palette.dark(), qreal(.8)));
618 p->setBrush(tab->palette.window());
619 p->setRenderHint(QPainter::Antialiasing);
620 p->drawPath(path);
621 }
622 break;
623 #endif // QT_CONFIG(tabbar)
624 #if QT_CONFIG(lineedit)
625 case PE_PanelLineEdit:
626 if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
627 p->fillRect(panel->rect.adjusted(panel->lineWidth, panel->lineWidth, -panel->lineWidth, -panel->lineWidth),
628 panel->palette.brush(QPalette::Base));
629
630 if (panel->lineWidth > 0)
631 proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
632 }
633 break;
634 #endif // QT_CONFIG(lineedit)
635 #if QT_CONFIG(columnview)
636 case PE_IndicatorColumnViewArrow: {
637 if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
638 bool reverse = (viewOpt->direction == Qt::RightToLeft);
639 p->save();
640 QPainterPath path;
641 int x = viewOpt->rect.x() + 1;
642 int offset = (viewOpt->rect.height() / 3);
643 int height = (viewOpt->rect.height()) - offset * 2;
644 if (height % 2 == 1)
645 --height;
646 int x2 = x + height - 1;
647 if (reverse) {
648 x = viewOpt->rect.x() + viewOpt->rect.width() - 1;
649 x2 = x - height + 1;
650 }
651 path.moveTo(x, viewOpt->rect.y() + offset);
652 path.lineTo(x, viewOpt->rect.y() + offset + height);
653 path.lineTo(x2, viewOpt->rect.y() + offset+height/2);
654 path.closeSubpath();
655 if (viewOpt->state & QStyle::State_Selected ) {
656 if (viewOpt->showDecorationSelected) {
657 QColor color = viewOpt->palette.color(QPalette::Active, QPalette::HighlightedText);
658 p->setPen(color);
659 p->setBrush(color);
660 } else {
661 QColor color = viewOpt->palette.color(QPalette::Active, QPalette::WindowText);
662 p->setPen(color);
663 p->setBrush(color);
664 }
665
666 } else {
667 QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Mid);
668 p->setPen(color);
669 p->setBrush(color);
670 }
671 p->drawPath(path);
672
673 // draw the vertical and top triangle line
674 if (!(viewOpt->state & QStyle::State_Selected)) {
675 QPainterPath lines;
676 lines.moveTo(x, viewOpt->rect.y() + offset);
677 lines.lineTo(x, viewOpt->rect.y() + offset + height);
678 lines.moveTo(x, viewOpt->rect.y() + offset);
679 lines.lineTo(x2, viewOpt->rect.y() + offset+height/2);
680 QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Dark);
681 p->setPen(color);
682 p->drawPath(lines);
683 }
684 p->restore();
685 }
686 break; }
687 #endif //QT_CONFIG(columnview)
688 case PE_IndicatorItemViewItemDrop: {
689 QRect rect = opt->rect;
690 if (opt->rect.height() == 0)
691 p->drawLine(rect.topLeft(), rect.topRight());
692 else
693 p->drawRect(rect);
694 break; }
695 #if QT_CONFIG(itemviews)
696 case PE_PanelItemViewRow:
697 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
698 QPalette::ColorGroup cg = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
699 ? QPalette::Normal : QPalette::Disabled;
700 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
701 cg = QPalette::Inactive;
702
703 if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, opt, widget))
704 p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight));
705 else if (vopt->features & QStyleOptionViewItem::Alternate)
706 p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase));
707 }
708 break;
709 case PE_PanelItemViewItem:
710 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
711 QPalette::ColorGroup cg = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
712 ? QPalette::Normal : QPalette::Disabled;
713 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
714 cg = QPalette::Inactive;
715
716 if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) {
717 p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight));
718 } else {
719 if (vopt->backgroundBrush.style() != Qt::NoBrush) {
720 QPointF oldBO = p->brushOrigin();
721 p->setBrushOrigin(vopt->rect.topLeft());
722 p->fillRect(vopt->rect, vopt->backgroundBrush);
723 p->setBrushOrigin(oldBO);
724 }
725
726 if (vopt->state & QStyle::State_Selected) {
727 QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, opt, widget);
728 p->fillRect(textRect, vopt->palette.brush(cg, QPalette::Highlight));
729 }
730 }
731 }
732 break;
733 #endif // QT_CONFIG(itemviews)
734 case PE_PanelScrollAreaCorner: {
735 const QBrush brush(opt->palette.brush(QPalette::Window));
736 p->fillRect(opt->rect, brush);
737 } break;
738 case PE_IndicatorArrowUp:
739 case PE_IndicatorArrowDown:
740 case PE_IndicatorArrowRight:
741 case PE_IndicatorArrowLeft:
742 {
743 if (opt->rect.width() <= 1 || opt->rect.height() <= 1)
744 break;
745 QRect r = opt->rect;
746 int size = qMin(r.height(), r.width());
747 QPixmap pixmap;
748 QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-")
749 % QLatin1String(metaObject()->className()), opt, QSize(size, size))
750 % HexString<uint>(pe);
751 if (!QPixmapCache::find(pixmapName, &pixmap)) {
752 qreal pixelRatio = p->device()->devicePixelRatioF();
753 int border = qRound(pixelRatio*(size/5));
754 int sqsize = qRound(pixelRatio*(2*(size/2)));
755 QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied);
756 image.fill(0);
757 QPainter imagePainter(&image);
758
759 QPolygon a;
760 switch (pe) {
761 case PE_IndicatorArrowUp:
762 a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
763 break;
764 case PE_IndicatorArrowDown:
765 a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
766 break;
767 case PE_IndicatorArrowRight:
768 a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
769 break;
770 case PE_IndicatorArrowLeft:
771 a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
772 break;
773 default:
774 break;
775 }
776
777 int bsx = 0;
778 int bsy = 0;
779
780 if (opt->state & State_Sunken) {
781 bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget);
782 bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget);
783 }
784
785 QRect bounds = a.boundingRect();
786 int sx = sqsize / 2 - bounds.center().x() - 1;
787 int sy = sqsize / 2 - bounds.center().y() - 1;
788 imagePainter.translate(sx + bsx, sy + bsy);
789 imagePainter.setPen(opt->palette.buttonText().color());
790 imagePainter.setBrush(opt->palette.buttonText());
791 imagePainter.setRenderHint(QPainter::Qt4CompatiblePainting);
792
793 if (!(opt->state & State_Enabled)) {
794 imagePainter.translate(1, 1);
795 imagePainter.setBrush(opt->palette.light().color());
796 imagePainter.setPen(opt->palette.light().color());
797 imagePainter.drawPolygon(a);
798 imagePainter.translate(-1, -1);
799 imagePainter.setBrush(opt->palette.mid().color());
800 imagePainter.setPen(opt->palette.mid().color());
801 }
802
803 imagePainter.drawPolygon(a);
804 imagePainter.end();
805 pixmap = QPixmap::fromImage(image);
806 pixmap.setDevicePixelRatio(pixelRatio);
807 QPixmapCache::insert(pixmapName, pixmap);
808 }
809 int xOffset = r.x() + (r.width() - size)/2;
810 int yOffset = r.y() + (r.height() - size)/2;
811 p->drawPixmap(xOffset, yOffset, pixmap);
812 }
813 break;
814 default:
815 break;
816 }
817 }
818
819 #if QT_CONFIG(toolbutton)
drawArrow(const QStyle * style,const QStyleOptionToolButton * toolbutton,const QRect & rect,QPainter * painter,const QWidget * widget=nullptr)820 static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton,
821 const QRect &rect, QPainter *painter, const QWidget *widget = nullptr)
822 {
823 QStyle::PrimitiveElement pe;
824 switch (toolbutton->arrowType) {
825 case Qt::LeftArrow:
826 pe = QStyle::PE_IndicatorArrowLeft;
827 break;
828 case Qt::RightArrow:
829 pe = QStyle::PE_IndicatorArrowRight;
830 break;
831 case Qt::UpArrow:
832 pe = QStyle::PE_IndicatorArrowUp;
833 break;
834 case Qt::DownArrow:
835 pe = QStyle::PE_IndicatorArrowDown;
836 break;
837 default:
838 return;
839 }
840 QStyleOption arrowOpt = *toolbutton;
841 arrowOpt.rect = rect;
842 style->drawPrimitive(pe, &arrowOpt, painter, widget);
843 }
844 #endif // QT_CONFIG(toolbutton)
845
viewItemTextLayout(QTextLayout & textLayout,int lineWidth,int maxHeight=-1,int * lastVisibleLine=nullptr)846 static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth, int maxHeight = -1, int *lastVisibleLine = nullptr)
847 {
848 if (lastVisibleLine)
849 *lastVisibleLine = -1;
850 qreal height = 0;
851 qreal widthUsed = 0;
852 textLayout.beginLayout();
853 int i = 0;
854 while (true) {
855 QTextLine line = textLayout.createLine();
856 if (!line.isValid())
857 break;
858 line.setLineWidth(lineWidth);
859 line.setPosition(QPointF(0, height));
860 height += line.height();
861 widthUsed = qMax(widthUsed, line.naturalTextWidth());
862 // we assume that the height of the next line is the same as the current one
863 if (maxHeight > 0 && lastVisibleLine && height + line.height() > maxHeight) {
864 const QTextLine nextLine = textLayout.createLine();
865 *lastVisibleLine = nextLine.isValid() ? i : -1;
866 break;
867 }
868 ++i;
869 }
870 textLayout.endLayout();
871 return QSizeF(widthUsed, height);
872 }
873
calculateElidedText(const QString & text,const QTextOption & textOption,const QFont & font,const QRect & textRect,const Qt::Alignment valign,Qt::TextElideMode textElideMode,int flags,bool lastVisibleLineShouldBeElided,QPointF * paintStartPosition) const874 QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTextOption &textOption,
875 const QFont &font, const QRect &textRect, const Qt::Alignment valign,
876 Qt::TextElideMode textElideMode, int flags,
877 bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const
878 {
879 QTextLayout textLayout(text, font);
880 textLayout.setTextOption(textOption);
881
882 // In AlignVCenter mode when more than one line is displayed and the height only allows
883 // some of the lines it makes no sense to display those. From a users perspective it makes
884 // more sense to see the start of the text instead something inbetween.
885 const bool vAlignmentOptimization = paintStartPosition && valign.testFlag(Qt::AlignVCenter);
886
887 int lastVisibleLine = -1;
888 viewItemTextLayout(textLayout, textRect.width(), vAlignmentOptimization ? textRect.height() : -1, &lastVisibleLine);
889
890 const QRectF boundingRect = textLayout.boundingRect();
891 // don't care about LTR/RTL here, only need the height
892 const QRect layoutRect = QStyle::alignedRect(Qt::LayoutDirectionAuto, valign,
893 boundingRect.size().toSize(), textRect);
894
895 if (paintStartPosition)
896 *paintStartPosition = QPointF(textRect.x(), layoutRect.top());
897
898 QString ret;
899 qreal height = 0;
900 const int lineCount = textLayout.lineCount();
901 for (int i = 0; i < lineCount; ++i) {
902 const QTextLine line = textLayout.lineAt(i);
903 height += line.height();
904
905 // above visible rect
906 if (height + layoutRect.top() <= textRect.top()) {
907 if (paintStartPosition)
908 paintStartPosition->ry() += line.height();
909 continue;
910 }
911
912 const int start = line.textStart();
913 const int length = line.textLength();
914 const bool drawElided = line.naturalTextWidth() > textRect.width();
915 bool elideLastVisibleLine = lastVisibleLine == i;
916 if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) {
917 const QTextLine nextLine = textLayout.lineAt(i + 1);
918 const int nextHeight = height + nextLine.height() / 2;
919 // elide when less than the next half line is visible
920 if (nextHeight + layoutRect.top() > textRect.height() + textRect.top())
921 elideLastVisibleLine = true;
922 }
923
924 QString text = textLayout.text().mid(start, length);
925 if (drawElided || elideLastVisibleLine) {
926 if (elideLastVisibleLine) {
927 if (text.endsWith(QChar::LineSeparator))
928 text.chop(1);
929 text += QChar(0x2026);
930 }
931 const QStackTextEngine engine(text, font);
932 ret += engine.elidedText(textElideMode, textRect.width(), flags);
933
934 // no newline for the last line (last visible or real)
935 // sometimes drawElided is true but no eliding is done so the text ends
936 // with QChar::LineSeparator - don't add another one. This happened with
937 // arabic text in the testcase for QTBUG-72805
938 if (i < lineCount - 1 &&
939 !ret.endsWith(QChar::LineSeparator))
940 ret += QChar::LineSeparator;
941 } else {
942 ret += text;
943 }
944
945 // below visible text, can stop
946 if ((height + layoutRect.top() >= textRect.bottom()) ||
947 (lastVisibleLine >= 0 && lastVisibleLine == i))
948 break;
949 }
950 return ret;
951 }
952
953 #if QT_CONFIG(itemviews)
954
viewItemSize(const QStyleOptionViewItem * option,int role) const955 QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int role) const
956 {
957 const QWidget *widget = option->widget;
958 switch (role) {
959 case Qt::CheckStateRole:
960 if (option->features & QStyleOptionViewItem::HasCheckIndicator)
961 return QSize(proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option, widget),
962 proxyStyle->pixelMetric(QStyle::PM_IndicatorHeight, option, widget));
963 break;
964 case Qt::DisplayRole:
965 if (option->features & QStyleOptionViewItem::HasDisplay) {
966 QTextOption textOption;
967 textOption.setWrapMode(QTextOption::WordWrap);
968 QTextLayout textLayout(option->text, option->font);
969 textLayout.setTextOption(textOption);
970 const bool wrapText = option->features & QStyleOptionViewItem::WrapText;
971 const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1;
972 QRect bounds = option->rect;
973 switch (option->decorationPosition) {
974 case QStyleOptionViewItem::Left:
975 case QStyleOptionViewItem::Right: {
976 if (wrapText && bounds.isValid()) {
977 int width = bounds.width() - 2 * textMargin;
978 if (option->features & QStyleOptionViewItem::HasDecoration)
979 width -= option->decorationSize.width() + 2 * textMargin;
980 bounds.setWidth(width);
981 } else
982 bounds.setWidth(QFIXED_MAX);
983 break;
984 }
985 case QStyleOptionViewItem::Top:
986 case QStyleOptionViewItem::Bottom:
987 if (wrapText)
988 bounds.setWidth(bounds.isValid() ? bounds.width() - 2 * textMargin : option->decorationSize.width());
989 else
990 bounds.setWidth(QFIXED_MAX);
991 break;
992 default:
993 break;
994 }
995
996 if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator)
997 bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option) - 2 * textMargin);
998
999 const int lineWidth = bounds.width();
1000 const QSizeF size = viewItemTextLayout(textLayout, lineWidth);
1001 return QSize(qCeil(size.width()) + 2 * textMargin, qCeil(size.height()));
1002 }
1003 break;
1004 case Qt::DecorationRole:
1005 if (option->features & QStyleOptionViewItem::HasDecoration) {
1006 return option->decorationSize;
1007 }
1008 break;
1009 default:
1010 break;
1011 }
1012
1013 return QSize(0, 0);
1014 }
1015
viewItemDrawText(QPainter * p,const QStyleOptionViewItem * option,const QRect & rect) const1016 void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const
1017 {
1018 const QWidget *widget = option->widget;
1019 const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1;
1020
1021 QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
1022 const bool wrapText = option->features & QStyleOptionViewItem::WrapText;
1023 QTextOption textOption;
1024 textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
1025 textOption.setTextDirection(option->direction);
1026 textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment));
1027
1028 QPointF paintPosition;
1029 const QString newText = calculateElidedText(option->text, textOption,
1030 option->font, textRect, option->displayAlignment,
1031 option->textElideMode, 0,
1032 true, &paintPosition);
1033
1034 QTextLayout textLayout(newText, option->font);
1035 textLayout.setTextOption(textOption);
1036 viewItemTextLayout(textLayout, textRect.width());
1037 textLayout.draw(p, paintPosition);
1038 }
1039
1040 /*! \internal
1041 compute the position for the different component of an item (pixmap, text, checkbox)
1042
1043 Set sizehint to false to layout the elements inside opt->rect. Set sizehint to true to ignore
1044 opt->rect and return rectangles in infinite space
1045
1046 Code duplicated in QItemDelegate::doLayout
1047 */
viewItemLayout(const QStyleOptionViewItem * opt,QRect * checkRect,QRect * pixmapRect,QRect * textRect,bool sizehint) const1048 void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect,
1049 QRect *pixmapRect, QRect *textRect, bool sizehint) const
1050 {
1051 Q_ASSERT(checkRect && pixmapRect && textRect);
1052 *pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole));
1053 *textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole));
1054 *checkRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::CheckStateRole));
1055
1056 const QWidget *widget = opt->widget;
1057 const bool hasCheck = checkRect->isValid();
1058 const bool hasPixmap = pixmapRect->isValid();
1059 const bool hasText = textRect->isValid();
1060 const bool hasMargin = (hasText | hasPixmap | hasCheck);
1061 const int frameHMargin = hasMargin ?
1062 proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1063 const int textMargin = hasText ? frameHMargin : 0;
1064 const int pixmapMargin = hasPixmap ? frameHMargin : 0;
1065 const int checkMargin = hasCheck ? frameHMargin : 0;
1066 const int x = opt->rect.left();
1067 const int y = opt->rect.top();
1068 int w, h;
1069
1070 if (textRect->height() == 0 && (!hasPixmap || !sizehint)) {
1071 //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
1072 textRect->setHeight(opt->fontMetrics.height());
1073 }
1074
1075 QSize pm(0, 0);
1076 if (hasPixmap) {
1077 pm = pixmapRect->size();
1078 pm.rwidth() += 2 * pixmapMargin;
1079 }
1080 if (sizehint) {
1081 h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
1082 if (opt->decorationPosition == QStyleOptionViewItem::Left
1083 || opt->decorationPosition == QStyleOptionViewItem::Right) {
1084 w = textRect->width() + pm.width();
1085 } else {
1086 w = qMax(textRect->width(), pm.width());
1087 }
1088 } else {
1089 w = opt->rect.width();
1090 h = opt->rect.height();
1091 }
1092
1093 int cw = 0;
1094 QRect check;
1095 if (hasCheck) {
1096 cw = checkRect->width() + 2 * checkMargin;
1097 if (sizehint) w += cw;
1098 if (opt->direction == Qt::RightToLeft) {
1099 check.setRect(x + w - cw, y, cw, h);
1100 } else {
1101 check.setRect(x, y, cw, h);
1102 }
1103 }
1104
1105 QRect display;
1106 QRect decoration;
1107 switch (opt->decorationPosition) {
1108 case QStyleOptionViewItem::Top: {
1109 if (hasPixmap)
1110 pm.setHeight(pm.height() + pixmapMargin); // add space
1111 h = sizehint ? textRect->height() : h - pm.height();
1112
1113 if (opt->direction == Qt::RightToLeft) {
1114 decoration.setRect(x, y, w - cw, pm.height());
1115 display.setRect(x, y + pm.height(), w - cw, h);
1116 } else {
1117 decoration.setRect(x + cw, y, w - cw, pm.height());
1118 display.setRect(x + cw, y + pm.height(), w - cw, h);
1119 }
1120 break; }
1121 case QStyleOptionViewItem::Bottom: {
1122 if (hasText)
1123 textRect->setHeight(textRect->height() + textMargin); // add space
1124 h = sizehint ? textRect->height() + pm.height() : h;
1125
1126 if (opt->direction == Qt::RightToLeft) {
1127 display.setRect(x, y, w - cw, textRect->height());
1128 decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
1129 } else {
1130 display.setRect(x + cw, y, w - cw, textRect->height());
1131 decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
1132 }
1133 break; }
1134 case QStyleOptionViewItem::Left: {
1135 if (opt->direction == Qt::LeftToRight) {
1136 decoration.setRect(x + cw, y, pm.width(), h);
1137 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
1138 } else {
1139 display.setRect(x, y, w - pm.width() - cw, h);
1140 decoration.setRect(display.right() + 1, y, pm.width(), h);
1141 }
1142 break; }
1143 case QStyleOptionViewItem::Right: {
1144 if (opt->direction == Qt::LeftToRight) {
1145 display.setRect(x + cw, y, w - pm.width() - cw, h);
1146 decoration.setRect(display.right() + 1, y, pm.width(), h);
1147 } else {
1148 decoration.setRect(x, y, pm.width(), h);
1149 display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
1150 }
1151 break; }
1152 default:
1153 qWarning("doLayout: decoration position is invalid");
1154 decoration = *pixmapRect;
1155 break;
1156 }
1157
1158 if (!sizehint) { // we only need to do the internal layout if we are going to paint
1159 *checkRect = QStyle::alignedRect(opt->direction, Qt::AlignCenter,
1160 checkRect->size(), check);
1161 *pixmapRect = QStyle::alignedRect(opt->direction, opt->decorationAlignment,
1162 pixmapRect->size(), decoration);
1163 // the text takes up all available space, unless the decoration is not shown as selected
1164 if (opt->showDecorationSelected)
1165 *textRect = display;
1166 else
1167 *textRect = QStyle::alignedRect(opt->direction, opt->displayAlignment,
1168 textRect->size().boundedTo(display.size()), display);
1169 } else {
1170 *checkRect = check;
1171 *pixmapRect = decoration;
1172 *textRect = display;
1173 }
1174 }
1175 #endif // QT_CONFIG(itemviews)
1176
1177 #if QT_CONFIG(toolbutton)
toolButtonElideText(const QStyleOptionToolButton * option,const QRect & textRect,int flags) const1178 QString QCommonStylePrivate::toolButtonElideText(const QStyleOptionToolButton *option,
1179 const QRect &textRect, int flags) const
1180 {
1181 if (option->fontMetrics.horizontalAdvance(option->text) <= textRect.width())
1182 return option->text;
1183
1184 QString text = option->text;
1185 text.replace('\n', QChar::LineSeparator);
1186 QTextOption textOption;
1187 textOption.setWrapMode(QTextOption::ManualWrap);
1188 textOption.setTextDirection(option->direction);
1189
1190 return calculateElidedText(text, textOption,
1191 option->font, textRect, Qt::AlignTop,
1192 Qt::ElideMiddle, flags,
1193 false, nullptr);
1194 }
1195 #endif // QT_CONFIG(toolbutton)
1196
1197 #if QT_CONFIG(tabbar)
1198 /*! \internal
1199 Compute the textRect and the pixmapRect from the opt rect
1200
1201 Uses the same computation than in QTabBar::tabSizeHint
1202 */
tabLayout(const QStyleOptionTab * opt,const QWidget * widget,QRect * textRect,QRect * iconRect) const1203 void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
1204 {
1205 Q_ASSERT(textRect);
1206 Q_ASSERT(iconRect);
1207 QRect tr = opt->rect;
1208 bool verticalTabs = opt->shape == QTabBar::RoundedEast
1209 || opt->shape == QTabBar::RoundedWest
1210 || opt->shape == QTabBar::TriangularEast
1211 || opt->shape == QTabBar::TriangularWest;
1212 if (verticalTabs)
1213 tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform
1214
1215 int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget);
1216 int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget);
1217 int hpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
1218 int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2;
1219 if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
1220 verticalShift = -verticalShift;
1221 tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);
1222 bool selected = opt->state & QStyle::State_Selected;
1223 if (selected) {
1224 tr.setTop(tr.top() - verticalShift);
1225 tr.setRight(tr.right() - horizontalShift);
1226 }
1227
1228 // left widget
1229 if (!opt->leftButtonSize.isEmpty()) {
1230 tr.setLeft(tr.left() + 4 +
1231 (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width()));
1232 }
1233 // right widget
1234 if (!opt->rightButtonSize.isEmpty()) {
1235 tr.setRight(tr.right() - 4 -
1236 (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width()));
1237 }
1238
1239 // icon
1240 if (!opt->icon.isNull()) {
1241 QSize iconSize = opt->iconSize;
1242 if (!iconSize.isValid()) {
1243 int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize, opt);
1244 iconSize = QSize(iconExtent, iconExtent);
1245 }
1246 QSize tabIconSize = opt->icon.actualSize(iconSize,
1247 (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
1248 (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off);
1249 // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
1250 tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height()));
1251
1252 const int offsetX = (iconSize.width() - tabIconSize.width()) / 2;
1253 *iconRect = QRect(tr.left() + offsetX, tr.center().y() - tabIconSize.height() / 2,
1254 tabIconSize.width(), tabIconSize.height());
1255 if (!verticalTabs)
1256 *iconRect = QStyle::visualRect(opt->direction, opt->rect, *iconRect);
1257 tr.setLeft(tr.left() + tabIconSize.width() + 4);
1258 }
1259
1260 if (!verticalTabs)
1261 tr = QStyle::visualRect(opt->direction, opt->rect, tr);
1262
1263 *textRect = tr;
1264 }
1265 #endif // QT_CONFIG(tabbar)
1266
1267 #if QT_CONFIG(animation)
1268 /*! \internal */
animationTargets() const1269 QList<const QObject*> QCommonStylePrivate::animationTargets() const
1270 {
1271 return animations.keys();
1272 }
1273
1274 /*! \internal */
animation(const QObject * target) const1275 QStyleAnimation * QCommonStylePrivate::animation(const QObject *target) const
1276 {
1277 return animations.value(target);
1278 }
1279
1280 /*! \internal */
startAnimation(QStyleAnimation * animation) const1281 void QCommonStylePrivate::startAnimation(QStyleAnimation *animation) const
1282 {
1283 Q_Q(const QCommonStyle);
1284 stopAnimation(animation->target());
1285 q->connect(animation, SIGNAL(destroyed()), SLOT(_q_removeAnimation()), Qt::UniqueConnection);
1286 animations.insert(animation->target(), animation);
1287 animation->start();
1288 }
1289
1290 /*! \internal */
stopAnimation(const QObject * target) const1291 void QCommonStylePrivate::stopAnimation(const QObject *target) const
1292 {
1293 QStyleAnimation *animation = animations.take(target);
1294 if (animation) {
1295 animation->stop();
1296 delete animation;
1297 }
1298 }
1299
1300 /*! \internal */
_q_removeAnimation()1301 void QCommonStylePrivate::_q_removeAnimation()
1302 {
1303 Q_Q(QCommonStyle);
1304 QObject *animation = q->sender();
1305 if (animation)
1306 animations.remove(animation->parent());
1307 }
1308 #endif
1309
1310 /*!
1311 \reimp
1312 */
drawControl(ControlElement element,const QStyleOption * opt,QPainter * p,const QWidget * widget) const1313 void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
1314 QPainter *p, const QWidget *widget) const
1315 {
1316 Q_D(const QCommonStyle);
1317 switch (element) {
1318
1319 case CE_PushButton:
1320 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1321 proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
1322 QStyleOptionButton subopt = *btn;
1323 subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
1324 proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
1325 if (btn->state & State_HasFocus) {
1326 QStyleOptionFocusRect fropt;
1327 fropt.QStyleOption::operator=(*btn);
1328 fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
1329 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1330 }
1331 }
1332 break;
1333 case CE_PushButtonBevel:
1334 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1335 QRect br = btn->rect;
1336 int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
1337 if (btn->features & QStyleOptionButton::DefaultButton)
1338 proxy()->drawPrimitive(PE_FrameDefaultButton, opt, p, widget);
1339 if (btn->features & QStyleOptionButton::AutoDefaultButton)
1340 br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
1341 if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton))
1342 || btn->state & (State_Sunken | State_On)
1343 || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) {
1344 QStyleOptionButton tmpBtn = *btn;
1345 tmpBtn.rect = br;
1346 proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, p, widget);
1347 }
1348 if (btn->features & QStyleOptionButton::HasMenu) {
1349 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
1350 QRect ir = btn->rect;
1351 QStyleOptionButton newBtn = *btn;
1352 newBtn.rect = QRect(ir.right() - mbi + 2, ir.height()/2 - mbi/2 + 3, mbi - 6, mbi - 6);
1353 newBtn.rect = visualRect(btn->direction, br, newBtn.rect);
1354 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
1355 }
1356 }
1357 break;
1358 case CE_PushButtonLabel:
1359 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1360 QRect textRect = button->rect;
1361 uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
1362 if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
1363 tf |= Qt::TextHideMnemonic;
1364
1365 if (!button->icon.isNull()) {
1366 //Center both icon and text
1367 QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
1368 if (mode == QIcon::Normal && button->state & State_HasFocus)
1369 mode = QIcon::Active;
1370 QIcon::State state = QIcon::Off;
1371 if (button->state & State_On)
1372 state = QIcon::On;
1373
1374 QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
1375 int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
1376 int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
1377 int labelWidth = pixmapWidth;
1378 int labelHeight = pixmapHeight;
1379 int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
1380 if (!button->text.isEmpty()) {
1381 int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
1382 labelWidth += (textWidth + iconSpacing);
1383 }
1384
1385 QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
1386 textRect.y() + (textRect.height() - labelHeight) / 2,
1387 pixmapWidth, pixmapHeight);
1388
1389 iconRect = visualRect(button->direction, textRect, iconRect);
1390
1391 if (button->direction == Qt::RightToLeft) {
1392 tf |= Qt::AlignRight;
1393 textRect.setRight(iconRect.left() - iconSpacing / 2);
1394 } else {
1395 tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
1396 textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing / 2);
1397 }
1398
1399 if (button->state & (State_On | State_Sunken))
1400 iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
1401 proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
1402 p->drawPixmap(iconRect, pixmap);
1403 } else {
1404 tf |= Qt::AlignHCenter;
1405 }
1406 if (button->state & (State_On | State_Sunken))
1407 textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
1408 proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
1409
1410 if (button->features & QStyleOptionButton::HasMenu) {
1411 int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
1412 if (button->direction == Qt::LeftToRight)
1413 textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
1414 else
1415 textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
1416 }
1417 proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
1418 button->text, QPalette::ButtonText);
1419 }
1420 break;
1421 case CE_RadioButton:
1422 case CE_CheckBox:
1423 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1424 bool isRadio = (element == CE_RadioButton);
1425 QStyleOptionButton subopt = *btn;
1426 subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
1427 : SE_CheckBoxIndicator, btn, widget);
1428 proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
1429 &subopt, p, widget);
1430 subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
1431 : SE_CheckBoxContents, btn, widget);
1432 proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
1433 if (btn->state & State_HasFocus) {
1434 QStyleOptionFocusRect fropt;
1435 fropt.QStyleOption::operator=(*btn);
1436 fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
1437 : SE_CheckBoxFocusRect, btn, widget);
1438 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1439 }
1440 }
1441 break;
1442 case CE_RadioButtonLabel:
1443 case CE_CheckBoxLabel:
1444 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1445 uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
1446
1447 if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
1448 alignment |= Qt::TextHideMnemonic;
1449 QPixmap pix;
1450 QRect textRect = btn->rect;
1451 if (!btn->icon.isNull()) {
1452 pix = btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
1453 proxy()->drawItemPixmap(p, btn->rect, alignment, pix);
1454 if (btn->direction == Qt::RightToLeft)
1455 textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
1456 else
1457 textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
1458 }
1459 if (!btn->text.isEmpty()){
1460 proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
1461 btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
1462 }
1463 }
1464 break;
1465 #if QT_CONFIG(menu)
1466 case CE_MenuScroller: {
1467 QStyleOption arrowOpt = *opt;
1468 arrowOpt.state |= State_Enabled;
1469 proxy()->drawPrimitive(((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp),
1470 &arrowOpt, p, widget);
1471 break; }
1472 case CE_MenuTearoff:
1473 if (opt->state & State_Selected)
1474 p->fillRect(opt->rect, opt->palette.brush(QPalette::Highlight));
1475 else
1476 p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
1477 p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
1478 p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2 - 1,
1479 opt->rect.x() + opt->rect.width() - 4,
1480 opt->rect.y() + opt->rect.height() / 2 - 1);
1481 p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
1482 p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2,
1483 opt->rect.x() + opt->rect.width() - 4, opt->rect.y() + opt->rect.height() / 2);
1484 break;
1485 #endif // QT_CONFIG(menu)
1486 #if QT_CONFIG(menubar)
1487 case CE_MenuBarItem:
1488 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1489 uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip
1490 | Qt::TextSingleLine;
1491 if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
1492 alignment |= Qt::TextHideMnemonic;
1493 int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt);
1494 QPixmap pix = mbi->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1495 if (!pix.isNull())
1496 proxy()->drawItemPixmap(p,mbi->rect, alignment, pix);
1497 else
1498 proxy()->drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled,
1499 mbi->text, QPalette::ButtonText);
1500 }
1501 break;
1502 case CE_MenuBarEmptyArea:
1503 if (widget && !widget->testAttribute(Qt::WA_NoSystemBackground))
1504 p->eraseRect(opt->rect);
1505 break;
1506 #endif // QT_CONFIG(menubar)
1507 #if QT_CONFIG(progressbar)
1508 case CE_ProgressBar:
1509 if (const QStyleOptionProgressBar *pb
1510 = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1511 QStyleOptionProgressBar subopt = *pb;
1512 subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget);
1513 proxy()->drawControl(CE_ProgressBarGroove, &subopt, p, widget);
1514 subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget);
1515 proxy()->drawControl(CE_ProgressBarContents, &subopt, p, widget);
1516 if (pb->textVisible) {
1517 subopt.rect = subElementRect(SE_ProgressBarLabel, pb, widget);
1518 proxy()->drawControl(CE_ProgressBarLabel, &subopt, p, widget);
1519 }
1520 }
1521 break;
1522 case CE_ProgressBarGroove:
1523 if (opt->rect.isValid())
1524 qDrawShadePanel(p, opt->rect, opt->palette, true, 1,
1525 &opt->palette.brush(QPalette::Window));
1526 break;
1527 case CE_ProgressBarLabel:
1528 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1529 const bool vertical = pb->orientation == Qt::Vertical;
1530 if (!vertical) {
1531 QPalette::ColorRole textRole = QPalette::NoRole;
1532 if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible
1533 && ((qint64(pb->progress) - qint64(pb->minimum)) * 2 >= (qint64(pb->maximum) - qint64(pb->minimum)))) {
1534 textRole = QPalette::HighlightedText;
1535 //Draw text shadow, This will increase readability when the background of same color
1536 QRect shadowRect(pb->rect);
1537 shadowRect.translate(1,1);
1538 QColor shadowColor = (pb->palette.color(textRole).value() <= 128)
1539 ? QColor(255,255,255,160) : QColor(0,0,0,160);
1540 QPalette shadowPalette = pb->palette;
1541 shadowPalette.setColor(textRole, shadowColor);
1542 proxy()->drawItemText(p, shadowRect, Qt::AlignCenter | Qt::TextSingleLine, shadowPalette,
1543 pb->state & State_Enabled, pb->text, textRole);
1544 }
1545 proxy()->drawItemText(p, pb->rect, Qt::AlignCenter | Qt::TextSingleLine, pb->palette,
1546 pb->state & State_Enabled, pb->text, textRole);
1547 }
1548 }
1549 break;
1550 case CE_ProgressBarContents:
1551 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1552
1553 QRect rect = pb->rect;
1554 const bool vertical = pb->orientation == Qt::Vertical;
1555 const bool inverted = pb->invertedAppearance;
1556 qint64 minimum = qint64(pb->minimum);
1557 qint64 maximum = qint64(pb->maximum);
1558 qint64 progress = qint64(pb->progress);
1559
1560 QTransform m;
1561
1562 if (vertical) {
1563 rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
1564 m.rotate(90);
1565 m.translate(0, -(rect.height() + rect.y()*2));
1566 }
1567
1568 QPalette pal2 = pb->palette;
1569 // Correct the highlight color if it is the same as the background
1570 if (pal2.highlight() == pal2.window())
1571 pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
1572 QPalette::Highlight));
1573 bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1574 if (inverted)
1575 reverse = !reverse;
1576 int w = rect.width();
1577 if (pb->minimum == 0 && pb->maximum == 0) {
1578 // draw busy indicator
1579 int x = (progress - minimum) % (w * 2);
1580 if (x > w)
1581 x = 2 * w - x;
1582 x = reverse ? rect.right() - x : x + rect.x();
1583 p->setPen(QPen(pal2.highlight().color(), 4));
1584 p->drawLine(x, rect.y(), x, rect.height());
1585 } else {
1586 const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
1587 if (!unit_width)
1588 return;
1589
1590 int u;
1591 if (unit_width > 1)
1592 u = ((rect.width() + unit_width) / unit_width);
1593 else
1594 u = w / unit_width;
1595 qint64 p_v = progress - minimum;
1596 qint64 t_s = (maximum - minimum) ? (maximum - minimum) : qint64(1);
1597
1598 if (u > 0 && p_v >= INT_MAX / u && t_s >= u) {
1599 // scale down to something usable.
1600 p_v /= u;
1601 t_s /= u;
1602 }
1603
1604 // nu < tnu, if last chunk is only a partial chunk
1605 int tnu, nu;
1606 tnu = nu = p_v * u / t_s;
1607
1608 if (nu * unit_width > w)
1609 --nu;
1610
1611 // Draw nu units out of a possible u of unit_width
1612 // width, each a rectangle bordered by background
1613 // color, all in a sunken panel with a percentage text
1614 // display at the end.
1615 int x = 0;
1616 int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0)
1617 : rect.x();
1618
1619 QStyleOptionProgressBar pbBits = *pb;
1620 pbBits.rect = rect;
1621 pbBits.palette = pal2;
1622 int myY = pbBits.rect.y();
1623 int myHeight = pbBits.rect.height();
1624 pbBits.state = State_None;
1625 for (int i = 0; i < nu; ++i) {
1626 pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
1627 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1628 proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1629 x += reverse ? -unit_width : unit_width;
1630 }
1631
1632 // Draw the last partial chunk to fill up the
1633 // progress bar entirely
1634 if (nu < tnu) {
1635 int pixels_left = w - (nu * unit_width);
1636 int offset = reverse ? x0 + x + unit_width-pixels_left : x0 + x;
1637 pbBits.rect.setRect(offset, myY, pixels_left, myHeight);
1638 pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1639 proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1640 }
1641 }
1642 }
1643 break;
1644 #endif // QT_CONFIG(progressbar)
1645 case CE_HeaderLabel:
1646 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
1647 QRect rect = header->rect;
1648 if (!header->icon.isNull()) {
1649 int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt);
1650 QPixmap pixmap
1651 = header->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1652 int pixw = pixmap.width() / pixmap.devicePixelRatio();
1653
1654 QRect aligned = alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size() / pixmap.devicePixelRatio(), rect);
1655 QRect inter = aligned.intersected(rect);
1656 p->drawPixmap(inter.x(), inter.y(), pixmap,
1657 inter.x() - aligned.x(), inter.y() - aligned.y(),
1658 aligned.width() * pixmap.devicePixelRatio(),
1659 pixmap.height() * pixmap.devicePixelRatio());
1660
1661 const int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
1662 if (header->direction == Qt::LeftToRight)
1663 rect.setLeft(rect.left() + pixw + margin);
1664 else
1665 rect.setRight(rect.right() - pixw - margin);
1666 }
1667 if (header->state & QStyle::State_On) {
1668 QFont fnt = p->font();
1669 fnt.setBold(true);
1670 p->setFont(fnt);
1671 }
1672 proxy()->drawItemText(p, rect, header->textAlignment, header->palette,
1673 (header->state & State_Enabled), header->text, QPalette::ButtonText);
1674 }
1675 break;
1676 #if QT_CONFIG(toolbutton)
1677 case CE_ToolButtonLabel:
1678 if (const QStyleOptionToolButton *toolbutton
1679 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
1680 QRect rect = toolbutton->rect;
1681 int shiftX = 0;
1682 int shiftY = 0;
1683 if (toolbutton->state & (State_Sunken | State_On)) {
1684 shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, toolbutton, widget);
1685 shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, toolbutton, widget);
1686 }
1687 // Arrow type always overrules and is always shown
1688 bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow;
1689 if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty())
1690 || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) {
1691 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1692 if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1693 alignment |= Qt::TextHideMnemonic;
1694 rect.translate(shiftX, shiftY);
1695 p->setFont(toolbutton->font);
1696 proxy()->drawItemText(p, rect, alignment, toolbutton->palette,
1697 opt->state & State_Enabled, toolbutton->text,
1698 QPalette::ButtonText);
1699 } else {
1700 QPixmap pm;
1701 QSize pmSize = toolbutton->iconSize;
1702 if (!toolbutton->icon.isNull()) {
1703 QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off;
1704 QIcon::Mode mode;
1705 if (!(toolbutton->state & State_Enabled))
1706 mode = QIcon::Disabled;
1707 else if ((opt->state & State_MouseOver) && (opt->state & State_AutoRaise))
1708 mode = QIcon::Active;
1709 else
1710 mode = QIcon::Normal;
1711 pm = toolbutton->icon.pixmap(qt_getWindow(widget), toolbutton->rect.size().boundedTo(toolbutton->iconSize),
1712 mode, state);
1713 pmSize = pm.size() / pm.devicePixelRatio();
1714 }
1715
1716 if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) {
1717 p->setFont(toolbutton->font);
1718 QRect pr = rect,
1719 tr = rect;
1720 int alignment = Qt::TextShowMnemonic;
1721 if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1722 alignment |= Qt::TextHideMnemonic;
1723
1724 if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
1725 pr.setHeight(pmSize.height() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint()
1726 tr.adjust(0, pr.height() - 1, 0, -1);
1727 pr.translate(shiftX, shiftY);
1728 if (!hasArrow) {
1729 proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm);
1730 } else {
1731 drawArrow(proxy(), toolbutton, pr, p, widget);
1732 }
1733 alignment |= Qt::AlignCenter;
1734 } else {
1735 pr.setWidth(pmSize.width() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint()
1736 tr.adjust(pr.width(), 0, 0, 0);
1737 pr.translate(shiftX, shiftY);
1738 if (!hasArrow) {
1739 proxy()->drawItemPixmap(p, QStyle::visualRect(opt->direction, rect, pr), Qt::AlignCenter, pm);
1740 } else {
1741 drawArrow(proxy(), toolbutton, pr, p, widget);
1742 }
1743 alignment |= Qt::AlignLeft | Qt::AlignVCenter;
1744 }
1745 tr.translate(shiftX, shiftY);
1746 const QString text = d->toolButtonElideText(toolbutton, tr, alignment);
1747 proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
1748 toolbutton->state & State_Enabled, text,
1749 QPalette::ButtonText);
1750 } else {
1751 rect.translate(shiftX, shiftY);
1752 if (hasArrow) {
1753 drawArrow(proxy(), toolbutton, rect, p, widget);
1754 } else {
1755 proxy()->drawItemPixmap(p, rect, Qt::AlignCenter, pm);
1756 }
1757 }
1758 }
1759 }
1760 break;
1761 #endif // QT_CONFIG(toolbutton)
1762 #if QT_CONFIG(toolbox)
1763 case CE_ToolBoxTab:
1764 if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1765 proxy()->drawControl(CE_ToolBoxTabShape, tb, p, widget);
1766 proxy()->drawControl(CE_ToolBoxTabLabel, tb, p, widget);
1767 }
1768 break;
1769 case CE_ToolBoxTabShape:
1770 if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1771 p->setPen(tb->palette.mid().color().darker(150));
1772 bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
1773 p->setRenderHint(QPainter::Qt4CompatiblePainting);
1774 int d = 20 + tb->rect.height() - 3;
1775 if (tb->direction != Qt::RightToLeft) {
1776 const QPoint points[] = {
1777 QPoint(-1, tb->rect.height() + 1),
1778 QPoint(-1, 1),
1779 QPoint(tb->rect.width() - d, 1),
1780 QPoint(tb->rect.width() - 20, tb->rect.height() - 2),
1781 QPoint(tb->rect.width() - 1, tb->rect.height() - 2),
1782 QPoint(tb->rect.width() - 1, tb->rect.height() + 1),
1783 QPoint(-1, tb->rect.height() + 1),
1784 };
1785 p->drawPolygon(points, sizeof points / sizeof *points);
1786 } else {
1787 const QPoint points[] = {
1788 QPoint(tb->rect.width(), tb->rect.height() + 1),
1789 QPoint(tb->rect.width(), 1),
1790 QPoint(d - 1, 1),
1791 QPoint(20 - 1, tb->rect.height() - 2),
1792 QPoint(0, tb->rect.height() - 2),
1793 QPoint(0, tb->rect.height() + 1),
1794 QPoint(tb->rect.width(), tb->rect.height() + 1),
1795 };
1796 p->drawPolygon(points, sizeof points / sizeof *points);
1797 }
1798 p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
1799 p->setPen(tb->palette.light().color());
1800 if (tb->direction != Qt::RightToLeft) {
1801 p->drawLine(0, 2, tb->rect.width() - d, 2);
1802 p->drawLine(tb->rect.width() - d - 1, 2, tb->rect.width() - 21, tb->rect.height() - 1);
1803 p->drawLine(tb->rect.width() - 20, tb->rect.height() - 1,
1804 tb->rect.width(), tb->rect.height() - 1);
1805 } else {
1806 p->drawLine(tb->rect.width() - 1, 2, d - 1, 2);
1807 p->drawLine(d, 2, 20, tb->rect.height() - 1);
1808 p->drawLine(19, tb->rect.height() - 1,
1809 -1, tb->rect.height() - 1);
1810 }
1811 p->setBrush(Qt::NoBrush);
1812 }
1813 break;
1814 #endif // QT_CONFIG(toolbox)
1815 #if QT_CONFIG(tabbar)
1816 case CE_TabBarTab:
1817 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1818 proxy()->drawControl(CE_TabBarTabShape, tab, p, widget);
1819 proxy()->drawControl(CE_TabBarTabLabel, tab, p, widget);
1820 }
1821 break;
1822 case CE_TabBarTabShape:
1823 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1824 p->save();
1825
1826 QRect rect(tab->rect);
1827 bool selected = tab->state & State_Selected;
1828 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1829 int tabOverlap = onlyOne ? 0 : proxy()->pixelMetric(PM_TabBarTabOverlap, opt, widget);
1830
1831 if (!selected) {
1832 switch (tab->shape) {
1833 case QTabBar::TriangularNorth:
1834 rect.adjust(0, 0, 0, -tabOverlap);
1835 if(!selected)
1836 rect.adjust(1, 1, -1, 0);
1837 break;
1838 case QTabBar::TriangularSouth:
1839 rect.adjust(0, tabOverlap, 0, 0);
1840 if(!selected)
1841 rect.adjust(1, 0, -1, -1);
1842 break;
1843 case QTabBar::TriangularEast:
1844 rect.adjust(tabOverlap, 0, 0, 0);
1845 if(!selected)
1846 rect.adjust(0, 1, -1, -1);
1847 break;
1848 case QTabBar::TriangularWest:
1849 rect.adjust(0, 0, -tabOverlap, 0);
1850 if(!selected)
1851 rect.adjust(1, 1, 0, -1);
1852 break;
1853 default:
1854 break;
1855 }
1856 }
1857
1858 p->setPen(QPen(tab->palette.windowText(), 0));
1859 if (selected) {
1860 p->setBrush(tab->palette.base());
1861 } else {
1862 if (widget && widget->parentWidget())
1863 p->setBrush(widget->parentWidget()->palette().window());
1864 else
1865 p->setBrush(tab->palette.window());
1866 }
1867
1868 int y;
1869 int x;
1870 QPolygon a(10);
1871 switch (tab->shape) {
1872 case QTabBar::TriangularNorth:
1873 case QTabBar::TriangularSouth: {
1874 a.setPoint(0, 0, -1);
1875 a.setPoint(1, 0, 0);
1876 y = rect.height() - 2;
1877 x = y / 3;
1878 a.setPoint(2, x++, y - 1);
1879 ++x;
1880 a.setPoint(3, x++, y++);
1881 a.setPoint(4, x, y);
1882
1883 int i;
1884 int right = rect.width() - 1;
1885 for (i = 0; i < 5; ++i)
1886 a.setPoint(9 - i, right - a.point(i).x(), a.point(i).y());
1887 if (tab->shape == QTabBar::TriangularNorth)
1888 for (i = 0; i < 10; ++i)
1889 a.setPoint(i, a.point(i).x(), rect.height() - 1 - a.point(i).y());
1890
1891 a.translate(rect.left(), rect.top());
1892 p->setRenderHint(QPainter::Antialiasing);
1893 p->translate(0, 0.5);
1894
1895 QPainterPath path;
1896 path.addPolygon(a);
1897 p->drawPath(path);
1898 break; }
1899 case QTabBar::TriangularEast:
1900 case QTabBar::TriangularWest: {
1901 a.setPoint(0, -1, 0);
1902 a.setPoint(1, 0, 0);
1903 x = rect.width() - 2;
1904 y = x / 3;
1905 a.setPoint(2, x - 1, y++);
1906 ++y;
1907 a.setPoint(3, x++, y++);
1908 a.setPoint(4, x, y);
1909 int i;
1910 int bottom = rect.height() - 1;
1911 for (i = 0; i < 5; ++i)
1912 a.setPoint(9 - i, a.point(i).x(), bottom - a.point(i).y());
1913 if (tab->shape == QTabBar::TriangularWest)
1914 for (i = 0; i < 10; ++i)
1915 a.setPoint(i, rect.width() - 1 - a.point(i).x(), a.point(i).y());
1916 a.translate(rect.left(), rect.top());
1917 p->setRenderHint(QPainter::Antialiasing);
1918 p->translate(0.5, 0);
1919 QPainterPath path;
1920 path.addPolygon(a);
1921 p->drawPath(path);
1922 break; }
1923 default:
1924 break;
1925 }
1926 p->restore();
1927 }
1928 break;
1929 case CE_ToolBoxTabLabel:
1930 if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1931 bool enabled = tb->state & State_Enabled;
1932 bool selected = tb->state & State_Selected;
1933 int iconExtent = proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb, widget);
1934 QPixmap pm = tb->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent),
1935 enabled ? QIcon::Normal : QIcon::Disabled);
1936
1937 QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget);
1938 QRect tr, ir;
1939 int ih = 0;
1940 if (pm.isNull()) {
1941 tr = cr;
1942 tr.adjust(4, 0, -8, 0);
1943 } else {
1944 int iw = pm.width() / pm.devicePixelRatio() + 4;
1945 ih = pm.height()/ pm.devicePixelRatio();
1946 ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
1947 tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
1948 }
1949
1950 if (selected && proxy()->styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb, widget)) {
1951 QFont f(p->font());
1952 f.setBold(true);
1953 p->setFont(f);
1954 }
1955
1956 QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width());
1957
1958 if (ih)
1959 p->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm);
1960
1961 int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
1962 if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, tb, widget))
1963 alignment |= Qt::TextHideMnemonic;
1964 proxy()->drawItemText(p, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText);
1965
1966 if (!txt.isEmpty() && opt->state & State_HasFocus) {
1967 QStyleOptionFocusRect opt;
1968 opt.rect = tr;
1969 opt.palette = tb->palette;
1970 opt.state = QStyle::State_None;
1971 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, widget);
1972 }
1973 }
1974 break;
1975 case CE_TabBarTabLabel:
1976 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1977 QRect tr = tab->rect;
1978 bool verticalTabs = tab->shape == QTabBar::RoundedEast
1979 || tab->shape == QTabBar::RoundedWest
1980 || tab->shape == QTabBar::TriangularEast
1981 || tab->shape == QTabBar::TriangularWest;
1982
1983 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1984 if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1985 alignment |= Qt::TextHideMnemonic;
1986
1987 if (verticalTabs) {
1988 p->save();
1989 int newX, newY, newRot;
1990 if (tab->shape == QTabBar::RoundedEast || tab->shape == QTabBar::TriangularEast) {
1991 newX = tr.width() + tr.x();
1992 newY = tr.y();
1993 newRot = 90;
1994 } else {
1995 newX = tr.x();
1996 newY = tr.y() + tr.height();
1997 newRot = -90;
1998 }
1999 QTransform m = QTransform::fromTranslate(newX, newY);
2000 m.rotate(newRot);
2001 p->setTransform(m, true);
2002 }
2003 QRect iconRect;
2004 d->tabLayout(tab, widget, &tr, &iconRect);
2005 tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect
2006
2007 if (!tab->icon.isNull()) {
2008 QPixmap tabIcon = tab->icon.pixmap(qt_getWindow(widget), tab->iconSize,
2009 (tab->state & State_Enabled) ? QIcon::Normal
2010 : QIcon::Disabled,
2011 (tab->state & State_Selected) ? QIcon::On
2012 : QIcon::Off);
2013 p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
2014 }
2015
2016 proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
2017 if (verticalTabs)
2018 p->restore();
2019
2020 if (tab->state & State_HasFocus) {
2021 const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);
2022
2023 int x1, x2;
2024 x1 = tab->rect.left();
2025 x2 = tab->rect.right() - 1;
2026
2027 QStyleOptionFocusRect fropt;
2028 fropt.QStyleOption::operator=(*tab);
2029 fropt.rect.setRect(x1 + 1 + OFFSET, tab->rect.y() + OFFSET,
2030 x2 - x1 - 2*OFFSET, tab->rect.height() - 2*OFFSET);
2031 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
2032 }
2033 }
2034 break;
2035 #endif // QT_CONFIG(tabbar)
2036 #if QT_CONFIG(sizegrip)
2037 case CE_SizeGrip: {
2038 p->save();
2039 int x, y, w, h;
2040 opt->rect.getRect(&x, &y, &w, &h);
2041
2042 int sw = qMin(h, w);
2043 if (h > w)
2044 p->translate(0, h - w);
2045 else
2046 p->translate(w - h, 0);
2047
2048 int sx = x;
2049 int sy = y;
2050 int s = sw / 3;
2051
2052 Qt::Corner corner;
2053 if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt))
2054 corner = sgOpt->corner;
2055 else if (opt->direction == Qt::RightToLeft)
2056 corner = Qt::BottomLeftCorner;
2057 else
2058 corner = Qt::BottomRightCorner;
2059
2060 if (corner == Qt::BottomLeftCorner) {
2061 sx = x + sw;
2062 for (int i = 0; i < 4; ++i) {
2063 p->setPen(QPen(opt->palette.light().color(), 1));
2064 p->drawLine(x, sy - 1 , sx + 1, sw);
2065 p->setPen(QPen(opt->palette.dark().color(), 1));
2066 p->drawLine(x, sy, sx, sw);
2067 p->setPen(QPen(opt->palette.dark().color(), 1));
2068 p->drawLine(x, sy + 1, sx - 1, sw);
2069 sx -= s;
2070 sy += s;
2071 }
2072 } else if (corner == Qt::BottomRightCorner) {
2073 for (int i = 0; i < 4; ++i) {
2074 p->setPen(QPen(opt->palette.light().color(), 1));
2075 p->drawLine(sx - 1, sw, sw, sy - 1);
2076 p->setPen(QPen(opt->palette.dark().color(), 1));
2077 p->drawLine(sx, sw, sw, sy);
2078 p->setPen(QPen(opt->palette.dark().color(), 1));
2079 p->drawLine(sx + 1, sw, sw, sy + 1);
2080 sx += s;
2081 sy += s;
2082 }
2083 } else if (corner == Qt::TopRightCorner) {
2084 sy = y + sw;
2085 for (int i = 0; i < 4; ++i) {
2086 p->setPen(QPen(opt->palette.light().color(), 1));
2087 p->drawLine(sx - 1, y, sw, sy + 1);
2088 p->setPen(QPen(opt->palette.dark().color(), 1));
2089 p->drawLine(sx, y, sw, sy);
2090 p->setPen(QPen(opt->palette.dark().color(), 1));
2091 p->drawLine(sx + 1, y, sw, sy - 1);
2092 sx += s;
2093 sy -= s;
2094 }
2095 } else if (corner == Qt::TopLeftCorner) {
2096 for (int i = 0; i < 4; ++i) {
2097 p->setPen(QPen(opt->palette.light().color(), 1));
2098 p->drawLine(x, sy - 1, sx - 1, y);
2099 p->setPen(QPen(opt->palette.dark().color(), 1));
2100 p->drawLine(x, sy, sx, y);
2101 p->setPen(QPen(opt->palette.dark().color(), 1));
2102 p->drawLine(x, sy + 1, sx + 1, y);
2103 sx += s;
2104 sy += s;
2105 }
2106 }
2107 p->restore();
2108 break; }
2109 #endif // QT_CONFIG(sizegrip)
2110 #if QT_CONFIG(rubberband)
2111 case CE_RubberBand: {
2112 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
2113 QPixmap tiledPixmap(16, 16);
2114 QPainter pixmapPainter(&tiledPixmap);
2115 pixmapPainter.setPen(Qt::NoPen);
2116 pixmapPainter.setBrush(Qt::Dense4Pattern);
2117 pixmapPainter.setBackground(QBrush(opt->palette.base()));
2118 pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
2119 pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
2120 pixmapPainter.end();
2121 // ### workaround for borked XRENDER
2122 tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
2123
2124 p->save();
2125 QRect r = opt->rect;
2126 QStyleHintReturnMask mask;
2127 if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
2128 p->setClipRegion(mask.region);
2129 p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
2130 p->setPen(opt->palette.color(QPalette::Active, QPalette::WindowText));
2131 p->setBrush(Qt::NoBrush);
2132 p->drawRect(r.adjusted(0, 0, -1, -1));
2133 if (rbOpt->shape == QRubberBand::Rectangle)
2134 p->drawRect(r.adjusted(3, 3, -4, -4));
2135 p->restore();
2136 }
2137 break; }
2138 #endif // QT_CONFIG(rubberband)
2139 #if QT_CONFIG(dockwidget)
2140 case CE_DockWidgetTitle:
2141 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
2142 QRect r = dwOpt->rect.adjusted(0, 0, -1, -1);
2143 if (dwOpt->movable) {
2144 p->setPen(dwOpt->palette.color(QPalette::Dark));
2145 p->drawRect(r);
2146 }
2147
2148 if (!dwOpt->title.isEmpty()) {
2149 const bool verticalTitleBar = dwOpt->verticalTitleBar;
2150
2151 if (verticalTitleBar) {
2152 r = r.transposed();
2153
2154 p->save();
2155 p->translate(r.left(), r.top() + r.width());
2156 p->rotate(-90);
2157 p->translate(-r.left(), -r.top());
2158 }
2159
2160 const int indent = p->fontMetrics().descent();
2161 proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1),
2162 Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
2163 dwOpt->state & State_Enabled, dwOpt->title,
2164 QPalette::WindowText);
2165
2166 if (verticalTitleBar)
2167 p->restore();
2168 }
2169 }
2170 break;
2171 #endif // QT_CONFIG(dockwidget)
2172 case CE_Header:
2173 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2174 QRegion clipRegion = p->clipRegion();
2175 p->setClipRect(opt->rect);
2176 proxy()->drawControl(CE_HeaderSection, header, p, widget);
2177 QStyleOptionHeader subopt = *header;
2178 subopt.rect = subElementRect(SE_HeaderLabel, header, widget);
2179 if (subopt.rect.isValid())
2180 proxy()->drawControl(CE_HeaderLabel, &subopt, p, widget);
2181 if (header->sortIndicator != QStyleOptionHeader::None) {
2182 subopt.rect = subElementRect(SE_HeaderArrow, opt, widget);
2183 proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, p, widget);
2184 }
2185 p->setClipRegion(clipRegion);
2186 }
2187 break;
2188 case CE_FocusFrame:
2189 p->fillRect(opt->rect, opt->palette.windowText());
2190 break;
2191 case CE_HeaderSection:
2192 qDrawShadePanel(p, opt->rect, opt->palette,
2193 opt->state & State_Sunken, 1,
2194 &opt->palette.brush(QPalette::Button));
2195 break;
2196 case CE_HeaderEmptyArea:
2197 p->fillRect(opt->rect, opt->palette.window());
2198 break;
2199 #if QT_CONFIG(combobox)
2200 case CE_ComboBoxLabel:
2201 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2202 QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
2203 p->save();
2204 p->setClipRect(editRect);
2205 if (!cb->currentIcon.isNull()) {
2206 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
2207 : QIcon::Disabled;
2208 QPixmap pixmap = cb->currentIcon.pixmap(qt_getWindow(widget), cb->iconSize, mode);
2209 QRect iconRect(editRect);
2210 iconRect.setWidth(cb->iconSize.width() + 4);
2211 iconRect = alignedRect(cb->direction,
2212 Qt::AlignLeft | Qt::AlignVCenter,
2213 iconRect.size(), editRect);
2214 if (cb->editable)
2215 p->fillRect(iconRect, opt->palette.brush(QPalette::Base));
2216 proxy()->drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
2217
2218 if (cb->direction == Qt::RightToLeft)
2219 editRect.translate(-4 - cb->iconSize.width(), 0);
2220 else
2221 editRect.translate(cb->iconSize.width() + 4, 0);
2222 }
2223 if (!cb->currentText.isEmpty() && !cb->editable) {
2224 proxy()->drawItemText(p, editRect.adjusted(1, 0, -1, 0),
2225 visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
2226 cb->palette, cb->state & State_Enabled, cb->currentText);
2227 }
2228 p->restore();
2229 }
2230 break;
2231 #endif // QT_CONFIG(combobox)
2232 #if QT_CONFIG(toolbar)
2233 case CE_ToolBar:
2234 if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
2235 // Compatibility with styles that use PE_PanelToolBar
2236 QStyleOptionFrame frame;
2237 frame.QStyleOption::operator=(*toolBar);
2238 frame.lineWidth = toolBar->lineWidth;
2239 frame.midLineWidth = toolBar->midLineWidth;
2240 proxy()->drawPrimitive(PE_PanelToolBar, opt, p, widget);
2241
2242 if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
2243 break;
2244 qDrawShadePanel(p, toolBar->rect, toolBar->palette, false, toolBar->lineWidth,
2245 &toolBar->palette.brush(QPalette::Button));
2246 }
2247 break;
2248 #endif // QT_CONFIG(toolbar)
2249 case CE_ColumnViewGrip: {
2250 // draw background gradients
2251 QLinearGradient g(0, 0, opt->rect.width(), 0);
2252 g.setColorAt(0, opt->palette.color(QPalette::Active, QPalette::Mid));
2253 g.setColorAt(0.5, Qt::white);
2254 p->fillRect(QRect(0, 0, opt->rect.width(), opt->rect.height()), g);
2255
2256 // draw the two lines
2257 QPen pen(p->pen());
2258 pen.setWidth(opt->rect.width()/20);
2259 pen.setColor(opt->palette.color(QPalette::Active, QPalette::Dark));
2260 p->setPen(pen);
2261
2262 int line1starting = opt->rect.width()*8 / 20;
2263 int line2starting = opt->rect.width()*13 / 20;
2264 int top = opt->rect.height()*20/75;
2265 int bottom = opt->rect.height() - 1 - top;
2266 p->drawLine(line1starting, top, line1starting, bottom);
2267 p->drawLine(line2starting, top, line2starting, bottom);
2268 }
2269 break;
2270
2271 #if QT_CONFIG(itemviews)
2272 case CE_ItemViewItem:
2273 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
2274 p->save();
2275 p->setClipRect(opt->rect);
2276
2277 QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
2278 QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
2279 QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
2280
2281 // draw the background
2282 proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);
2283
2284 // draw the check mark
2285 if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
2286 QStyleOptionViewItem option(*vopt);
2287 option.rect = checkRect;
2288 option.state = option.state & ~QStyle::State_HasFocus;
2289
2290 switch (vopt->checkState) {
2291 case Qt::Unchecked:
2292 option.state |= QStyle::State_Off;
2293 break;
2294 case Qt::PartiallyChecked:
2295 option.state |= QStyle::State_NoChange;
2296 break;
2297 case Qt::Checked:
2298 option.state |= QStyle::State_On;
2299 break;
2300 }
2301 proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, p, widget);
2302 }
2303
2304 // draw the icon
2305 QIcon::Mode mode = QIcon::Normal;
2306 if (!(vopt->state & QStyle::State_Enabled))
2307 mode = QIcon::Disabled;
2308 else if (vopt->state & QStyle::State_Selected)
2309 mode = QIcon::Selected;
2310 QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
2311 vopt->icon.paint(p, iconRect, vopt->decorationAlignment, mode, state);
2312
2313 // draw the text
2314 if (!vopt->text.isEmpty()) {
2315 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
2316 ? QPalette::Normal : QPalette::Disabled;
2317 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
2318 cg = QPalette::Inactive;
2319
2320 if (vopt->state & QStyle::State_Selected) {
2321 p->setPen(vopt->palette.color(cg, QPalette::HighlightedText));
2322 } else {
2323 p->setPen(vopt->palette.color(cg, QPalette::Text));
2324 }
2325 if (vopt->state & QStyle::State_Editing) {
2326 p->setPen(vopt->palette.color(cg, QPalette::Text));
2327 p->drawRect(textRect.adjusted(0, 0, -1, -1));
2328 }
2329
2330 d->viewItemDrawText(p, vopt, textRect);
2331 }
2332
2333 // draw the focus rect
2334 if (vopt->state & QStyle::State_HasFocus) {
2335 QStyleOptionFocusRect o;
2336 o.QStyleOption::operator=(*vopt);
2337 o.rect = proxy()->subElementRect(SE_ItemViewItemFocusRect, vopt, widget);
2338 o.state |= QStyle::State_KeyboardFocusChange;
2339 o.state |= QStyle::State_Item;
2340 QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled)
2341 ? QPalette::Normal : QPalette::Disabled;
2342 o.backgroundColor = vopt->palette.color(cg, (vopt->state & QStyle::State_Selected)
2343 ? QPalette::Highlight : QPalette::Window);
2344 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, p, widget);
2345 }
2346
2347 p->restore();
2348 }
2349 break;
2350
2351 #endif // QT_CONFIG(itemviews)
2352 #ifndef QT_NO_FRAME
2353 case CE_ShapedFrame:
2354 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2355 int frameShape = f->frameShape;
2356 int frameShadow = QFrame::Plain;
2357 if (f->state & QStyle::State_Sunken) {
2358 frameShadow = QFrame::Sunken;
2359 } else if (f->state & QStyle::State_Raised) {
2360 frameShadow = QFrame::Raised;
2361 }
2362
2363 int lw = f->lineWidth;
2364 int mlw = f->midLineWidth;
2365 QPalette::ColorRole foregroundRole = QPalette::WindowText;
2366 if (widget)
2367 foregroundRole = widget->foregroundRole();
2368
2369 switch (frameShape) {
2370 case QFrame::Box:
2371 if (frameShadow == QFrame::Plain) {
2372 qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2373 } else {
2374 qDrawShadeRect(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
2375 }
2376 break;
2377 case QFrame::StyledPanel:
2378 //keep the compatibility with Qt 4.4 if there is a proxy style.
2379 //be sure to call drawPrimitive(QStyle::PE_Frame) on the proxy style
2380 if (widget) {
2381 widget->style()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
2382 } else {
2383 proxy()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
2384 }
2385 break;
2386 case QFrame::Panel:
2387 if (frameShadow == QFrame::Plain) {
2388 qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2389 } else {
2390 qDrawShadePanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw);
2391 }
2392 break;
2393 case QFrame::WinPanel:
2394 if (frameShadow == QFrame::Plain) {
2395 qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2396 } else {
2397 qDrawWinPanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken);
2398 }
2399 break;
2400 case QFrame::HLine:
2401 case QFrame::VLine: {
2402 QPoint p1, p2;
2403 if (frameShape == QFrame::HLine) {
2404 p1 = QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height() / 2);
2405 p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y());
2406 } else {
2407 p1 = QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
2408 p2 = QPoint(p1.x(), p1.y() + opt->rect.height());
2409 }
2410 if (frameShadow == QFrame::Plain) {
2411 QPen oldPen = p->pen();
2412 p->setPen(QPen(opt->palette.brush(foregroundRole), lw));
2413 p->drawLine(p1, p2);
2414 p->setPen(oldPen);
2415 } else {
2416 qDrawShadeLine(p, p1, p2, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
2417 }
2418 break;
2419 }
2420 }
2421 }
2422 break;
2423 #endif
2424 default:
2425 break;
2426 }
2427 #if !QT_CONFIG(tabbar) && !QT_CONFIG(itemviews)
2428 Q_UNUSED(d);
2429 #endif
2430 }
2431
2432 /*!
2433 \reimp
2434 */
subElementRect(SubElement sr,const QStyleOption * opt,const QWidget * widget) const2435 QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
2436 const QWidget *widget) const
2437 {
2438 Q_D(const QCommonStyle);
2439 QRect r;
2440 switch (sr) {
2441 case SE_PushButtonContents:
2442 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2443 int dx1, dx2;
2444 dx1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
2445 if (btn->features & QStyleOptionButton::AutoDefaultButton)
2446 dx1 += proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2447 dx2 = dx1 * 2;
2448 r.setRect(opt->rect.x() + dx1, opt->rect.y() + dx1, opt->rect.width() - dx2,
2449 opt->rect.height() - dx2);
2450 r = visualRect(opt->direction, opt->rect, r);
2451 }
2452 break;
2453 case SE_PushButtonFocusRect:
2454 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2455 int dbw1 = 0, dbw2 = 0;
2456 if (btn->features & QStyleOptionButton::AutoDefaultButton){
2457 dbw1 = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2458 dbw2 = dbw1 * 2;
2459 }
2460
2461 int dfw1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget) + 1,
2462 dfw2 = dfw1 * 2;
2463
2464 r.setRect(btn->rect.x() + dfw1 + dbw1, btn->rect.y() + dfw1 + dbw1,
2465 btn->rect.width() - dfw2 - dbw2, btn->rect.height()- dfw2 - dbw2);
2466 r = visualRect(opt->direction, opt->rect, r);
2467 }
2468 break;
2469 case SE_PushButtonBevel:
2470 {
2471 r = opt->rect;
2472 r = visualRect(opt->direction, opt->rect, r);
2473 }
2474 break;
2475 case SE_CheckBoxIndicator:
2476 {
2477 int h = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
2478 r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
2479 proxy()->pixelMetric(PM_IndicatorWidth, opt, widget), h);
2480 r = visualRect(opt->direction, opt->rect, r);
2481 }
2482 break;
2483
2484 case SE_CheckBoxContents:
2485 {
2486 // Deal with the logical first, then convert it back to screen coords.
2487 QRect ir = visualRect(opt->direction, opt->rect,
2488 subElementRect(SE_CheckBoxIndicator, opt, widget));
2489 int spacing = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget);
2490 r.setRect(ir.right() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
2491 opt->rect.height());
2492 r = visualRect(opt->direction, opt->rect, r);
2493 }
2494 break;
2495
2496 case SE_CheckBoxFocusRect:
2497 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2498 if (btn->icon.isNull() && btn->text.isEmpty()) {
2499 r = subElementRect(SE_CheckBoxIndicator, opt, widget);
2500 r.adjust(1, 1, -1, -1);
2501 break;
2502 }
2503 // As above, deal with the logical first, then convert it back to screen coords.
2504 QRect cr = visualRect(btn->direction, btn->rect,
2505 subElementRect(SE_CheckBoxContents, btn, widget));
2506
2507 QRect iconRect, textRect;
2508 if (!btn->text.isEmpty()) {
2509 textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft
2510 | Qt::AlignVCenter | Qt::TextShowMnemonic,
2511 btn->state & State_Enabled, btn->text);
2512 }
2513 if (!btn->icon.isNull()) {
2514 iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2515 | Qt::TextShowMnemonic,
2516 btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, QIcon::Normal));
2517 if (!textRect.isEmpty())
2518 textRect.translate(iconRect.right() + 4, 0);
2519 }
2520 r = iconRect | textRect;
2521 r.adjust(-3, -2, 3, 2);
2522 r = r.intersected(btn->rect);
2523 r = visualRect(btn->direction, btn->rect, r);
2524 }
2525 break;
2526
2527 case SE_RadioButtonIndicator:
2528 {
2529 int h = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget);
2530 r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
2531 proxy()->pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), h);
2532 r = visualRect(opt->direction, opt->rect, r);
2533 }
2534 break;
2535
2536 case SE_RadioButtonContents:
2537 {
2538 QRect ir = visualRect(opt->direction, opt->rect,
2539 subElementRect(SE_RadioButtonIndicator, opt, widget));
2540 int spacing = proxy()->pixelMetric(PM_RadioButtonLabelSpacing, opt, widget);
2541 r.setRect(ir.left() + ir.width() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
2542 opt->rect.height());
2543 r = visualRect(opt->direction, opt->rect, r);
2544 break;
2545 }
2546
2547 case SE_RadioButtonFocusRect:
2548 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2549 if (btn->icon.isNull() && btn->text.isEmpty()) {
2550 r = subElementRect(SE_RadioButtonIndicator, opt, widget);
2551 r.adjust(1, 1, -1, -1);
2552 break;
2553 }
2554 QRect cr = visualRect(btn->direction, btn->rect,
2555 subElementRect(SE_RadioButtonContents, opt, widget));
2556
2557 QRect iconRect, textRect;
2558 if (!btn->text.isEmpty()){
2559 textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2560 | Qt::TextShowMnemonic, btn->state & State_Enabled, btn->text);
2561 }
2562 if (!btn->icon.isNull()) {
2563 iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic,
2564 btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, QIcon::Normal));
2565 if (!textRect.isEmpty())
2566 textRect.translate(iconRect.right() + 4, 0);
2567 }
2568 r = iconRect | textRect;
2569 r.adjust(-3, -2, 3, 2);
2570 r = r.intersected(btn->rect);
2571 r = visualRect(btn->direction, btn->rect, r);
2572 }
2573 break;
2574 #if QT_CONFIG(slider)
2575 case SE_SliderFocusRect:
2576 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2577 int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
2578 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
2579 if (slider->orientation == Qt::Horizontal)
2580 r.setRect(0, tickOffset - 1, slider->rect.width(), thickness + 2);
2581 else
2582 r.setRect(tickOffset - 1, 0, thickness + 2, slider->rect.height());
2583 r = r.intersected(slider->rect);
2584 r = visualRect(opt->direction, opt->rect, r);
2585 }
2586 break;
2587 #endif // QT_CONFIG(slider)
2588 #if QT_CONFIG(progressbar)
2589 case SE_ProgressBarGroove:
2590 case SE_ProgressBarContents:
2591 case SE_ProgressBarLabel:
2592 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
2593 int textw = 0;
2594 const bool vertical = pb->orientation == Qt::Vertical;
2595 if (!vertical) {
2596 if (pb->textVisible)
2597 textw = qMax(pb->fontMetrics.horizontalAdvance(pb->text), pb->fontMetrics.horizontalAdvance(QLatin1String("100%"))) + 6;
2598 }
2599
2600 if ((pb->textAlignment & Qt::AlignCenter) == 0) {
2601 if (sr != SE_ProgressBarLabel)
2602 r.setCoords(pb->rect.left(), pb->rect.top(),
2603 pb->rect.right() - textw, pb->rect.bottom());
2604 else
2605 r.setCoords(pb->rect.right() - textw, pb->rect.top(),
2606 pb->rect.right(), pb->rect.bottom());
2607 } else {
2608 r = pb->rect;
2609 }
2610 r = visualRect(pb->direction, pb->rect, r);
2611 }
2612 break;
2613 #endif // QT_CONFIG(progressbar)
2614 #if QT_CONFIG(combobox)
2615 case SE_ComboBoxFocusRect:
2616 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2617 int margin = cb->frame ? 3 : 0;
2618 r.setRect(opt->rect.left() + margin, opt->rect.top() + margin,
2619 opt->rect.width() - 2*margin - 16, opt->rect.height() - 2*margin);
2620 r = visualRect(opt->direction, opt->rect, r);
2621 }
2622 break;
2623 #endif // QT_CONFIG(combobox)
2624 #if QT_CONFIG(toolbox)
2625 case SE_ToolBoxTabContents:
2626 r = opt->rect;
2627 r.adjust(0, 0, -30, 0);
2628 break;
2629 #endif // QT_CONFIG(toolbox)
2630 case SE_HeaderLabel: {
2631 int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
2632 r.setRect(opt->rect.x() + margin, opt->rect.y() + margin,
2633 opt->rect.width() - margin * 2, opt->rect.height() - margin * 2);
2634
2635 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2636 // Subtract width needed for arrow, if there is one
2637 if (header->sortIndicator != QStyleOptionHeader::None) {
2638 if (opt->state & State_Horizontal)
2639 r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2));
2640 else
2641 r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2));
2642 }
2643 }
2644 r = visualRect(opt->direction, opt->rect, r);
2645 break; }
2646 case SE_HeaderArrow: {
2647 int h = opt->rect.height();
2648 int w = opt->rect.width();
2649 int x = opt->rect.x();
2650 int y = opt->rect.y();
2651 int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
2652
2653 if (opt->state & State_Horizontal) {
2654 int horiz_size = h / 2;
2655 r.setRect(x + w - margin * 2 - horiz_size, y + 5,
2656 horiz_size, h - margin * 2 - 5);
2657 } else {
2658 int vert_size = w / 2;
2659 r.setRect(x + 5, y + h - margin * 2 - vert_size,
2660 w - margin * 2 - 5, vert_size);
2661 }
2662 r = visualRect(opt->direction, opt->rect, r);
2663 break; }
2664
2665 case SE_RadioButtonClickRect:
2666 r = subElementRect(SE_RadioButtonFocusRect, opt, widget);
2667 r |= subElementRect(SE_RadioButtonIndicator, opt, widget);
2668 break;
2669 case SE_CheckBoxClickRect:
2670 r = subElementRect(SE_CheckBoxFocusRect, opt, widget);
2671 r |= subElementRect(SE_CheckBoxIndicator, opt, widget);
2672 break;
2673 #if QT_CONFIG(tabwidget)
2674 case SE_TabWidgetTabBar:
2675 if (const QStyleOptionTabWidgetFrame *twf
2676 = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2677 r.setSize(twf->tabBarSize);
2678 const uint alingMask = Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter;
2679 switch (twf->shape) {
2680 case QTabBar::RoundedNorth:
2681 case QTabBar::TriangularNorth:
2682 // Constrain the size now, otherwise, center could get off the page
2683 // This of course repeated for all the other directions
2684 r.setWidth(qMin(r.width(), twf->rect.width()
2685 - twf->leftCornerWidgetSize.width()
2686 - twf->rightCornerWidgetSize.width()));
2687 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2688 default:
2689 case Qt::AlignLeft:
2690 r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0));
2691 break;
2692 case Qt::AlignHCenter:
2693 r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
2694 + (twf->leftCornerWidgetSize.width() / 2)
2695 - (twf->rightCornerWidgetSize.width() / 2), 0));
2696 break;
2697 case Qt::AlignRight:
2698 r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
2699 - twf->rightCornerWidgetSize.width(), 0));
2700 break;
2701 }
2702 r = visualRect(twf->direction, twf->rect, r);
2703 break;
2704 case QTabBar::RoundedSouth:
2705 case QTabBar::TriangularSouth:
2706 r.setWidth(qMin(r.width(), twf->rect.width()
2707 - twf->leftCornerWidgetSize.width()
2708 - twf->rightCornerWidgetSize.width()));
2709 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2710 default:
2711 case Qt::AlignLeft:
2712 r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(),
2713 twf->rect.height() - twf->tabBarSize.height()));
2714 break;
2715 case Qt::AlignHCenter:
2716 r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
2717 + (twf->leftCornerWidgetSize.width() / 2)
2718 - (twf->rightCornerWidgetSize.width() / 2),
2719 twf->rect.height() - twf->tabBarSize.height()));
2720 break;
2721 case Qt::AlignRight:
2722 r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
2723 - twf->rightCornerWidgetSize.width(),
2724 twf->rect.height() - twf->tabBarSize.height()));
2725 break;
2726 }
2727 r = visualRect(twf->direction, twf->rect, r);
2728 break;
2729 case QTabBar::RoundedEast:
2730 case QTabBar::TriangularEast:
2731 r.setHeight(qMin(r.height(), twf->rect.height()
2732 - twf->leftCornerWidgetSize.height()
2733 - twf->rightCornerWidgetSize.height()));
2734 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2735 default:
2736 case Qt::AlignLeft:
2737 r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2738 twf->leftCornerWidgetSize.height()));
2739 break;
2740 case Qt::AlignHCenter:
2741 r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2742 twf->rect.center().y() - r.height() / 2));
2743 break;
2744 case Qt::AlignRight:
2745 r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2746 twf->rect.height() - twf->tabBarSize.height()
2747 - twf->rightCornerWidgetSize.height()));
2748 break;
2749 }
2750 break;
2751 case QTabBar::RoundedWest:
2752 case QTabBar::TriangularWest:
2753 r.setHeight(qMin(r.height(), twf->rect.height()
2754 - twf->leftCornerWidgetSize.height()
2755 - twf->rightCornerWidgetSize.height()));
2756 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2757 default:
2758 case Qt::AlignLeft:
2759 r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height()));
2760 break;
2761 case Qt::AlignHCenter:
2762 r.moveTopLeft(QPoint(0, twf->rect.center().y() - r.height() / 2));
2763 break;
2764 case Qt::AlignRight:
2765 r.moveTopLeft(QPoint(0, twf->rect.height() - twf->tabBarSize.height()
2766 - twf->rightCornerWidgetSize.height()));
2767 break;
2768 }
2769 break;
2770 }
2771 }
2772 break;
2773 case SE_TabWidgetTabPane:
2774 case SE_TabWidgetTabContents:
2775 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2776 QStyleOptionTab tabopt;
2777 tabopt.shape = twf->shape;
2778 int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &tabopt, widget);
2779 if (twf->lineWidth == 0)
2780 overlap = 0;
2781 switch (twf->shape) {
2782 case QTabBar::RoundedNorth:
2783 case QTabBar::TriangularNorth:
2784 r = QRect(QPoint(0,qMax(twf->tabBarSize.height() - overlap, 0)),
2785 QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
2786 break;
2787 case QTabBar::RoundedSouth:
2788 case QTabBar::TriangularSouth:
2789 r = QRect(QPoint(0,0), QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
2790 break;
2791 case QTabBar::RoundedEast:
2792 case QTabBar::TriangularEast:
2793 r = QRect(QPoint(0, 0), QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
2794 break;
2795 case QTabBar::RoundedWest:
2796 case QTabBar::TriangularWest:
2797 r = QRect(QPoint(qMax(twf->tabBarSize.width() - overlap, 0), 0),
2798 QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
2799 break;
2800 }
2801 if (sr == SE_TabWidgetTabContents && twf->lineWidth > 0)
2802 r.adjust(2, 2, -2, -2);
2803 }
2804 break;
2805 case SE_TabWidgetLeftCorner:
2806 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2807 QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2808 switch (twf->shape) {
2809 case QTabBar::RoundedNorth:
2810 case QTabBar::TriangularNorth:
2811 r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()),
2812 twf->leftCornerWidgetSize);
2813 break;
2814 case QTabBar::RoundedSouth:
2815 case QTabBar::TriangularSouth:
2816 r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
2817 break;
2818 default:
2819 break;
2820 }
2821 r = visualRect(twf->direction, twf->rect, r);
2822 }
2823 break;
2824 case SE_TabWidgetRightCorner:
2825 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2826 QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2827 switch (twf->shape) {
2828 case QTabBar::RoundedNorth:
2829 case QTabBar::TriangularNorth:
2830 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2831 paneRect.y() - twf->rightCornerWidgetSize.height()),
2832 twf->rightCornerWidgetSize);
2833 break;
2834 case QTabBar::RoundedSouth:
2835 case QTabBar::TriangularSouth:
2836 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2837 paneRect.height()), twf->rightCornerWidgetSize);
2838 break;
2839 default:
2840 break;
2841 }
2842 r = visualRect(twf->direction, twf->rect, r);
2843 }
2844 break;
2845 case SE_TabBarTabText:
2846 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2847 QRect dummyIconRect;
2848 d->tabLayout(tab, widget, &r, &dummyIconRect);
2849 }
2850 break;
2851 case SE_TabBarTabLeftButton:
2852 case SE_TabBarTabRightButton:
2853 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2854 bool selected = tab->state & State_Selected;
2855 int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
2856 int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
2857 int hpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
2858 hpadding = qMax(hpadding, 4); //workaround KStyle returning 0 because they workaround an old bug in Qt
2859
2860 bool verticalTabs = tab->shape == QTabBar::RoundedEast
2861 || tab->shape == QTabBar::RoundedWest
2862 || tab->shape == QTabBar::TriangularEast
2863 || tab->shape == QTabBar::TriangularWest;
2864
2865 QRect tr = tab->rect;
2866 if (tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::TriangularSouth)
2867 verticalShift = -verticalShift;
2868 if (verticalTabs) {
2869 qSwap(horizontalShift, verticalShift);
2870 horizontalShift *= -1;
2871 verticalShift *= -1;
2872 }
2873 if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest)
2874 horizontalShift = -horizontalShift;
2875
2876 tr.adjust(0, 0, horizontalShift, verticalShift);
2877 if (selected)
2878 {
2879 tr.setBottom(tr.bottom() - verticalShift);
2880 tr.setRight(tr.right() - horizontalShift);
2881 }
2882
2883 QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
2884 int w = size.width();
2885 int h = size.height();
2886 int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
2887 int midWidth = ((tr.width() - w) / 2);
2888
2889 bool atTheTop = true;
2890 switch (tab->shape) {
2891 case QTabBar::RoundedWest:
2892 case QTabBar::TriangularWest:
2893 atTheTop = (sr == SE_TabBarTabLeftButton);
2894 break;
2895 case QTabBar::RoundedEast:
2896 case QTabBar::TriangularEast:
2897 atTheTop = (sr == SE_TabBarTabRightButton);
2898 break;
2899 default:
2900 if (sr == SE_TabBarTabLeftButton)
2901 r = QRect(tab->rect.x() + hpadding, midHeight, w, h);
2902 else
2903 r = QRect(tab->rect.right() - w - hpadding, midHeight, w, h);
2904 r = visualRect(tab->direction, tab->rect, r);
2905 }
2906 if (verticalTabs) {
2907 if (atTheTop)
2908 r = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h);
2909 else
2910 r = QRect(midWidth, tr.y() + hpadding, w, h);
2911 }
2912 }
2913
2914 break;
2915 #endif // QT_CONFIG(tabwidget)
2916 #if QT_CONFIG(tabbar)
2917 case SE_TabBarTearIndicator:
2918 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2919 switch (tab->shape) {
2920 case QTabBar::RoundedNorth:
2921 case QTabBar::TriangularNorth:
2922 case QTabBar::RoundedSouth:
2923 case QTabBar::TriangularSouth:
2924 r.setRect(tab->rect.left(), tab->rect.top(), 8, opt->rect.height());
2925 break;
2926 case QTabBar::RoundedWest:
2927 case QTabBar::TriangularWest:
2928 case QTabBar::RoundedEast:
2929 case QTabBar::TriangularEast:
2930 r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), 8);
2931 break;
2932 default:
2933 break;
2934 }
2935 r = visualRect(opt->direction, opt->rect, r);
2936 }
2937 break;
2938 case SE_TabBarScrollLeftButton: {
2939 const bool vertical = opt->rect.width() < opt->rect.height();
2940 const Qt::LayoutDirection ld = widget->layoutDirection();
2941 const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, nullptr, widget), QApplication::globalStrut().width());
2942 const int buttonOverlap = proxy()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, nullptr, widget);
2943
2944 r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth)
2945 : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height()));
2946 break; }
2947 case SE_TabBarScrollRightButton: {
2948 const bool vertical = opt->rect.width() < opt->rect.height();
2949 const Qt::LayoutDirection ld = widget->layoutDirection();
2950 const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, nullptr, widget), QApplication::globalStrut().width());
2951
2952 r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth)
2953 : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height()));
2954 break; }
2955 #endif
2956 case SE_TreeViewDisclosureItem:
2957 r = opt->rect;
2958 break;
2959 case SE_LineEditContents:
2960 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2961 r = f->rect.adjusted(f->lineWidth, f->lineWidth, -f->lineWidth, -f->lineWidth);
2962 r = visualRect(opt->direction, opt->rect, r);
2963 }
2964 break;
2965 case SE_FrameContents:
2966 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2967 int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, f, widget);
2968 r = opt->rect.adjusted(fw, fw, -fw, -fw);
2969 r = visualRect(opt->direction, opt->rect, r);
2970 }
2971 break;
2972 case SE_ShapedFrameContents:
2973 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2974 int frameShape = f->frameShape;
2975 int frameShadow = QFrame::Plain;
2976 if (f->state & QStyle::State_Sunken) {
2977 frameShadow = QFrame::Sunken;
2978 } else if (f->state & QStyle::State_Raised) {
2979 frameShadow = QFrame::Raised;
2980 }
2981
2982 int frameWidth = 0;
2983
2984 switch (frameShape) {
2985 case QFrame::NoFrame:
2986 frameWidth = 0;
2987 break;
2988
2989 case QFrame::Box:
2990 case QFrame::HLine:
2991 case QFrame::VLine:
2992 switch (frameShadow) {
2993 case QFrame::Plain:
2994 frameWidth = f->lineWidth;
2995 break;
2996 case QFrame::Raised:
2997 case QFrame::Sunken:
2998 frameWidth = (short)(f->lineWidth*2 + f->midLineWidth);
2999 break;
3000 }
3001 break;
3002
3003 case QFrame::StyledPanel:
3004 //keep the compatibility with Qt 4.4 if there is a proxy style.
3005 //be sure to call drawPrimitive(QStyle::SE_FrameContents) on the proxy style
3006 if (widget)
3007 return widget->style()->subElementRect(QStyle::SE_FrameContents, opt, widget);
3008 else
3009 return subElementRect(QStyle::SE_FrameContents, opt, widget);
3010
3011 case QFrame::WinPanel:
3012 frameWidth = 2;
3013 break;
3014
3015 case QFrame::Panel:
3016 switch (frameShadow) {
3017 case QFrame::Plain:
3018 case QFrame::Raised:
3019 case QFrame::Sunken:
3020 frameWidth = f->lineWidth;
3021 break;
3022 }
3023 break;
3024 }
3025 r = f->rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth);
3026 }
3027 break;
3028 #if QT_CONFIG(dockwidget)
3029 case SE_DockWidgetCloseButton:
3030 case SE_DockWidgetFloatButton:
3031 case SE_DockWidgetTitleBarText:
3032 case SE_DockWidgetIcon: {
3033 int iconSize = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
3034 int buttonMargin = proxy()->pixelMetric(PM_DockWidgetTitleBarButtonMargin, opt, widget);
3035 int margin = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, opt, widget);
3036 QRect rect = opt->rect;
3037
3038 const QStyleOptionDockWidget *dwOpt
3039 = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
3040 bool canClose = dwOpt == nullptr ? true : dwOpt->closable;
3041 bool canFloat = dwOpt == nullptr ? false : dwOpt->floatable;
3042
3043 const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
3044
3045 // If this is a vertical titlebar, we transpose and work as if it was
3046 // horizontal, then transpose again.
3047
3048 if (verticalTitleBar)
3049 rect = rect.transposed();
3050
3051 do {
3052
3053 int right = rect.right();
3054 int left = rect.left();
3055
3056 QRect closeRect;
3057 if (canClose) {
3058 QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton,
3059 opt, widget).actualSize(QSize(iconSize, iconSize));
3060 sz += QSize(buttonMargin, buttonMargin);
3061 if (verticalTitleBar)
3062 sz = sz.transposed();
3063 closeRect = QRect(right - sz.width(),
3064 rect.center().y() - sz.height()/2,
3065 sz.width(), sz.height());
3066 right = closeRect.left() - 1;
3067 }
3068 if (sr == SE_DockWidgetCloseButton) {
3069 r = closeRect;
3070 break;
3071 }
3072
3073 QRect floatRect;
3074 if (canFloat) {
3075 QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarNormalButton,
3076 opt, widget).actualSize(QSize(iconSize, iconSize));
3077 sz += QSize(buttonMargin, buttonMargin);
3078 if (verticalTitleBar)
3079 sz = sz.transposed();
3080 floatRect = QRect(right - sz.width(),
3081 rect.center().y() - sz.height()/2,
3082 sz.width(), sz.height());
3083 right = floatRect.left() - 1;
3084 }
3085 if (sr == SE_DockWidgetFloatButton) {
3086 r = floatRect;
3087 break;
3088 }
3089
3090 QRect iconRect;
3091 if (const QDockWidget *dw = qobject_cast<const QDockWidget*>(widget)) {
3092 QIcon icon;
3093 if (dw->isFloating())
3094 icon = dw->windowIcon();
3095 if (!icon.isNull()
3096 && icon.cacheKey() != QApplication::windowIcon().cacheKey()) {
3097 QSize sz = icon.actualSize(QSize(r.height(), r.height()));
3098 if (verticalTitleBar)
3099 sz = sz.transposed();
3100 iconRect = QRect(left, rect.center().y() - sz.height()/2,
3101 sz.width(), sz.height());
3102 left = iconRect.right() + margin;
3103 }
3104 }
3105 if (sr == SE_DockWidgetIcon) {
3106 r = iconRect;
3107 break;
3108 }
3109
3110 QRect textRect = QRect(left, rect.top(),
3111 right - left, rect.height());
3112 if (sr == SE_DockWidgetTitleBarText) {
3113 r = textRect;
3114 break;
3115 }
3116
3117 } while (false);
3118
3119 if (verticalTitleBar) {
3120 r = QRect(rect.left() + r.top() - rect.top(),
3121 rect.top() + rect.right() - r.right(),
3122 r.height(), r.width());
3123 } else {
3124 r = visualRect(opt->direction, rect, r);
3125 }
3126 break;
3127 }
3128 #endif
3129 #if QT_CONFIG(itemviews)
3130 case SE_ItemViewItemCheckIndicator:
3131 if (!qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
3132 r = subElementRect(SE_CheckBoxIndicator, opt, widget);
3133 break;
3134 }
3135 Q_FALLTHROUGH();
3136 case SE_ItemViewItemDecoration:
3137 case SE_ItemViewItemText:
3138 case SE_ItemViewItemFocusRect:
3139 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
3140 if (!d->isViewItemCached(*vopt)) {
3141 d->viewItemLayout(vopt, &d->checkRect, &d->decorationRect, &d->displayRect, false);
3142 if (d->cachedOption) {
3143 delete d->cachedOption;
3144 d->cachedOption = nullptr;
3145 }
3146 d->cachedOption = new QStyleOptionViewItem(*vopt);
3147 }
3148 if (sr == SE_ItemViewItemCheckIndicator)
3149 r = d->checkRect;
3150 else if (sr == SE_ItemViewItemDecoration)
3151 r = d->decorationRect;
3152 else if (sr == SE_ItemViewItemText || sr == SE_ItemViewItemFocusRect)
3153 r = d->displayRect;
3154 }
3155 break;
3156 #endif // QT_CONFIG(itemviews)
3157 #if QT_CONFIG(toolbar)
3158 case SE_ToolBarHandle:
3159 if (const QStyleOptionToolBar *tbopt = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
3160 if (tbopt->features & QStyleOptionToolBar::Movable) {
3161 ///we need to access the widget here because the style option doesn't
3162 //have all the information we need (ie. the layout's margin)
3163 const QToolBar *tb = qobject_cast<const QToolBar*>(widget);
3164 const QMargins margins = tb && tb->layout() ? tb->layout()->contentsMargins() : QMargins(2, 2, 2, 2);
3165 const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
3166 if (tbopt->state & QStyle::State_Horizontal) {
3167 r = QRect(margins.left(), margins.top(),
3168 handleExtent,
3169 tbopt->rect.height() - (margins.top() + margins.bottom()));
3170 r = QStyle::visualRect(tbopt->direction, tbopt->rect, r);
3171 } else {
3172 r = QRect(margins.left(), margins.top(),
3173 tbopt->rect.width() - (margins.left() + margins.right()),
3174 handleExtent);
3175 }
3176 }
3177 }
3178 break;
3179 #endif // QT_CONFIG(toolbar)
3180 default:
3181 break;
3182 }
3183 return r;
3184 #if !QT_CONFIG(tabwidget) && !QT_CONFIG(itemviews)
3185 Q_UNUSED(d);
3186 #endif
3187 }
3188
3189 #if QT_CONFIG(dial)
3190
3191 // in lieu of std::array, minimal API
3192 template <int N>
3193 struct StaticPolygonF
3194 {
3195 QPointF data[N];
3196
sizeStaticPolygonF3197 Q_DECL_CONSTEXPR int size() const { return N; }
cbeginStaticPolygonF3198 Q_DECL_CONSTEXPR const QPointF *cbegin() const { return data; }
operator []StaticPolygonF3199 Q_DECL_CONSTEXPR const QPointF &operator[](int idx) const { return data[idx]; }
3200 };
3201
calcArrow(const QStyleOptionSlider * dial,qreal & a)3202 static StaticPolygonF<3> calcArrow(const QStyleOptionSlider *dial, qreal &a)
3203 {
3204 int width = dial->rect.width();
3205 int height = dial->rect.height();
3206 int r = qMin(width, height) / 2;
3207 int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
3208
3209 if (dial->maximum == dial->minimum)
3210 a = Q_PI / 2;
3211 else if (dial->dialWrapping)
3212 a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI
3213 / (dial->maximum - dial->minimum);
3214 else
3215 a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI
3216 / (dial->maximum - dial->minimum)) / 6;
3217
3218 int xc = width / 2;
3219 int yc = height / 2;
3220
3221 int len = r - QStyleHelper::calcBigLineSize(r) - 5;
3222 if (len < 5)
3223 len = 5;
3224 int back = len / 2;
3225
3226 StaticPolygonF<3> arrow = {{
3227 QPointF(0.5 + xc + len * qCos(a),
3228 0.5 + yc - len * qSin(a)),
3229 QPointF(0.5 + xc + back * qCos(a + Q_PI * 5 / 6),
3230 0.5 + yc - back * qSin(a + Q_PI * 5 / 6)),
3231 QPointF(0.5 + xc + back * qCos(a - Q_PI * 5 / 6),
3232 0.5 + yc - back * qSin(a - Q_PI * 5 / 6)),
3233 }};
3234 return arrow;
3235 }
3236
3237 #endif // QT_CONFIG(dial)
3238
3239 /*!
3240 \reimp
3241 */
drawComplexControl(ComplexControl cc,const QStyleOptionComplex * opt,QPainter * p,const QWidget * widget) const3242 void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
3243 QPainter *p, const QWidget *widget) const
3244 {
3245 switch (cc) {
3246 #if QT_CONFIG(slider)
3247 case CC_Slider:
3248 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3249 if (slider->subControls == SC_SliderTickmarks) {
3250 int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
3251 int ticks = slider->tickPosition;
3252 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
3253 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
3254 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
3255 int interval = slider->tickInterval;
3256 if (interval <= 0) {
3257 interval = slider->singleStep;
3258 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
3259 available)
3260 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
3261 0, available) < 3)
3262 interval = slider->pageStep;
3263 }
3264 if (!interval)
3265 interval = 1;
3266 int fudge = len / 2;
3267 int pos;
3268 // Since there is no subrect for tickmarks do a translation here.
3269 p->save();
3270 p->translate(slider->rect.x(), slider->rect.y());
3271 p->setPen(slider->palette.windowText().color());
3272 int v = slider->minimum;
3273 while (v <= slider->maximum + 1) {
3274 if (v == slider->maximum + 1 && interval == 1)
3275 break;
3276 const int v_ = qMin(v, slider->maximum);
3277 pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
3278 v_, available) + fudge;
3279 if (slider->orientation == Qt::Horizontal) {
3280 if (ticks & QSlider::TicksAbove)
3281 p->drawLine(pos, 0, pos, tickOffset - 2);
3282 if (ticks & QSlider::TicksBelow)
3283 p->drawLine(pos, tickOffset + thickness + 1, pos,
3284 slider->rect.height()-1);
3285 } else {
3286 if (ticks & QSlider::TicksAbove)
3287 p->drawLine(0, pos, tickOffset - 2, pos);
3288 if (ticks & QSlider::TicksBelow)
3289 p->drawLine(tickOffset + thickness + 1, pos,
3290 slider->rect.width()-1, pos);
3291 }
3292 // in the case where maximum is max int
3293 int nextInterval = v + interval;
3294 if (nextInterval < v)
3295 break;
3296 v = nextInterval;
3297 }
3298 p->restore();
3299 }
3300 }
3301 break;
3302 #endif // QT_CONFIG(slider)
3303 #if QT_CONFIG(scrollbar)
3304 case CC_ScrollBar:
3305 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3306 // Make a copy here and reset it for each primitive.
3307 QStyleOptionSlider newScrollbar = *scrollbar;
3308 State saveFlags = scrollbar->state;
3309
3310 if (scrollbar->subControls & SC_ScrollBarSubLine) {
3311 newScrollbar.state = saveFlags;
3312 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubLine, widget);
3313 if (newScrollbar.rect.isValid()) {
3314 if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine))
3315 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3316 proxy()->drawControl(CE_ScrollBarSubLine, &newScrollbar, p, widget);
3317 }
3318 }
3319 if (scrollbar->subControls & SC_ScrollBarAddLine) {
3320 newScrollbar.rect = scrollbar->rect;
3321 newScrollbar.state = saveFlags;
3322 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddLine, widget);
3323 if (newScrollbar.rect.isValid()) {
3324 if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine))
3325 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3326 proxy()->drawControl(CE_ScrollBarAddLine, &newScrollbar, p, widget);
3327 }
3328 }
3329 if (scrollbar->subControls & SC_ScrollBarSubPage) {
3330 newScrollbar.rect = scrollbar->rect;
3331 newScrollbar.state = saveFlags;
3332 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubPage, widget);
3333 if (newScrollbar.rect.isValid()) {
3334 if (!(scrollbar->activeSubControls & SC_ScrollBarSubPage))
3335 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3336 proxy()->drawControl(CE_ScrollBarSubPage, &newScrollbar, p, widget);
3337 }
3338 }
3339 if (scrollbar->subControls & SC_ScrollBarAddPage) {
3340 newScrollbar.rect = scrollbar->rect;
3341 newScrollbar.state = saveFlags;
3342 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddPage, widget);
3343 if (newScrollbar.rect.isValid()) {
3344 if (!(scrollbar->activeSubControls & SC_ScrollBarAddPage))
3345 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3346 proxy()->drawControl(CE_ScrollBarAddPage, &newScrollbar, p, widget);
3347 }
3348 }
3349 if (scrollbar->subControls & SC_ScrollBarFirst) {
3350 newScrollbar.rect = scrollbar->rect;
3351 newScrollbar.state = saveFlags;
3352 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarFirst, widget);
3353 if (newScrollbar.rect.isValid()) {
3354 if (!(scrollbar->activeSubControls & SC_ScrollBarFirst))
3355 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3356 proxy()->drawControl(CE_ScrollBarFirst, &newScrollbar, p, widget);
3357 }
3358 }
3359 if (scrollbar->subControls & SC_ScrollBarLast) {
3360 newScrollbar.rect = scrollbar->rect;
3361 newScrollbar.state = saveFlags;
3362 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarLast, widget);
3363 if (newScrollbar.rect.isValid()) {
3364 if (!(scrollbar->activeSubControls & SC_ScrollBarLast))
3365 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3366 proxy()->drawControl(CE_ScrollBarLast, &newScrollbar, p, widget);
3367 }
3368 }
3369 if (scrollbar->subControls & SC_ScrollBarSlider) {
3370 newScrollbar.rect = scrollbar->rect;
3371 newScrollbar.state = saveFlags;
3372 newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSlider, widget);
3373 if (newScrollbar.rect.isValid()) {
3374 if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
3375 newScrollbar.state &= ~(State_Sunken | State_MouseOver);
3376 proxy()->drawControl(CE_ScrollBarSlider, &newScrollbar, p, widget);
3377
3378 if (scrollbar->state & State_HasFocus) {
3379 QStyleOptionFocusRect fropt;
3380 fropt.QStyleOption::operator=(newScrollbar);
3381 fropt.rect.setRect(newScrollbar.rect.x() + 2, newScrollbar.rect.y() + 2,
3382 newScrollbar.rect.width() - 5,
3383 newScrollbar.rect.height() - 5);
3384 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
3385 }
3386 }
3387 }
3388 }
3389 break;
3390 #endif // QT_CONFIG(scrollbar)
3391 #if QT_CONFIG(spinbox)
3392 case CC_SpinBox:
3393 if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
3394 QStyleOptionSpinBox copy = *sb;
3395 PrimitiveElement pe;
3396
3397 if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
3398 QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
3399 qDrawWinPanel(p, r, sb->palette, true);
3400 }
3401
3402 if (sb->subControls & SC_SpinBoxUp) {
3403 copy.subControls = SC_SpinBoxUp;
3404 QPalette pal2 = sb->palette;
3405 if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
3406 pal2.setCurrentColorGroup(QPalette::Disabled);
3407 copy.state &= ~State_Enabled;
3408 }
3409
3410 copy.palette = pal2;
3411
3412 if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
3413 copy.state |= State_On;
3414 copy.state |= State_Sunken;
3415 } else {
3416 copy.state |= State_Raised;
3417 copy.state &= ~State_Sunken;
3418 }
3419 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
3420 : PE_IndicatorSpinUp);
3421
3422 copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
3423 proxy()->drawPrimitive(PE_PanelButtonBevel, ©, p, widget);
3424 copy.rect.adjust(3, 0, -4, 0);
3425 proxy()->drawPrimitive(pe, ©, p, widget);
3426 }
3427
3428 if (sb->subControls & SC_SpinBoxDown) {
3429 copy.subControls = SC_SpinBoxDown;
3430 copy.state = sb->state;
3431 QPalette pal2 = sb->palette;
3432 if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
3433 pal2.setCurrentColorGroup(QPalette::Disabled);
3434 copy.state &= ~State_Enabled;
3435 }
3436 copy.palette = pal2;
3437
3438 if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
3439 copy.state |= State_On;
3440 copy.state |= State_Sunken;
3441 } else {
3442 copy.state |= State_Raised;
3443 copy.state &= ~State_Sunken;
3444 }
3445 pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
3446 : PE_IndicatorSpinDown);
3447
3448 copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
3449 proxy()->drawPrimitive(PE_PanelButtonBevel, ©, p, widget);
3450 copy.rect.adjust(3, 0, -4, 0);
3451 proxy()->drawPrimitive(pe, ©, p, widget);
3452 }
3453 }
3454 break;
3455 #endif // QT_CONFIG(spinbox)
3456 #if QT_CONFIG(toolbutton)
3457 case CC_ToolButton:
3458 if (const QStyleOptionToolButton *toolbutton
3459 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
3460 QRect button, menuarea;
3461 button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
3462 menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
3463
3464 State bflags = toolbutton->state & ~State_Sunken;
3465
3466 if (bflags & State_AutoRaise) {
3467 if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
3468 bflags &= ~State_Raised;
3469 }
3470 }
3471 State mflags = bflags;
3472 if (toolbutton->state & State_Sunken) {
3473 if (toolbutton->activeSubControls & SC_ToolButton)
3474 bflags |= State_Sunken;
3475 mflags |= State_Sunken;
3476 }
3477
3478 QStyleOption tool = *toolbutton;
3479 if (toolbutton->subControls & SC_ToolButton) {
3480 if (bflags & (State_Sunken | State_On | State_Raised)) {
3481 tool.rect = button;
3482 tool.state = bflags;
3483 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3484 }
3485 }
3486
3487 if (toolbutton->state & State_HasFocus) {
3488 QStyleOptionFocusRect fr;
3489 fr.QStyleOption::operator=(*toolbutton);
3490 fr.rect.adjust(3, 3, -3, -3);
3491 if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
3492 fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
3493 toolbutton, widget), 0);
3494 proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
3495 }
3496 QStyleOptionToolButton label = *toolbutton;
3497 label.state = bflags;
3498 int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
3499 label.rect = button.adjusted(fw, fw, -fw, -fw);
3500 proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
3501
3502 if (toolbutton->subControls & SC_ToolButtonMenu) {
3503 tool.rect = menuarea;
3504 tool.state = mflags;
3505 if (mflags & (State_Sunken | State_On | State_Raised))
3506 proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
3507 proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
3508 } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
3509 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
3510 QRect ir = toolbutton->rect;
3511 QStyleOptionToolButton newBtn = *toolbutton;
3512 newBtn.rect = QRect(ir.right() + 5 - mbi, ir.y() + ir.height() - mbi + 4, mbi - 6, mbi - 6);
3513 newBtn.rect = visualRect(toolbutton->direction, button, newBtn.rect);
3514 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
3515 }
3516 }
3517 break;
3518 #endif // QT_CONFIG(toolbutton)
3519 case CC_TitleBar:
3520 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
3521 QRect ir;
3522 if (opt->subControls & SC_TitleBarLabel) {
3523 QColor left = tb->palette.highlight().color();
3524 QColor right = tb->palette.base().color();
3525
3526 QBrush fillBrush(left);
3527 if (left != right) {
3528 QPoint p1(tb->rect.x(), tb->rect.top() + tb->rect.height()/2);
3529 QPoint p2(tb->rect.right(), tb->rect.top() + tb->rect.height()/2);
3530 QLinearGradient lg(p1, p2);
3531 lg.setColorAt(0, left);
3532 lg.setColorAt(1, right);
3533 fillBrush = lg;
3534 }
3535
3536 p->fillRect(opt->rect, fillBrush);
3537
3538 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
3539
3540 p->setPen(tb->palette.highlightedText().color());
3541 p->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(),
3542 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
3543 }
3544
3545 bool down = false;
3546 QPixmap pm;
3547
3548 QStyleOption tool = *tb;
3549 if (tb->subControls & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3550 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarCloseButton, widget);
3551 down = tb->activeSubControls & SC_TitleBarCloseButton && (opt->state & State_Sunken);
3552 if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool
3553 #if QT_CONFIG(dockwidget)
3554 || qobject_cast<const QDockWidget *>(widget)
3555 #endif
3556 )
3557 pm = proxy()->standardIcon(SP_DockWidgetCloseButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3558 else
3559 pm = proxy()->standardIcon(SP_TitleBarCloseButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3560 tool.rect = ir;
3561 tool.state = down ? State_Sunken : State_Raised;
3562 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3563
3564 p->save();
3565 if (down)
3566 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3567 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3568 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3569 p->restore();
3570 }
3571
3572 if (tb->subControls & SC_TitleBarMaxButton
3573 && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
3574 && !(tb->titleBarState & Qt::WindowMaximized)) {
3575 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMaxButton, widget);
3576
3577 down = tb->activeSubControls & SC_TitleBarMaxButton && (opt->state & State_Sunken);
3578 pm = proxy()->standardIcon(SP_TitleBarMaxButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3579 tool.rect = ir;
3580 tool.state = down ? State_Sunken : State_Raised;
3581 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3582
3583 p->save();
3584 if (down)
3585 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3586 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3587 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3588 p->restore();
3589 }
3590
3591 if (tb->subControls & SC_TitleBarMinButton
3592 && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
3593 && !(tb->titleBarState & Qt::WindowMinimized)) {
3594 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMinButton, widget);
3595 down = tb->activeSubControls & SC_TitleBarMinButton && (opt->state & State_Sunken);
3596 pm = proxy()->standardIcon(SP_TitleBarMinButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3597 tool.rect = ir;
3598 tool.state = down ? State_Sunken : State_Raised;
3599 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3600
3601 p->save();
3602 if (down)
3603 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3604 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3605 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3606 p->restore();
3607 }
3608
3609 bool drawNormalButton = (tb->subControls & SC_TitleBarNormalButton)
3610 && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3611 && (tb->titleBarState & Qt::WindowMinimized))
3612 || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3613 && (tb->titleBarState & Qt::WindowMaximized)));
3614
3615 if (drawNormalButton) {
3616 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarNormalButton, widget);
3617 down = tb->activeSubControls & SC_TitleBarNormalButton && (opt->state & State_Sunken);
3618 pm = proxy()->standardIcon(SP_TitleBarNormalButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3619 tool.rect = ir;
3620 tool.state = down ? State_Sunken : State_Raised;
3621 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3622
3623 p->save();
3624 if (down)
3625 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3626 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3627 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3628 p->restore();
3629 }
3630
3631 if (tb->subControls & SC_TitleBarShadeButton
3632 && tb->titleBarFlags & Qt::WindowShadeButtonHint
3633 && !(tb->titleBarState & Qt::WindowMinimized)) {
3634 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarShadeButton, widget);
3635 down = (tb->activeSubControls & SC_TitleBarShadeButton && (opt->state & State_Sunken));
3636 pm = proxy()->standardIcon(SP_TitleBarShadeButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3637 tool.rect = ir;
3638 tool.state = down ? State_Sunken : State_Raised;
3639 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3640 p->save();
3641 if (down)
3642 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3643 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3644 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3645 p->restore();
3646 }
3647
3648 if (tb->subControls & SC_TitleBarUnshadeButton
3649 && tb->titleBarFlags & Qt::WindowShadeButtonHint
3650 && tb->titleBarState & Qt::WindowMinimized) {
3651 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarUnshadeButton, widget);
3652
3653 down = tb->activeSubControls & SC_TitleBarUnshadeButton && (opt->state & State_Sunken);
3654 pm = proxy()->standardIcon(SP_TitleBarUnshadeButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3655 tool.rect = ir;
3656 tool.state = down ? State_Sunken : State_Raised;
3657 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3658 p->save();
3659 if (down)
3660 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3661 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3662 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3663 p->restore();
3664 }
3665 if (tb->subControls & SC_TitleBarContextHelpButton
3666 && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
3667 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarContextHelpButton, widget);
3668
3669 down = tb->activeSubControls & SC_TitleBarContextHelpButton && (opt->state & State_Sunken);
3670 pm = proxy()->standardIcon(SP_TitleBarContextHelpButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10));
3671 tool.rect = ir;
3672 tool.state = down ? State_Sunken : State_Raised;
3673 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
3674 p->save();
3675 if (down)
3676 p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
3677 proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
3678 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3679 p->restore();
3680 }
3681 if (tb->subControls & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3682 ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarSysMenu, widget);
3683 if (!tb->icon.isNull()) {
3684 tb->icon.paint(p, ir);
3685 } else {
3686 int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
3687 pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(iconSize, iconSize));
3688 tool.rect = ir;
3689 p->save();
3690 proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
3691 p->restore();
3692 }
3693 }
3694 }
3695 break;
3696 #if QT_CONFIG(dial)
3697 case CC_Dial:
3698 if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3699 // OK, this is more a port of things over
3700 p->save();
3701
3702 // avoid dithering
3703 if (p->paintEngine()->hasFeature(QPaintEngine::Antialiasing))
3704 p->setRenderHint(QPainter::Antialiasing);
3705
3706 int width = dial->rect.width();
3707 int height = dial->rect.height();
3708 qreal r = qMin(width, height) / 2;
3709 qreal d_ = r / 6;
3710 qreal dx = dial->rect.x() + d_ + (width - 2 * r) / 2 + 1;
3711 qreal dy = dial->rect.y() + d_ + (height - 2 * r) / 2 + 1;
3712 QRect br = QRect(int(dx), int(dy), int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2));
3713
3714 QPalette pal = opt->palette;
3715 // draw notches
3716 if (dial->subControls & QStyle::SC_DialTickmarks) {
3717 p->setPen(pal.windowText().color());
3718 p->drawLines(QStyleHelper::calcLines(dial));
3719 }
3720
3721 if (dial->state & State_Enabled) {
3722 p->setBrush(pal.brush(QPalette::ColorRole(proxy()->styleHint(SH_Dial_BackgroundRole,
3723 dial, widget))));
3724 p->setPen(Qt::NoPen);
3725 p->drawEllipse(br);
3726 p->setBrush(Qt::NoBrush);
3727 }
3728 p->setPen(QPen(pal.dark().color()));
3729 p->drawArc(br, 60 * 16, 180 * 16);
3730 p->setPen(QPen(pal.light().color()));
3731 p->drawArc(br, 240 * 16, 180 * 16);
3732
3733 qreal a;
3734 const StaticPolygonF<3> arrow = calcArrow(dial, a);
3735
3736 p->setPen(Qt::NoPen);
3737 p->setBrush(pal.button());
3738 p->setRenderHint(QPainter::Qt4CompatiblePainting);
3739 p->drawPolygon(arrow.cbegin(), arrow.size());
3740
3741 a = QStyleHelper::angle(QPointF(width / 2, height / 2), arrow[0]);
3742 p->setBrush(Qt::NoBrush);
3743
3744 if (a <= 0 || a > 200) {
3745 p->setPen(pal.light().color());
3746 p->drawLine(arrow[2], arrow[0]);
3747 p->drawLine(arrow[1], arrow[2]);
3748 p->setPen(pal.dark().color());
3749 p->drawLine(arrow[0], arrow[1]);
3750 } else if (a > 0 && a < 45) {
3751 p->setPen(pal.light().color());
3752 p->drawLine(arrow[2], arrow[0]);
3753 p->setPen(pal.dark().color());
3754 p->drawLine(arrow[1], arrow[2]);
3755 p->drawLine(arrow[0], arrow[1]);
3756 } else if (a >= 45 && a < 135) {
3757 p->setPen(pal.dark().color());
3758 p->drawLine(arrow[2], arrow[0]);
3759 p->drawLine(arrow[1], arrow[2]);
3760 p->setPen(pal.light().color());
3761 p->drawLine(arrow[0], arrow[1]);
3762 } else if (a >= 135 && a < 200) {
3763 p->setPen(pal.dark().color());
3764 p->drawLine(arrow[2], arrow[0]);
3765 p->setPen(pal.light().color());
3766 p->drawLine(arrow[0], arrow[1]);
3767 p->drawLine(arrow[1], arrow[2]);
3768 }
3769
3770 // draw focus rect around the dial
3771 QStyleOptionFocusRect fropt;
3772 fropt.rect = dial->rect;
3773 fropt.state = dial->state;
3774 fropt.palette = dial->palette;
3775 if (fropt.state & QStyle::State_HasFocus) {
3776 br.adjust(0, 0, 2, 2);
3777 if (dial->subControls & SC_DialTickmarks) {
3778 int r = qMin(width, height) / 2;
3779 br.translate(-r / 6, - r / 6);
3780 br.setWidth(br.width() + r / 3);
3781 br.setHeight(br.height() + r / 3);
3782 }
3783 fropt.rect = br.adjusted(-2, -2, 2, 2);
3784 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, p, widget);
3785 }
3786 p->restore();
3787 }
3788 break;
3789 #endif // QT_CONFIG(dial)
3790 #if QT_CONFIG(groupbox)
3791 case CC_GroupBox:
3792 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
3793 // Draw frame
3794 QRect textRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
3795 QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
3796 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
3797 QStyleOptionFrame frame;
3798 frame.QStyleOption::operator=(*groupBox);
3799 frame.features = groupBox->features;
3800 frame.lineWidth = groupBox->lineWidth;
3801 frame.midLineWidth = groupBox->midLineWidth;
3802 frame.rect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
3803 p->save();
3804 QRegion region(groupBox->rect);
3805 if (!groupBox->text.isEmpty()) {
3806 bool ltr = groupBox->direction == Qt::LeftToRight;
3807 QRect finalRect;
3808 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
3809 finalRect = checkBoxRect.united(textRect);
3810 finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
3811 } else {
3812 finalRect = textRect;
3813 }
3814 region -= finalRect;
3815 }
3816 p->setClipRegion(region);
3817 proxy()->drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
3818 p->restore();
3819 }
3820
3821 // Draw title
3822 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
3823 QColor textColor = groupBox->textColor;
3824 if (textColor.isValid())
3825 p->setPen(textColor);
3826 int alignment = int(groupBox->textAlignment);
3827 if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, opt, widget))
3828 alignment |= Qt::TextHideMnemonic;
3829
3830 proxy()->drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
3831 groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
3832 textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
3833
3834 if (groupBox->state & State_HasFocus) {
3835 QStyleOptionFocusRect fropt;
3836 fropt.QStyleOption::operator=(*groupBox);
3837 fropt.rect = textRect;
3838 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
3839 }
3840 }
3841
3842 // Draw checkbox
3843 if (groupBox->subControls & SC_GroupBoxCheckBox) {
3844 QStyleOptionButton box;
3845 box.QStyleOption::operator=(*groupBox);
3846 box.rect = checkBoxRect;
3847 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, p, widget);
3848 }
3849 }
3850 break;
3851 #endif // QT_CONFIG(groupbox)
3852 #if QT_CONFIG(mdiarea)
3853 case CC_MdiControls:
3854 {
3855 QStyleOptionButton btnOpt;
3856 btnOpt.QStyleOption::operator=(*opt);
3857 btnOpt.state &= ~State_MouseOver;
3858 int bsx = 0;
3859 int bsy = 0;
3860 const int buttonIconMetric = proxy()->pixelMetric(PM_TitleBarButtonIconSize, &btnOpt, widget);
3861 const QSize buttonIconSize(buttonIconMetric, buttonIconMetric);
3862 if (opt->subControls & QStyle::SC_MdiCloseButton) {
3863 if (opt->activeSubControls & QStyle::SC_MdiCloseButton && (opt->state & State_Sunken)) {
3864 btnOpt.state |= State_Sunken;
3865 btnOpt.state &= ~State_Raised;
3866 bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
3867 bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
3868 } else {
3869 btnOpt.state |= State_Raised;
3870 btnOpt.state &= ~State_Sunken;
3871 bsx = 0;
3872 bsy = 0;
3873 }
3874 btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiCloseButton, widget);
3875 proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget);
3876 QPixmap pm = proxy()->standardIcon(SP_TitleBarCloseButton).pixmap(qt_getWindow(widget), buttonIconSize);
3877 proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm);
3878 }
3879 if (opt->subControls & QStyle::SC_MdiNormalButton) {
3880 if (opt->activeSubControls & QStyle::SC_MdiNormalButton && (opt->state & State_Sunken)) {
3881 btnOpt.state |= State_Sunken;
3882 btnOpt.state &= ~State_Raised;
3883 bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
3884 bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
3885 } else {
3886 btnOpt.state |= State_Raised;
3887 btnOpt.state &= ~State_Sunken;
3888 bsx = 0;
3889 bsy = 0;
3890 }
3891 btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiNormalButton, widget);
3892 proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget);
3893 QPixmap pm = proxy()->standardIcon(SP_TitleBarNormalButton).pixmap(qt_getWindow(widget), buttonIconSize);
3894 proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm);
3895 }
3896 if (opt->subControls & QStyle::SC_MdiMinButton) {
3897 if (opt->activeSubControls & QStyle::SC_MdiMinButton && (opt->state & State_Sunken)) {
3898 btnOpt.state |= State_Sunken;
3899 btnOpt.state &= ~State_Raised;
3900 bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
3901 bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
3902 } else {
3903 btnOpt.state |= State_Raised;
3904 btnOpt.state &= ~State_Sunken;
3905 bsx = 0;
3906 bsy = 0;
3907 }
3908 btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiMinButton, widget);
3909 proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget);
3910 QPixmap pm = proxy()->standardIcon(SP_TitleBarMinButton).pixmap(qt_getWindow(widget), buttonIconSize);
3911 proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm);
3912 }
3913 }
3914 break;
3915 #endif // QT_CONFIG(mdiarea)
3916 default:
3917 qWarning("QCommonStyle::drawComplexControl: Control %d not handled", cc);
3918 }
3919 }
3920
3921 /*!
3922 \reimp
3923 */
hitTestComplexControl(ComplexControl cc,const QStyleOptionComplex * opt,const QPoint & pt,const QWidget * widget) const3924 QStyle::SubControl QCommonStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
3925 const QPoint &pt, const QWidget *widget) const
3926 {
3927 SubControl sc = SC_None;
3928 switch (cc) {
3929 #if QT_CONFIG(slider)
3930 case CC_Slider:
3931 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3932 QRect r = proxy()->subControlRect(cc, slider, SC_SliderHandle, widget);
3933 if (r.isValid() && r.contains(pt)) {
3934 sc = SC_SliderHandle;
3935 } else {
3936 r = proxy()->subControlRect(cc, slider, SC_SliderGroove ,widget);
3937 if (r.isValid() && r.contains(pt))
3938 sc = SC_SliderGroove;
3939 }
3940 }
3941 break;
3942 #endif // QT_CONFIG(slider)
3943 #if QT_CONFIG(scrollbar)
3944 case CC_ScrollBar:
3945 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
3946 QRect r;
3947 uint ctrl = SC_ScrollBarAddLine;
3948 while (ctrl <= SC_ScrollBarGroove) {
3949 r = proxy()->subControlRect(cc, scrollbar, QStyle::SubControl(ctrl), widget);
3950 if (r.isValid() && r.contains(pt)) {
3951 sc = QStyle::SubControl(ctrl);
3952 break;
3953 }
3954 ctrl <<= 1;
3955 }
3956 }
3957 break;
3958 #endif // QT_CONFIG(scrollbar)
3959 #if QT_CONFIG(toolbutton)
3960 case CC_ToolButton:
3961 if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
3962 QRect r;
3963 uint ctrl = SC_ToolButton;
3964 while (ctrl <= SC_ToolButtonMenu) {
3965 r = proxy()->subControlRect(cc, toolbutton, QStyle::SubControl(ctrl), widget);
3966 if (r.isValid() && r.contains(pt)) {
3967 sc = QStyle::SubControl(ctrl);
3968 break;
3969 }
3970 ctrl <<= 1;
3971 }
3972 }
3973 break;
3974 #endif // QT_CONFIG(toolbutton)
3975 #if QT_CONFIG(spinbox)
3976 case CC_SpinBox:
3977 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
3978 QRect r;
3979 uint ctrl = SC_SpinBoxUp;
3980 while (ctrl <= SC_SpinBoxEditField) {
3981 r = proxy()->subControlRect(cc, spinbox, QStyle::SubControl(ctrl), widget);
3982 if (r.isValid() && r.contains(pt)) {
3983 sc = QStyle::SubControl(ctrl);
3984 break;
3985 }
3986 ctrl <<= 1;
3987 }
3988 }
3989 break;
3990 #endif // QT_CONFIG(spinbox)
3991 case CC_TitleBar:
3992 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
3993 QRect r;
3994 uint ctrl = SC_TitleBarSysMenu;
3995
3996 while (ctrl <= SC_TitleBarLabel) {
3997 r = proxy()->subControlRect(cc, tb, QStyle::SubControl(ctrl), widget);
3998 if (r.isValid() && r.contains(pt)) {
3999 sc = QStyle::SubControl(ctrl);
4000 break;
4001 }
4002 ctrl <<= 1;
4003 }
4004 }
4005 break;
4006 #if QT_CONFIG(combobox)
4007 case CC_ComboBox:
4008 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
4009 QRect r;
4010 uint ctrl = SC_ComboBoxArrow; // Start here and go down.
4011 while (ctrl > 0) {
4012 r = proxy()->subControlRect(cc, cb, QStyle::SubControl(ctrl), widget);
4013 if (r.isValid() && r.contains(pt)) {
4014 sc = QStyle::SubControl(ctrl);
4015 break;
4016 }
4017 ctrl >>= 1;
4018 }
4019 }
4020 break;
4021 #endif // QT_CONFIG(combobox)
4022 #if QT_CONFIG(groupbox)
4023 case CC_GroupBox:
4024 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
4025 QRect r;
4026 uint ctrl = SC_GroupBoxCheckBox;
4027 while (ctrl <= SC_GroupBoxFrame) {
4028 r = proxy()->subControlRect(cc, groupBox, QStyle::SubControl(ctrl), widget);
4029 if (r.isValid() && r.contains(pt)) {
4030 sc = QStyle::SubControl(ctrl);
4031 break;
4032 }
4033 ctrl <<= 1;
4034 }
4035 }
4036 break;
4037 #endif // QT_CONFIG(groupbox)
4038 case CC_MdiControls:
4039 {
4040 QRect r;
4041 uint ctrl = SC_MdiMinButton;
4042 while (ctrl <= SC_MdiCloseButton) {
4043 r = proxy()->subControlRect(CC_MdiControls, opt, QStyle::SubControl(ctrl), widget);
4044 if (r.isValid() && r.contains(pt) && (opt->subControls & ctrl)) {
4045 sc = QStyle::SubControl(ctrl);
4046 return sc;
4047 }
4048 ctrl <<= 1;
4049 }
4050 }
4051 break;
4052 default:
4053 qWarning("QCommonStyle::hitTestComplexControl: Case %d not handled", cc);
4054 }
4055 return sc;
4056 }
4057
4058 /*!
4059 \reimp
4060 */
subControlRect(ComplexControl cc,const QStyleOptionComplex * opt,SubControl sc,const QWidget * widget) const4061 QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
4062 SubControl sc, const QWidget *widget) const
4063 {
4064 QRect ret;
4065 switch (cc) {
4066 #if QT_CONFIG(slider)
4067 case CC_Slider:
4068 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4069 int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
4070 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
4071
4072 switch (sc) {
4073 case SC_SliderHandle: {
4074 int sliderPos = 0;
4075 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
4076 bool horizontal = slider->orientation == Qt::Horizontal;
4077 sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum,
4078 slider->sliderPosition,
4079 (horizontal ? slider->rect.width()
4080 : slider->rect.height()) - len,
4081 slider->upsideDown);
4082 if (horizontal)
4083 ret.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness);
4084 else
4085 ret.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len);
4086 break; }
4087 case SC_SliderGroove:
4088 if (slider->orientation == Qt::Horizontal)
4089 ret.setRect(slider->rect.x(), slider->rect.y() + tickOffset,
4090 slider->rect.width(), thickness);
4091 else
4092 ret.setRect(slider->rect.x() + tickOffset, slider->rect.y(),
4093 thickness, slider->rect.height());
4094 break;
4095 default:
4096 break;
4097 }
4098 ret = visualRect(slider->direction, slider->rect, ret);
4099 }
4100 break;
4101 #endif // QT_CONFIG(slider)
4102 #if QT_CONFIG(scrollbar)
4103 case CC_ScrollBar:
4104 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4105 const QRect scrollBarRect = scrollbar->rect;
4106 int sbextent = 0;
4107 if (!proxy()->styleHint(SH_ScrollBar_Transient, scrollbar, widget))
4108 sbextent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar, widget);
4109 int maxlen = ((scrollbar->orientation == Qt::Horizontal) ?
4110 scrollBarRect.width() : scrollBarRect.height()) - (sbextent * 2);
4111 int sliderlen;
4112
4113 // calculate slider length
4114 if (scrollbar->maximum != scrollbar->minimum) {
4115 uint range = scrollbar->maximum - scrollbar->minimum;
4116 sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep);
4117
4118 int slidermin = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollbar, widget);
4119 if (sliderlen < slidermin || range > INT_MAX / 2)
4120 sliderlen = slidermin;
4121 if (sliderlen > maxlen)
4122 sliderlen = maxlen;
4123 } else {
4124 sliderlen = maxlen;
4125 }
4126
4127 int sliderstart = sbextent + sliderPositionFromValue(scrollbar->minimum,
4128 scrollbar->maximum,
4129 scrollbar->sliderPosition,
4130 maxlen - sliderlen,
4131 scrollbar->upsideDown);
4132
4133 switch (sc) {
4134 case SC_ScrollBarSubLine: // top/left button
4135 if (scrollbar->orientation == Qt::Horizontal) {
4136 int buttonWidth = qMin(scrollBarRect.width() / 2, sbextent);
4137 ret.setRect(0, 0, buttonWidth, scrollBarRect.height());
4138 } else {
4139 int buttonHeight = qMin(scrollBarRect.height() / 2, sbextent);
4140 ret.setRect(0, 0, scrollBarRect.width(), buttonHeight);
4141 }
4142 break;
4143 case SC_ScrollBarAddLine: // bottom/right button
4144 if (scrollbar->orientation == Qt::Horizontal) {
4145 int buttonWidth = qMin(scrollBarRect.width()/2, sbextent);
4146 ret.setRect(scrollBarRect.width() - buttonWidth, 0, buttonWidth, scrollBarRect.height());
4147 } else {
4148 int buttonHeight = qMin(scrollBarRect.height()/2, sbextent);
4149 ret.setRect(0, scrollBarRect.height() - buttonHeight, scrollBarRect.width(), buttonHeight);
4150 }
4151 break;
4152 case SC_ScrollBarSubPage: // between top/left button and slider
4153 if (scrollbar->orientation == Qt::Horizontal)
4154 ret.setRect(sbextent, 0, sliderstart - sbextent, scrollBarRect.height());
4155 else
4156 ret.setRect(0, sbextent, scrollBarRect.width(), sliderstart - sbextent);
4157 break;
4158 case SC_ScrollBarAddPage: // between bottom/right button and slider
4159 if (scrollbar->orientation == Qt::Horizontal)
4160 ret.setRect(sliderstart + sliderlen, 0,
4161 maxlen - sliderstart - sliderlen + sbextent, scrollBarRect.height());
4162 else
4163 ret.setRect(0, sliderstart + sliderlen, scrollBarRect.width(),
4164 maxlen - sliderstart - sliderlen + sbextent);
4165 break;
4166 case SC_ScrollBarGroove:
4167 if (scrollbar->orientation == Qt::Horizontal)
4168 ret.setRect(sbextent, 0, scrollBarRect.width() - sbextent * 2,
4169 scrollBarRect.height());
4170 else
4171 ret.setRect(0, sbextent, scrollBarRect.width(),
4172 scrollBarRect.height() - sbextent * 2);
4173 break;
4174 case SC_ScrollBarSlider:
4175 if (scrollbar->orientation == Qt::Horizontal)
4176 ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height());
4177 else
4178 ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen);
4179 break;
4180 default:
4181 break;
4182 }
4183 ret = visualRect(scrollbar->direction, scrollBarRect, ret);
4184 }
4185 break;
4186 #endif // QT_CONFIG(scrollbar)
4187 #if QT_CONFIG(spinbox)
4188 case CC_SpinBox:
4189 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
4190 QSize bs;
4191 int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
4192 bs.setHeight(qMax(8, spinbox->rect.height()/2 - fw));
4193 // 1.6 -approximate golden mean
4194 bs.setWidth(qMax(16, qMin(bs.height() * 8 / 5, spinbox->rect.width() / 4)));
4195 bs = bs.expandedTo(QApplication::globalStrut());
4196 int y = fw + spinbox->rect.y();
4197 int x, lx, rx;
4198 x = spinbox->rect.x() + spinbox->rect.width() - fw - bs.width();
4199 lx = fw;
4200 rx = x - fw;
4201 switch (sc) {
4202 case SC_SpinBoxUp:
4203 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
4204 return QRect();
4205 ret = QRect(x, y, bs.width(), bs.height());
4206 break;
4207 case SC_SpinBoxDown:
4208 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
4209 return QRect();
4210
4211 ret = QRect(x, y + bs.height(), bs.width(), bs.height());
4212 break;
4213 case SC_SpinBoxEditField:
4214 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
4215 ret = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
4216 } else {
4217 ret = QRect(lx, fw, rx, spinbox->rect.height() - 2*fw);
4218 }
4219 break;
4220 case SC_SpinBoxFrame:
4221 ret = spinbox->rect;
4222 default:
4223 break;
4224 }
4225 ret = visualRect(spinbox->direction, spinbox->rect, ret);
4226 }
4227 break;
4228 #endif // Qt_NO_SPINBOX
4229 #if QT_CONFIG(toolbutton)
4230 case CC_ToolButton:
4231 if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
4232 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, tb, widget);
4233 ret = tb->rect;
4234 switch (sc) {
4235 case SC_ToolButton:
4236 if ((tb->features
4237 & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
4238 == QStyleOptionToolButton::MenuButtonPopup)
4239 ret.adjust(0, 0, -mbi, 0);
4240 break;
4241 case SC_ToolButtonMenu:
4242 if ((tb->features
4243 & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
4244 == QStyleOptionToolButton::MenuButtonPopup)
4245 ret.adjust(ret.width() - mbi, 0, 0, 0);
4246 break;
4247 default:
4248 break;
4249 }
4250 ret = visualRect(tb->direction, tb->rect, ret);
4251 }
4252 break;
4253 #endif // QT_CONFIG(toolbutton)
4254 #if QT_CONFIG(combobox)
4255 case CC_ComboBox:
4256 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
4257 const qreal dpi = QStyleHelper::dpi(opt);
4258 const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height();
4259 const int margin = cb->frame ? qRound(QStyleHelper::dpiScaled(3, dpi)) : 0;
4260 const int bmarg = cb->frame ? qRound(QStyleHelper::dpiScaled(2, dpi)) : 0;
4261 const int xpos = x + wi - bmarg - qRound(QStyleHelper::dpiScaled(16, dpi));
4262
4263
4264 switch (sc) {
4265 case SC_ComboBoxFrame:
4266 ret = cb->rect;
4267 break;
4268 case SC_ComboBoxArrow:
4269 ret.setRect(xpos, y + bmarg, qRound(QStyleHelper::dpiScaled(16, opt)), he - 2*bmarg);
4270 break;
4271 case SC_ComboBoxEditField:
4272 ret.setRect(x + margin, y + margin, wi - 2 * margin - qRound(QStyleHelper::dpiScaled(16, dpi)), he - 2 * margin);
4273 break;
4274 case SC_ComboBoxListBoxPopup:
4275 ret = cb->rect;
4276 break;
4277 default:
4278 break;
4279 }
4280 ret = visualRect(cb->direction, cb->rect, ret);
4281 }
4282 break;
4283 #endif // QT_CONFIG(combobox)
4284 case CC_TitleBar:
4285 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
4286 const int controlMargin = 2;
4287 const int controlHeight = tb->rect.height() - controlMargin *2;
4288 const int delta = controlHeight + controlMargin;
4289 int offset = 0;
4290
4291 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
4292 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
4293
4294 switch (sc) {
4295 case SC_TitleBarLabel:
4296 if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
4297 ret = tb->rect;
4298 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
4299 ret.adjust(delta, 0, -delta, 0);
4300 if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
4301 ret.adjust(0, 0, -delta, 0);
4302 if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
4303 ret.adjust(0, 0, -delta, 0);
4304 if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
4305 ret.adjust(0, 0, -delta, 0);
4306 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
4307 ret.adjust(0, 0, -delta, 0);
4308 }
4309 break;
4310 case SC_TitleBarContextHelpButton:
4311 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
4312 offset += delta;
4313 Q_FALLTHROUGH();
4314 case SC_TitleBarMinButton:
4315 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
4316 offset += delta;
4317 else if (sc == SC_TitleBarMinButton)
4318 break;
4319 Q_FALLTHROUGH();
4320 case SC_TitleBarNormalButton:
4321 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
4322 offset += delta;
4323 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
4324 offset += delta;
4325 else if (sc == SC_TitleBarNormalButton)
4326 break;
4327 Q_FALLTHROUGH();
4328 case SC_TitleBarMaxButton:
4329 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
4330 offset += delta;
4331 else if (sc == SC_TitleBarMaxButton)
4332 break;
4333 Q_FALLTHROUGH();
4334 case SC_TitleBarShadeButton:
4335 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
4336 offset += delta;
4337 else if (sc == SC_TitleBarShadeButton)
4338 break;
4339 Q_FALLTHROUGH();
4340 case SC_TitleBarUnshadeButton:
4341 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
4342 offset += delta;
4343 else if (sc == SC_TitleBarUnshadeButton)
4344 break;
4345 Q_FALLTHROUGH();
4346 case SC_TitleBarCloseButton:
4347 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
4348 offset += delta;
4349 else if (sc == SC_TitleBarCloseButton)
4350 break;
4351 ret.setRect(tb->rect.right() - offset, tb->rect.top() + controlMargin,
4352 controlHeight, controlHeight);
4353 break;
4354 case SC_TitleBarSysMenu:
4355 if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
4356 ret.setRect(tb->rect.left() + controlMargin, tb->rect.top() + controlMargin,
4357 controlHeight, controlHeight);
4358 }
4359 break;
4360 default:
4361 break;
4362 }
4363 ret = visualRect(tb->direction, tb->rect, ret);
4364 }
4365 break;
4366 #if QT_CONFIG(groupbox)
4367 case CC_GroupBox: {
4368 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
4369 switch (sc) {
4370 case SC_GroupBoxFrame:
4371 case SC_GroupBoxContents: {
4372 int topMargin = 0;
4373 int topHeight = 0;
4374 int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
4375 bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
4376 if (groupBox->text.size() || hasCheckBox) {
4377 int checkBoxHeight = hasCheckBox ? proxy()->pixelMetric(PM_IndicatorHeight, groupBox, widget) : 0;
4378 topHeight = qMax(groupBox->fontMetrics.height(), checkBoxHeight);
4379 if (verticalAlignment & Qt::AlignVCenter)
4380 topMargin = topHeight / 2;
4381 else if (verticalAlignment & Qt::AlignTop)
4382 topMargin = topHeight;
4383 }
4384
4385 QRect frameRect = groupBox->rect;
4386 frameRect.setTop(topMargin);
4387
4388 if (sc == SC_GroupBoxFrame) {
4389 ret = frameRect;
4390 break;
4391 }
4392
4393 int frameWidth = 0;
4394 if ((groupBox->features & QStyleOptionFrame::Flat) == 0)
4395 frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, groupBox, widget);
4396 ret = frameRect.adjusted(frameWidth, frameWidth + topHeight - topMargin,
4397 -frameWidth, -frameWidth);
4398 break;
4399 }
4400 case SC_GroupBoxCheckBox:
4401 case SC_GroupBoxLabel: {
4402 QFontMetrics fontMetrics = groupBox->fontMetrics;
4403 int th = fontMetrics.height();
4404 int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
4405 int marg = (groupBox->features & QStyleOptionFrame::Flat) ? 0 : 8;
4406 ret = groupBox->rect.adjusted(marg, 0, -marg, 0);
4407
4408 int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
4409 int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
4410 int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget) - 1;
4411 bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
4412 int checkBoxWidth = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
4413 int checkBoxHeight = hasCheckBox ? indicatorHeight : 0;
4414
4415 int h = qMax(th, checkBoxHeight);
4416 ret.setHeight(h);
4417
4418 // Adjusted rect for label + indicatorWidth + indicatorSpace
4419 QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment,
4420 QSize(tw + checkBoxWidth, h), ret);
4421
4422 // Adjust totalRect if checkbox is set
4423 if (hasCheckBox) {
4424 bool ltr = groupBox->direction == Qt::LeftToRight;
4425 int left = 0;
4426 // Adjust for check box
4427 if (sc == SC_GroupBoxCheckBox) {
4428 left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
4429 int top = totalRect.top() + (h - checkBoxHeight) / 2;
4430 totalRect.setRect(left, top, indicatorWidth, indicatorHeight);
4431 // Adjust for label
4432 } else {
4433 left = ltr ? (totalRect.left() + checkBoxWidth - 2) : totalRect.left();
4434 int top = totalRect.top() + (h - th) / 2;
4435 totalRect.setRect(left, top, totalRect.width() - checkBoxWidth, th);
4436 }
4437 }
4438 ret = totalRect;
4439 break;
4440 }
4441 default:
4442 break;
4443 }
4444 }
4445 break;
4446 }
4447 #endif // QT_CONFIG(groupbox)
4448 #if QT_CONFIG(mdiarea)
4449 case CC_MdiControls:
4450 {
4451 int numSubControls = 0;
4452 if (opt->subControls & SC_MdiCloseButton)
4453 ++numSubControls;
4454 if (opt->subControls & SC_MdiMinButton)
4455 ++numSubControls;
4456 if (opt->subControls & SC_MdiNormalButton)
4457 ++numSubControls;
4458 if (numSubControls == 0)
4459 break;
4460
4461 int buttonWidth = opt->rect.width() / numSubControls - 1;
4462 int offset = 0;
4463 switch (sc) {
4464 case SC_MdiCloseButton:
4465 // Only one sub control, no offset needed.
4466 if (numSubControls == 1)
4467 break;
4468 offset += buttonWidth + 2;
4469 Q_FALLTHROUGH();
4470 case SC_MdiNormalButton:
4471 // No offset needed if
4472 // 1) There's only one sub control
4473 // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
4474 if (numSubControls == 1 || (numSubControls == 2 && !(opt->subControls & SC_MdiMinButton)))
4475 break;
4476 if (opt->subControls & SC_MdiNormalButton)
4477 offset += buttonWidth;
4478 break;
4479 default:
4480 break;
4481 }
4482
4483 // Subtract one pixel if we only have one sub control. At this point
4484 // buttonWidth is the actual width + 1 pixel margin, but we don't want the
4485 // margin when there are no other controllers.
4486 if (numSubControls == 1)
4487 --buttonWidth;
4488 ret = QRect(offset, 0, buttonWidth, opt->rect.height());
4489 break;
4490 }
4491 #endif // QT_CONFIG(mdiarea)
4492 default:
4493 qWarning("QCommonStyle::subControlRect: Case %d not handled", cc);
4494 }
4495 #if !QT_CONFIG(slider) && !QT_CONFIG(spinbox) && !QT_CONFIG(toolbutton) && !QT_CONFIG(groupbox)
4496 Q_UNUSED(widget);
4497 #endif
4498 return ret;
4499 }
4500
4501 /*! \reimp */
pixelMetric(PixelMetric m,const QStyleOption * opt,const QWidget * widget) const4502 int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *widget) const
4503 {
4504 int ret;
4505
4506 switch (m) {
4507 case PM_FocusFrameVMargin:
4508 case PM_FocusFrameHMargin:
4509 ret = 2;
4510 break;
4511 case PM_MenuBarVMargin:
4512 case PM_MenuBarHMargin:
4513 ret = 0;
4514 break;
4515 case PM_DialogButtonsSeparator:
4516 ret = int(QStyleHelper::dpiScaled(5, opt));
4517 break;
4518 case PM_DialogButtonsButtonWidth:
4519 ret = int(QStyleHelper::dpiScaled(70, opt));
4520 break;
4521 case PM_DialogButtonsButtonHeight:
4522 ret = int(QStyleHelper::dpiScaled(30, opt));
4523 break;
4524 case PM_TitleBarHeight: {
4525 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
4526 if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) {
4527 ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 16);
4528 #if QT_CONFIG(dockwidget)
4529 } else if (qobject_cast<const QDockWidget*>(widget)) {
4530 ret = qMax(widget->fontMetrics().height(), int(QStyleHelper::dpiScaled(13, opt)));
4531 #endif
4532 } else {
4533 ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 18);
4534 }
4535 } else {
4536 ret = int(QStyleHelper::dpiScaled(18., opt));
4537 }
4538
4539 break; }
4540 case PM_TitleBarButtonSize:
4541 ret = int(QStyleHelper::dpiScaled(16., opt));
4542 break;
4543 case PM_TitleBarButtonIconSize:
4544 ret = int(QStyleHelper::dpiScaled(16., opt));
4545 break;
4546
4547 case PM_ScrollBarSliderMin:
4548 ret = int(QStyleHelper::dpiScaled(9., opt));
4549 break;
4550
4551 case PM_ButtonMargin:
4552 ret = int(QStyleHelper::dpiScaled(6., opt));
4553 break;
4554
4555 case PM_DockWidgetTitleBarButtonMargin:
4556 ret = int(QStyleHelper::dpiScaled(2., opt));
4557 break;
4558
4559 case PM_ButtonDefaultIndicator:
4560 ret = 0;
4561 break;
4562
4563 case PM_MenuButtonIndicator:
4564 ret = int(QStyleHelper::dpiScaled(12, opt));
4565 break;
4566
4567 case PM_ButtonShiftHorizontal:
4568 case PM_ButtonShiftVertical:
4569
4570 case PM_DefaultFrameWidth:
4571 ret = 2;
4572 break;
4573
4574 case PM_ComboBoxFrameWidth:
4575 case PM_SpinBoxFrameWidth:
4576 case PM_MenuPanelWidth:
4577 case PM_TabBarBaseOverlap:
4578 case PM_TabBarBaseHeight:
4579 ret = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
4580 break;
4581
4582 case PM_MdiSubWindowFrameWidth:
4583 ret = int(QStyleHelper::dpiScaled(4, opt));
4584 break;
4585
4586 case PM_MdiSubWindowMinimizedWidth:
4587 ret = int(QStyleHelper::dpiScaled(196, opt));
4588 break;
4589
4590 #if QT_CONFIG(scrollbar)
4591 case PM_ScrollBarExtent:
4592 if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4593 int s = sb->orientation == Qt::Horizontal ?
4594 QApplication::globalStrut().height()
4595 : QApplication::globalStrut().width();
4596 ret = qMax(16, s);
4597 } else {
4598 ret = int(QStyleHelper::dpiScaled(16, opt));
4599 }
4600 break;
4601 #endif
4602 case PM_MaximumDragDistance:
4603 ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::MaximumScrollBarDragDistance).toInt();
4604 break;
4605
4606 #if QT_CONFIG(slider)
4607 case PM_SliderThickness:
4608 ret = int(QStyleHelper::dpiScaled(16, opt));
4609 break;
4610
4611 case PM_SliderTickmarkOffset:
4612 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4613 int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height()
4614 : sl->rect.width();
4615 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, sl, widget);
4616 int ticks = sl->tickPosition;
4617
4618 if (ticks == QSlider::TicksBothSides)
4619 ret = (space - thickness) / 2;
4620 else if (ticks == QSlider::TicksAbove)
4621 ret = space - thickness;
4622 else
4623 ret = 0;
4624 } else {
4625 ret = 0;
4626 }
4627 break;
4628
4629 case PM_SliderSpaceAvailable:
4630 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4631 if (sl->orientation == Qt::Horizontal)
4632 ret = sl->rect.width() - proxy()->pixelMetric(PM_SliderLength, sl, widget);
4633 else
4634 ret = sl->rect.height() - proxy()->pixelMetric(PM_SliderLength, sl, widget);
4635 } else {
4636 ret = 0;
4637 }
4638 break;
4639 #endif // QT_CONFIG(slider)
4640 #if QT_CONFIG(dockwidget)
4641 case PM_DockWidgetSeparatorExtent:
4642 ret = int(QStyleHelper::dpiScaled(6, opt));
4643 break;
4644
4645 case PM_DockWidgetHandleExtent:
4646 ret = int(QStyleHelper::dpiScaled(8, opt));
4647 break;
4648 case PM_DockWidgetTitleMargin:
4649 ret = 0;
4650 break;
4651 case PM_DockWidgetFrameWidth:
4652 ret = 1;
4653 break;
4654 #endif // QT_CONFIG(dockwidget)
4655
4656 case PM_SpinBoxSliderHeight:
4657 case PM_MenuBarPanelWidth:
4658 ret = 2;
4659 break;
4660
4661 case PM_MenuBarItemSpacing:
4662 ret = 0;
4663 break;
4664
4665 #if QT_CONFIG(toolbar)
4666 case PM_ToolBarFrameWidth:
4667 ret = 1;
4668 break;
4669
4670 case PM_ToolBarItemMargin:
4671 ret = 0;
4672 break;
4673
4674 case PM_ToolBarItemSpacing:
4675 ret = int(QStyleHelper::dpiScaled(4, opt));
4676 break;
4677
4678 case PM_ToolBarHandleExtent:
4679 ret = int(QStyleHelper::dpiScaled(8, opt));
4680 break;
4681
4682 case PM_ToolBarSeparatorExtent:
4683 ret = int(QStyleHelper::dpiScaled(6, opt));
4684 break;
4685
4686 case PM_ToolBarExtensionExtent:
4687 ret = int(QStyleHelper::dpiScaled(12, opt));
4688 break;
4689 #endif // QT_CONFIG(toolbar)
4690
4691 #if QT_CONFIG(tabbar)
4692 case PM_TabBarTabOverlap:
4693 ret = 3;
4694 break;
4695
4696 case PM_TabBarTabHSpace:
4697 ret = int(QStyleHelper::dpiScaled(24, opt));
4698 break;
4699
4700 case PM_TabBarTabShiftHorizontal:
4701 ret = 0;
4702 break;
4703
4704 case PM_TabBarTabShiftVertical:
4705 ret = 2;
4706 break;
4707
4708 case PM_TabBarTabVSpace: {
4709 const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt);
4710 if (tb && (tb->shape == QTabBar::RoundedNorth || tb->shape == QTabBar::RoundedSouth
4711 || tb->shape == QTabBar::RoundedWest || tb->shape == QTabBar::RoundedEast))
4712 ret = 8;
4713 else
4714 if(tb && (tb->shape == QTabBar::TriangularWest || tb->shape == QTabBar::TriangularEast))
4715 ret = 3;
4716 else
4717 ret = 2;
4718 break; }
4719 #endif
4720
4721 case PM_ProgressBarChunkWidth:
4722 ret = 9;
4723 break;
4724
4725 case PM_IndicatorWidth:
4726 ret = int(QStyleHelper::dpiScaled(13, opt));
4727 break;
4728
4729 case PM_IndicatorHeight:
4730 ret = int(QStyleHelper::dpiScaled(13, opt));
4731 break;
4732
4733 case PM_ExclusiveIndicatorWidth:
4734 ret = int(QStyleHelper::dpiScaled(12, opt));
4735 break;
4736
4737 case PM_ExclusiveIndicatorHeight:
4738 ret = int(QStyleHelper::dpiScaled(12, opt));
4739 break;
4740
4741 case PM_MenuTearoffHeight:
4742 ret = int(QStyleHelper::dpiScaled(10, opt));
4743 break;
4744
4745 case PM_MenuScrollerHeight:
4746 ret = int(QStyleHelper::dpiScaled(10, opt));
4747 break;
4748
4749 case PM_MenuDesktopFrameWidth:
4750 case PM_MenuHMargin:
4751 case PM_MenuVMargin:
4752 ret = 0;
4753 break;
4754
4755 case PM_HeaderMargin:
4756 ret = int(QStyleHelper::dpiScaled(4, opt));
4757 break;
4758 case PM_HeaderMarkSize:
4759 ret = int(QStyleHelper::dpiScaled(16, opt));
4760 break;
4761 case PM_HeaderGripMargin:
4762 ret = int(QStyleHelper::dpiScaled(4, opt));
4763 break;
4764 case PM_HeaderDefaultSectionSizeHorizontal:
4765 ret = int(QStyleHelper::dpiScaled(100, opt));
4766 break;
4767 case PM_HeaderDefaultSectionSizeVertical:
4768 ret = int(QStyleHelper::dpiScaled(30, opt));
4769 break;
4770 case PM_TabBarScrollButtonWidth:
4771 ret = int(QStyleHelper::dpiScaled(16, opt));
4772 break;
4773 case PM_LayoutLeftMargin:
4774 case PM_LayoutTopMargin:
4775 case PM_LayoutRightMargin:
4776 case PM_LayoutBottomMargin:
4777 {
4778 bool isWindow = false;
4779 if (opt) {
4780 isWindow = (opt->state & State_Window);
4781 } else if (widget) {
4782 isWindow = widget->isWindow();
4783 }
4784 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
4785 ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin, opt);
4786 QT_WARNING_POP
4787 }
4788 break;
4789 case PM_LayoutHorizontalSpacing:
4790 case PM_LayoutVerticalSpacing:
4791 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
4792 ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing, opt);
4793 QT_WARNING_POP
4794 break;
4795
4796 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
4797 case PM_DefaultTopLevelMargin:
4798 ret = int(QStyleHelper::dpiScaled(11, opt));
4799 break;
4800 case PM_DefaultChildMargin:
4801 ret = int(QStyleHelper::dpiScaled(9, opt));
4802 break;
4803 case PM_DefaultLayoutSpacing:
4804 ret = int(QStyleHelper::dpiScaled(6, opt));
4805 break;
4806 QT_WARNING_POP
4807
4808 case PM_ToolBarIconSize:
4809 ret = 0;
4810 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
4811 ret = theme->themeHint(QPlatformTheme::ToolBarIconSize).toInt();
4812 if (ret <= 0)
4813 ret = int(QStyleHelper::dpiScaled(24, opt));
4814 break;
4815
4816 case PM_TabBarIconSize:
4817 ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
4818 break;
4819 case PM_ListViewIconSize:
4820 #if QT_CONFIG(filedialog)
4821 if (qobject_cast<const QSidebar *>(widget))
4822 ret = int(QStyleHelper::dpiScaled(24., opt));
4823 else
4824 #endif
4825 ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
4826 break;
4827
4828 case PM_ButtonIconSize:
4829 case PM_SmallIconSize:
4830 ret = int(QStyleHelper::dpiScaled(16, opt));
4831 break;
4832 case PM_IconViewIconSize:
4833 ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
4834 break;
4835
4836 case PM_LargeIconSize:
4837 ret = int(QStyleHelper::dpiScaled(32, opt));
4838 break;
4839
4840 case PM_ToolTipLabelFrameWidth:
4841 ret = 1;
4842 break;
4843 case PM_CheckBoxLabelSpacing:
4844 case PM_RadioButtonLabelSpacing:
4845 ret = int(QStyleHelper::dpiScaled(6, opt));
4846 break;
4847 case PM_SizeGripSize:
4848 ret = int(QStyleHelper::dpiScaled(13, opt));
4849 break;
4850 case PM_MessageBoxIconSize:
4851 #ifdef Q_OS_MAC
4852 if (QGuiApplication::desktopSettingsAware()) {
4853 ret = 64; // No DPI scaling, it's handled elsewhere.
4854 } else
4855 #endif
4856 {
4857 ret = int(QStyleHelper::dpiScaled(32, opt));
4858 }
4859 break;
4860 case PM_TextCursorWidth:
4861 ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::TextCursorWidth).toInt();
4862 break;
4863 case PM_TabBar_ScrollButtonOverlap:
4864 ret = 1;
4865 break;
4866 case PM_TabCloseIndicatorWidth:
4867 case PM_TabCloseIndicatorHeight:
4868 ret = int(QStyleHelper::dpiScaled(16, opt));
4869 break;
4870 case PM_ScrollView_ScrollBarSpacing:
4871 ret = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
4872 break;
4873 case PM_ScrollView_ScrollBarOverlap:
4874 ret = 0;
4875 break;
4876 case PM_SubMenuOverlap:
4877 ret = -proxy()->pixelMetric(QStyle::PM_MenuPanelWidth, opt, widget);
4878 break;
4879 case PM_TreeViewIndentation:
4880 ret = int(QStyleHelper::dpiScaled(20, opt));
4881 break;
4882 default:
4883 ret = 0;
4884 break;
4885 }
4886
4887 return ret;
4888 }
4889
4890 /*!
4891 \reimp
4892 */
sizeFromContents(ContentsType ct,const QStyleOption * opt,const QSize & csz,const QWidget * widget) const4893 QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
4894 const QSize &csz, const QWidget *widget) const
4895 {
4896 Q_D(const QCommonStyle);
4897 QSize sz(csz);
4898 switch (ct) {
4899 case CT_PushButton:
4900 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
4901 int w = csz.width(),
4902 h = csz.height(),
4903 bm = proxy()->pixelMetric(PM_ButtonMargin, btn, widget),
4904 fw = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget) * 2;
4905 w += bm + fw;
4906 h += bm + fw;
4907 if (btn->features & QStyleOptionButton::AutoDefaultButton){
4908 int dbw = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget) * 2;
4909 w += dbw;
4910 h += dbw;
4911 }
4912 sz = QSize(w, h);
4913 }
4914 break;
4915 case CT_RadioButton:
4916 case CT_CheckBox:
4917 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
4918 bool isRadio = (ct == CT_RadioButton);
4919
4920 int w = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth
4921 : PM_IndicatorWidth, btn, widget);
4922 int h = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
4923 : PM_IndicatorHeight, btn, widget);
4924
4925 int margins = 0;
4926 // we add 4 pixels for label margins
4927 if (!btn->icon.isNull() || !btn->text.isEmpty())
4928 margins = 4 + proxy()->pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
4929 : PM_CheckBoxLabelSpacing, opt, widget);
4930 sz += QSize(w + margins, 4);
4931 sz.setHeight(qMax(sz.height(), h));
4932 }
4933 break;
4934 #if QT_CONFIG(menu)
4935 case CT_MenuItem:
4936 if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
4937 bool checkable = mi->menuHasCheckableItems;
4938 int maxpmw = mi->maxIconWidth;
4939 int w = sz.width(), h = sz.height();
4940 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
4941 w = 10;
4942 h = 2;
4943 } else {
4944 h = mi->fontMetrics.height() + 8;
4945 if (!mi->icon.isNull()) {
4946 int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt);
4947 h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
4948 }
4949 }
4950 if (mi->text.contains(QLatin1Char('\t')))
4951 w += 12;
4952 if (maxpmw > 0)
4953 w += maxpmw + 6;
4954 if (checkable && maxpmw < 20)
4955 w += 20 - maxpmw;
4956 if (checkable || maxpmw > 0)
4957 w += 2;
4958 w += 12;
4959 sz = QSize(w, h);
4960 }
4961 break;
4962 #endif // QT_CONFIG(menu)
4963 #if QT_CONFIG(toolbutton)
4964 case CT_ToolButton:
4965 sz = QSize(sz.width() + 6, sz.height() + 5);
4966 break;
4967 #endif // QT_CONFIG(toolbutton)
4968 #if QT_CONFIG(combobox)
4969 case CT_ComboBox:
4970 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
4971 int fw = cmb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0;
4972 const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin, opt) + 1);
4973 // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
4974 int other = qMax(23, 2*textMargins + proxy()->pixelMetric(QStyle::PM_ScrollBarExtent, opt, widget));
4975 sz = QSize(sz.width() + fw + other, sz.height() + fw);
4976 }
4977 break;
4978 #endif // QT_CONFIG(combobox)
4979 case CT_HeaderSection:
4980 if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
4981 bool nullIcon = hdr->icon.isNull();
4982 int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr, widget);
4983 int iconSize = nullIcon ? 0 : proxy()->pixelMetric(QStyle::PM_SmallIconSize, hdr, widget);
4984 QSize txt = hdr->fontMetrics.size(0, hdr->text);
4985 sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
4986 sz.setWidth((nullIcon ? 0 : margin) + iconSize
4987 + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
4988 if (hdr->sortIndicator != QStyleOptionHeader::None) {
4989 int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr, widget);
4990 if (hdr->orientation == Qt::Horizontal)
4991 sz.rwidth() += sz.height() + margin;
4992 else
4993 sz.rheight() += sz.width() + margin;
4994 }
4995 }
4996 break;
4997 case CT_TabWidget:
4998 sz += QSize(4, 4);
4999 break;
5000 case CT_LineEdit:
5001 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
5002 sz += QSize(2*f->lineWidth, 2*f->lineWidth);
5003 break;
5004 #if QT_CONFIG(groupbox)
5005 case CT_GroupBox:
5006 if (const QStyleOptionGroupBox *styleOpt = qstyleoption_cast<const QStyleOptionGroupBox *>(opt))
5007 sz += QSize(styleOpt->features.testFlag(QStyleOptionFrame::Flat) ? 0 : 16, 0);
5008 break;
5009 #endif // QT_CONFIG(groupbox)
5010 case CT_MdiControls:
5011 if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
5012 const int buttonSize = proxy()->pixelMetric(PM_TitleBarButtonSize, styleOpt, widget);
5013 int width = 1;
5014 if (styleOpt->subControls & SC_MdiMinButton)
5015 width += buttonSize + 1;
5016 if (styleOpt->subControls & SC_MdiNormalButton)
5017 width += buttonSize + 1;
5018 if (styleOpt->subControls & SC_MdiCloseButton)
5019 width += buttonSize + 1;
5020 sz = QSize(width, buttonSize);
5021 } else {
5022 const int buttonSize = proxy()->pixelMetric(PM_TitleBarButtonSize, opt, widget);
5023 sz = QSize(1 + 3 * (buttonSize + 1), buttonSize);
5024 }
5025 break;
5026 #if QT_CONFIG(itemviews)
5027 case CT_ItemViewItem:
5028 if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
5029 QRect decorationRect, displayRect, checkRect;
5030 d->viewItemLayout(vopt, &checkRect, &decorationRect, &displayRect, true);
5031 sz = (decorationRect|displayRect|checkRect).size();
5032 if (decorationRect.isValid() && sz.height() == decorationRect.height())
5033 sz.rheight() += 2; // Prevent icons from overlapping.
5034 }
5035 break;
5036 #else
5037 Q_UNUSED(d);
5038 #endif // QT_CONFIG(itemviews)
5039 #if QT_CONFIG(spinbox)
5040 case CT_SpinBox:
5041 if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
5042 // Add button + frame widths
5043 const qreal dpi = QStyleHelper::dpi(opt);
5044 const bool hasButtons = (vopt->buttonSymbols != QAbstractSpinBox::NoButtons);
5045 const int buttonWidth = hasButtons ? qRound(QStyleHelper::dpiScaled(16, dpi)) : 0;
5046 const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
5047 sz += QSize(buttonWidth + 2*fw, 2*fw);
5048 }
5049 break;
5050 #endif
5051 case CT_ScrollBar:
5052 case CT_MenuBar:
5053 case CT_Menu:
5054 case CT_MenuBarItem:
5055 case CT_Slider:
5056 case CT_ProgressBar:
5057 case CT_TabBarTab:
5058 // just return the contentsSize for now
5059 Q_FALLTHROUGH();
5060 default:
5061 break;
5062 }
5063 return sz;
5064 }
5065
5066
5067 /*! \reimp */
styleHint(StyleHint sh,const QStyleOption * opt,const QWidget * widget,QStyleHintReturn * hret) const5068 int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget,
5069 QStyleHintReturn *hret) const
5070 {
5071 int ret = 0;
5072
5073 switch (sh) {
5074 case SH_Menu_KeyboardSearch:
5075 ret = false;
5076 break;
5077 case SH_Slider_AbsoluteSetButtons:
5078 ret = Qt::MiddleButton;
5079 break;
5080 case SH_Slider_PageSetButtons:
5081 ret = Qt::LeftButton;
5082 break;
5083 case SH_ScrollBar_ContextMenu:
5084 ret = true;
5085 break;
5086 #if QT_CONFIG(dialogbuttonbox)
5087 case SH_DialogButtons_DefaultButton: // This value not used anywhere.
5088 ret = QDialogButtonBox::AcceptRole;
5089 break;
5090 #endif
5091 #if QT_CONFIG(groupbox)
5092 case SH_GroupBox_TextLabelVerticalAlignment:
5093 ret = Qt::AlignVCenter;
5094 break;
5095
5096 case SH_GroupBox_TextLabelColor:
5097 ret = opt ? int(opt->palette.color(QPalette::Text).rgba()) : 0;
5098 break;
5099 #endif // QT_CONFIG(groupbox)
5100
5101 case SH_ListViewExpand_SelectMouseType:
5102 case SH_TabBar_SelectMouseType:
5103 ret = QEvent::MouseButtonPress;
5104 break;
5105
5106
5107 case SH_TabBar_Alignment:
5108 ret = Qt::AlignLeft;
5109 break;
5110
5111 case SH_Header_ArrowAlignment:
5112 ret = Qt::AlignRight | Qt::AlignVCenter;
5113 break;
5114
5115 case SH_TitleBar_AutoRaise:
5116 ret = false;
5117 break;
5118
5119 case SH_Menu_SubMenuPopupDelay:
5120 ret = 256;
5121 break;
5122
5123 case SH_Menu_SloppySubMenus:
5124 ret = true;
5125 break;
5126
5127 case SH_Menu_SubMenuUniDirection:
5128 ret = false;
5129 break;
5130 case SH_Menu_SubMenuUniDirectionFailCount:
5131 ret = 1;
5132 break;
5133 case SH_Menu_SubMenuSloppySelectOtherActions:
5134 ret = true;
5135 break;
5136 case SH_Menu_SubMenuSloppyCloseTimeout:
5137 ret = 1000;
5138 break;
5139 case SH_Menu_SubMenuResetWhenReenteringParent:
5140 ret = false;
5141 break;
5142 case SH_Menu_SubMenuDontStartSloppyOnLeave:
5143 ret = false;
5144 break;
5145
5146 case SH_ProgressDialog_TextLabelAlignment:
5147 ret = Qt::AlignCenter;
5148 break;
5149
5150 case SH_BlinkCursorWhenTextSelected:
5151 #if defined(Q_OS_DARWIN)
5152 ret = 0;
5153 #else
5154 ret = 1;
5155 #endif
5156 break;
5157
5158 case SH_Table_GridLineColor:
5159 if (opt)
5160 ret = opt->palette.color(QPalette::Mid).rgba();
5161 else
5162 ret = -1;
5163 break;
5164 case SH_LineEdit_PasswordCharacter: {
5165 const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
5166 const QPlatformTheme::ThemeHint hintType = QPlatformTheme::PasswordMaskCharacter;
5167 const QVariant hint = theme ? theme->themeHint(hintType) : QPlatformTheme::defaultThemeHint(hintType);
5168 ret = hint.toChar().unicode();
5169 break;
5170 }
5171 case SH_LineEdit_PasswordMaskDelay:
5172 ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::PasswordMaskDelay).toInt();
5173 break;
5174 case SH_ToolBox_SelectedPageTitleBold:
5175 ret = 1;
5176 break;
5177
5178 case SH_UnderlineShortcut:
5179 ret = 1;
5180 break;
5181
5182 case SH_SpinBox_ClickAutoRepeatRate:
5183 ret = 150;
5184 break;
5185
5186 case SH_SpinBox_ClickAutoRepeatThreshold:
5187 ret = 500;
5188 break;
5189
5190 case SH_SpinBox_KeyPressAutoRepeatRate:
5191 ret = 75;
5192 break;
5193
5194 case SH_Menu_SelectionWrap:
5195 ret = true;
5196 break;
5197
5198 case SH_Menu_FillScreenWithScroll:
5199 ret = true;
5200 break;
5201
5202 case SH_ToolTipLabel_Opacity:
5203 ret = 255;
5204 break;
5205
5206 case SH_Button_FocusPolicy:
5207 ret = Qt::StrongFocus;
5208 break;
5209
5210 case SH_MessageBox_UseBorderForButtonSpacing:
5211 ret = 0;
5212 break;
5213
5214 case SH_ToolButton_PopupDelay:
5215 ret = 600;
5216 break;
5217
5218 case SH_FocusFrame_Mask:
5219 ret = 1;
5220 if (widget) {
5221 if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
5222 mask->region = widget->rect();
5223 const int vmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt);
5224 const int hmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt);
5225 mask->region -= QRect(widget->rect().adjusted(hmargin, vmargin, -hmargin, -vmargin));
5226 }
5227 }
5228 break;
5229 #if QT_CONFIG(rubberband)
5230 case SH_RubberBand_Mask:
5231 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
5232 ret = 0;
5233 if (rbOpt->shape == QRubberBand::Rectangle) {
5234 ret = true;
5235 if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
5236 mask->region = opt->rect;
5237 const int margin = proxy()->pixelMetric(PM_DefaultFrameWidth, opt) * 2;
5238 mask->region -= opt->rect.adjusted(margin, margin, -margin, -margin);
5239 }
5240 }
5241 }
5242 break;
5243 #endif // QT_CONFIG(rubberband)
5244 case SH_SpinControls_DisableOnBounds:
5245 ret = 1;
5246 break;
5247
5248 case SH_Dial_BackgroundRole:
5249 ret = QPalette::Window;
5250 break;
5251
5252 case SH_ComboBox_LayoutDirection:
5253 ret = opt ? opt->direction : Qt::LeftToRight;
5254 break;
5255
5256 case SH_ItemView_EllipsisLocation:
5257 ret = Qt::AlignTrailing;
5258 break;
5259
5260 case SH_ItemView_ShowDecorationSelected:
5261 ret = false;
5262 break;
5263
5264 case SH_ItemView_ActivateItemOnSingleClick:
5265 ret = 0;
5266 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
5267 ret = theme->themeHint(QPlatformTheme::ItemViewActivateItemOnSingleClick).toBool() ? 1 : 0;
5268 break;
5269 case SH_TitleBar_ModifyNotification:
5270 ret = true;
5271 break;
5272 case SH_ScrollBar_RollBetweenButtons:
5273 ret = false;
5274 break;
5275 case SH_TabBar_ElideMode:
5276 ret = Qt::ElideNone;
5277 break;
5278 #if QT_CONFIG(dialogbuttonbox)
5279 case SH_DialogButtonLayout:
5280 ret = QDialogButtonBox::WinLayout;
5281 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
5282 ret = theme->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt();
5283 break;
5284 #endif
5285 case SH_ComboBox_PopupFrameStyle:
5286 ret = QFrame::StyledPanel | QFrame::Plain;
5287 break;
5288 case SH_MessageBox_TextInteractionFlags:
5289 ret = Qt::LinksAccessibleByMouse;
5290 break;
5291 case SH_DialogButtonBox_ButtonsHaveIcons:
5292 ret = 0;
5293 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
5294 ret = theme->themeHint(QPlatformTheme::DialogButtonBoxButtonsHaveIcons).toBool() ? 1 : 0;
5295 break;
5296 case SH_SpellCheckUnderlineStyle:
5297 ret = QTextCharFormat::WaveUnderline;
5298 break;
5299 case SH_MessageBox_CenterButtons:
5300 ret = true;
5301 break;
5302 case SH_ItemView_MovementWithoutUpdatingSelection:
5303 ret = true;
5304 break;
5305 case SH_FocusFrame_AboveWidget:
5306 ret = false;
5307 break;
5308 #if QT_CONFIG(tabwidget)
5309 case SH_TabWidget_DefaultTabPosition:
5310 ret = QTabWidget::North;
5311 break;
5312 #endif
5313 case SH_ToolBar_Movable:
5314 ret = true;
5315 break;
5316 case SH_TextControl_FocusIndicatorTextCharFormat:
5317 ret = true;
5318 if (QStyleHintReturnVariant *vret = qstyleoption_cast<QStyleHintReturnVariant*>(hret)) {
5319 QPen outline(opt->palette.color(QPalette::Text), 1, Qt::DotLine);
5320 QTextCharFormat fmt;
5321 fmt.setProperty(QTextFormat::OutlinePen, outline);
5322 vret->variant = fmt;
5323 }
5324 break;
5325 #if QT_CONFIG(wizard)
5326 case SH_WizardStyle:
5327 ret = QWizard::ClassicStyle;
5328 break;
5329 #endif
5330 #if QT_CONFIG(formlayout)
5331 case SH_FormLayoutWrapPolicy:
5332 ret = QFormLayout::DontWrapRows;
5333 break;
5334 case SH_FormLayoutFieldGrowthPolicy:
5335 ret = QFormLayout::AllNonFixedFieldsGrow;
5336 break;
5337 #endif
5338 case SH_FormLayoutFormAlignment:
5339 ret = Qt::AlignLeft | Qt::AlignTop;
5340 break;
5341 case SH_FormLayoutLabelAlignment:
5342 ret = Qt::AlignLeft;
5343 break;
5344 case SH_ItemView_ArrowKeysNavigateIntoChildren:
5345 ret = false;
5346 break;
5347 case SH_ItemView_DrawDelegateFrame:
5348 ret = 0;
5349 break;
5350 #if QT_CONFIG(tabbar)
5351 case SH_TabBar_CloseButtonPosition:
5352 ret = QTabBar::RightSide;
5353 break;
5354 case SH_TabBar_ChangeCurrentDelay:
5355 ret = 500;
5356 break;
5357 #endif
5358 case SH_DockWidget_ButtonsHaveFrame:
5359 ret = true;
5360 break;
5361 case SH_ToolButtonStyle:
5362 ret = 0;
5363 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
5364 ret = theme->themeHint(QPlatformTheme::ToolButtonStyle).toInt();
5365 break;
5366 case SH_RequestSoftwareInputPanel:
5367 ret = RSIP_OnMouseClick;
5368 break;
5369 case SH_ScrollBar_Transient:
5370 ret = false;
5371 break;
5372 case SH_Menu_SupportsSections:
5373 ret = false;
5374 break;
5375 #ifndef QT_NO_TOOLTIP
5376 case SH_ToolTip_WakeUpDelay:
5377 ret = 700;
5378 break;
5379 case SH_ToolTip_FallAsleepDelay:
5380 ret = 2000;
5381 break;
5382 #endif
5383 case SH_Widget_Animate:
5384 // TODO Qt6: move this code in the SH_Widget_Animation_Duration case
5385 // and replace false with 0 and true with 200.
5386 #if QT_CONFIG(treeview)
5387 if (qobject_cast<const QTreeView*>(widget)) {
5388 ret = false;
5389 } else
5390 #endif
5391 {
5392 ret = true;
5393 }
5394 break;
5395 case SH_Splitter_OpaqueResize:
5396 ret = true;
5397 break;
5398 #if QT_CONFIG(itemviews)
5399 case SH_ItemView_ScrollMode:
5400 ret = QAbstractItemView::ScrollPerItem;
5401 break;
5402 #endif
5403 case SH_TitleBar_ShowToolTipsOnButtons:
5404 ret = true;
5405 break;
5406 case SH_Widget_Animation_Duration:
5407 ret = styleHint(SH_Widget_Animate, opt, widget, hret) ? 200 : 0;
5408 break;
5409 case SH_ComboBox_AllowWheelScrolling:
5410 ret = true;
5411 break;
5412 case SH_SpinBox_ButtonsInsideFrame:
5413 ret = true;
5414 break;
5415 case SH_SpinBox_StepModifier:
5416 ret = Qt::ControlModifier;
5417 break;
5418 default:
5419 ret = 0;
5420 break;
5421 }
5422
5423 return ret;
5424 }
5425
5426 #if QT_CONFIG(imageformat_xpm)
cachedPixmapFromXPM(const char * const * xpm)5427 static QPixmap cachedPixmapFromXPM(const char * const *xpm)
5428 {
5429 QPixmap result;
5430 const QString tag = QString::asprintf("xpm:0x%p", static_cast<const void*>(xpm));
5431 if (!QPixmapCache::find(tag, &result)) {
5432 result = QPixmap(xpm);
5433 QPixmapCache::insert(tag, result);
5434 }
5435 return result;
5436 }
5437
titleBarMenuCachedPixmapFromXPM()5438 static inline QPixmap titleBarMenuCachedPixmapFromXPM() { return cachedPixmapFromXPM(qt_menu_xpm); }
5439 #endif // QT_CONFIG(imageformat_xpm)
5440
5441 #ifndef QT_NO_IMAGEFORMAT_PNG
clearText16IconPath()5442 static inline QString clearText16IconPath()
5443 {
5444 return QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png");
5445 }
5446 #endif // !QT_NO_IMAGEFORMAT_PNG
5447
5448 #if defined(Q_OS_WIN) || QT_CONFIG(imageformat_png)
clearTextIcon(bool rtl)5449 static QIcon clearTextIcon(bool rtl)
5450 {
5451 const QString directionalThemeName = rtl
5452 ? QStringLiteral("edit-clear-locationbar-ltr") : QStringLiteral("edit-clear-locationbar-rtl");
5453 if (QIcon::hasThemeIcon(directionalThemeName))
5454 return QIcon::fromTheme(directionalThemeName);
5455 const QString themeName = QStringLiteral("edit-clear");
5456 if (QIcon::hasThemeIcon(themeName))
5457 return QIcon::fromTheme(themeName);
5458
5459 QIcon icon;
5460 #ifndef QT_NO_IMAGEFORMAT_PNG
5461 QPixmap clearText16(clearText16IconPath());
5462 Q_ASSERT(!clearText16.size().isEmpty());
5463 icon.addPixmap(clearText16);
5464 QPixmap clearText32(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-32.png"));
5465 Q_ASSERT(!clearText32.size().isEmpty());
5466 icon.addPixmap(clearText32);
5467 clearText32.setDevicePixelRatio(2); // The 32x32 pixmap can also be used for 16x16/devicePixelRatio=2
5468 icon.addPixmap(clearText32);
5469 #endif // !QT_NO_IMAGEFORMAT_PNG
5470 return icon;
5471 }
5472 #endif
5473
5474 /*! \reimp */
standardPixmap(StandardPixmap sp,const QStyleOption * option,const QWidget * widget) const5475 QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
5476 const QWidget *widget) const
5477 {
5478 const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QGuiApplication::isRightToLeft());
5479 #ifdef QT_NO_IMAGEFORMAT_PNG
5480 Q_UNUSED(widget);
5481 Q_UNUSED(sp);
5482 #else
5483 QPixmap pixmap;
5484
5485 if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
5486 switch (sp) {
5487 case SP_DialogYesButton:
5488 case SP_DialogOkButton:
5489 pixmap = QIcon::fromTheme(QLatin1String("dialog-ok")).pixmap(16);
5490 break;
5491 case SP_DialogApplyButton:
5492 pixmap = QIcon::fromTheme(QLatin1String("dialog-ok-apply")).pixmap(16);
5493 break;
5494 case SP_DialogDiscardButton:
5495 pixmap = QIcon::fromTheme(QLatin1String("edit-delete")).pixmap(16);
5496 break;
5497 case SP_DialogCloseButton:
5498 pixmap = QIcon::fromTheme(QLatin1String("dialog-close")).pixmap(16);
5499 break;
5500 case SP_DirHomeIcon:
5501 pixmap = QIcon::fromTheme(QLatin1String("user-home")).pixmap(16);
5502 break;
5503 case SP_MessageBoxInformation:
5504 pixmap = QIcon::fromTheme(QLatin1String("messagebox_info")).pixmap(16);
5505 break;
5506 case SP_MessageBoxWarning:
5507 pixmap = QIcon::fromTheme(QLatin1String("messagebox_warning")).pixmap(16);
5508 break;
5509 case SP_MessageBoxCritical:
5510 pixmap = QIcon::fromTheme(QLatin1String("messagebox_critical")).pixmap(16);
5511 break;
5512 case SP_MessageBoxQuestion:
5513 pixmap = QIcon::fromTheme(QLatin1String("help")).pixmap(16);
5514 break;
5515 case SP_DialogOpenButton:
5516 case SP_DirOpenIcon:
5517 pixmap = QIcon::fromTheme(QLatin1String("folder-open")).pixmap(16);
5518 break;
5519 case SP_FileIcon:
5520 pixmap = QIcon::fromTheme(QLatin1String("text-x-generic"),
5521 QIcon::fromTheme(QLatin1String("empty"))).pixmap(16);
5522 break;
5523 case SP_DirClosedIcon:
5524 case SP_DirIcon:
5525 pixmap = QIcon::fromTheme(QLatin1String("folder")).pixmap(16);
5526 break;
5527 case SP_DriveFDIcon:
5528 pixmap = QIcon::fromTheme(QLatin1String("media-floppy"),
5529 QIcon::fromTheme(QLatin1String("3floppy_unmount"))).pixmap(16);
5530 break;
5531 case SP_ComputerIcon:
5532 pixmap = QIcon::fromTheme(QLatin1String("computer"),
5533 QIcon::fromTheme(QLatin1String("system"))).pixmap(16);
5534 break;
5535 case SP_DesktopIcon:
5536 pixmap = QIcon::fromTheme(QLatin1String("user-desktop"),
5537 QIcon::fromTheme(QLatin1String("desktop"))).pixmap(16);
5538 break;
5539 case SP_TrashIcon:
5540 pixmap = QIcon::fromTheme(QLatin1String("user-trash"),
5541 QIcon::fromTheme(QLatin1String("trashcan_empty"))).pixmap(16);
5542 break;
5543 case SP_DriveCDIcon:
5544 case SP_DriveDVDIcon:
5545 pixmap = QIcon::fromTheme(QLatin1String("media-optical"),
5546 QIcon::fromTheme(QLatin1String("cdrom_unmount"))).pixmap(16);
5547 break;
5548 case SP_DriveHDIcon:
5549 pixmap = QIcon::fromTheme(QLatin1String("drive-harddisk"),
5550 QIcon::fromTheme(QLatin1String("hdd_unmount"))).pixmap(16);
5551 break;
5552 case SP_FileDialogToParent:
5553 pixmap = QIcon::fromTheme(QLatin1String("go-up"),
5554 QIcon::fromTheme(QLatin1String("up"))).pixmap(16);
5555 break;
5556 case SP_FileDialogNewFolder:
5557 pixmap = QIcon::fromTheme(QLatin1String("folder_new")).pixmap(16);
5558 break;
5559 case SP_ArrowUp:
5560 pixmap = QIcon::fromTheme(QLatin1String("go-up"),
5561 QIcon::fromTheme(QLatin1String("up"))).pixmap(16);
5562 break;
5563 case SP_ArrowDown:
5564 pixmap = QIcon::fromTheme(QLatin1String("go-down"),
5565 QIcon::fromTheme(QLatin1String("down"))).pixmap(16);
5566 break;
5567 case SP_ArrowRight:
5568 pixmap = QIcon::fromTheme(QLatin1String("go-next"),
5569 QIcon::fromTheme(QLatin1String("forward"))).pixmap(16);
5570 break;
5571 case SP_ArrowLeft:
5572 pixmap = QIcon::fromTheme(QLatin1String("go-previous"),
5573 QIcon::fromTheme(QLatin1String("back"))).pixmap(16);
5574 break;
5575 case SP_FileDialogDetailedView:
5576 pixmap = QIcon::fromTheme(QLatin1String("view_detailed")).pixmap(16);
5577 break;
5578 case SP_FileDialogListView:
5579 pixmap = QIcon::fromTheme(QLatin1String("view_icon")).pixmap(16);
5580 break;
5581 case SP_BrowserReload:
5582 pixmap = QIcon::fromTheme(QLatin1String("reload")).pixmap(16);
5583 break;
5584 case SP_BrowserStop:
5585 pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(16);
5586 break;
5587 case SP_MediaPlay:
5588 pixmap = QIcon::fromTheme(QLatin1String("media-playback-start")).pixmap(16);
5589 break;
5590 case SP_MediaPause:
5591 pixmap = QIcon::fromTheme(QLatin1String("media-playback-pause")).pixmap(16);
5592 break;
5593 case SP_MediaStop:
5594 pixmap = QIcon::fromTheme(QLatin1String("media-playback-stop")).pixmap(16);
5595 break;
5596 case SP_MediaSeekForward:
5597 pixmap = QIcon::fromTheme(QLatin1String("media-seek-forward")).pixmap(16);
5598 break;
5599 case SP_MediaSeekBackward:
5600 pixmap = QIcon::fromTheme(QLatin1String("media-seek-backward")).pixmap(16);
5601 break;
5602 case SP_MediaSkipForward:
5603 pixmap = QIcon::fromTheme(QLatin1String("media-skip-forward")).pixmap(16);
5604 break;
5605 case SP_MediaSkipBackward:
5606 pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
5607 break;
5608 case SP_DialogResetButton:
5609 pixmap = QIcon::fromTheme(QLatin1String("edit-clear")).pixmap(24);
5610 break;
5611 case SP_DialogHelpButton:
5612 pixmap = QIcon::fromTheme(QLatin1String("help-contents")).pixmap(24);
5613 break;
5614 case SP_DialogNoButton:
5615 case SP_DialogCancelButton:
5616 pixmap = QIcon::fromTheme(QLatin1String("dialog-cancel"),
5617 QIcon::fromTheme(QLatin1String("process-stop"))).pixmap(24);
5618 break;
5619 case SP_DialogSaveButton:
5620 pixmap = QIcon::fromTheme(QLatin1String("document-save")).pixmap(24);
5621 break;
5622 case SP_FileLinkIcon:
5623 pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16);
5624 if (!pixmap.isNull()) {
5625 QPixmap fileIcon = QIcon::fromTheme(QLatin1String("text-x-generic")).pixmap(16);
5626 if (fileIcon.isNull())
5627 fileIcon = QIcon::fromTheme(QLatin1String("empty")).pixmap(16);
5628 if (!fileIcon.isNull()) {
5629 QPainter painter(&fileIcon);
5630 painter.drawPixmap(0, 0, 16, 16, pixmap);
5631 return fileIcon;
5632 }
5633 }
5634 break;
5635 case SP_DirLinkIcon:
5636 pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16);
5637 if (!pixmap.isNull()) {
5638 QPixmap dirIcon = QIcon::fromTheme(QLatin1String("folder")).pixmap(16);
5639 if (!dirIcon.isNull()) {
5640 QPainter painter(&dirIcon);
5641 painter.drawPixmap(0, 0, 16, 16, pixmap);
5642 return dirIcon;
5643 }
5644 }
5645 break;
5646 case SP_LineEditClearButton:
5647 pixmap = clearTextIcon(rtl).pixmap(16);
5648 break;
5649 default:
5650 break;
5651 }
5652 }
5653
5654 if (!pixmap.isNull())
5655 return pixmap;
5656 #endif //QT_NO_IMAGEFORMAT_PNG
5657 switch (sp) {
5658 #ifndef QT_NO_IMAGEFORMAT_XPM
5659 case SP_ToolBarHorizontalExtensionButton:
5660 if (rtl) {
5661 QImage im(tb_extension_arrow_h_xpm);
5662 im = im.convertToFormat(QImage::Format_ARGB32).mirrored(true, false);
5663 return QPixmap::fromImage(im);
5664 }
5665 return cachedPixmapFromXPM(tb_extension_arrow_h_xpm);
5666 case SP_ToolBarVerticalExtensionButton:
5667 return cachedPixmapFromXPM(tb_extension_arrow_v_xpm);
5668 case SP_FileDialogStart:
5669 return cachedPixmapFromXPM(filedialog_start_xpm);
5670 case SP_FileDialogEnd:
5671 return cachedPixmapFromXPM(filedialog_end_xpm);
5672 #endif
5673 #ifndef QT_NO_IMAGEFORMAT_PNG
5674 case SP_CommandLink:
5675 case SP_ArrowForward:
5676 if (rtl)
5677 return proxy()->standardPixmap(SP_ArrowLeft, option, widget);
5678 return proxy()->standardPixmap(SP_ArrowRight, option, widget);
5679 case SP_ArrowBack:
5680 if (rtl)
5681 return proxy()->standardPixmap(SP_ArrowRight, option, widget);
5682 return proxy()->standardPixmap(SP_ArrowLeft, option, widget);
5683 case SP_ArrowLeft:
5684 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png"));
5685 case SP_ArrowRight:
5686 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png"));
5687 case SP_ArrowUp:
5688 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png"));
5689 case SP_ArrowDown:
5690 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png"));
5691 case SP_FileDialogToParent:
5692 return proxy()->standardPixmap(SP_ArrowUp, option, widget);
5693 case SP_FileDialogNewFolder:
5694 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"));
5695 case SP_FileDialogDetailedView:
5696 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png"));
5697 case SP_FileDialogInfoView:
5698 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png"));
5699 case SP_FileDialogContentsView:
5700 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png"));
5701 case SP_FileDialogListView:
5702 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png"));
5703 case SP_FileDialogBack:
5704 return proxy()->standardPixmap(SP_ArrowBack, option, widget);
5705 case SP_DriveHDIcon:
5706 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/harddrive-16.png"));
5707 case SP_TrashIcon:
5708 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png"));
5709 case SP_DriveFDIcon:
5710 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/floppy-16.png"));
5711 case SP_DriveNetIcon:
5712 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/networkdrive-16.png"));
5713 case SP_DesktopIcon:
5714 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/desktop-16.png"));
5715 case SP_ComputerIcon:
5716 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/computer-16.png"));
5717 case SP_DriveCDIcon:
5718 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png"));
5719 case SP_DriveDVDIcon:
5720 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png"));
5721 case SP_DirHomeIcon:
5722 case SP_DirOpenIcon:
5723 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png"));
5724 case SP_DirIcon:
5725 case SP_DirClosedIcon:
5726 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png"));
5727 case SP_DirLinkIcon:
5728 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirlink-16.png"));
5729 case SP_FileIcon:
5730 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
5731 case SP_FileLinkIcon:
5732 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png"));
5733 case SP_DialogOkButton:
5734 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png"));
5735 case SP_DialogCancelButton:
5736 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png"));
5737 case SP_DialogHelpButton:
5738 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png"));
5739 case SP_DialogOpenButton:
5740 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"));
5741 case SP_DialogSaveButton:
5742 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"));
5743 case SP_DialogCloseButton:
5744 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"));
5745 case SP_DialogApplyButton:
5746 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png"));
5747 case SP_DialogResetButton:
5748 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png"));
5749 case SP_DialogDiscardButton:
5750 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png"));
5751 case SP_DialogYesButton:
5752 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png"));
5753 case SP_DialogNoButton:
5754 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png"));
5755 case SP_BrowserReload:
5756 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png"));
5757 case SP_BrowserStop:
5758 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png"));
5759 case SP_MediaPlay:
5760 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png"));
5761 case SP_MediaPause:
5762 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png"));
5763 case SP_MediaStop:
5764 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png"));
5765 case SP_MediaSeekForward:
5766 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png"));
5767 case SP_MediaSeekBackward:
5768 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png"));
5769 case SP_MediaSkipForward:
5770 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png"));
5771 case SP_MediaSkipBackward:
5772 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png"));
5773 case SP_MediaVolume:
5774 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"));
5775 case SP_MediaVolumeMuted:
5776 return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"));
5777 case SP_LineEditClearButton:
5778 return QPixmap(clearText16IconPath());
5779 #endif // QT_NO_IMAGEFORMAT_PNG
5780 default:
5781 break;
5782 }
5783
5784 #ifndef QT_NO_IMAGEFORMAT_XPM
5785 switch (sp) {
5786 case SP_TitleBarMenuButton:
5787 return titleBarMenuCachedPixmapFromXPM();
5788 case SP_TitleBarShadeButton:
5789 return cachedPixmapFromXPM(qt_shade_xpm);
5790 case SP_TitleBarUnshadeButton:
5791 return cachedPixmapFromXPM(qt_unshade_xpm);
5792 case SP_TitleBarNormalButton:
5793 return cachedPixmapFromXPM(qt_normalizeup_xpm);
5794 case SP_TitleBarMinButton:
5795 return cachedPixmapFromXPM(qt_minimize_xpm);
5796 case SP_TitleBarMaxButton:
5797 return cachedPixmapFromXPM(qt_maximize_xpm);
5798 case SP_TitleBarCloseButton:
5799 return cachedPixmapFromXPM(qt_close_xpm);
5800 case SP_TitleBarContextHelpButton:
5801 return cachedPixmapFromXPM(qt_help_xpm);
5802 case SP_DockWidgetCloseButton:
5803 return cachedPixmapFromXPM(dock_widget_close_xpm);
5804 case SP_MessageBoxInformation:
5805 return cachedPixmapFromXPM(information_xpm);
5806 case SP_MessageBoxWarning:
5807 return cachedPixmapFromXPM(warning_xpm);
5808 case SP_MessageBoxCritical:
5809 return cachedPixmapFromXPM(critical_xpm);
5810 case SP_MessageBoxQuestion:
5811 return cachedPixmapFromXPM(question_xpm);
5812 default:
5813 break;
5814 }
5815 #endif //QT_NO_IMAGEFORMAT_XPM
5816
5817 #if !QT_CONFIG(imageformat_png) && !QT_CONFIG(imageformat_xpm) && !QT_CONFIG(imageformat_png)
5818 Q_UNUSED(rtl);
5819 #endif
5820
5821 return QPixmap();
5822 }
5823
5824 #if QT_CONFIG(imageformat_png)
iconResourcePrefix()5825 static inline QString iconResourcePrefix() { return QStringLiteral(":/qt-project.org/styles/commonstyle/images/"); }
iconPngSuffix()5826 static inline QString iconPngSuffix() { return QStringLiteral(".png"); }
5827
addIconFiles(const QString & prefix,const int sizes[],size_t count,QIcon & icon)5828 static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon)
5829 {
5830 for (size_t i = 0; i < count; ++i)
5831 icon.addFile(prefix + QString::number(sizes[i]) + iconPngSuffix());
5832 }
5833
5834 static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64};
5835 static const int titleBarSizes[] = {16, 32, 48};
5836 static const int toolBarExtHSizes[] = {8, 16, 32};
5837 static const int toolBarExtVSizes[] = {5, 10, 20};
5838 #endif // imageformat_png
5839
5840 /*!
5841 \internal
5842 */
standardIcon(StandardPixmap standardIcon,const QStyleOption * option,const QWidget * widget) const5843 QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
5844 const QWidget *widget) const
5845 {
5846 QIcon icon;
5847 const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QGuiApplication::isRightToLeft());
5848
5849 #ifdef Q_OS_WIN
5850 switch (standardIcon) {
5851 case SP_DriveCDIcon:
5852 case SP_DriveDVDIcon:
5853 case SP_DriveNetIcon:
5854 case SP_DriveHDIcon:
5855 case SP_DriveFDIcon:
5856 case SP_FileIcon:
5857 case SP_FileLinkIcon:
5858 case SP_DesktopIcon:
5859 case SP_ComputerIcon:
5860 case SP_VistaShield:
5861 case SP_MessageBoxInformation:
5862 case SP_MessageBoxWarning:
5863 case SP_MessageBoxCritical:
5864 case SP_MessageBoxQuestion:
5865 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
5866 QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
5867 for (int size = 16 ; size <= 32 ; size += 16) {
5868 QPixmap pixmap = theme->standardPixmap(sp, QSizeF(size, size));
5869 icon.addPixmap(pixmap, QIcon::Normal);
5870 }
5871 }
5872 break;
5873 case SP_DirIcon:
5874 case SP_DirLinkIcon:
5875 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
5876 QPlatformTheme::StandardPixmap spOff = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
5877 QPlatformTheme::StandardPixmap spOn = standardIcon == SP_DirIcon ? QPlatformTheme::DirOpenIcon :
5878 QPlatformTheme::DirLinkOpenIcon;
5879 for (int size = 16 ; size <= 32 ; size += 16) {
5880 QSizeF pixSize(size, size);
5881 QPixmap pixmap = theme->standardPixmap(spOff, pixSize);
5882 icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
5883 pixmap = theme->standardPixmap(spOn, pixSize);
5884 icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
5885 }
5886 }
5887 break;
5888 case SP_LineEditClearButton:
5889 icon = clearTextIcon(rtl);
5890 break;
5891 default:
5892 break;
5893 }
5894 if (!icon.isNull())
5895 return icon;
5896
5897 #endif
5898
5899 if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
5900 switch (standardIcon) {
5901 case SP_DirHomeIcon:
5902 icon = QIcon::fromTheme(QLatin1String("user-home"));
5903 break;
5904 case SP_MessageBoxInformation:
5905 icon = QIcon::fromTheme(QLatin1String("dialog-information"));
5906 break;
5907 case SP_MessageBoxWarning:
5908 icon = QIcon::fromTheme(QLatin1String("dialog-warning"));
5909 break;
5910 case SP_MessageBoxCritical:
5911 icon = QIcon::fromTheme(QLatin1String("dialog-error"));
5912 break;
5913 case SP_MessageBoxQuestion:
5914 icon = QIcon::fromTheme(QLatin1String("dialog-question"));
5915 break;
5916 case SP_DialogOpenButton:
5917 case SP_DirOpenIcon:
5918 icon = QIcon::fromTheme(QLatin1String("folder-open"));
5919 break;
5920 case SP_DialogSaveButton:
5921 icon = QIcon::fromTheme(QLatin1String("document-save"));
5922 break;
5923 case SP_DialogApplyButton:
5924 icon = QIcon::fromTheme(QLatin1String("dialog-ok-apply"));
5925 break;
5926 case SP_DialogYesButton:
5927 case SP_DialogOkButton:
5928 icon = QIcon::fromTheme(QLatin1String("dialog-ok"));
5929 break;
5930 case SP_DialogDiscardButton:
5931 icon = QIcon::fromTheme(QLatin1String("edit-delete"));
5932 break;
5933 case SP_DialogResetButton:
5934 icon = QIcon::fromTheme(QLatin1String("edit-clear"));
5935 break;
5936 case SP_DialogHelpButton:
5937 icon = QIcon::fromTheme(QLatin1String("help-contents"));
5938 break;
5939 case SP_FileIcon:
5940 icon = QIcon::fromTheme(QLatin1String("text-x-generic"));
5941 break;
5942 case SP_DirClosedIcon:
5943 case SP_DirIcon:
5944 icon = QIcon::fromTheme(QLatin1String("folder"));
5945 break;
5946 case SP_DriveFDIcon:
5947 icon = QIcon::fromTheme(QLatin1String("floppy_unmount"));
5948 break;
5949 case SP_ComputerIcon:
5950 icon = QIcon::fromTheme(QLatin1String("computer"),
5951 QIcon::fromTheme(QLatin1String("system")));
5952 break;
5953 case SP_DesktopIcon:
5954 icon = QIcon::fromTheme(QLatin1String("user-desktop"));
5955 break;
5956 case SP_TrashIcon:
5957 icon = QIcon::fromTheme(QLatin1String("user-trash"));
5958 break;
5959 case SP_DriveCDIcon:
5960 case SP_DriveDVDIcon:
5961 icon = QIcon::fromTheme(QLatin1String("media-optical"));
5962 break;
5963 case SP_DriveHDIcon:
5964 icon = QIcon::fromTheme(QLatin1String("drive-harddisk"));
5965 break;
5966 case SP_FileDialogToParent:
5967 icon = QIcon::fromTheme(QLatin1String("go-up"));
5968 break;
5969 case SP_FileDialogNewFolder:
5970 icon = QIcon::fromTheme(QLatin1String("folder-new"));
5971 break;
5972 case SP_ArrowUp:
5973 icon = QIcon::fromTheme(QLatin1String("go-up"));
5974 break;
5975 case SP_ArrowDown:
5976 icon = QIcon::fromTheme(QLatin1String("go-down"));
5977 break;
5978 case SP_ArrowRight:
5979 icon = QIcon::fromTheme(QLatin1String("go-next"));
5980 break;
5981 case SP_ArrowLeft:
5982 icon = QIcon::fromTheme(QLatin1String("go-previous"));
5983 break;
5984 case SP_DialogNoButton:
5985 case SP_DialogCancelButton:
5986 icon = QIcon::fromTheme(QLatin1String("dialog-cancel"),
5987 QIcon::fromTheme(QLatin1String("process-stop")));
5988 break;
5989 case SP_DialogCloseButton:
5990 icon = QIcon::fromTheme(QLatin1String("window-close"));
5991 break;
5992 case SP_FileDialogDetailedView:
5993 icon = QIcon::fromTheme(QLatin1String("view-list-details"));
5994 break;
5995 case SP_FileDialogListView:
5996 icon = QIcon::fromTheme(QLatin1String("view-list-icons"));
5997 break;
5998 case SP_BrowserReload:
5999 icon = QIcon::fromTheme(QLatin1String("view-refresh"));
6000 break;
6001 case SP_BrowserStop:
6002 icon = QIcon::fromTheme(QLatin1String("process-stop"));
6003 break;
6004 case SP_MediaPlay:
6005 icon = QIcon::fromTheme(QLatin1String("media-playback-start"));
6006 break;
6007 case SP_MediaPause:
6008 icon = QIcon::fromTheme(QLatin1String("media-playback-pause"));
6009 break;
6010 case SP_MediaStop:
6011 icon = QIcon::fromTheme(QLatin1String("media-playback-stop"));
6012 break;
6013 case SP_MediaSeekForward:
6014 icon = QIcon::fromTheme(QLatin1String("media-seek-forward"));
6015 break;
6016 case SP_MediaSeekBackward:
6017 icon = QIcon::fromTheme(QLatin1String("media-seek-backward"));
6018 break;
6019 case SP_MediaSkipForward:
6020 icon = QIcon::fromTheme(QLatin1String("media-skip-forward"));
6021 break;
6022 case SP_MediaSkipBackward:
6023 icon = QIcon::fromTheme(QLatin1String("media-skip-backward"));
6024 break;
6025 case SP_MediaVolume:
6026 icon = QIcon::fromTheme(QLatin1String("audio-volume-medium"));
6027 break;
6028 case SP_MediaVolumeMuted:
6029 icon = QIcon::fromTheme(QLatin1String("audio-volume-muted"));
6030 break;
6031 case SP_ArrowForward:
6032 if (rtl)
6033 return QCommonStyle::standardIcon(SP_ArrowLeft, option, widget);
6034 return QCommonStyle::standardIcon(SP_ArrowRight, option, widget);
6035 case SP_ArrowBack:
6036 if (rtl)
6037 return QCommonStyle::standardIcon(SP_ArrowRight, option, widget);
6038 return QCommonStyle::standardIcon(SP_ArrowLeft, option, widget);
6039 case SP_FileLinkIcon:
6040 {
6041 QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link"));
6042 if (!linkIcon.isNull()) {
6043 QIcon baseIcon = QCommonStyle::standardIcon(SP_FileIcon, option, widget);
6044 const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off);
6045 for (int i = 0 ; i < sizes.size() ; ++i) {
6046 int size = sizes[i].width();
6047 QPixmap basePixmap = baseIcon.pixmap(qt_getWindow(widget), QSize(size, size));
6048 QPixmap linkPixmap = linkIcon.pixmap(qt_getWindow(widget), QSize(size / 2, size / 2));
6049 QPainter painter(&basePixmap);
6050 painter.drawPixmap(size/2, size/2, linkPixmap);
6051 icon.addPixmap(basePixmap);
6052 }
6053 }
6054 }
6055 break;
6056 case SP_DirLinkIcon:
6057 {
6058 QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link"));
6059 if (!linkIcon.isNull()) {
6060 QIcon baseIcon = QCommonStyle::standardIcon(SP_DirIcon, option, widget);
6061 const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off);
6062 for (int i = 0 ; i < sizes.size() ; ++i) {
6063 int size = sizes[i].width();
6064 QPixmap basePixmap = baseIcon.pixmap(qt_getWindow(widget), QSize(size, size));
6065 QPixmap linkPixmap = linkIcon.pixmap(qt_getWindow(widget), QSize(size / 2, size / 2));
6066 QPainter painter(&basePixmap);
6067 painter.drawPixmap(size/2, size/2, linkPixmap);
6068 icon.addPixmap(basePixmap);
6069 }
6070 }
6071 }
6072 break;
6073 default:
6074 break;
6075 }
6076 } // if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty())
6077
6078 if (!icon.isNull())
6079 return icon;
6080
6081 #if defined(Q_OS_MAC)
6082 if (QGuiApplication::desktopSettingsAware()) {
6083 switch (standardIcon) {
6084 case SP_DirIcon: {
6085 // A rather special case
6086 QIcon closeIcon = QCommonStyle::standardIcon(SP_DirClosedIcon, option, widget);
6087 QIcon openIcon = QCommonStyle::standardIcon(SP_DirOpenIcon, option, widget);
6088 closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
6089 closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
6090 closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
6091 closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
6092 return closeIcon;
6093 }
6094
6095 case SP_TitleBarNormalButton:
6096 case SP_TitleBarCloseButton: {
6097 QIcon titleBarIcon;
6098 if (standardIcon == SP_TitleBarCloseButton) {
6099 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-16.png"));
6100 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
6101 } else {
6102 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-16.png"));
6103 titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
6104 }
6105 return titleBarIcon;
6106 }
6107
6108 case SP_MessageBoxQuestion:
6109 case SP_MessageBoxInformation:
6110 case SP_MessageBoxWarning:
6111 case SP_MessageBoxCritical:
6112 case SP_DesktopIcon:
6113 case SP_TrashIcon:
6114 case SP_ComputerIcon:
6115 case SP_DriveFDIcon:
6116 case SP_DriveHDIcon:
6117 case SP_DriveCDIcon:
6118 case SP_DriveDVDIcon:
6119 case SP_DriveNetIcon:
6120 case SP_DirOpenIcon:
6121 case SP_DirClosedIcon:
6122 case SP_DirLinkIcon:
6123 case SP_FileLinkIcon:
6124 case SP_FileIcon:
6125 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
6126 QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
6127 QIcon retIcon;
6128 const QList<QSize> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<QSize> >();
6129 for (const QSize &size : sizes) {
6130 QPixmap mainIcon;
6131 const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size.width());
6132 if (standardIcon >= QStyle::SP_CustomBase) {
6133 mainIcon = theme->standardPixmap(sp, QSizeF(size));
6134 } else if (QPixmapCache::find(cacheKey, &mainIcon) == false) {
6135 mainIcon = theme->standardPixmap(sp, QSizeF(size));
6136 QPixmapCache::insert(cacheKey, mainIcon);
6137 }
6138
6139 retIcon.addPixmap(mainIcon);
6140 }
6141 if (!retIcon.isNull())
6142 return retIcon;
6143 }
6144
6145 default:
6146 break;
6147 }
6148 } // if (QGuiApplication::desktopSettingsAware())
6149 #endif // Q_OS_MAC
6150
6151 switch (standardIcon) {
6152 #ifndef QT_NO_IMAGEFORMAT_PNG
6153 case SP_TitleBarMinButton:
6154 addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-min-"),
6155 titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
6156 break;
6157 case SP_TitleBarMaxButton:
6158 addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-max-"),
6159 titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
6160 break;
6161 case SP_TitleBarShadeButton:
6162 addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-shade-"),
6163 titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
6164
6165 break;
6166 case SP_TitleBarUnshadeButton:
6167 addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-unshade-"),
6168 titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
6169 break;
6170 case SP_TitleBarContextHelpButton:
6171 addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-contexthelp-"),
6172 titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
6173 break;
6174 case SP_FileDialogNewFolder:
6175 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16));
6176 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32));
6177 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-128.png"), QSize(128, 128));
6178 break;
6179 case SP_FileDialogBack:
6180 return QCommonStyle::standardIcon(SP_ArrowBack, option, widget);
6181 case SP_FileDialogToParent:
6182 return QCommonStyle::standardIcon(SP_ArrowUp, option, widget);
6183 case SP_FileDialogDetailedView:
6184 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png"), QSize(16, 16));
6185 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-32.png"), QSize(32, 32));
6186 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-128.png"), QSize(128, 128));
6187 break;
6188 case SP_FileDialogInfoView:
6189 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png"), QSize(16, 16));
6190 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-32.png"), QSize(32, 32));
6191 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-128.png"), QSize(128, 128));
6192 break;
6193 case SP_FileDialogContentsView:
6194 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png"), QSize(16, 16));
6195 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-32.png"), QSize(32, 32));
6196 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-128.png"), QSize(128, 128));
6197 break;
6198 case SP_FileDialogListView:
6199 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png"), QSize(16, 16));
6200 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-32.png"), QSize(32, 32));
6201 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-128.png"), QSize(128, 128));
6202 break;
6203 case SP_DialogOkButton:
6204 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png"), QSize(16, 16));
6205 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-32.png"), QSize(32, 32));
6206 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-128.png"), QSize(128, 128));
6207 break;
6208 case SP_DialogCancelButton:
6209 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png"), QSize(16, 16));
6210 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-32.png"), QSize(32, 32));
6211 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-128.png"), QSize(128, 128));
6212 break;
6213 case SP_DialogHelpButton:
6214 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png"), QSize(16, 16));
6215 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-32.png"), QSize(32, 32));
6216 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-128.png"), QSize(128, 128));
6217 break;
6218 case SP_DialogOpenButton:
6219 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"), QSize(16, 16));
6220 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-32.png"), QSize(32, 32));
6221 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-128.png"), QSize(128, 128));
6222 break;
6223 case SP_DialogSaveButton:
6224 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"), QSize(16, 16));
6225 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-32.png"), QSize(32, 32));
6226 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-128.png"), QSize(128, 128));
6227 break;
6228 case SP_DialogCloseButton:
6229 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"), QSize(16, 16));
6230 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-32.png"), QSize(32, 32));
6231 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-128.png"), QSize(128, 128));
6232 break;
6233 case SP_DialogApplyButton:
6234 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png"), QSize(16, 16));
6235 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-32.png"), QSize(32, 32));
6236 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-128.png"), QSize(128, 128));
6237 break;
6238 case SP_DialogResetButton:
6239 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png"), QSize(16, 16));
6240 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-32.png"), QSize(32, 32));
6241 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-128.png"), QSize(128, 128));
6242 break;
6243 case SP_DialogDiscardButton:
6244 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png"), QSize(16, 16));
6245 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-32.png"), QSize(32, 32));
6246 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-128.png"), QSize(128, 128));
6247 break;
6248 case SP_DialogYesButton:
6249 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png"), QSize(16, 16));
6250 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-32.png"), QSize(32, 32));
6251 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-128.png"), QSize(128, 128));
6252 break;
6253 case SP_DialogNoButton:
6254 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png"), QSize(16, 16));
6255 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-32.png"), QSize(32, 32));
6256 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-128.png"), QSize(128, 128));
6257 break;
6258 case SP_ArrowForward:
6259 if (rtl)
6260 return QCommonStyle::standardIcon(SP_ArrowLeft, option, widget);
6261 return QCommonStyle::standardIcon(SP_ArrowRight, option, widget);
6262 case SP_ArrowBack:
6263 if (rtl)
6264 return QCommonStyle::standardIcon(SP_ArrowRight, option, widget);
6265 return QCommonStyle::standardIcon(SP_ArrowLeft, option, widget);
6266 case SP_ArrowLeft:
6267 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png"), QSize(16, 16));
6268 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-32.png"), QSize(32, 32));
6269 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-128.png"), QSize(128, 128));
6270 break;
6271 case SP_ArrowRight:
6272 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png"), QSize(16, 16));
6273 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-32.png"), QSize(32, 32));
6274 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-128.png"), QSize(128, 128));
6275 break;
6276 case SP_ArrowUp:
6277 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png"), QSize(16, 16));
6278 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-32.png"), QSize(32, 32));
6279 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-128.png"), QSize(128, 128));
6280 break;
6281 case SP_ArrowDown:
6282 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png"), QSize(16, 16));
6283 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-32.png"), QSize(32, 32));
6284 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-128.png"), QSize(128, 128));
6285 break;
6286 case SP_DirHomeIcon:
6287 case SP_DirIcon:
6288 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png"),
6289 QSize(), QIcon::Normal, QIcon::Off);
6290 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png"),
6291 QSize(), QIcon::Normal, QIcon::On);
6292 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-32.png"),
6293 QSize(32, 32), QIcon::Normal, QIcon::Off);
6294 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-32.png"),
6295 QSize(32, 32), QIcon::Normal, QIcon::On);
6296 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-128.png"),
6297 QSize(128, 128), QIcon::Normal, QIcon::Off);
6298 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-128.png"),
6299 QSize(128, 128), QIcon::Normal, QIcon::On);
6300 break;
6301 case SP_DriveCDIcon:
6302 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png"), QSize(16, 16));
6303 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-32.png"), QSize(32, 32));
6304 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-128.png"), QSize(128, 128));
6305 break;
6306 case SP_DriveDVDIcon:
6307 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png"), QSize(16, 16));
6308 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-32.png"), QSize(32, 32));
6309 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-128.png"), QSize(128, 128));
6310 break;
6311 case SP_FileIcon:
6312 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"), QSize(16, 16));
6313 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-32.png"), QSize(32, 32));
6314 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-128.png"), QSize(128, 128));
6315 break;
6316 case SP_FileLinkIcon:
6317 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png"), QSize(16, 16));
6318 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-32.png"), QSize(32, 32));
6319 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-128.png"), QSize(128, 128));
6320 break;
6321 case SP_TrashIcon:
6322 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png"), QSize(16, 16));
6323 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-32.png"), QSize(32, 32));
6324 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-128.png"), QSize(128, 128));
6325 break;
6326 case SP_BrowserReload:
6327 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png"), QSize(24, 24));
6328 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-32.png"), QSize(32, 32));
6329 break;
6330 case SP_BrowserStop:
6331 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png"), QSize(24, 24));
6332 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-32.png"), QSize(32, 32));
6333 break;
6334 case SP_MediaPlay:
6335 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-16.png"), QSize(16, 16));
6336 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png"), QSize(32, 32));
6337 break;
6338 case SP_MediaPause:
6339 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-16.png"), QSize(16, 16));
6340 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png"), QSize(32, 32));
6341 break;
6342 case SP_MediaStop:
6343 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-16.png"), QSize(16, 16));
6344 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png"), QSize(32, 32));
6345 break;
6346 case SP_MediaSeekForward:
6347 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-16.png"), QSize(16, 16));
6348 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png"), QSize(32, 32));
6349 break;
6350 case SP_MediaSeekBackward:
6351 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-16.png"), QSize(16, 16));
6352 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png"), QSize(32, 32));
6353 break;
6354 case SP_MediaSkipForward:
6355 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-16.png"), QSize(16, 16));
6356 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png"), QSize(32, 32));
6357 break;
6358 case SP_MediaSkipBackward:
6359 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-16.png"), QSize(16, 16));
6360 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png"), QSize(32, 32));
6361 break;
6362 case SP_MediaVolume:
6363 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"), QSize(16, 16));
6364 break;
6365 case SP_MediaVolumeMuted:
6366 icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"), QSize(16, 16));
6367 break;
6368 case SP_TitleBarCloseButton:
6369 addIconFiles(iconResourcePrefix() + QStringLiteral("closedock-"),
6370 dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon);
6371 break;
6372 case SP_TitleBarMenuButton:
6373 # ifndef QT_NO_IMAGEFORMAT_XPM
6374 icon.addPixmap(titleBarMenuCachedPixmapFromXPM());
6375 # endif
6376 icon.addFile(QLatin1String(":/qt-project.org/qmessagebox/images/qtlogo-64.png"));
6377 break;
6378 case SP_TitleBarNormalButton:
6379 addIconFiles(iconResourcePrefix() + QStringLiteral("normalizedockup-"),
6380 dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon);
6381 break;
6382 case SP_ToolBarHorizontalExtensionButton: {
6383 QString prefix = iconResourcePrefix() + QStringLiteral("toolbar-ext-h-");
6384 if (rtl)
6385 prefix += QStringLiteral("rtl-");
6386 addIconFiles(prefix, toolBarExtHSizes, sizeof(toolBarExtHSizes)/sizeof(toolBarExtHSizes[0]), icon);
6387 }
6388 break;
6389 case SP_ToolBarVerticalExtensionButton:
6390 addIconFiles(iconResourcePrefix() + QStringLiteral("toolbar-ext-v-"),
6391 toolBarExtVSizes, sizeof(toolBarExtVSizes)/sizeof(toolBarExtVSizes[0]), icon);
6392 break;
6393 #endif // QT_NO_IMAGEFORMAT_PNG
6394 default:
6395 icon.addPixmap(proxy()->standardPixmap(standardIcon, option, widget));
6396 break;
6397 }
6398 return icon;
6399 }
6400
qt_intensity(uint r,uint g,uint b)6401 static inline uint qt_intensity(uint r, uint g, uint b)
6402 {
6403 // 30% red, 59% green, 11% blue
6404 return (77 * r + 150 * g + 28 * b) / 255;
6405 }
6406
6407 /*! \reimp */
generatedIconPixmap(QIcon::Mode iconMode,const QPixmap & pixmap,const QStyleOption * opt) const6408 QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
6409 const QStyleOption *opt) const
6410 {
6411 switch (iconMode) {
6412 case QIcon::Disabled: {
6413 QImage im = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
6414
6415 // Create a colortable based on the background (black -> bg -> white)
6416 QColor bg = opt->palette.color(QPalette::Disabled, QPalette::Window);
6417 int red = bg.red();
6418 int green = bg.green();
6419 int blue = bg.blue();
6420 uchar reds[256], greens[256], blues[256];
6421 for (int i=0; i<128; ++i) {
6422 reds[i] = uchar((red * (i<<1)) >> 8);
6423 greens[i] = uchar((green * (i<<1)) >> 8);
6424 blues[i] = uchar((blue * (i<<1)) >> 8);
6425 }
6426 for (int i=0; i<128; ++i) {
6427 reds[i+128] = uchar(qMin(red + (i << 1), 255));
6428 greens[i+128] = uchar(qMin(green + (i << 1), 255));
6429 blues[i+128] = uchar(qMin(blue + (i << 1), 255));
6430 }
6431
6432 int intensity = qt_intensity(red, green, blue);
6433 const int factor = 191;
6434
6435 // High intensity colors needs dark shifting in the color table, while
6436 // low intensity colors needs light shifting. This is to increase the
6437 // perceived contrast.
6438 if ((red - factor > green && red - factor > blue)
6439 || (green - factor > red && green - factor > blue)
6440 || (blue - factor > red && blue - factor > green))
6441 intensity = qMin(255, intensity + 91);
6442 else if (intensity <= 128)
6443 intensity -= 51;
6444
6445 for (int y=0; y<im.height(); ++y) {
6446 QRgb *scanLine = (QRgb*)im.scanLine(y);
6447 for (int x=0; x<im.width(); ++x) {
6448 QRgb pixel = *scanLine;
6449 // Calculate color table index, taking intensity adjustment
6450 // and a magic offset into account.
6451 uint ci = uint(qGray(pixel)/3 + (130 - intensity / 3));
6452 *scanLine = qRgba(reds[ci], greens[ci], blues[ci], qAlpha(pixel));
6453 ++scanLine;
6454 }
6455 }
6456
6457 return QPixmap::fromImage(im);
6458 }
6459 case QIcon::Selected: {
6460 QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
6461 QColor color = opt->palette.color(QPalette::Normal, QPalette::Highlight);
6462 color.setAlphaF(qreal(0.3));
6463 QPainter painter(&img);
6464 painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
6465 painter.fillRect(0, 0, img.width(), img.height(), color);
6466 painter.end();
6467 return QPixmap::fromImage(img); }
6468 case QIcon::Active:
6469 return pixmap;
6470 default:
6471 break;
6472 }
6473 return pixmap;
6474 }
6475
6476 /*!
6477 \reimp
6478 */
layoutSpacing(QSizePolicy::ControlType,QSizePolicy::ControlType,Qt::Orientation,const QStyleOption *,const QWidget *) const6479 int QCommonStyle::layoutSpacing(QSizePolicy::ControlType /* control1 */, QSizePolicy::ControlType /* control2 */,
6480 Qt::Orientation /* orientation */, const QStyleOption * /* option */,
6481 const QWidget * /* widget */) const
6482 {
6483 return -1;
6484 }
6485
6486 /*!
6487 \reimp
6488 */
polish(QPalette & pal)6489 void QCommonStyle::polish(QPalette &pal)
6490 {
6491 QStyle::polish(pal);
6492 }
6493
6494 /*!
6495 \reimp
6496 */
polish(QWidget * widget)6497 void QCommonStyle::polish(QWidget *widget)
6498 {
6499 QStyle::polish(widget);
6500 }
6501
6502 /*!
6503 \reimp
6504 */
unpolish(QWidget * widget)6505 void QCommonStyle::unpolish(QWidget *widget)
6506 {
6507 QStyle::unpolish(widget);
6508 }
6509
6510 /*!
6511 \reimp
6512 */
polish(QApplication * app)6513 void QCommonStyle::polish(QApplication *app)
6514 {
6515 QStyle::polish(app);
6516 }
6517
6518 /*!
6519 \reimp
6520 */
unpolish(QApplication * application)6521 void QCommonStyle::unpolish(QApplication *application)
6522 {
6523 Q_D(const QCommonStyle);
6524 d->tabBarcloseButtonIcon = QIcon();
6525 QStyle::unpolish(application);
6526 }
6527
6528
6529 QT_END_NAMESPACE
6530
6531 #include "moc_qcommonstyle.cpp"
6532