QMenu: Enable sloppy submenu mouse navigation
[qt:qt.git] / src / gui / styles / qcommonstyle.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 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
92 QT_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 */
120 QCommonStyle::QCommonStyle()
121     : QStyle(*new QCommonStylePrivate)
122 { }
123
124 /*! \internal
125 */
126 QCommonStyle::QCommonStyle(QCommonStylePrivate &dd)
127     : QStyle(dd)
128 { }
129
130 /*!
131     Destroys the style.
132 */
133 QCommonStyle::~QCommonStyle()
134 { }
135
136
137 /*!
138     \reimp
139 */
140 void 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
808 static 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
838 QSize 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
902 static 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
921 void 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 */
999 void 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  */
1132 void 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 */
1197 void 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 */
2313 QRect 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
3062 static 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 */
3101 void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
3102                                       QPainter *p, const QWidget *widget) const
3103 {
3104     switch (cc) {