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