Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging into master-integr...
[qt:android-lighthouse.git] / src / gui / styles / qcommonstyle.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
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                 bounds.setWidth(wrapText ? option->decorationSize.width() : QFIXED_MAX);
866                 break;
867             default:
868                 break;
869             }
870
871             qreal height = 0, widthUsed = 0;
872             textLayout.beginLayout();
873             while (true) {
874                 QTextLine line = textLayout.createLine();
875                 if (!line.isValid())
876                     break;
877                 line.setLineWidth(bounds.width());
878                 line.setPosition(QPointF(0, height));
879                 height += line.height();
880                 widthUsed = qMax(widthUsed, line.naturalTextWidth());
881             }
882             textLayout.endLayout();
883             const QSize size(qCeil(widthUsed), qCeil(height));
884             return QSize(size.width() + 2 * textMargin, size.height());
885         }
886         break;
887     case Qt::DecorationRole:
888         if (option->features & QStyleOptionViewItemV2::HasDecoration) {
889             return option->decorationSize;
890         }
891         break;
892     default:
893         break;
894     }
895
896     return QSize(0, 0);
897 }
898
899 static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
900 {
901     qreal height = 0;
902     qreal widthUsed = 0;
903     textLayout.beginLayout();
904     while (true) {
905         QTextLine line = textLayout.createLine();
906         if (!line.isValid())
907             break;
908         line.setLineWidth(lineWidth);
909         line.setPosition(QPointF(0, height));
910         height += line.height();
911         widthUsed = qMax(widthUsed, line.naturalTextWidth());
912     }
913     textLayout.endLayout();
914     return QSizeF(widthUsed, height);
915 }
916
917
918 void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const
919 {
920     const QWidget *widget = option->widget;
921     const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
922
923     QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
924     const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
925     QTextOption textOption;
926     textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
927     textOption.setTextDirection(option->direction);
928     textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment));
929     QTextLayout textLayout;
930     textLayout.setTextOption(textOption);
931     textLayout.setFont(option->font);
932     textLayout.setText(option->text);
933
934     viewItemTextLayout(textLayout, textRect.width());
935
936     QString elidedText;
937     qreal height = 0;
938     qreal width = 0;
939     int elidedIndex = -1;
940     const int lineCount = textLayout.lineCount();
941     for (int j = 0; j < lineCount; ++j) {
942         const QTextLine line = textLayout.lineAt(j);
943         if (j + 1 <= lineCount - 1) {
944             const QTextLine nextLine = textLayout.lineAt(j + 1);
945             if ((nextLine.y() + nextLine.height()) > textRect.height()) {
946                 int start = line.textStart();
947                 int length = line.textLength() + nextLine.textLength();
948                 const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
949                 elidedText = engine.elidedText(option->textElideMode, textRect.width());
950                 height += line.height();
951                 width = textRect.width();
952                 elidedIndex = j;
953                 break;
954             }
955         }
956         if (line.naturalTextWidth() > textRect.width()) {
957             int start = line.textStart();
958             int length = line.textLength();
959             const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
960             elidedText = engine.elidedText(option->textElideMode, textRect.width());
961             height += line.height();
962             width = textRect.width();
963             elidedIndex = j;
964             break;
965         }
966         width = qMax<qreal>(width, line.width());
967         height += line.height();
968     }
969
970     const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
971                                                  QSize(int(width), int(height)), textRect);
972     const QPointF position = layoutRect.topLeft();
973     for (int i = 0; i < lineCount; ++i) {
974         const QTextLine line = textLayout.lineAt(i);
975         if (i == elidedIndex) {
976             qreal x = position.x() + line.x();
977             qreal y = position.y() + line.y() + line.ascent();
978             p->save();
979             p->setFont(option->font);
980             p->drawText(QPointF(x, y), elidedText);
981             p->restore();
982             break;
983         }
984         line.draw(p, position);
985     }
986 }
987
988 /*! \internal
989     compute the position for the different component of an item (pixmap, text, checkbox)
990
991     Set sizehint to false to layout the elements inside opt->rect. Set sizehint to true to ignore
992    opt->rect and return rectangles in infinite space
993
994     Code duplicated in QItemDelegate::doLayout
995 */
996 void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt,  QRect *checkRect,
997                                          QRect *pixmapRect, QRect *textRect, bool sizehint) const
998 {
999     Q_ASSERT(checkRect && pixmapRect && textRect);
1000     *pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole));
1001     *textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole));
1002     *checkRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::CheckStateRole));
1003
1004     const QWidget *widget = opt->widget;
1005     const bool hasCheck = checkRect->isValid();
1006     const bool hasPixmap = pixmapRect->isValid();
1007     const bool hasText = textRect->isValid();
1008     const int textMargin = hasText ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1009     const int pixmapMargin = hasPixmap ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1010     const int checkMargin = hasCheck ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1011     int x = opt->rect.left();
1012     int y = opt->rect.top();
1013     int w, h;
1014
1015     if (textRect->height() == 0 && (!hasPixmap || !sizehint)) {
1016         //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
1017         textRect->setHeight(opt->fontMetrics.height());
1018     }
1019
1020     QSize pm(0, 0);
1021     if (hasPixmap) {
1022         pm = pixmapRect->size();
1023         pm.rwidth() += 2 * pixmapMargin;
1024     }
1025     if (sizehint) {
1026         h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
1027         if (opt->decorationPosition == QStyleOptionViewItem::Left
1028             || opt->decorationPosition == QStyleOptionViewItem::Right) {
1029             w = textRect->width() + pm.width();
1030         } else {
1031             w = qMax(textRect->width(), pm.width());
1032         }
1033     } else {
1034         w = opt->rect.width();
1035         h = opt->rect.height();
1036     }
1037
1038     int cw = 0;
1039     QRect check;
1040     if (hasCheck) {
1041         cw = checkRect->width() + 2 * checkMargin;
1042         if (sizehint) w += cw;
1043         if (opt->direction == Qt::RightToLeft) {
1044             check.setRect(x + w - cw, y, cw, h);
1045         } else {
1046             check.setRect(x, y, cw, h);
1047         }
1048     }
1049
1050     QRect display;
1051     QRect decoration;
1052     switch (opt->decorationPosition) {
1053     case QStyleOptionViewItem::Top: {
1054         if (hasPixmap)
1055             pm.setHeight(pm.height() + pixmapMargin); // add space
1056         h = sizehint ? textRect->height() : h - pm.height();
1057
1058         if (opt->direction == Qt::RightToLeft) {
1059             decoration.setRect(x, y, w - cw, pm.height());
1060             display.setRect(x, y + pm.height(), w - cw, h);
1061         } else {
1062             decoration.setRect(x + cw, y, w - cw, pm.height());
1063             display.setRect(x + cw, y + pm.height(), w - cw, h);
1064         }
1065         break; }
1066     case QStyleOptionViewItem::Bottom: {
1067         if (hasText)
1068             textRect->setHeight(textRect->height() + textMargin); // add space
1069         h = sizehint ? textRect->height() + pm.height() : h;
1070
1071         if (opt->direction == Qt::RightToLeft) {
1072             display.setRect(x, y, w - cw, textRect->height());
1073             decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
1074         } else {
1075             display.setRect(x + cw, y, w - cw, textRect->height());
1076             decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
1077         }
1078         break; }
1079     case QStyleOptionViewItem::Left: {
1080         if (opt->direction == Qt::LeftToRight) {
1081             decoration.setRect(x + cw, y, pm.width(), h);
1082             display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
1083         } else {
1084             display.setRect(x, y, w - pm.width() - cw, h);
1085             decoration.setRect(display.right() + 1, y, pm.width(), h);
1086         }
1087         break; }
1088     case QStyleOptionViewItem::Right: {
1089         if (opt->direction == Qt::LeftToRight) {
1090             display.setRect(x + cw, y, w - pm.width() - cw, h);
1091             decoration.setRect(display.right() + 1, y, pm.width(), h);
1092         } else {
1093             decoration.setRect(x, y, pm.width(), h);
1094             display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
1095         }
1096         break; }
1097     default:
1098         qWarning("doLayout: decoration position is invalid");
1099         decoration = *pixmapRect;
1100         break;
1101     }
1102
1103     if (!sizehint) { // we only need to do the internal layout if we are going to paint
1104         *checkRect = QStyle::alignedRect(opt->direction, Qt::AlignCenter,
1105                                          checkRect->size(), check);
1106         *pixmapRect = QStyle::alignedRect(opt->direction, opt->decorationAlignment,
1107                                           pixmapRect->size(), decoration);
1108         // the text takes up all available space, unless the decoration is not shown as selected
1109         if (opt->showDecorationSelected)
1110             *textRect = display;
1111         else
1112             *textRect = QStyle::alignedRect(opt->direction, opt->displayAlignment,
1113                                             textRect->size().boundedTo(display.size()), display);
1114     } else {
1115         *checkRect = check;
1116         *pixmapRect = decoration;
1117         *textRect = display;
1118     }
1119 }
1120 #endif // QT_NO_ITEMVIEWS
1121
1122
1123 #ifndef QT_NO_TABBAR
1124 /*! \internal
1125     Compute the textRect and the pixmapRect from the opt rect
1126
1127     Uses the same computation than in QTabBar::tabSizeHint
1128  */
1129 void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
1130 {
1131     Q_ASSERT(textRect);
1132     Q_ASSERT(iconRect);
1133     QRect tr = opt->rect;
1134     bool verticalTabs = opt->shape == QTabBar::RoundedEast
1135                         || opt->shape == QTabBar::RoundedWest
1136                         || opt->shape == QTabBar::TriangularEast
1137                         || opt->shape == QTabBar::TriangularWest;
1138     if (verticalTabs)
1139         tr.setRect(0, 0, tr.height(), tr.width()); //0, 0 as we will have a translate transform
1140
1141     int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget);
1142     int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget);
1143     int hpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
1144     int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2;
1145     if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
1146         verticalShift = -verticalShift;
1147     tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);
1148     bool selected = opt->state & QStyle::State_Selected;
1149     if (selected) {
1150         tr.setTop(tr.top() - verticalShift);
1151         tr.setRight(tr.right() - horizontalShift);
1152     }
1153
1154     // left widget
1155     if (!opt->leftButtonSize.isEmpty()) {
1156         tr.setLeft(tr.left() + 4 +
1157             (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width()));
1158     }
1159     // right widget
1160     if (!opt->rightButtonSize.isEmpty()) {
1161         tr.setRight(tr.right() - 4 -
1162         (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width()));
1163     }
1164
1165     // icon
1166     if (!opt->icon.isNull()) {
1167         QSize iconSize = opt->iconSize;
1168         if (!iconSize.isValid()) {
1169             int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize);
1170             iconSize = QSize(iconExtent, iconExtent);
1171         }
1172         QSize tabIconSize = opt->icon.actualSize(iconSize,
1173                         (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
1174                         (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off  );
1175
1176         *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
1177                     tabIconSize.width(), tabIconSize .height());
1178         if (!verticalTabs)
1179             *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);
1180         tr.setLeft(tr.left() + tabIconSize.width() + 4);
1181     }
1182
1183     if (!verticalTabs)
1184         tr = proxyStyle->visualRect(opt->direction, opt->rect, tr);
1185
1186     *textRect = tr;
1187 }
1188 #endif //QT_NO_TABBAR
1189
1190
1191 /*!
1192   \reimp
1193 */
1194 void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
1195                                QPainter *p, const QWidget *widget) const
1196 {
1197     Q_D(const QCommonStyle);
1198     switch (element) {
1199
1200     case CE_PushButton:
1201         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1202             proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
1203             QStyleOptionButton subopt = *btn;
1204             subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
1205             proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
1206             if (btn->state & State_HasFocus) {
1207                 QStyleOptionFocusRect fropt;
1208                 fropt.QStyleOption::operator=(*btn);
1209                 fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
1210                 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1211             }
1212         }
1213         break;
1214     case CE_PushButtonBevel:
1215         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1216             QRect br = btn->rect;
1217             int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
1218             if (btn->features & QStyleOptionButton::DefaultButton)
1219                 proxy()->drawPrimitive(PE_FrameDefaultButton, opt, p, widget);
1220             if (btn->features & QStyleOptionButton::AutoDefaultButton)
1221                 br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
1222             if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton))
1223                 || btn->state & (State_Sunken | State_On)
1224                 || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) {
1225                 QStyleOptionButton tmpBtn = *btn;
1226                 tmpBtn.rect = br;
1227                 proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, p, widget);
1228             }
1229             if (btn->features & QStyleOptionButton::HasMenu) {
1230                 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
1231                 QRect ir = btn->rect;
1232                 QStyleOptionButton newBtn = *btn;
1233                 newBtn.rect = QRect(ir.right() - mbi + 2, ir.height()/2 - mbi/2 + 3, mbi - 6, mbi - 6);
1234                 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
1235             }
1236         }
1237         break;
1238  case CE_PushButtonLabel:
1239         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1240             QRect textRect = button->rect;
1241             uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
1242             if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
1243                 tf |= Qt::TextHideMnemonic;
1244
1245             if (!button->icon.isNull()) {
1246                 //Center both icon and text
1247                 QRect iconRect;
1248                 QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
1249                 if (mode == QIcon::Normal && button->state & State_HasFocus)
1250                     mode = QIcon::Active;
1251                 QIcon::State state = QIcon::Off;
1252                 if (button->state & State_On)
1253                     state = QIcon::On;
1254
1255                 QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
1256                 int labelWidth = pixmap.width();
1257                 int labelHeight = pixmap.height();
1258                 int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
1259                 int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
1260                 if (!button->text.isEmpty())
1261                     labelWidth += (textWidth + iconSpacing);
1262
1263                 iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
1264                                  textRect.y() + (textRect.height() - labelHeight) / 2,
1265                                  pixmap.width(), pixmap.height());
1266
1267                 iconRect = visualRect(button->direction, textRect, iconRect);
1268
1269                 tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
1270
1271                 if (button->direction == Qt::RightToLeft)
1272                     textRect.setRight(iconRect.left() - iconSpacing);
1273                 else
1274                     textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
1275
1276                 if (button->state & (State_On | State_Sunken))
1277                     iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
1278                                        proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
1279                 p->drawPixmap(iconRect, pixmap);
1280             } else {
1281                 tf |= Qt::AlignHCenter;
1282             }
1283             if (button->state & (State_On | State_Sunken))
1284                 textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
1285                              proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
1286
1287             if (button->features & QStyleOptionButton::HasMenu) {
1288                 int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
1289                 if (button->direction == Qt::LeftToRight)
1290                     textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
1291                 else
1292                     textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
1293             }
1294             proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
1295                          button->text, QPalette::ButtonText);
1296         }
1297         break;
1298     case CE_RadioButton:
1299     case CE_CheckBox:
1300         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1301             bool isRadio = (element == CE_RadioButton);
1302             QStyleOptionButton subopt = *btn;
1303             subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
1304                                                  : SE_CheckBoxIndicator, btn, widget);
1305             proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
1306                           &subopt, p, widget);
1307             subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
1308                                                  : SE_CheckBoxContents, btn, widget);
1309             proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
1310             if (btn->state & State_HasFocus) {
1311                 QStyleOptionFocusRect fropt;
1312                 fropt.QStyleOption::operator=(*btn);
1313                 fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
1314                                                     : SE_CheckBoxFocusRect, btn, widget);
1315                 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1316             }
1317         }
1318         break;
1319     case CE_RadioButtonLabel:
1320     case CE_CheckBoxLabel:
1321         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1322             uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
1323
1324             if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
1325                 alignment |= Qt::TextHideMnemonic;
1326             QPixmap pix;
1327             QRect textRect = btn->rect;
1328             if (!btn->icon.isNull()) {
1329                 pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
1330                 proxy()->drawItemPixmap(p, btn->rect, alignment, pix);
1331                 if (btn->direction == Qt::RightToLeft)
1332                     textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
1333                 else
1334                     textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
1335             }
1336             if (!btn->text.isEmpty()){
1337                 proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
1338                     btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
1339             }
1340         }
1341         break;
1342 #ifndef QT_NO_MENU
1343     case CE_MenuScroller: {
1344         p->fillRect(opt->rect, opt->palette.background());
1345         QStyleOption arrowOpt = *opt;
1346         arrowOpt.state |= State_Enabled;
1347         proxy()->drawPrimitive(((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp),
1348                     &arrowOpt, p, widget);
1349         break; }
1350     case CE_MenuTearoff:
1351         if (opt->state & State_Selected)
1352             p->fillRect(opt->rect, opt->palette.brush(QPalette::Highlight));
1353         else
1354             p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
1355         p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
1356         p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2 - 1,
1357                     opt->rect.x() + opt->rect.width() - 4,
1358                     opt->rect.y() + opt->rect.height() / 2 - 1);
1359         p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
1360         p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2,
1361                     opt->rect.x() + opt->rect.width() - 4, opt->rect.y() + opt->rect.height() / 2);
1362         break;
1363 #endif // QT_NO_MENU
1364 #ifndef QT_NO_MENUBAR
1365     case CE_MenuBarItem:
1366         if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1367             uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip
1368                             | Qt::TextSingleLine;
1369             if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
1370                 alignment |= Qt::TextHideMnemonic;
1371             QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1372             if (!pix.isNull())
1373                 proxy()->drawItemPixmap(p,mbi->rect, alignment, pix);
1374             else
1375                 proxy()->drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled,
1376                              mbi->text, QPalette::ButtonText);
1377         }
1378         break;
1379     case CE_MenuBarEmptyArea:
1380         if (widget && !widget->testAttribute(Qt::WA_NoSystemBackground))
1381             p->eraseRect(opt->rect);
1382         break;
1383 #endif // QT_NO_MENUBAR
1384 #ifndef QT_NO_PROGRESSBAR
1385     case CE_ProgressBar:
1386         if (const QStyleOptionProgressBar *pb
1387                 = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1388             QStyleOptionProgressBarV2 subopt = *pb;
1389             subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget);
1390             proxy()->drawControl(CE_ProgressBarGroove, &subopt, p, widget);
1391             subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget);
1392             proxy()->drawControl(CE_ProgressBarContents, &subopt, p, widget);
1393             if (pb->textVisible) {
1394                 subopt.rect = subElementRect(SE_ProgressBarLabel, pb, widget);
1395                 proxy()->drawControl(CE_ProgressBarLabel, &subopt, p, widget);
1396             }
1397         }
1398         break;
1399     case CE_ProgressBarGroove:
1400         if (opt->rect.isValid())
1401             qDrawShadePanel(p, opt->rect, opt->palette, true, 1,
1402                             &opt->palette.brush(QPalette::Window));
1403         break;
1404     case CE_ProgressBarLabel:
1405         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1406             bool vertical = false;
1407             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
1408                 vertical = (pb2->orientation == Qt::Vertical);
1409             }
1410             if (!vertical) {
1411                 QPalette::ColorRole textRole = QPalette::NoRole;
1412                 if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible
1413                     && ((qint64(pb->progress) - qint64(pb->minimum)) * 2 >= (qint64(pb->maximum) - qint64(pb->minimum)))) {
1414                     textRole = QPalette::HighlightedText;
1415                     //Draw text shadow, This will increase readability when the background of same color
1416                     QRect shadowRect(pb->rect);
1417                     shadowRect.translate(1,1);
1418                     QColor shadowColor = (pb->palette.color(textRole).value() <= 128)
1419                        ? QColor(255,255,255,160) : QColor(0,0,0,160);
1420                     QPalette shadowPalette = pb->palette;
1421                     shadowPalette.setColor(textRole, shadowColor);
1422                     proxy()->drawItemText(p, shadowRect, Qt::AlignCenter | Qt::TextSingleLine, shadowPalette,
1423                                  pb->state & State_Enabled, pb->text, textRole);
1424                 }
1425                 proxy()->drawItemText(p, pb->rect, Qt::AlignCenter | Qt::TextSingleLine, pb->palette,
1426                              pb->state & State_Enabled, pb->text, textRole);
1427             }
1428         }
1429         break;
1430     case CE_ProgressBarContents:
1431         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1432
1433             QRect rect = pb->rect;
1434             bool vertical = false;
1435             bool inverted = false;
1436             qint64 minimum = qint64(pb->minimum);
1437             qint64 maximum = qint64(pb->maximum);
1438             qint64 progress = qint64(pb->progress);
1439
1440             // Get extra style options if version 2
1441             const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
1442             if (pb2) {
1443                 vertical = (pb2->orientation == Qt::Vertical);
1444                 inverted = pb2->invertedAppearance;
1445             }
1446             QMatrix m;
1447
1448             if (vertical) {
1449                 rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
1450                 m.rotate(90);
1451                 m.translate(0, -(rect.height() + rect.y()*2));
1452             }
1453
1454             QPalette pal2 = pb->palette;
1455             // Correct the highlight color if it is the same as the background
1456             if (pal2.highlight() == pal2.background())
1457                 pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
1458                                                                      QPalette::Highlight));
1459             bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1460             if (inverted)
1461                 reverse = !reverse;
1462             int w = rect.width();
1463             if (pb->minimum == 0 && pb->maximum == 0) {
1464                 // draw busy indicator
1465                 int x = (progress - minimum) % (w * 2);
1466                 if (x > w)
1467                     x = 2 * w - x;
1468                 x = reverse ? rect.right() - x : x + rect.x();
1469                 p->setPen(QPen(pal2.highlight().color(), 4));
1470                 p->drawLine(x, rect.y(), x, rect.height());
1471             } else {
1472                 const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
1473                 if (!unit_width)
1474                     return;
1475
1476                 int u;
1477                 if (unit_width > 1)
1478                     u = ((rect.width() + unit_width) / unit_width);
1479                 else
1480                     u = w / unit_width;
1481                 qint64 p_v = progress - minimum;
1482                 qint64 t_s = (maximum - minimum) ? (maximum - minimum) : qint64(1);
1483
1484                 if (u > 0 && p_v >= INT_MAX / u && t_s >= u) {
1485                     // scale down to something usable.
1486                     p_v /= u;
1487                     t_s /= u;
1488                 }
1489
1490                 // nu < tnu, if last chunk is only a partial chunk
1491                 int tnu, nu;
1492                 tnu = nu = p_v * u / t_s;
1493
1494                 if (nu * unit_width > w)
1495                     --nu;
1496
1497                 // Draw nu units out of a possible u of unit_width
1498                 // width, each a rectangle bordered by background
1499                 // color, all in a sunken panel with a percentage text
1500                 // display at the end.
1501                 int x = 0;
1502                 int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0)
1503                                  : rect.x();
1504
1505                 QStyleOptionProgressBarV2 pbBits = *pb;
1506                 pbBits.rect = rect;
1507                 pbBits.palette = pal2;
1508                 int myY = pbBits.rect.y();
1509                 int myHeight = pbBits.rect.height();
1510                 pbBits.state = State_None;
1511                 for (int i = 0; i < nu; ++i) {
1512                     pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
1513                     pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1514                     proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1515                     x += reverse ? -unit_width : unit_width;
1516                 }
1517
1518                 // Draw the last partial chunk to fill up the
1519                 // progress bar entirely
1520                 if (nu < tnu) {
1521                     int pixels_left = w - (nu * unit_width);
1522                     int offset = reverse ? x0 + x + unit_width-pixels_left : x0 + x;
1523                     pbBits.rect.setRect(offset, myY, pixels_left, myHeight);
1524                     pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1525                     proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1526                 }
1527             }
1528         }
1529         break;
1530 #endif // QT_NO_PROGRESSBAR
1531     case CE_HeaderLabel:
1532         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
1533             QRect rect = header->rect;
1534             if (!header->icon.isNull()) {
1535                 QPixmap pixmap
1536                     = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1537                 int pixw = pixmap.width();
1538
1539                 QRect aligned = alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size(), rect);
1540                 QRect inter = aligned.intersected(rect);
1541                 p->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
1542
1543                 if (header->direction == Qt::LeftToRight)
1544                     rect.setLeft(rect.left() + pixw + 2);
1545                 else
1546                     rect.setRight(rect.right() - pixw - 2);
1547             }
1548             if (header->state & QStyle::State_On) {
1549                 QFont fnt = p->font();
1550                 fnt.setBold(true);
1551                 p->setFont(fnt);
1552             }
1553             proxy()->drawItemText(p, rect, header->textAlignment, header->palette,
1554                          (header->state & State_Enabled), header->text, QPalette::ButtonText);
1555         }
1556         break;
1557 #ifndef QT_NO_TOOLBUTTON
1558     case CE_ToolButtonLabel:
1559         if (const QStyleOptionToolButton *toolbutton
1560                 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
1561             QRect rect = toolbutton->rect;
1562             int shiftX = 0;
1563             int shiftY = 0;
1564             if (toolbutton->state & (State_Sunken | State_On)) {
1565                 shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, toolbutton, widget);
1566                 shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, toolbutton, widget);
1567             }
1568             // Arrow type always overrules and is always shown
1569             bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow;
1570             if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty())
1571                 || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) {
1572                 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1573                 if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1574                     alignment |= Qt::TextHideMnemonic;
1575                 rect.translate(shiftX, shiftY);
1576                 p->setFont(toolbutton->font);
1577                 proxy()->drawItemText(p, rect, alignment, toolbutton->palette,
1578                              opt->state & State_Enabled, toolbutton->text,
1579                              QPalette::ButtonText);
1580             } else {
1581                 QPixmap pm;
1582                 QSize pmSize = toolbutton->iconSize;
1583                 if (!toolbutton->icon.isNull()) {
1584                     QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off;
1585                     QIcon::Mode mode;
1586                     if (!(toolbutton->state & State_Enabled))
1587                         mode = QIcon::Disabled;
1588                     else if ((opt->state & State_MouseOver) && (opt->state & State_AutoRaise))
1589                         mode = QIcon::Active;
1590                     else
1591                         mode = QIcon::Normal;
1592                     pm = toolbutton->icon.pixmap(toolbutton->rect.size().boundedTo(toolbutton->iconSize),
1593                                                  mode, state);
1594                     pmSize = pm.size();
1595                 }
1596
1597                 if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) {
1598                     p->setFont(toolbutton->font);
1599                     QRect pr = rect,
1600                     tr = rect;
1601                     int alignment = Qt::TextShowMnemonic;
1602                     if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1603                         alignment |= Qt::TextHideMnemonic;
1604
1605                     if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
1606                         pr.setHeight(pmSize.height() + 6);
1607                         tr.adjust(0, pr.height() - 1, 0, -2);
1608                         pr.translate(shiftX, shiftY);
1609                         if (!hasArrow) {
1610                             proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm);
1611                         } else {
1612                             drawArrow(this, toolbutton, pr, p, widget);
1613                         }
1614                         alignment |= Qt::AlignCenter;
1615                     } else {
1616                         pr.setWidth(pmSize.width() + 8);
1617                         tr.adjust(pr.width(), 0, 0, 0);
1618                         pr.translate(shiftX, shiftY);
1619                         if (!hasArrow) {
1620                             proxy()->drawItemPixmap(p, QStyle::visualRect(opt->direction, rect, pr), Qt::AlignCenter, pm);
1621                         } else {
1622                             drawArrow(this, toolbutton, pr, p, widget);
1623                         }
1624                         alignment |= Qt::AlignLeft | Qt::AlignVCenter;
1625                     }
1626                     tr.translate(shiftX, shiftY);
1627                     proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
1628                                  toolbutton->state & State_Enabled, toolbutton->text,
1629                                  QPalette::ButtonText);
1630                 } else {
1631                     rect.translate(shiftX, shiftY);
1632                     if (hasArrow) {
1633                         drawArrow(this, toolbutton, rect, p, widget);
1634                     } else {
1635                         proxy()->drawItemPixmap(p, rect, Qt::AlignCenter, pm);
1636                     }
1637                 }
1638             }
1639         }
1640         break;
1641 #endif // QT_NO_TOOLBUTTON
1642 #ifndef QT_NO_TOOLBOX
1643     case CE_ToolBoxTab:
1644         if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1645             proxy()->drawControl(CE_ToolBoxTabShape, tb, p, widget);
1646             proxy()->drawControl(CE_ToolBoxTabLabel, tb, p, widget);
1647         }
1648         break;
1649     case CE_ToolBoxTabShape:
1650         if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1651             int d = 20 + tb->rect.height() - 3;
1652             QPolygon a(7);
1653             if (tb->direction != Qt::RightToLeft) {
1654                 a.setPoint(0, -1, tb->rect.height() + 1);
1655                 a.setPoint(1, -1, 1);
1656                 a.setPoint(2, tb->rect.width() - d, 1);
1657                 a.setPoint(3, tb->rect.width() - 20, tb->rect.height() - 2);
1658                 a.setPoint(4, tb->rect.width() - 1, tb->rect.height() - 2);
1659                 a.setPoint(5, tb->rect.width() - 1, tb->rect.height() + 1);
1660                 a.setPoint(6, -1, tb->rect.height() + 1);
1661             } else {
1662                 a.setPoint(0, tb->rect.width(), tb->rect.height() + 1);
1663                 a.setPoint(1, tb->rect.width(), 1);
1664                 a.setPoint(2, d - 1, 1);
1665                 a.setPoint(3, 20 - 1, tb->rect.height() - 2);
1666                 a.setPoint(4, 0, tb->rect.height() - 2);
1667                 a.setPoint(5, 0, tb->rect.height() + 1);
1668                 a.setPoint(6, tb->rect.width(), tb->rect.height() + 1);
1669             }
1670
1671             p->setPen(tb->palette.mid().color().darker(150));
1672             p->drawPolygon(a);
1673             p->setPen(tb->palette.light().color());
1674             if (tb->direction != Qt::RightToLeft) {
1675                 p->drawLine(0, 2, tb->rect.width() - d, 2);
1676                 p->drawLine(tb->rect.width() - d - 1, 2, tb->rect.width() - 21, tb->rect.height() - 1);
1677                 p->drawLine(tb->rect.width() - 20, tb->rect.height() - 1,
1678                             tb->rect.width(), tb->rect.height() - 1);
1679             } else {
1680                 p->drawLine(tb->rect.width() - 1, 2, d - 1, 2);
1681                 p->drawLine(d, 2, 20, tb->rect.height() - 1);
1682                 p->drawLine(19, tb->rect.height() - 1,
1683                             -1, tb->rect.height() - 1);
1684             }
1685             p->setBrush(Qt::NoBrush);
1686         }
1687         break;
1688 #endif // QT_NO_TOOLBOX
1689 #ifndef QT_NO_TABBAR
1690     case CE_TabBarTab:
1691         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1692             proxy()->drawControl(CE_TabBarTabShape, tab, p, widget);
1693             proxy()->drawControl(CE_TabBarTabLabel, tab, p, widget);
1694         }
1695         break;
1696     case CE_TabBarTabShape:
1697         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1698             p->save();
1699
1700             QRect rect(tab->rect);
1701             bool selected = tab->state & State_Selected;
1702             bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1703             int tabOverlap = onlyOne ? 0 : proxy()->pixelMetric(PM_TabBarTabOverlap, opt, widget);
1704
1705             if (!selected) {
1706                 switch (tab->shape) {
1707                 case QTabBar::TriangularNorth:
1708                     rect.adjust(0, 0, 0, -tabOverlap);
1709                     if(!selected)
1710                         rect.adjust(1, 1, -1, 0);
1711                     break;
1712                 case QTabBar::TriangularSouth:
1713                     rect.adjust(0, tabOverlap, 0, 0);
1714                     if(!selected)
1715                         rect.adjust(1, 0, -1, -1);
1716                     break;
1717                 case QTabBar::TriangularEast:
1718                     rect.adjust(tabOverlap, 0, 0, 0);
1719                     if(!selected)
1720                         rect.adjust(0, 1, -1, -1);
1721                     break;
1722                 case QTabBar::TriangularWest:
1723                     rect.adjust(0, 0, -tabOverlap, 0);
1724                     if(!selected)
1725                         rect.adjust(1, 1, 0, -1);
1726                     break;
1727                 default:
1728                     break;
1729                 }
1730             }
1731
1732             p->setPen(QPen(tab->palette.foreground(), 0));
1733             if (selected) {
1734                 p->setBrush(tab->palette.base());
1735             } else {
1736                 if (widget && widget->parentWidget())
1737                     p->setBrush(widget->parentWidget()->palette().background());
1738                 else
1739                     p->setBrush(tab->palette.background());
1740             }
1741
1742             int y;
1743             int x;
1744             QPolygon a(10);
1745             switch (tab->shape) {
1746             case QTabBar::TriangularNorth:
1747             case QTabBar::TriangularSouth: {
1748                 a.setPoint(0, 0, -1);
1749                 a.setPoint(1, 0, 0);
1750                 y = rect.height() - 2;
1751                 x = y / 3;
1752                 a.setPoint(2, x++, y - 1);
1753                 ++x;
1754                 a.setPoint(3, x++, y++);
1755                 a.setPoint(4, x, y);
1756
1757                 int i;
1758                 int right = rect.width() - 1;
1759                 for (i = 0; i < 5; ++i)
1760                     a.setPoint(9 - i, right - a.point(i).x(), a.point(i).y());
1761                 if (tab->shape == QTabBar::TriangularNorth)
1762                     for (i = 0; i < 10; ++i)
1763                         a.setPoint(i, a.point(i).x(), rect.height() - 1 - a.point(i).y());
1764
1765                 a.translate(rect.left(), rect.top());
1766                 p->setRenderHint(QPainter::Antialiasing);
1767                 p->translate(0, 0.5);
1768
1769                 QPainterPath path;
1770                 path.addPolygon(a);
1771                 p->drawPath(path);
1772                 break; }
1773             case QTabBar::TriangularEast:
1774             case QTabBar::TriangularWest: {
1775                 a.setPoint(0, -1, 0);
1776                 a.setPoint(1, 0, 0);
1777                 x = rect.width() - 2;
1778                 y = x / 3;
1779                 a.setPoint(2, x - 1, y++);
1780                 ++y;
1781                 a.setPoint(3, x++, y++);
1782                 a.setPoint(4, x, y);
1783                 int i;
1784                 int bottom = rect.height() - 1;
1785                 for (i = 0; i < 5; ++i)
1786                     a.setPoint(9 - i, a.point(i).x(), bottom - a.point(i).y());
1787                 if (tab->shape == QTabBar::TriangularWest)
1788                     for (i = 0; i < 10; ++i)
1789                         a.setPoint(i, rect.width() - 1 - a.point(i).x(), a.point(i).y());
1790                 a.translate(rect.left(), rect.top());
1791                 p->setRenderHint(QPainter::Antialiasing);
1792                 p->translate(0.5, 0);
1793                 QPainterPath path;
1794                 path.addPolygon(a);
1795                 p->drawPath(path);
1796                 break; }
1797             default:
1798                 break;
1799             }
1800             p->restore();
1801         }
1802         break;
1803     case CE_ToolBoxTabLabel:
1804         if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1805             bool enabled = tb->state & State_Enabled;
1806             bool selected = tb->state & State_Selected;
1807             QPixmap pm = tb->icon.pixmap(proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb, widget),
1808                                          enabled ? QIcon::Normal : QIcon::Disabled);
1809
1810             QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget);
1811             QRect tr, ir;
1812             int ih = 0;
1813             if (pm.isNull()) {
1814                 tr = cr;
1815                 tr.adjust(4, 0, -8, 0);
1816             } else {
1817                 int iw = pm.width() + 4;
1818                 ih = pm.height();
1819                 ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
1820                 tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
1821             }
1822
1823             if (selected && proxy()->styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb, widget)) {
1824                 QFont f(p->font());
1825                 f.setBold(true);
1826                 p->setFont(f);
1827             }
1828
1829             QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width());
1830
1831             if (ih)
1832                 p->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm);
1833
1834             int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
1835             if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, tb, widget))
1836                 alignment |= Qt::TextHideMnemonic;
1837             proxy()->drawItemText(p, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText);
1838
1839             if (!txt.isEmpty() && opt->state & State_HasFocus) {
1840                 QStyleOptionFocusRect opt;
1841                 opt.rect = tr;
1842                 opt.palette = tb->palette;
1843                 opt.state = QStyle::State_None;
1844                 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, widget);
1845             }
1846         }
1847         break;
1848     case CE_TabBarTabLabel:
1849         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1850             QStyleOptionTabV3 tabV2(*tab);
1851             QRect tr = tabV2.rect;
1852             bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
1853                                 || tabV2.shape == QTabBar::RoundedWest
1854                                 || tabV2.shape == QTabBar::TriangularEast
1855                                 || tabV2.shape == QTabBar::TriangularWest;
1856
1857             int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1858             if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1859                 alignment |= Qt::TextHideMnemonic;
1860
1861             if (verticalTabs) {
1862                 p->save();
1863                 int newX, newY, newRot;
1864                 if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
1865                     newX = tr.width() + tr.x();
1866                     newY = tr.y();
1867                     newRot = 90;
1868                 } else {
1869                     newX = tr.x();
1870                     newY = tr.y() + tr.height();
1871                     newRot = -90;
1872                 }
1873                 QTransform m = QTransform::fromTranslate(newX, newY);
1874                 m.rotate(newRot);
1875                 p->setTransform(m, true);
1876             }
1877             QRect iconRect;
1878             d->tabLayout(&tabV2, widget, &tr, &iconRect);
1879             tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect
1880
1881             if (!tabV2.icon.isNull()) {
1882                 QPixmap tabIcon = tabV2.icon.pixmap(tabV2.iconSize,
1883                                                     (tabV2.state & State_Enabled) ? QIcon::Normal
1884                                                                                   : QIcon::Disabled,
1885                                                     (tabV2.state & State_Selected) ? QIcon::On
1886                                                                                    : QIcon::Off);
1887                 p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
1888             }
1889
1890             proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
1891             if (verticalTabs)
1892                 p->restore();
1893
1894             if (tabV2.state & State_HasFocus) {
1895                 const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);
1896
1897                 int x1, x2;
1898                 x1 = tabV2.rect.left();
1899                 x2 = tabV2.rect.right() - 1;
1900
1901                 QStyleOptionFocusRect fropt;
1902                 fropt.QStyleOption::operator=(*tab);
1903                 fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
1904                                    x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
1905                 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1906             }
1907         }
1908         break;
1909 #endif // QT_NO_TABBAR
1910 #ifndef QT_NO_SIZEGRIP
1911     case CE_SizeGrip: {
1912         p->save();
1913         int x, y, w, h;
1914         opt->rect.getRect(&x, &y, &w, &h);
1915
1916         int sw = qMin(h, w);
1917         if (h > w)
1918             p->translate(0, h - w);
1919         else
1920             p->translate(w - h, 0);
1921
1922         int sx = x;
1923         int sy = y;
1924         int s = sw / 3;
1925
1926         Qt::Corner corner;
1927         if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt))
1928             corner = sgOpt->corner;
1929         else if (opt->direction == Qt::RightToLeft)
1930             corner = Qt::BottomLeftCorner;
1931         else
1932             corner = Qt::BottomRightCorner;
1933
1934         if (corner == Qt::BottomLeftCorner) {
1935             sx = x + sw;
1936             for (int i = 0; i < 4; ++i) {
1937                 p->setPen(QPen(opt->palette.light().color(), 1));
1938                 p->drawLine(x, sy - 1 , sx + 1, sw);
1939                 p->setPen(QPen(opt->palette.dark().color(), 1));
1940                 p->drawLine(x, sy, sx, sw);
1941                 p->setPen(QPen(opt->palette.dark().color(), 1));
1942                 p->drawLine(x, sy + 1, sx - 1, sw);
1943                 sx -= s;
1944                 sy += s;
1945             }
1946         } else if (corner == Qt::BottomRightCorner) {
1947             for (int i = 0; i < 4; ++i) {
1948                 p->setPen(QPen(opt->palette.light().color(), 1));
1949                 p->drawLine(sx - 1, sw, sw, sy - 1);
1950                 p->setPen(QPen(opt->palette.dark().color(), 1));
1951                 p->drawLine(sx, sw, sw, sy);
1952                 p->setPen(QPen(opt->palette.dark().color(), 1));
1953                 p->drawLine(sx + 1, sw, sw, sy + 1);
1954                 sx += s;
1955                 sy += s;
1956             }
1957         } else if (corner == Qt::TopRightCorner) {
1958             sy = y + sw;
1959             for (int i = 0; i < 4; ++i) {
1960                 p->setPen(QPen(opt->palette.light().color(), 1));
1961                 p->drawLine(sx - 1, y, sw, sy + 1);
1962                 p->setPen(QPen(opt->palette.dark().color(), 1));
1963                 p->drawLine(sx, y, sw, sy);
1964                 p->setPen(QPen(opt->palette.dark().color(), 1));
1965                 p->drawLine(sx + 1, y, sw, sy - 1);
1966                 sx += s;
1967                 sy -= s;
1968             }
1969         } else if (corner == Qt::TopLeftCorner) {
1970             for (int i = 0; i < 4; ++i) {
1971                 p->setPen(QPen(opt->palette.light().color(), 1));
1972                 p->drawLine(x, sy - 1, sx - 1, y);
1973                 p->setPen(QPen(opt->palette.dark().color(), 1));
1974                 p->drawLine(x, sy, sx, y);
1975                 p->setPen(QPen(opt->palette.dark().color(), 1));
1976                 p->drawLine(x, sy + 1, sx + 1, y);
1977                 sx += s;
1978                 sy += s;
1979             }
1980         }
1981         p->restore();
1982         break; }
1983 #endif // QT_NO_SIZEGRIP
1984 #ifndef QT_NO_RUBBERBAND
1985     case CE_RubberBand: {
1986         if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
1987             QPixmap tiledPixmap(16, 16);
1988             QPainter pixmapPainter(&tiledPixmap);
1989             pixmapPainter.setPen(Qt::NoPen);
1990             pixmapPainter.setBrush(Qt::Dense4Pattern);
1991             pixmapPainter.setBackground(QBrush(opt->palette.base()));
1992             pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
1993             pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
1994             pixmapPainter.end();
1995             // ### workaround for borked XRENDER
1996             tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
1997
1998             p->save();
1999             QRect r = opt->rect;
2000             QStyleHintReturnMask mask;
2001             if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
2002                 p->setClipRegion(mask.region);
2003             p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
2004             p->setPen(opt->palette.color(QPalette::Active, QPalette::WindowText));
2005             p->setBrush(Qt::NoBrush);
2006             p->drawRect(r.adjusted(0, 0, -1, -1));
2007             if (rbOpt->shape == QRubberBand::Rectangle)
2008                 p->drawRect(r.adjusted(3, 3, -4, -4));
2009             p->restore();
2010         }
2011         break; }
2012 #endif // QT_NO_RUBBERBAND
2013 #ifndef QT_NO_DOCKWIDGET
2014     case CE_DockWidgetTitle:
2015         if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
2016             QRect r = dwOpt->rect.adjusted(0, 0, -1, -1);
2017             if (dwOpt->movable) {
2018                 p->setPen(dwOpt->palette.color(QPalette::Dark));
2019                 p->drawRect(r);
2020             }
2021
2022             if (!dwOpt->title.isEmpty()) {
2023                 const QStyleOptionDockWidgetV2 *v2
2024                     = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
2025                 bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
2026
2027                 if (verticalTitleBar) {
2028                     QSize s = r.size();
2029                     s.transpose();
2030                     r.setSize(s);
2031
2032                     p->save();
2033                     p->translate(r.left(), r.top() + r.width());
2034                     p->rotate(-90);
2035                     p->translate(-r.left(), -r.top());
2036                 }
2037
2038                 const int indent = p->fontMetrics().descent();
2039                 proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1),
2040                               Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
2041                               dwOpt->state & State_Enabled, dwOpt->title,
2042                               QPalette::WindowText);
2043
2044                 if (verticalTitleBar)
2045                     p->restore();
2046             }
2047         }
2048         break;
2049 #endif // QT_NO_DOCKWIDGET
2050     case CE_Header:
2051         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2052             QRegion clipRegion = p->clipRegion();
2053             p->setClipRect(opt->rect);
2054             proxy()->drawControl(CE_HeaderSection, header, p, widget);
2055             QStyleOptionHeader subopt = *header;
2056             subopt.rect = subElementRect(SE_HeaderLabel, header, widget);
2057             if (subopt.rect.isValid())
2058                 proxy()->drawControl(CE_HeaderLabel, &subopt, p, widget);
2059             if (header->sortIndicator != QStyleOptionHeader::None) {
2060                 subopt.rect = subElementRect(SE_HeaderArrow, opt, widget);
2061                 proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, p, widget);
2062             }
2063             p->setClipRegion(clipRegion);
2064         }
2065         break;
2066     case CE_FocusFrame:
2067             p->fillRect(opt->rect, opt->palette.foreground());
2068         break;
2069     case CE_HeaderSection:
2070             qDrawShadePanel(p, opt->rect, opt->palette,
2071                         opt->state & State_Sunken, 1,
2072                         &opt->palette.brush(QPalette::Button));
2073         break;
2074     case CE_HeaderEmptyArea:
2075             p->fillRect(opt->rect, opt->palette.background());
2076         break;
2077 #ifndef QT_NO_COMBOBOX
2078     case CE_ComboBoxLabel:
2079         if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2080             QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
2081             p->save();
2082             p->setClipRect(editRect);
2083             if (!cb->currentIcon.isNull()) {
2084                 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
2085                                                              : QIcon::Disabled;
2086                 QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
2087                 QRect iconRect(editRect);
2088                 iconRect.setWidth(cb->iconSize.width() + 4);
2089                 iconRect = alignedRect(cb->direction,
2090                                        Qt::AlignLeft | Qt::AlignVCenter,
2091                                        iconRect.size(), editRect);
2092                 if (cb->editable)
2093                     p->fillRect(iconRect, opt->palette.brush(QPalette::Base));
2094                 proxy()->drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
2095
2096                 if (cb->direction == Qt::RightToLeft)
2097                     editRect.translate(-4 - cb->iconSize.width(), 0);
2098                 else
2099                     editRect.translate(cb->iconSize.width() + 4, 0);
2100             }
2101             if (!cb->currentText.isEmpty() && !cb->editable) {
2102                 proxy()->drawItemText(p, editRect.adjusted(1, 0, -1, 0),
2103                              visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
2104                              cb->palette, cb->state & State_Enabled, cb->currentText);
2105             }
2106             p->restore();
2107         }
2108         break;
2109 #endif // QT_NO_COMBOBOX
2110 #ifndef QT_NO_TOOLBAR
2111     case CE_ToolBar:
2112         if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
2113             // Compatibility with styles that use PE_PanelToolBar
2114             QStyleOptionFrame frame;
2115             frame.QStyleOption::operator=(*toolBar);
2116             frame.lineWidth = toolBar->lineWidth;
2117             frame.midLineWidth = toolBar->midLineWidth;
2118             proxy()->drawPrimitive(PE_PanelToolBar, opt, p, widget);
2119
2120             if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
2121                 break;
2122             qDrawShadePanel(p, toolBar->rect, toolBar->palette, false, toolBar->lineWidth,
2123                             &toolBar->palette.brush(QPalette::Button));
2124         }
2125         break;
2126 #endif // QT_NO_TOOLBAR
2127     case CE_ColumnViewGrip: {
2128         // draw background gradients
2129         QLinearGradient g(0, 0, opt->rect.width(), 0);
2130         g.setColorAt(0, opt->palette.color(QPalette::Active, QPalette::Mid));
2131         g.setColorAt(0.5, Qt::white);
2132         p->fillRect(QRect(0, 0, opt->rect.width(), opt->rect.height()), g);
2133
2134         // draw the two lines
2135         QPen pen(p->pen());
2136         pen.setWidth(opt->rect.width()/20);
2137         pen.setColor(opt->palette.color(QPalette::Active, QPalette::Dark));
2138         p->setPen(pen);
2139
2140         int line1starting = opt->rect.width()*8 / 20;
2141         int line2starting = opt->rect.width()*13 / 20;
2142         int top = opt->rect.height()*20/75;
2143         int bottom = opt->rect.height() - 1 - top;
2144         p->drawLine(line1starting, top, line1starting, bottom);
2145         p->drawLine(line2starting, top, line2starting, bottom);
2146         }
2147         break;
2148
2149 #ifndef QT_NO_ITEMVIEWS
2150     case CE_ItemViewItem:
2151         if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
2152             p->save();
2153             p->setClipRect(opt->rect);
2154
2155             QRect checkRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
2156             QRect iconRect = subElementRect(SE_ItemViewItemDecoration, vopt, widget);
2157             QRect textRect = subElementRect(SE_ItemViewItemText, vopt, widget);
2158
2159             // draw the background
2160             proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);
2161
2162             // draw the check mark
2163             if (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) {
2164                 QStyleOptionViewItemV4 option(*vopt);
2165                 option.rect = checkRect;
2166                 option.state = option.state & ~QStyle::State_HasFocus;
2167
2168                 switch (vopt->checkState) {
2169                 case Qt::Unchecked:
2170                     option.state |= QStyle::State_Off;
2171                     break;
2172                 case Qt::PartiallyChecked:
2173                     option.state |= QStyle::State_NoChange;
2174                     break;
2175                 case Qt::Checked:
2176                     option.state |= QStyle::State_On;
2177                     break;
2178                 }
2179                 proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, p, widget);
2180             }
2181
2182             // draw the icon
2183             QIcon::Mode mode = QIcon::Normal;
2184             if (!(vopt->state & QStyle::State_Enabled))
2185                 mode = QIcon::Disabled;
2186             else if (vopt->state & QStyle::State_Selected)
2187                 mode = QIcon::Selected;
2188             QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
2189             vopt->icon.paint(p, iconRect, vopt->decorationAlignment, mode, state);
2190
2191             // draw the text
2192             if (!vopt->text.isEmpty()) {
2193                 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
2194                                       ? QPalette::Normal : QPalette::Disabled;
2195                 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
2196                     cg = QPalette::Inactive;
2197
2198                 if (vopt->state & QStyle::State_Selected) {
2199                     p->setPen(vopt->palette.color(cg, QPalette::HighlightedText));
2200                 } else {
2201                     p->setPen(vopt->palette.color(cg, QPalette::Text));
2202                 }
2203                 if (vopt->state & QStyle::State_Editing) {
2204                     p->setPen(vopt->palette.color(cg, QPalette::Text));
2205                     p->drawRect(textRect.adjusted(0, 0, -1, -1));
2206                 }
2207
2208                 d->viewItemDrawText(p, vopt, textRect);
2209             }
2210
2211             // draw the focus rect
2212              if (vopt->state & QStyle::State_HasFocus) {
2213                 QStyleOptionFocusRect o;
2214                 o.QStyleOption::operator=(*vopt);
2215                 o.rect = proxy()->subElementRect(SE_ItemViewItemFocusRect, vopt, widget);
2216                 o.state |= QStyle::State_KeyboardFocusChange;
2217                 o.state |= QStyle::State_Item;
2218                 QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled)
2219                               ? QPalette::Normal : QPalette::Disabled;
2220                 o.backgroundColor = vopt->palette.color(cg, (vopt->state & QStyle::State_Selected)
2221                                              ? QPalette::Highlight : QPalette::Window);
2222                 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, p, widget);
2223             }
2224
2225              p->restore();
2226         }
2227         break;
2228
2229 #endif // QT_NO_ITEMVIEWS
2230 #ifndef QT_NO_FRAME
2231     case CE_ShapedFrame:
2232         if (const QStyleOptionFrameV3 *f = qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) {
2233             int frameShape  = f->frameShape;
2234             int frameShadow = QFrame::Plain;
2235             if (f->state & QStyle::State_Sunken) {
2236                 frameShadow = QFrame::Sunken;
2237             } else if (f->state & QStyle::State_Raised) {
2238                 frameShadow = QFrame::Raised;
2239             }
2240
2241             int lw = f->lineWidth;
2242             int mlw = f->midLineWidth;
2243             QPalette::ColorRole foregroundRole = QPalette::WindowText;
2244             if (widget)
2245                 foregroundRole = widget->foregroundRole();
2246
2247             switch (frameShape) {
2248             case QFrame::Box:
2249                 if (frameShadow == QFrame::Plain) {
2250                     qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2251                 } else {
2252                     qDrawShadeRect(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
2253                 }
2254                 break;
2255             case QFrame::StyledPanel:
2256                 //keep the compatibility with Qt 4.4 if there is a proxy style.
2257                 //be sure to call drawPrimitive(QStyle::PE_Frame) on the proxy style
2258                 if (widget) {
2259                     widget->style()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
2260                 } else {
2261                     proxy()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
2262                 }
2263                 break;
2264             case QFrame::Panel:
2265                 if (frameShadow == QFrame::Plain) {
2266                     qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2267                 } else {
2268                     qDrawShadePanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw);
2269                 }
2270                 break;
2271             case QFrame::WinPanel:
2272                 if (frameShadow == QFrame::Plain) {
2273                     qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2274                 } else {
2275                     qDrawWinPanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken);
2276                 }
2277                 break;
2278             case QFrame::HLine:
2279             case QFrame::VLine: {
2280                 QPoint p1, p2;
2281                 if (frameShape == QFrame::HLine) {
2282                     p1 = QPoint(opt->rect.x(), opt->rect.height() / 2);
2283                     p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y());
2284                 } else {
2285                     p1 = QPoint(opt->rect.x()+opt->rect.width() / 2, 0);
2286                     p2 = QPoint(p1.x(), opt->rect.height());
2287                 }
2288                 if (frameShadow == QFrame::Plain) {
2289                     QPen oldPen = p->pen();
2290                     p->setPen(QPen(opt->palette.brush(foregroundRole), lw));
2291                     p->drawLine(p1, p2);
2292                     p->setPen(oldPen);
2293                 } else {
2294                     qDrawShadeLine(p, p1, p2, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
2295                 }
2296                 break;
2297                 }
2298             }
2299         }
2300         break;
2301 #endif
2302     default:
2303         break;
2304     }
2305 }
2306
2307 /*!
2308   \reimp
2309 */
2310 QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
2311                                    const QWidget *widget) const
2312 {
2313     Q_D(const QCommonStyle);
2314     QRect r;
2315     switch (sr) {
2316     case SE_PushButtonContents:
2317         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2318             int dx1, dx2;
2319             dx1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
2320             if (btn->features & QStyleOptionButton::AutoDefaultButton)
2321                 dx1 += proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2322             dx2 = dx1 * 2;
2323             r.setRect(opt->rect.x() + dx1, opt->rect.y() + dx1, opt->rect.width() - dx2,
2324                       opt->rect.height() - dx2);
2325             r = visualRect(opt->direction, opt->rect, r);
2326         }
2327         break;
2328     case SE_PushButtonFocusRect:
2329         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2330             int dbw1 = 0, dbw2 = 0;
2331             if (btn->features & QStyleOptionButton::AutoDefaultButton){
2332                 dbw1 = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2333                 dbw2 = dbw1 * 2;
2334             }
2335
2336             int dfw1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget) + 1,
2337                 dfw2 = dfw1 * 2;
2338
2339             r.setRect(btn->rect.x() + dfw1 + dbw1, btn->rect.y() + dfw1 + dbw1,
2340                       btn->rect.width() - dfw2 - dbw2, btn->rect.height()- dfw2 - dbw2);
2341             r = visualRect(opt->direction, opt->rect, r);
2342         }
2343         break;
2344     case SE_CheckBoxIndicator:
2345         {
2346             int h = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
2347             r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
2348                       proxy()->pixelMetric(PM_IndicatorWidth, opt, widget), h);
2349             r = visualRect(opt->direction, opt->rect, r);
2350         }
2351         break;
2352
2353     case SE_CheckBoxContents:
2354         {
2355             // Deal with the logical first, then convert it back to screen coords.
2356             QRect ir = visualRect(opt->direction, opt->rect,
2357                                   subElementRect(SE_CheckBoxIndicator, opt, widget));
2358             int spacing = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget);
2359             r.setRect(ir.right() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
2360                       opt->rect.height());
2361             r = visualRect(opt->direction, opt->rect, r);
2362         }
2363         break;
2364
2365     case SE_CheckBoxFocusRect:
2366         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2367             if (btn->icon.isNull() && btn->text.isEmpty()) {
2368                 r = subElementRect(SE_CheckBoxIndicator, opt, widget);
2369                 r.adjust(1, 1, -1, -1);
2370                 break;
2371             }
2372             // As above, deal with the logical first, then convert it back to screen coords.
2373             QRect cr = visualRect(btn->direction, btn->rect,
2374                                   subElementRect(SE_CheckBoxContents, btn, widget));
2375
2376             QRect iconRect, textRect;
2377             if (!btn->text.isEmpty()) {
2378                 textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft
2379                                         | Qt::AlignVCenter | Qt::TextShowMnemonic,
2380                                         btn->state & State_Enabled, btn->text);
2381             }
2382             if (!btn->icon.isNull()) {
2383                 iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2384                                         | Qt::TextShowMnemonic,
2385                                    btn->icon.pixmap(btn->iconSize, QIcon::Normal));
2386                 if (!textRect.isEmpty())
2387                     textRect.translate(iconRect.right() + 4, 0);
2388             }
2389             r = iconRect | textRect;
2390             r.adjust(-3, -2, 3, 2);
2391             r = r.intersected(btn->rect);
2392             r = visualRect(btn->direction, btn->rect, r);
2393         }
2394         break;
2395
2396     case SE_RadioButtonIndicator:
2397         {
2398             int h = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget);
2399             r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
2400                     proxy()->pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), h);
2401             r = visualRect(opt->direction, opt->rect, r);
2402         }
2403         break;
2404
2405     case SE_RadioButtonContents:
2406         {
2407             QRect ir = visualRect(opt->direction, opt->rect,
2408                                   subElementRect(SE_RadioButtonIndicator, opt, widget));
2409             int spacing = proxy()->pixelMetric(PM_RadioButtonLabelSpacing, opt, widget);
2410             r.setRect(ir.left() + ir.width() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
2411                       opt->rect.height());
2412             r = visualRect(opt->direction, opt->rect, r);
2413             break;
2414         }
2415
2416     case SE_RadioButtonFocusRect:
2417         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2418             if (btn->icon.isNull() && btn->text.isEmpty()) {
2419                 r = subElementRect(SE_RadioButtonIndicator, opt, widget);
2420                 r.adjust(1, 1, -1, -1);
2421                 break;
2422             }
2423             QRect cr = visualRect(btn->direction, btn->rect,
2424                                   subElementRect(SE_RadioButtonContents, opt, widget));
2425
2426             QRect iconRect, textRect;
2427             if (!btn->text.isEmpty()){
2428                 textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2429                                  | Qt::TextShowMnemonic, btn->state & State_Enabled, btn->text);
2430             }
2431             if (!btn->icon.isNull()) {
2432                 iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic,
2433                                    btn->icon.pixmap(btn->iconSize, QIcon::Normal));
2434                 if (!textRect.isEmpty())
2435                     textRect.translate(iconRect.right() + 4, 0);
2436             }
2437             r = iconRect | textRect;
2438             r.adjust(-3, -2, 3, 2);
2439             r = r.intersected(btn->rect);
2440             r = visualRect(btn->direction, btn->rect, r);
2441         }
2442         break;
2443 #ifndef QT_NO_SLIDER
2444     case SE_SliderFocusRect:
2445         if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2446             int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
2447             int thickness  = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
2448             if (slider->orientation == Qt::Horizontal)
2449                 r.setRect(0, tickOffset - 1, slider->rect.width(), thickness + 2);
2450             else
2451                 r.setRect(tickOffset - 1, 0, thickness + 2, slider->rect.height());
2452             r = r.intersected(slider->rect);
2453             r = visualRect(opt->direction, opt->rect, r);
2454         }
2455         break;
2456 #endif // QT_NO_SLIDER
2457 #ifndef QT_NO_PROGRESSBAR
2458     case SE_ProgressBarGroove:
2459     case SE_ProgressBarContents:
2460     case SE_ProgressBarLabel:
2461         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
2462             int textw = 0;
2463             bool vertical = false;
2464             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
2465                 vertical = (pb2->orientation == Qt::Vertical);
2466             }
2467             if (!vertical) {
2468                 if (pb->textVisible)
2469                     textw = qMax(pb->fontMetrics.width(pb->text), pb->fontMetrics.width(QLatin1String("100%"))) + 6;
2470             }
2471
2472             if ((pb->textAlignment & Qt::AlignCenter) == 0) {
2473                 if (sr != SE_ProgressBarLabel)
2474                     r.setCoords(pb->rect.left(), pb->rect.top(),
2475                                 pb->rect.right() - textw, pb->rect.bottom());
2476                 else
2477                     r.setCoords(pb->rect.right() - textw, pb->rect.top(),
2478                                 pb->rect.right(), pb->rect.bottom());
2479             } else {
2480                 r = pb->rect;
2481             }
2482             r = visualRect(pb->direction, pb->rect, r);
2483         }
2484         break;
2485 #endif // QT_NO_PROGRESSBAR
2486 #ifdef QT3_SUPPORT
2487     case SE_Q3DockWindowHandleRect:
2488         if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
2489             if (!dw->docked || !dw->closeEnabled)
2490                 r.setRect(0, 0, dw->rect.width(), dw->rect.height());
2491             else {
2492                 if (dw->state & State_Horizontal)
2493                     r.setRect(0, 15, dw->rect.width(), dw->rect.height() - 15);
2494                 else
2495                     r.setRect(0, 1, dw->rect.width() - 15, dw->rect.height() - 1);
2496             }
2497             r = visualRect(opt->direction, opt->rect, r);
2498         }
2499         break;
2500 #endif // QT3_SUPPORT
2501 #ifndef QT_NO_COMBOBOX
2502     case SE_ComboBoxFocusRect:
2503         if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2504             int margin = cb->frame ? 3 : 0;
2505             r.setRect(opt->rect.left() + margin, opt->rect.top() + margin,
2506                       opt->rect.width() - 2*margin - 16, opt->rect.height() - 2*margin);
2507             r = visualRect(opt->direction, opt->rect, r);
2508         }
2509         break;
2510 #endif // QT_NO_COMBOBOX
2511 #ifndef QT_NO_TOOLBOX
2512     case SE_ToolBoxTabContents:
2513         r = opt->rect;
2514         r.adjust(0, 0, -30, 0);
2515         break;
2516 #endif // QT_NO_TOOLBOX
2517     case SE_HeaderLabel: {
2518         int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
2519         r.setRect(opt->rect.x() + margin, opt->rect.y() + margin,
2520                   opt->rect.width() - margin * 2, opt->rect.height() - margin * 2);
2521
2522         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2523             // Subtract width needed for arrow, if there is one
2524             if (header->sortIndicator != QStyleOptionHeader::None) {
2525                 if (opt->state & State_Horizontal)
2526                     r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2));
2527                 else
2528                     r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2));
2529             }
2530         }
2531         r = visualRect(opt->direction, opt->rect, r);
2532         break; }
2533     case SE_HeaderArrow: {
2534         int h = opt->rect.height();
2535         int w = opt->rect.width();
2536         int x = opt->rect.x();
2537         int y = opt->rect.y();
2538         int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
2539
2540         if (opt->state & State_Horizontal) {
2541             int horiz_size = h / 2;
2542             r.setRect(x + w - margin * 2 - horiz_size, y + 5,
2543                       horiz_size, h - margin * 2 - 5);
2544         } else {
2545             int vert_size = w / 2;
2546             r.setRect(x + 5, y + h - margin * 2 - vert_size,
2547                       w - margin * 2 - 5, vert_size);
2548         }
2549         r = visualRect(opt->direction, opt->rect, r);
2550         break; }
2551
2552     case SE_RadioButtonClickRect:
2553         r = subElementRect(SE_RadioButtonFocusRect, opt, widget);
2554         r |= subElementRect(SE_RadioButtonIndicator, opt, widget);
2555         break;
2556     case SE_CheckBoxClickRect:
2557         r = subElementRect(SE_CheckBoxFocusRect, opt, widget);
2558         r |= subElementRect(SE_CheckBoxIndicator, opt, widget);
2559         break;
2560 #ifndef QT_NO_TABWIDGET
2561     case SE_TabWidgetTabBar:
2562         if (const QStyleOptionTabWidgetFrame *twf
2563                 = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2564             r.setSize(twf->tabBarSize);
2565             const uint alingMask = Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter;
2566             switch (twf->shape) {
2567             case QTabBar::RoundedNorth:
2568             case QTabBar::TriangularNorth:
2569                 // Constrain the size now, otherwise, center could get off the page
2570                 // This of course repeated for all the other directions
2571                 r.setWidth(qMin(r.width(), twf->rect.width()
2572                                             - twf->leftCornerWidgetSize.width()
2573                                             - twf->rightCornerWidgetSize.width()));
2574                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2575                 default:
2576                 case Qt::AlignLeft:
2577                     r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0));
2578                     break;
2579                 case Qt::AlignHCenter:
2580                     r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
2581                                          + (twf->leftCornerWidgetSize.width() / 2)
2582                                          - (twf->rightCornerWidgetSize.width() / 2), 0));
2583                     break;
2584                 case Qt::AlignRight:
2585                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
2586                                          - twf->rightCornerWidgetSize.width(), 0));
2587                     break;
2588                 }
2589                 r = visualRect(twf->direction, twf->rect, r);
2590                 break;
2591             case QTabBar::RoundedSouth:
2592             case QTabBar::TriangularSouth:
2593                 r.setWidth(qMin(r.width(), twf->rect.width()
2594                                             - twf->leftCornerWidgetSize.width()
2595                                             - twf->rightCornerWidgetSize.width()));
2596                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2597                 default:
2598                 case Qt::AlignLeft:
2599                     r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(),
2600                                          twf->rect.height() - twf->tabBarSize.height()));
2601                     break;
2602                 case Qt::AlignHCenter:
2603                     r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
2604                                          + (twf->leftCornerWidgetSize.width() / 2)
2605                                          - (twf->rightCornerWidgetSize.width() / 2),
2606                                          twf->rect.height() - twf->tabBarSize.height()));
2607                     break;
2608                 case Qt::AlignRight:
2609                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
2610                                          - twf->rightCornerWidgetSize.width(),
2611                                          twf->rect.height() - twf->tabBarSize.height()));
2612                     break;
2613                 }
2614                 r = visualRect(twf->direction, twf->rect, r);
2615                 break;
2616             case QTabBar::RoundedEast:
2617             case QTabBar::TriangularEast:
2618                 r.setHeight(qMin(r.height(), twf->rect.height()
2619                                             - twf->leftCornerWidgetSize.height()
2620                                             - twf->rightCornerWidgetSize.height()));
2621                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2622                 default:
2623                 case Qt::AlignLeft:
2624                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2625                                          twf->leftCornerWidgetSize.height()));
2626                     break;
2627                 case Qt::AlignHCenter:
2628                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2629                                          twf->rect.center().y() - r.height() / 2));
2630                     break;
2631                 case Qt::AlignRight:
2632                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2633                                          twf->rect.height() - twf->tabBarSize.height()
2634                                          - twf->rightCornerWidgetSize.height()));
2635                     break;
2636                 }
2637                 break;
2638             case QTabBar::RoundedWest:
2639             case QTabBar::TriangularWest:
2640                 r.setHeight(qMin(r.height(), twf->rect.height()
2641                                              - twf->leftCornerWidgetSize.height()
2642                                              - twf->rightCornerWidgetSize.height()));
2643                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2644                 default:
2645                 case Qt::AlignLeft:
2646                     r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height()));
2647                     break;
2648                 case Qt::AlignHCenter:
2649                     r.moveTopLeft(QPoint(0, twf->rect.center().y() - r.height() / 2));
2650                     break;
2651                 case Qt::AlignRight:
2652                     r.moveTopLeft(QPoint(0, twf->rect.height() - twf->tabBarSize.height()
2653                                          - twf->rightCornerWidgetSize.height()));
2654                     break;
2655                 }
2656                 break;
2657             }
2658         }
2659         break;
2660     case SE_TabWidgetTabPane:
2661     case SE_TabWidgetTabContents:
2662         if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2663             QStyleOptionTab tabopt;
2664             tabopt.shape = twf->shape;
2665             int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &tabopt, widget);
2666             if (twf->lineWidth == 0)
2667                 overlap = 0;
2668             switch (twf->shape) {
2669             case QTabBar::RoundedNorth:
2670             case QTabBar::TriangularNorth:
2671                 r = QRect(QPoint(0,qMax(twf->tabBarSize.height() - overlap, 0)),
2672                           QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
2673                 break;
2674             case QTabBar::RoundedSouth:
2675             case QTabBar::TriangularSouth:
2676                 r = QRect(QPoint(0,0), QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
2677                 break;
2678             case QTabBar::RoundedEast:
2679             case QTabBar::TriangularEast:
2680                 r = QRect(QPoint(0, 0), QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
2681                 break;
2682             case QTabBar::RoundedWest:
2683             case QTabBar::TriangularWest:
2684                 r = QRect(QPoint(qMax(twf->tabBarSize.width() - overlap, 0), 0),
2685                           QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
2686                 break;
2687             }
2688             if (sr == SE_TabWidgetTabContents && twf->lineWidth > 0)
2689                r.adjust(2, 2, -2, -2);
2690         }
2691         break;
2692     case SE_TabWidgetLeftCorner:
2693         if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2694             QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2695             switch (twf->shape) {
2696             case QTabBar::RoundedNorth:
2697             case QTabBar::TriangularNorth:
2698                 r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()),
2699                           twf->leftCornerWidgetSize);
2700                 break;
2701             case QTabBar::RoundedSouth:
2702             case QTabBar::TriangularSouth:
2703                 r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
2704                break;
2705             default:
2706                break;
2707             }
2708            r = visualRect(twf->direction, twf->rect, r);
2709         }
2710         break;
2711    case SE_TabWidgetRightCorner:
2712        if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2713            QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2714            switch (twf->shape) {
2715            case QTabBar::RoundedNorth:
2716            case QTabBar::TriangularNorth:
2717                 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2718                                  paneRect.y() - twf->rightCornerWidgetSize.height()),
2719                           twf->rightCornerWidgetSize);
2720                break;
2721            case QTabBar::RoundedSouth:
2722            case QTabBar::TriangularSouth:
2723                 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2724                                  paneRect.height()), twf->rightCornerWidgetSize);
2725                break;
2726            default:
2727                break;
2728            }
2729            r = visualRect(twf->direction, twf->rect, r);
2730         }
2731         break;
2732     case SE_TabBarTabText:
2733         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2734             QStyleOptionTabV3 tabV3(*tab);
2735             QRect dummyIconRect;
2736             d->tabLayout(&tabV3, widget, &r, &dummyIconRect);
2737         }
2738         break;
2739     case SE_TabBarTabLeftButton:
2740     case SE_TabBarTabRightButton:
2741         if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
2742             bool selected = tab->state & State_Selected;
2743             int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
2744             int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
2745             int hpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
2746             hpadding = qMax(hpadding, 4); //workaround KStyle returning 0 because they workaround an old bug in Qt
2747
2748             bool verticalTabs = tab->shape == QTabBar::RoundedEast
2749                     || tab->shape == QTabBar::RoundedWest
2750                     || tab->shape == QTabBar::TriangularEast
2751                     || tab->shape == QTabBar::TriangularWest;
2752
2753             QRect tr = tab->rect;
2754             if (tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::TriangularSouth)
2755                 verticalShift = -verticalShift;
2756             if (verticalTabs) {
2757                 qSwap(horizontalShift, verticalShift);
2758                 horizontalShift *= -1;
2759                 verticalShift *= -1;
2760             }
2761             if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest)
2762                 horizontalShift = -horizontalShift;
2763
2764             tr.adjust(0, 0, horizontalShift, verticalShift);
2765             if (selected)
2766             {
2767                 tr.setBottom(tr.bottom() - verticalShift);
2768                 tr.setRight(tr.right() - horizontalShift);
2769             }
2770
2771             QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
2772             int w = size.width();
2773             int h = size.height();
2774             int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
2775             int midWidth = ((tr.width() - w) / 2);
2776
2777             bool atTheTop = true;
2778             switch (tab->shape) {
2779             case QTabBar::RoundedWest:
2780             case QTabBar::TriangularWest:
2781                 atTheTop = (sr == SE_TabBarTabLeftButton);
2782                 break;
2783             case QTabBar::RoundedEast:
2784             case QTabBar::TriangularEast:
2785                 atTheTop = (sr == SE_TabBarTabRightButton);
2786                 break;
2787</