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