Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
[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             int pnt;
227             p->setPen(opt->palette.highlightedText().color());
228             QPoint offset(1, 1);
229             for (pnt = 0; pnt < a.size(); ++pnt)
230                 a[pnt].translate(offset.x(), offset.y());
231             p->drawLines(a);
232             for (pnt = 0; pnt < a.size(); ++pnt)
233                 a[pnt].translate(offset.x(), offset.y());
234         }
235         p->setPen(opt->palette.text().color());
236         p->drawLines(a);
237         break; }
238     case PE_Frame:
239     case PE_FrameMenu:
240         if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
241             if (pe == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) {
242                 qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
243                                 frame->lineWidth);
244             } else {
245                 qDrawPlainRect(p, frame->rect, frame->palette.foreground().color(), frame->lineWidth);
246             }
247         }
248         break;
249 #ifndef QT_NO_TOOLBAR
250     case PE_PanelMenuBar:
251         if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
252             break;
253         if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)){
254             qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth,
255                             &frame->palette.brush(QPalette::Button));
256
257         }
258         else if (const QStyleOptionToolBar *frame = qstyleoption_cast<const QStyleOptionToolBar *>(opt)){
259             qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth,
260                             &frame->palette.brush(QPalette::Button));
261         }
262
263         break;
264    case PE_PanelMenu:
265         break;
266     case PE_PanelToolBar:
267        break;
268 #endif // QT_NO_TOOLBAR
269 #ifndef QT_NO_PROGRESSBAR
270     case PE_IndicatorProgressChunk:
271         {
272             bool vertical = false;
273             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
274                 vertical = (pb2->orientation == Qt::Vertical);
275             if (!vertical) {
276                 p->fillRect(opt->rect.x(), opt->rect.y() + 3, opt->rect.width() -2, opt->rect.height() - 6,
277                             opt->palette.brush(QPalette::Highlight));
278             } else {
279                 p->fillRect(opt->rect.x() + 2, opt->rect.y(), opt->rect.width() -6, opt->rect.height() - 2,
280                             opt->palette.brush(QPalette::Highlight));
281             }
282         }
283         break;
284 #endif // QT_NO_PROGRESSBAR
285 #ifdef QT3_SUPPORT
286     case PE_Q3CheckListController:
287 #ifndef QT_NO_IMAGEFORMAT_XPM
288         p->drawPixmap(opt->rect.topLeft(), QPixmap(check_list_controller_xpm));
289 #endif
290         break;
291     case PE_Q3CheckListExclusiveIndicator:
292         if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
293             if (lv->items.isEmpty())
294                 return;
295             int x = lv->rect.x(),
296                 y = lv->rect.y();
297 #define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
298             static const int pts1[] = {                // dark lines
299                 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
300             static const int pts2[] = {                // black lines
301                 2,8, 1,7, 1,4, 2,3, 2,2, 3,2, 4,1, 7,1, 8,2, 9,2 };
302             static const int pts3[] = {                // background lines
303                 2,9, 3,9, 4,10, 7,10, 8,9, 9,9, 9,8, 10,7, 10,4, 9,3 };
304             static const int pts4[] = {                // white lines
305                 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
306                 11,4, 10,3, 10,2 };
307             // static const int pts5[] = {                // inner fill
308             //    4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
309             //QPolygon a;
310
311             if (lv->state & State_Enabled)
312                 p->setPen(lv->palette.text().color());
313             else
314                 p->setPen(QPen(lv->viewportPalette.color(QPalette::Disabled, QPalette::Text)));
315             QPolygon a(INTARRLEN(pts1), pts1);
316             a.translate(x, y);
317             //p->setPen(pal.dark());
318             p->drawPolyline(a);
319             a.setPoints(INTARRLEN(pts2), pts2);
320             a.translate(x, y);
321             p->drawPolyline(a);
322             a.setPoints(INTARRLEN(pts3), pts3);
323             a.translate(x, y);
324             //                p->setPen(black);
325             p->drawPolyline(a);
326             a.setPoints(INTARRLEN(pts4), pts4);
327             a.translate(x, y);
328             //                        p->setPen(blue);
329             p->drawPolyline(a);
330             //                a.setPoints(INTARRLEN(pts5), pts5);
331             //                a.translate(x, y);
332             //        QColor fillColor = isDown() ? g.background() : g.base();
333             //        p->setPen(fillColor);
334             //        p->setBrush(fillColor);
335             //        p->drawPolygon(a);
336             if (opt->state & State_On) {
337                 p->setPen(Qt::NoPen);
338                 p->setBrush(opt->palette.text());
339                 p->drawRect(x + 5, y + 4, 2, 4);
340                 p->drawRect(x + 4, y + 5, 4, 2);
341             }
342 #undef INTARRLEN
343         }
344         break;
345     case PE_Q3CheckListIndicator:
346         if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
347             if(lv->items.isEmpty())
348                 break;
349             QStyleOptionQ3ListViewItem item = lv->items.at(0);
350             int x = lv->rect.x(),
351                 y = lv->rect.y(),
352                 w = lv->rect.width(),
353                 h = lv->rect.width(),
354              marg = lv->itemMargin;
355
356             if (lv->state & State_Enabled)
357                 p->setPen(QPen(lv->palette.text().color(), 2));
358             else
359                 p->setPen(QPen(lv->viewportPalette.color(QPalette::Disabled, QPalette::Text), 2));
360             if (opt->state & State_Selected && !lv->rootIsDecorated
361                 && !(item.features & QStyleOptionQ3ListViewItem::ParentControl)) {
362                 p->fillRect(0, 0, x + marg + w + 4, item.height,
363                             lv->palette.brush(QPalette::Highlight));
364                 if (item.state & State_Enabled)
365                     p->setPen(QPen(lv->palette.highlightedText().color(), 2));
366             }
367
368             if (lv->state & State_NoChange)
369                 p->setBrush(lv->palette.brush(QPalette::Button));
370             p->drawRect(x + marg, y + 2, w - 4, h - 4);
371             /////////////////////
372                 ++x;
373                 ++y;
374                 if (lv->state & State_On || lv->state & State_NoChange) {
375                     QLineF lines[7];
376                     int i,
377                         xx = x + 1 + marg,
378                         yy = y + 5;
379                     for (i = 0; i < 3; ++i) {
380                         lines[i] = QLineF(xx, yy, xx, yy + 2);
381                         ++xx;
382                         ++yy;
383                     }
384                     yy -= 2;
385                     for (i = 3; i < 7; ++i) {
386                         lines[i] = QLineF(xx, yy, xx, yy + 2);
387                         ++xx;
388                         --yy;
389                     }
390                     p->drawLines(lines, 7);
391                 }
392         }
393         break;
394 #endif // QT3_SUPPORT
395     case PE_IndicatorBranch: {
396         int mid_h = opt->rect.x() + opt->rect.width() / 2;
397         int mid_v = opt->rect.y() + opt->rect.height() / 2;
398         int bef_h = mid_h;
399         int bef_v = mid_v;
400         int aft_h = mid_h;
401         int aft_v = mid_v;
402 #ifndef QT_NO_IMAGEFORMAT_XPM
403         static const int decoration_size = 9;
404         static QPixmap open(tree_branch_open_xpm);
405         static QPixmap closed(tree_branch_closed_xpm);
406         if (opt->state & State_Children) {
407             int delta = decoration_size / 2;
408             bef_h -= delta;
409             bef_v -= delta;
410             aft_h += delta;
411             aft_v += delta;
412             p->drawPixmap(bef_h, bef_v, opt->state & State_Open ? open : closed);
413         }
414 #endif // QT_NO_IMAGEFORMAT_XPM
415         if (opt->state & State_Item) {
416             if (opt->direction == Qt::RightToLeft)
417                 p->drawLine(opt->rect.left(), mid_v, bef_h, mid_v);
418             else
419                 p->drawLine(aft_h, mid_v, opt->rect.right(), mid_v);
420         }
421         if (opt->state & State_Sibling)
422             p->drawLine(mid_h, aft_v, mid_h, opt->rect.bottom());
423         if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
424             p->drawLine(mid_h, opt->rect.y(), mid_h, bef_v);
425         break; }
426 #ifdef QT3_SUPPORT
427     case PE_Q3Separator:
428         qDrawShadeLine(p, opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.bottom(),
429                        opt->palette, opt->state & State_Sunken, 1, 0);
430         break;
431 #endif // QT3_SUPPORT
432     case PE_FrameStatusBarItem:
433         qDrawShadeRect(p, opt->rect, opt->palette, true, 1, 0, 0);
434         break;
435     case PE_IndicatorHeaderArrow:
436         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
437             QPen oldPen = p->pen();
438             if (header->sortIndicator & QStyleOptionHeader::SortUp) {
439                 QPolygon pa(3);
440                 p->setPen(QPen(opt->palette.light(), 0));
441                 p->drawLine(opt->rect.x() + opt->rect.width(), opt->rect.y(),
442                             opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height());
443                 p->setPen(QPen(opt->palette.dark(), 0));
444                 pa.setPoint(0, opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height());
445                 pa.setPoint(1, opt->rect.x(), opt->rect.y());
446                 pa.setPoint(2, opt->rect.x() + opt->rect.width(), opt->rect.y());
447                 p->drawPolyline(pa);
448             } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
449                 QPolygon pa(3);
450                 p->setPen(QPen(opt->palette.light(), 0));
451                 pa.setPoint(0, opt->rect.x(), opt->rect.y() + opt->rect.height());
452                 pa.setPoint(1, opt->rect.x() + opt->rect.width(), opt->rect.y() + opt->rect.height());
453                 pa.setPoint(2, opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
454                 p->drawPolyline(pa);
455                 p->setPen(QPen(opt->palette.dark(), 0));
456                 p->drawLine(opt->rect.x(), opt->rect.y() + opt->rect.height(),
457                             opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
458             }
459             p->setPen(oldPen);
460         }
461         break;
462 #ifndef QT_NO_TABBAR
463     case PE_FrameTabBarBase:
464         if (const QStyleOptionTabBarBase *tbb
465                 = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) {
466             p->save();
467             switch (tbb->shape) {
468             case QTabBar::RoundedNorth:
469             case QTabBar::TriangularNorth:
470                 p->setPen(QPen(tbb->palette.light(), 0));
471                 p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
472                 break;
473             case QTabBar::RoundedWest:
474             case QTabBar::TriangularWest:
475                 p->setPen(QPen(tbb->palette.light(), 0));
476                 p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
477                 break;
478             case QTabBar::RoundedSouth:
479             case QTabBar::TriangularSouth:
480                 p->setPen(QPen(tbb->palette.shadow(), 0));
481                 p->drawLine(tbb->rect.left(), tbb->rect.bottom(),
482                             tbb->rect.right(), tbb->rect.bottom());
483                 p->setPen(QPen(tbb->palette.dark(), 0));
484                 p->drawLine(tbb->rect.left(), tbb->rect.bottom() - 1,
485                             tbb->rect.right() - 1, tbb->rect.bottom() - 1);
486                 break;
487             case QTabBar::RoundedEast:
488             case QTabBar::TriangularEast:
489                 p->setPen(QPen(tbb->palette.dark(), 0));
490                 p->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
491                 break;
492             }
493             p->restore();
494         }
495         break;
496     case PE_IndicatorTabClose: {
497         if (d->tabBarcloseButtonIcon.isNull()) {
498             d->tabBarcloseButtonIcon.addPixmap(QPixmap(
499                         QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-16.png")),
500                         QIcon::Normal, QIcon::Off);
501             d->tabBarcloseButtonIcon.addPixmap(QPixmap(
502                         QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-down-16.png")),
503                         QIcon::Normal, QIcon::On);
504             d->tabBarcloseButtonIcon.addPixmap(QPixmap(
505                         QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-hover-16.png")),
506                         QIcon::Active, QIcon::Off);
507         }
508
509         int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize);
510         QIcon::Mode mode = opt->state & State_Enabled ?
511                             (opt->state & State_Raised ? QIcon::Active : QIcon::Normal)
512                             : QIcon::Disabled;
513         if (!(opt->state & State_Raised)
514             && !(opt->state & State_Sunken)
515             && !(opt->state & QStyle::State_Selected))
516             mode = QIcon::Disabled;
517
518         QIcon::State state = opt->state & State_Sunken ? QIcon::On : QIcon::Off;
519         QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(size, mode, state);
520         proxy()->drawItemPixmap(p, opt->rect, Qt::AlignCenter, pixmap);
521         break;
522     }
523 #endif // QT_NO_TABBAR
524     case PE_FrameTabWidget:
525     case PE_FrameWindow:
526         qDrawWinPanel(p, opt->rect, opt->palette, false, 0);
527         break;
528     case PE_FrameLineEdit:
529         proxy()->drawPrimitive(PE_Frame, opt, p, widget);
530         break;
531 #ifndef QT_NO_GROUPBOX
532     case PE_FrameGroupBox:
533         if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
534             const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt);
535             if (frame2 && (frame2->features & QStyleOptionFrameV2::Flat)) {
536                 QRect fr = frame->rect;
537                 QPoint p1(fr.x(), fr.y() + 1);
538                 QPoint p2(fr.x() + fr.width(), p1.y());
539                 qDrawShadeLine(p, p1, p2, frame->palette, true,
540                                frame->lineWidth, frame->midLineWidth);
541             } else {
542                 qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(),
543                                frame->rect.height(), frame->palette, true,
544                                frame->lineWidth, frame->midLineWidth);
545             }
546         }
547         break;
548 #endif // QT_NO_GROUPBOX
549 #ifndef QT_NO_DOCKWIDGET
550     case PE_FrameDockWidget:
551         if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
552             int lw = frame->lineWidth;
553             if (lw <= 0)
554                 lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth);
555
556             qDrawShadePanel(p, frame->rect, frame->palette, false, lw);
557         }
558         break;
559 #endif // QT_NO_DOCKWIDGET
560 #ifndef QT_NO_TOOLBAR
561     case PE_IndicatorToolBarHandle:
562         p->save();
563         p->translate(opt->rect.x(), opt->rect.y());
564         if (opt->state & State_Horizontal) {
565             int x = opt->rect.width() / 3;
566             if (opt->direction == Qt::RightToLeft)
567                 x -= 2;
568             if (opt->rect.height() > 4) {
569                 qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
570                                 opt->palette, false, 1, 0);
571                 qDrawShadePanel(p, x+3, 2, 3, opt->rect.height() - 4,
572                                 opt->palette, false, 1, 0);
573             }
574         } else {
575             if (opt->rect.width() > 4) {
576                 int y = opt->rect.height() / 3;
577                 qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
578                                 opt->palette, false, 1, 0);
579                 qDrawShadePanel(p, 2, y+3, opt->rect.width() - 4, 3,
580                                 opt->palette, false, 1, 0);
581             }
582         }
583         p->restore();
584         break;
585     case PE_Q3DockWindowSeparator:
586         proxy()->drawPrimitive(PE_IndicatorToolBarSeparator, opt, p, widget);
587         break;
588     case PE_IndicatorToolBarSeparator:
589         {
590             QPoint p1, p2;
591             if (opt->state & State_Horizontal) {
592                 p1 = QPoint(opt->rect.width()/2, 0);
593                 p2 = QPoint(p1.x(), opt->rect.height());
594             } else {
595                 p1 = QPoint(0, opt->rect.height()/2);
596                 p2 = QPoint(opt->rect.width(), p1.y());
597             }
598             qDrawShadeLine(p, p1, p2, opt->palette, 1, 1, 0);
599             break;
600         }
601 #endif // QT_NO_TOOLBAR
602 #ifndef QT_NO_SPINBOX
603     case PE_IndicatorSpinPlus:
604     case PE_IndicatorSpinMinus: {
605         QRect r = opt->rect;
606         int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
607         QRect br = r.adjusted(fw, fw, -fw, -fw);
608
609         int offset = (opt->state & State_Sunken) ? 1 : 0;
610         int step = (br.width() + 4) / 5;
611         p->fillRect(br.x() + offset, br.y() + offset +br.height() / 2 - step / 2,
612                     br.width(), step,
613                     opt->palette.buttonText());
614         if (pe == PE_IndicatorSpinPlus)
615             p->fillRect(br.x() + br.width() / 2 - step / 2 + offset, br.y() + offset,
616                         step, br.height(),
617                         opt->palette.buttonText());
618
619         break; }
620     case PE_IndicatorSpinUp:
621     case PE_IndicatorSpinDown: {
622         QRect r = opt->rect;
623         int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
624         // QRect br = r.adjusted(fw, fw, -fw, -fw);
625         int x = r.x(), y = r.y(), w = r.width(), h = r.height();
626         int sw = w-4;
627         if (sw < 3)
628             break;
629         else if (!(sw & 1))
630             sw--;
631         sw -= (sw / 7) * 2;        // Empty border
632         int sh = sw/2 + 2;      // Must have empty row at foot of arrow
633
634         int sx = x + w / 2 - sw / 2;
635         int sy = y + h / 2 - sh / 2;
636
637         if (pe == PE_IndicatorSpinUp && fw)
638             --sy;
639
640         QPolygon a;
641         if (pe == PE_IndicatorSpinDown)
642             a.setPoints(3, 0, 1,  sw-1, 1,  sh-2, sh-1);
643         else
644             a.setPoints(3, 0, sh-1,  sw-1, sh-1,  sh-2, 1);
645         int bsx = 0;
646         int bsy = 0;
647         if (opt->state & State_Sunken) {
648             bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
649             bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
650         }
651         p->save();
652         p->translate(sx + bsx, sy + bsy);
653         p->setPen(opt->palette.buttonText().color());
654         p->setBrush(opt->palette.buttonText());
655         p->drawPolygon(a);
656         p->restore();
657         break; }
658 #endif // QT_NO_SPINBOX
659     case PE_PanelTipLabel: {
660         QBrush oldBrush = p->brush();
661         QPen oldPen = p->pen();
662         p->setPen(QPen(opt->palette.toolTipText(), 0));
663         p->setBrush(opt->palette.toolTipBase());
664         p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
665         p->setPen(oldPen);
666         p->setBrush(oldBrush);
667         break;
668     }
669 #ifndef QT_NO_TABBAR
670     case PE_IndicatorTabTear:
671         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
672             bool rtl = tab->direction == Qt::RightToLeft;
673             QRect rect = tab->rect;
674             QPainterPath path;
675
676             rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
677             rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
678
679             path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
680             int count = 4;
681             for(int jags = 1; jags <= count; ++jags, rtl = !rtl)
682                 path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
683
684             p->setPen(QPen(tab->palette.light(), qreal(.8)));
685             p->setBrush(tab->palette.background());
686             p->setRenderHint(QPainter::Antialiasing);
687             p->drawPath(path);
688         }
689         break;
690 #endif // QT_NO_TABBAR
691 #ifndef QT_NO_LINEEDIT
692     case PE_PanelLineEdit:
693         if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
694             p->fillRect(panel->rect.adjusted(panel->lineWidth, panel->lineWidth, -panel->lineWidth, -panel->lineWidth),
695                         panel->palette.brush(QPalette::Base));
696
697             if (panel->lineWidth > 0)
698                 proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
699         }
700         break;
701 #endif // QT_NO_LINEEDIT
702 #ifndef QT_NO_COLUMNVIEW
703     case PE_IndicatorColumnViewArrow: {
704     if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
705         bool reverse = (viewOpt->direction == Qt::RightToLeft);
706         p->save();
707         QPainterPath path;
708         int x = viewOpt->rect.x() + 1;
709         int offset = (viewOpt->rect.height() / 3);
710         int height = (viewOpt->rect.height()) - offset * 2;
711         if (height % 2 == 1)
712             --height;
713         int x2 = x + height - 1;
714         if (reverse) {
715             x = viewOpt->rect.x() + viewOpt->rect.width() - 1;
716             x2 = x - height + 1;
717         }
718         path.moveTo(x, viewOpt->rect.y() + offset);
719         path.lineTo(x, viewOpt->rect.y() + offset + height);
720         path.lineTo(x2, viewOpt->rect.y() + offset+height/2);
721         path.closeSubpath();
722         if (viewOpt->state & QStyle::State_Selected ) {
723             if (viewOpt->showDecorationSelected) {
724                 QColor color = viewOpt->palette.color(QPalette::Active, QPalette::HighlightedText);
725                 p->setPen(color);
726                 p->setBrush(color);
727             } else {
728                 QColor color = viewOpt->palette.color(QPalette::Active, QPalette::WindowText);
729                 p->setPen(color);
730                 p->setBrush(color);
731             }
732
733         } else {
734             QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Mid);
735             p->setPen(color);
736             p->setBrush(color);
737         }
738         p->drawPath(path);
739
740         // draw the vertical and top triangle line
741         if (!(viewOpt->state & QStyle::State_Selected)) {
742             QPainterPath lines;
743             lines.moveTo(x, viewOpt->rect.y() + offset);
744             lines.lineTo(x, viewOpt->rect.y() + offset + height);
745             lines.moveTo(x, viewOpt->rect.y() + offset);
746             lines.lineTo(x2, viewOpt->rect.y() + offset+height/2);
747             QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Dark);
748             p->setPen(color);
749             p->drawPath(lines);
750         }
751         p->restore();
752     }
753     break; }
754 #endif //QT_NO_COLUMNVIEW
755     case PE_IndicatorItemViewItemDrop: {
756         QRect rect = opt->rect;
757         if (opt->rect.height() == 0)
758             p->drawLine(rect.topLeft(), rect.topRight());
759         else
760             p->drawRect(rect);
761         break; }
762 #ifndef QT_NO_ITEMVIEWS
763     case PE_PanelItemViewRow:
764         if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
765             QPalette::ColorGroup cg = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
766                                       ? QPalette::Normal : QPalette::Disabled;
767             if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
768                 cg = QPalette::Inactive;
769
770             if ((vopt->state & QStyle::State_Selected) &&  proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, opt, widget))
771                 p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight));
772             else if (vopt->features & QStyleOptionViewItemV2::Alternate)
773                 p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase));
774         }
775         break;
776     case PE_PanelItemViewItem:
777         if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
778             QPalette::ColorGroup cg = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
779                                       ? QPalette::Normal : QPalette::Disabled;
780             if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
781                 cg = QPalette::Inactive;
782
783             if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) {
784                 p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight));
785             } else {
786                 if (vopt->backgroundBrush.style() != Qt::NoBrush) {
787                     QPointF oldBO = p->brushOrigin();
788                     p->setBrushOrigin(vopt->rect.topLeft());
789                     p->fillRect(vopt->rect, vopt->backgroundBrush);
790                     p->setBrushOrigin(oldBO);
791                 }
792
793                 if (vopt->state & QStyle::State_Selected) {
794                     QRect textRect = subElementRect(QStyle::SE_ItemViewItemText,  opt, widget);
795                     p->fillRect(textRect, vopt->palette.brush(cg, QPalette::Highlight));
796                 }
797             }
798         }
799         break;
800 #endif //QT_NO_ITEMVIEWS
801     case PE_PanelScrollAreaCorner: {
802         const QBrush brush(opt->palette.brush(QPalette::Window));
803         p->fillRect(opt->rect, brush);
804         } break;
805     default:
806         break;
807     }
808 }
809
810 #ifndef QT_NO_TOOLBUTTON
811 static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton,
812                       const QRect &rect, QPainter *painter, const QWidget *widget = 0)
813 {
814     QStyle::PrimitiveElement pe;
815     switch (toolbutton->arrowType) {
816     case Qt::LeftArrow:
817         pe = QStyle::PE_IndicatorArrowLeft;
818         break;
819     case Qt::RightArrow:
820         pe = QStyle::PE_IndicatorArrowRight;
821         break;
822     case Qt::UpArrow:
823         pe = QStyle::PE_IndicatorArrowUp;
824         break;
825     case Qt::DownArrow:
826         pe = QStyle::PE_IndicatorArrowDown;
827         break;
828     default:
829         return;
830     }
831     QStyleOption arrowOpt;
832     arrowOpt.rect = rect;
833     arrowOpt.palette = toolbutton->palette;
834     arrowOpt.state = toolbutton->state;
835     style->drawPrimitive(pe, &arrowOpt, painter, widget);
836 }
837 #endif // QT_NO_TOOLBUTTON
838
839 #ifndef QT_NO_ITEMVIEWS
840
841 QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, int role) const
842 {
843     Q_Q(const QCommonStyle);
844
845     const QWidget *widget = option->widget;
846     switch (role) {
847     case Qt::CheckStateRole:
848         if (option->features & QStyleOptionViewItemV2::HasCheckIndicator)
849             return QSize(q->pixelMetric(QStyle::PM_IndicatorWidth, option, widget),
850                          q->pixelMetric(QStyle::PM_IndicatorHeight, option, widget));
851         break;
852     case Qt::DisplayRole:
853         if (option->features & QStyleOptionViewItemV2::HasDisplay) {
854             QTextOption textOption;
855             textOption.setWrapMode(QTextOption::WordWrap);
856             QTextLayout textLayout;
857             textLayout.setTextOption(textOption);
858             textLayout.setFont(option->font);
859             textLayout.setText(option->text);
860             const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
861             const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1;
862             QRect bounds = option->rect;
863             switch (option->decorationPosition) {
864             case QStyleOptionViewItem::Left:
865             case QStyleOptionViewItem::Right:
866                 bounds.setWidth(wrapText && bounds.isValid() ? bounds.width() - 2 * textMargin : QFIXED_MAX);
867                 break;
868             case QStyleOptionViewItem::Top:
869             case QStyleOptionViewItem::Bottom:
870                 bounds.setWidth(wrapText ? option->decorationSize.width() : QFIXED_MAX);
871                 break;
872             default:
873                 break;
874             }
875
876             qreal height = 0, widthUsed = 0;
877             textLayout.beginLayout();
878             while (true) {
879                 QTextLine line = textLayout.createLine();
880                 if (!line.isValid())
881                     break;
882                 line.setLineWidth(bounds.width());
883                 line.setPosition(QPointF(0, height));
884                 height += line.height();
885                 widthUsed = qMax(widthUsed, line.naturalTextWidth());
886             }
887             textLayout.endLayout();
888             const QSize size(qCeil(widthUsed), qCeil(height));
889             return QSize(size.width() + 2 * textMargin, size.height());
890         }
891         break;
892     case Qt::DecorationRole:
893         if (option->features & QStyleOptionViewItemV2::HasDecoration) {
894             return option->decorationSize;
895         }
896         break;
897     default:
898         break;
899     }
900
901     return QSize(0, 0);
902 }
903
904 static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
905 {
906     qreal height = 0;
907     qreal widthUsed = 0;
908     textLayout.beginLayout();
909     while (true) {
910         QTextLine line = textLayout.createLine();
911         if (!line.isValid())
912             break;
913         line.setLineWidth(lineWidth);
914         line.setPosition(QPointF(0, height));
915         height += line.height();
916         widthUsed = qMax(widthUsed, line.naturalTextWidth());
917     }
918     textLayout.endLayout();
919     return QSizeF(widthUsed, height);
920 }
921
922 void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const
923 {
924     Q_Q(const QCommonStyle);
925     const QWidget *widget = option->widget;
926     const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
927
928     QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
929     const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
930     QTextOption textOption;
931     textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
932     textOption.setTextDirection(option->direction);
933     textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment));
934     QTextLayout textLayout;
935     textLayout.setTextOption(textOption);
936     textLayout.setFont(option->font);
937     textLayout.setText(option->text);
938
939     QSizeF textLayoutSize = viewItemTextLayout(textLayout, textRect.width());
940
941     QString elidedText;
942     qreal height = 0;
943     qreal width = 0;
944     int elidedIndex = -1;
945     const int lineCount = textLayout.lineCount();
946     for (int j = 0; j < lineCount; ++j) {
947         const QTextLine line = textLayout.lineAt(j);
948         if (j + 1 <= lineCount - 1) {
949             const QTextLine nextLine = textLayout.lineAt(j + 1);
950             if ((nextLine.y() + nextLine.height()) > textRect.height()) {
951                 int start = line.textStart();
952                 int length = line.textLength() + nextLine.textLength();
953                 const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
954                 elidedText = engine.elidedText(option->textElideMode, textRect.width());
955                 height += line.height();
956                 width = textRect.width();
957                 elidedIndex = j;
958                 break;
959             }
960         }
961         if (line.naturalTextWidth() > textRect.width()) {
962             int start = line.textStart();
963             int length = line.textLength();
964             const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
965             elidedText = engine.elidedText(option->textElideMode, textRect.width());
966             height += line.height();
967             width = textRect.width();
968             elidedIndex = j;
969             break;
970         }
971         width = qMax<qreal>(width, line.width());
972         height += line.height();
973     }
974
975     const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
976                                                  QSize(int(width), int(height)), textRect);
977     const QPointF position = layoutRect.topLeft();
978     for (int i = 0; i < lineCount; ++i) {
979         const QTextLine line = textLayout.lineAt(i);
980         if (i == elidedIndex) {
981             qreal x = position.x() + line.x();
982             qreal y = position.y() + line.y() + line.ascent();
983             p->save();
984             p->setFont(option->font);
985             p->drawText(QPointF(x, y), elidedText);
986             p->restore();
987             break;
988         }
989         line.draw(p, position);
990     }
991 }
992
993 /*! \internal
994     compute the position for the different component of an item (pixmap, text, checkbox)
995
996     Set sizehint to false to layout the elements inside opt->rect. Set sizehint to true to ignore
997    opt->rect and return rectangles in infinite space
998
999     Code duplicated in QItemDelegate::doLayout
1000 */
1001 void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt,  QRect *checkRect,
1002                                          QRect *pixmapRect, QRect *textRect, bool sizehint) const
1003 {
1004     Q_Q(const QCommonStyle);
1005     Q_ASSERT(checkRect && pixmapRect && textRect);
1006     *pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole));
1007     *textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole));
1008     *checkRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::CheckStateRole));
1009
1010     const QWidget *widget = opt->widget;
1011     const bool hasCheck = checkRect->isValid();
1012     const bool hasPixmap = pixmapRect->isValid();
1013     const bool hasText = textRect->isValid();
1014     const int textMargin = hasText ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1015     const int pixmapMargin = hasPixmap ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1016     const int checkMargin = hasCheck ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
1017     int x = opt->rect.left();
1018     int y = opt->rect.top();
1019     int w, h;
1020
1021     if (textRect->height() == 0 && (!hasPixmap || !sizehint)) {
1022         //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
1023         textRect->setHeight(opt->fontMetrics.height());
1024     }
1025
1026     QSize pm(0, 0);
1027     if (hasPixmap) {
1028         pm = pixmapRect->size();
1029         pm.rwidth() += 2 * pixmapMargin;
1030     }
1031     if (sizehint) {
1032         h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
1033         if (opt->decorationPosition == QStyleOptionViewItem::Left
1034             || opt->decorationPosition == QStyleOptionViewItem::Right) {
1035             w = textRect->width() + pm.width();
1036         } else {
1037             w = qMax(textRect->width(), pm.width());
1038         }
1039     } else {
1040         w = opt->rect.width();
1041         h = opt->rect.height();
1042     }
1043
1044     int cw = 0;
1045     QRect check;
1046     if (hasCheck) {
1047         cw = checkRect->width() + 2 * checkMargin;
1048         if (sizehint) w += cw;
1049         if (opt->direction == Qt::RightToLeft) {
1050             check.setRect(x + w - cw, y, cw, h);
1051         } else {
1052             check.setRect(x, y, cw, h);
1053         }
1054     }
1055
1056     QRect display;
1057     QRect decoration;
1058     switch (opt->decorationPosition) {
1059     case QStyleOptionViewItem::Top: {
1060         if (hasPixmap)
1061             pm.setHeight(pm.height() + pixmapMargin); // add space
1062         h = sizehint ? textRect->height() : h - pm.height();
1063
1064         if (opt->direction == Qt::RightToLeft) {
1065             decoration.setRect(x, y, w - cw, pm.height());
1066             display.setRect(x, y + pm.height(), w - cw, h);
1067         } else {
1068             decoration.setRect(x + cw, y, w - cw, pm.height());
1069             display.setRect(x + cw, y + pm.height(), w - cw, h);
1070         }
1071         break; }
1072     case QStyleOptionViewItem::Bottom: {
1073         if (hasText)
1074             textRect->setHeight(textRect->height() + textMargin); // add space
1075         h = sizehint ? textRect->height() + pm.height() : h;
1076
1077         if (opt->direction == Qt::RightToLeft) {
1078             display.setRect(x, y, w - cw, textRect->height());
1079             decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
1080         } else {
1081             display.setRect(x + cw, y, w - cw, textRect->height());
1082             decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
1083         }
1084         break; }
1085     case QStyleOptionViewItem::Left: {
1086         if (opt->direction == Qt::LeftToRight) {
1087             decoration.setRect(x + cw, y, pm.width(), h);
1088             display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
1089         } else {
1090             display.setRect(x, y, w - pm.width() - cw, h);
1091             decoration.setRect(display.right() + 1, y, pm.width(), h);
1092         }
1093         break; }
1094     case QStyleOptionViewItem::Right: {
1095         if (opt->direction == Qt::LeftToRight) {
1096             display.setRect(x + cw, y, w - pm.width() - cw, h);
1097             decoration.setRect(display.right() + 1, y, pm.width(), h);
1098         } else {
1099             decoration.setRect(x, y, pm.width(), h);
1100             display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
1101         }
1102         break; }
1103     default:
1104         qWarning("doLayout: decoration position is invalid");
1105         decoration = *pixmapRect;
1106         break;
1107     }
1108
1109     if (!sizehint) { // we only need to do the internal layout if we are going to paint
1110         *checkRect = QStyle::alignedRect(opt->direction, Qt::AlignCenter,
1111                                          checkRect->size(), check);
1112         *pixmapRect = QStyle::alignedRect(opt->direction, opt->decorationAlignment,
1113                                           pixmapRect->size(), decoration);
1114         // the text takes up all available space, unless the decoration is not shown as selected
1115         if (opt->showDecorationSelected)
1116             *textRect = display;
1117         else
1118             *textRect = QStyle::alignedRect(opt->direction, opt->displayAlignment,
1119                                             textRect->size().boundedTo(display.size()), display);
1120     } else {
1121         *checkRect = check;
1122         *pixmapRect = decoration;
1123         *textRect = display;
1124     }
1125 }
1126 #endif // QT_NO_ITEMVIEWS
1127
1128
1129 #ifndef QT_NO_TABBAR
1130 /*! \internal
1131     Compute the textRect and the pixmapRect from the opt rect
1132
1133     Uses the same computation than in QTabBar::tabSizeHint
1134  */
1135 void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
1136 {
1137     Q_ASSERT(textRect);
1138     Q_ASSERT(iconRect);
1139     QRect tr = opt->rect;
1140     bool verticalTabs = opt->shape == QTabBar::RoundedEast
1141                         || opt->shape == QTabBar::RoundedWest
1142                         || opt->shape == QTabBar::TriangularEast
1143                         || opt->shape == QTabBar::TriangularWest;
1144     if (verticalTabs)
1145         tr.setRect(0, 0, tr.height(), tr.width()); //0, 0 as we will have a translate transform
1146
1147     int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget);
1148     int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget);
1149     int hpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
1150     int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2;
1151     if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
1152         verticalShift = -verticalShift;
1153     tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);
1154     bool selected = opt->state & QStyle::State_Selected;
1155     if (selected) {
1156         tr.setTop(tr.top() - verticalShift);
1157         tr.setRight(tr.right() - horizontalShift);
1158     }
1159
1160     // left widget
1161     if (!opt->leftButtonSize.isEmpty()) {
1162         tr.setLeft(tr.left() + 4 +
1163             (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width()));
1164     }
1165     // right widget
1166     if (!opt->rightButtonSize.isEmpty()) {
1167         tr.setRight(tr.right() - 4 -
1168         (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width()));
1169     }
1170
1171     // icon
1172     if (!opt->icon.isNull()) {
1173         QSize iconSize = opt->iconSize;
1174         if (!iconSize.isValid()) {
1175             int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize);
1176             iconSize = QSize(iconExtent, iconExtent);
1177         }
1178         QSize tabIconSize = opt->icon.actualSize(iconSize,
1179                         (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
1180                         (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off  );
1181
1182         *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
1183                     tabIconSize.width(), tabIconSize .height());
1184         if (!verticalTabs)
1185             *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);
1186         tr.setLeft(tr.left() + tabIconSize.width() + 4);
1187     }
1188
1189     if (!verticalTabs)
1190         tr = proxyStyle->visualRect(opt->direction, opt->rect, tr);
1191
1192     *textRect = tr;
1193 }
1194 #endif //QT_NO_TABBAR
1195
1196
1197 /*!
1198   \reimp
1199 */
1200 void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
1201                                QPainter *p, const QWidget *widget) const
1202 {
1203     Q_D(const QCommonStyle);
1204     switch (element) {
1205
1206     case CE_PushButton:
1207         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1208             proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
1209             QStyleOptionButton subopt = *btn;
1210             subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
1211             proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
1212             if (btn->state & State_HasFocus) {
1213                 QStyleOptionFocusRect fropt;
1214                 fropt.QStyleOption::operator=(*btn);
1215                 fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
1216                 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1217             }
1218         }
1219         break;
1220     case CE_PushButtonBevel:
1221         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1222             QRect br = btn->rect;
1223             int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
1224             if (btn->features & QStyleOptionButton::DefaultButton)
1225                 proxy()->drawPrimitive(PE_FrameDefaultButton, opt, p, widget);
1226             if (btn->features & QStyleOptionButton::AutoDefaultButton)
1227                 br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
1228             if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton))
1229                 || btn->state & (State_Sunken | State_On)
1230                 || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) {
1231                 QStyleOptionButton tmpBtn = *btn;
1232                 tmpBtn.rect = br;
1233                 proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, p, widget);
1234             }
1235             if (btn->features & QStyleOptionButton::HasMenu) {
1236                 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
1237                 QRect ir = btn->rect;
1238                 QStyleOptionButton newBtn = *btn;
1239                 newBtn.rect = QRect(ir.right() - mbi + 2, ir.height()/2 - mbi/2 + 3, mbi - 6, mbi - 6);
1240                 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
1241             }
1242         }
1243         break;
1244  case CE_PushButtonLabel:
1245         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1246             QRect textRect = button->rect;
1247             uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
1248             if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
1249                 tf |= Qt::TextHideMnemonic;
1250
1251             if (!button->icon.isNull()) {
1252                 //Center both icon and text
1253                 QRect iconRect;
1254                 QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
1255                 if (mode == QIcon::Normal && button->state & State_HasFocus)
1256                     mode = QIcon::Active;
1257                 QIcon::State state = QIcon::Off;
1258                 if (button->state & State_On)
1259                     state = QIcon::On;
1260
1261                 QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
1262                 int labelWidth = pixmap.width();
1263                 int labelHeight = pixmap.height();
1264                 int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
1265                 int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
1266                 if (!button->text.isEmpty())
1267                     labelWidth += (textWidth + iconSpacing);
1268
1269                 iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
1270                                  textRect.y() + (textRect.height() - labelHeight) / 2,
1271                                  pixmap.width(), pixmap.height());
1272
1273                 iconRect = visualRect(button->direction, textRect, iconRect);
1274
1275                 tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
1276
1277                 if (button->direction == Qt::RightToLeft)
1278                     textRect.setRight(iconRect.left() - iconSpacing);
1279                 else
1280                     textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
1281
1282                 if (button->state & (State_On | State_Sunken))
1283                     iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
1284                                        proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
1285                 p->drawPixmap(iconRect, pixmap);
1286             } else {
1287                 tf |= Qt::AlignHCenter;
1288             }
1289             if (button->state & (State_On | State_Sunken))
1290                 textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
1291                              proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
1292
1293             if (button->features & QStyleOptionButton::HasMenu) {
1294                 int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
1295                 if (button->direction == Qt::LeftToRight)
1296                     textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
1297                 else
1298                     textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
1299             }
1300             proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
1301                          button->text, QPalette::ButtonText);
1302         }
1303         break;
1304     case CE_RadioButton:
1305     case CE_CheckBox:
1306         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1307             bool isRadio = (element == CE_RadioButton);
1308             QStyleOptionButton subopt = *btn;
1309             subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
1310                                                  : SE_CheckBoxIndicator, btn, widget);
1311             proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
1312                           &subopt, p, widget);
1313             subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
1314                                                  : SE_CheckBoxContents, btn, widget);
1315             proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
1316             if (btn->state & State_HasFocus) {
1317                 QStyleOptionFocusRect fropt;
1318                 fropt.QStyleOption::operator=(*btn);
1319                 fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
1320                                                     : SE_CheckBoxFocusRect, btn, widget);
1321                 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1322             }
1323         }
1324         break;
1325     case CE_RadioButtonLabel:
1326     case CE_CheckBoxLabel:
1327         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
1328             uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
1329
1330             if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
1331                 alignment |= Qt::TextHideMnemonic;
1332             QPixmap pix;
1333             QRect textRect = btn->rect;
1334             if (!btn->icon.isNull()) {
1335                 pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
1336                 proxy()->drawItemPixmap(p, btn->rect, alignment, pix);
1337                 if (btn->direction == Qt::RightToLeft)
1338                     textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
1339                 else
1340                     textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
1341             }
1342             if (!btn->text.isEmpty()){
1343                 proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
1344                     btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
1345             }
1346         }
1347         break;
1348 #ifndef QT_NO_MENU
1349     case CE_MenuScroller: {
1350         p->fillRect(opt->rect, opt->palette.background());
1351         QStyleOption arrowOpt = *opt;
1352         arrowOpt.state |= State_Enabled;
1353         proxy()->drawPrimitive(((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp),
1354                     &arrowOpt, p, widget);
1355         break; }
1356     case CE_MenuTearoff:
1357         if (opt->state & State_Selected)
1358             p->fillRect(opt->rect, opt->palette.brush(QPalette::Highlight));
1359         else
1360             p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
1361         p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
1362         p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2 - 1,
1363                     opt->rect.x() + opt->rect.width() - 4,
1364                     opt->rect.y() + opt->rect.height() / 2 - 1);
1365         p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
1366         p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2,
1367                     opt->rect.x() + opt->rect.width() - 4, opt->rect.y() + opt->rect.height() / 2);
1368         break;
1369 #endif // QT_NO_MENU
1370 #ifndef QT_NO_MENUBAR
1371     case CE_MenuBarItem:
1372         if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1373             uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip
1374                             | Qt::TextSingleLine;
1375             if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
1376                 alignment |= Qt::TextHideMnemonic;
1377             QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1378             if (!pix.isNull())
1379                 proxy()->drawItemPixmap(p,mbi->rect, alignment, pix);
1380             else
1381                 proxy()->drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled,
1382                              mbi->text, QPalette::ButtonText);
1383         }
1384         break;
1385     case CE_MenuBarEmptyArea:
1386         if (widget && !widget->testAttribute(Qt::WA_NoSystemBackground))
1387             p->eraseRect(opt->rect);
1388         break;
1389 #endif // QT_NO_MENUBAR
1390 #ifndef QT_NO_PROGRESSBAR
1391     case CE_ProgressBar:
1392         if (const QStyleOptionProgressBar *pb
1393                 = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1394             QStyleOptionProgressBarV2 subopt = *pb;
1395             subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget);
1396             proxy()->drawControl(CE_ProgressBarGroove, &subopt, p, widget);
1397             subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget);
1398             proxy()->drawControl(CE_ProgressBarContents, &subopt, p, widget);
1399             if (pb->textVisible) {
1400                 subopt.rect = subElementRect(SE_ProgressBarLabel, pb, widget);
1401                 proxy()->drawControl(CE_ProgressBarLabel, &subopt, p, widget);
1402             }
1403         }
1404         break;
1405     case CE_ProgressBarGroove:
1406         if (opt->rect.isValid())
1407             qDrawShadePanel(p, opt->rect, opt->palette, true, 1,
1408                             &opt->palette.brush(QPalette::Window));
1409         break;
1410     case CE_ProgressBarLabel:
1411         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1412             bool vertical = false;
1413             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
1414                 vertical = (pb2->orientation == Qt::Vertical);
1415             }
1416             if (!vertical) {
1417                 QPalette::ColorRole textRole = QPalette::NoRole;
1418                 if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible
1419                     && ((qint64(pb->progress) - qint64(pb->minimum)) * 2 >= (qint64(pb->maximum) - qint64(pb->minimum)))) {
1420                     textRole = QPalette::HighlightedText;
1421                     //Draw text shadow, This will increase readability when the background of same color
1422                     QRect shadowRect(pb->rect);
1423                     shadowRect.translate(1,1);
1424                     QColor shadowColor = (pb->palette.color(textRole).value() <= 128)
1425                        ? QColor(255,255,255,160) : QColor(0,0,0,160);
1426                     QPalette shadowPalette = pb->palette;
1427                     shadowPalette.setColor(textRole, shadowColor);
1428                     proxy()->drawItemText(p, shadowRect, Qt::AlignCenter | Qt::TextSingleLine, shadowPalette,
1429                                  pb->state & State_Enabled, pb->text, textRole);
1430                 }
1431                 proxy()->drawItemText(p, pb->rect, Qt::AlignCenter | Qt::TextSingleLine, pb->palette,
1432                              pb->state & State_Enabled, pb->text, textRole);
1433             }
1434         }
1435         break;
1436     case CE_ProgressBarContents:
1437         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1438
1439             QRect rect = pb->rect;
1440             bool vertical = false;
1441             bool inverted = false;
1442             qint64 minimum = qint64(pb->minimum);
1443             qint64 maximum = qint64(pb->maximum);
1444             qint64 progress = qint64(pb->progress);
1445
1446             // Get extra style options if version 2
1447             const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
1448             if (pb2) {
1449                 vertical = (pb2->orientation == Qt::Vertical);
1450                 inverted = pb2->invertedAppearance;
1451             }
1452             QMatrix m;
1453
1454             if (vertical) {
1455                 rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
1456                 m.rotate(90);
1457                 m.translate(0, -(rect.height() + rect.y()*2));
1458             }
1459
1460             QPalette pal2 = pb->palette;
1461             // Correct the highlight color if it is the same as the background
1462             if (pal2.highlight() == pal2.background())
1463                 pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
1464                                                                      QPalette::Highlight));
1465             bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1466             if (inverted)
1467                 reverse = !reverse;
1468             int w = rect.width();
1469             if (pb->minimum == 0 && pb->maximum == 0) {
1470                 // draw busy indicator
1471                 int x = (progress - minimum) % (w * 2);
1472                 if (x > w)
1473                     x = 2 * w - x;
1474                 x = reverse ? rect.right() - x : x + rect.x();
1475                 p->setPen(QPen(pal2.highlight().color(), 4));
1476                 p->drawLine(x, rect.y(), x, rect.height());
1477             } else {
1478                 const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
1479                 if (!unit_width)
1480                     return;
1481
1482                 int u;
1483                 if (unit_width > 1)
1484                     u = ((rect.width() + unit_width) / unit_width);
1485                 else
1486                     u = w / unit_width;
1487                 qint64 p_v = progress - minimum;
1488                 qint64 t_s = (maximum - minimum) ? (maximum - minimum) : qint64(1);
1489
1490                 if (u > 0 && p_v >= INT_MAX / u && t_s >= u) {
1491                     // scale down to something usable.
1492                     p_v /= u;
1493                     t_s /= u;
1494                 }
1495
1496                 // nu < tnu, if last chunk is only a partial chunk
1497                 int tnu, nu;
1498                 tnu = nu = p_v * u / t_s;
1499
1500                 if (nu * unit_width > w)
1501                     --nu;
1502
1503                 // Draw nu units out of a possible u of unit_width
1504                 // width, each a rectangle bordered by background
1505                 // color, all in a sunken panel with a percentage text
1506                 // display at the end.
1507                 int x = 0;
1508                 int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0)
1509                                  : rect.x();
1510
1511                 QStyleOptionProgressBarV2 pbBits = *pb;
1512                 pbBits.rect = rect;
1513                 pbBits.palette = pal2;
1514                 int myY = pbBits.rect.y();
1515                 int myHeight = pbBits.rect.height();
1516                 pbBits.state = State_None;
1517                 for (int i = 0; i < nu; ++i) {
1518                     pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
1519                     pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1520                     proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1521                     x += reverse ? -unit_width : unit_width;
1522                 }
1523
1524                 // Draw the last partial chunk to fill up the
1525                 // progress bar entirely
1526                 if (nu < tnu) {
1527                     int pixels_left = w - (nu * unit_width);
1528                     int offset = reverse ? x0 + x + unit_width-pixels_left : x0 + x;
1529                     pbBits.rect.setRect(offset, myY, pixels_left, myHeight);
1530                     pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
1531                     proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
1532                 }
1533             }
1534         }
1535         break;
1536 #endif // QT_NO_PROGRESSBAR
1537     case CE_HeaderLabel:
1538         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
1539             QRect rect = header->rect;
1540             if (!header->icon.isNull()) {
1541                 QPixmap pixmap
1542                     = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
1543                 int pixw = pixmap.width();
1544
1545                 QRect aligned = alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size(), rect);
1546                 QRect inter = aligned.intersected(rect);
1547                 p->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
1548
1549                 if (header->direction == Qt::LeftToRight)
1550                     rect.setLeft(rect.left() + pixw + 2);
1551                 else
1552                     rect.setRight(rect.right() - pixw - 2);
1553             }
1554             if (header->state & QStyle::State_On) {
1555                 QFont fnt = p->font();
1556                 fnt.setBold(true);
1557                 p->setFont(fnt);
1558             }
1559             proxy()->drawItemText(p, rect, header->textAlignment, header->palette,
1560                          (header->state & State_Enabled), header->text, QPalette::ButtonText);
1561         }
1562         break;
1563 #ifndef QT_NO_TOOLBUTTON
1564     case CE_ToolButtonLabel:
1565         if (const QStyleOptionToolButton *toolbutton
1566                 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
1567             QRect rect = toolbutton->rect;
1568             int shiftX = 0;
1569             int shiftY = 0;
1570             if (toolbutton->state & (State_Sunken | State_On)) {
1571                 shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, toolbutton, widget);
1572                 shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, toolbutton, widget);
1573             }
1574             // Arrow type always overrules and is always shown
1575             bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow;
1576             if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty())
1577                 || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) {
1578                 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1579                 if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1580                     alignment |= Qt::TextHideMnemonic;
1581                 rect.translate(shiftX, shiftY);
1582                 p->setFont(toolbutton->font);
1583                 proxy()->drawItemText(p, rect, alignment, toolbutton->palette,
1584                              opt->state & State_Enabled, toolbutton->text,
1585                              QPalette::ButtonText);
1586             } else {
1587                 QPixmap pm;
1588                 QSize pmSize = toolbutton->iconSize;
1589                 if (!toolbutton->icon.isNull()) {
1590                     QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off;
1591                     QIcon::Mode mode;
1592                     if (!(toolbutton->state & State_Enabled))
1593                         mode = QIcon::Disabled;
1594                     else if ((opt->state & State_MouseOver) && (opt->state & State_AutoRaise))
1595                         mode = QIcon::Active;
1596                     else
1597                         mode = QIcon::Normal;
1598                     pm = toolbutton->icon.pixmap(toolbutton->rect.size().boundedTo(toolbutton->iconSize),
1599                                                  mode, state);
1600                     pmSize = pm.size();
1601                 }
1602
1603                 if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) {
1604                     p->setFont(toolbutton->font);
1605                     QRect pr = rect,
1606                     tr = rect;
1607                     int alignment = Qt::TextShowMnemonic;
1608                     if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1609                         alignment |= Qt::TextHideMnemonic;
1610
1611                     if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
1612                         pr.setHeight(pmSize.height() + 6);
1613                         tr.adjust(0, pr.height() - 1, 0, -2);
1614                         pr.translate(shiftX, shiftY);
1615                         if (!hasArrow) {
1616                             proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm);
1617                         } else {
1618                             drawArrow(this, toolbutton, pr, p, widget);
1619                         }
1620                         alignment |= Qt::AlignCenter;
1621                     } else {
1622                         pr.setWidth(pmSize.width() + 8);
1623                         tr.adjust(pr.width(), 0, 0, 0);
1624                         pr.translate(shiftX, shiftY);
1625                         if (!hasArrow) {
1626                             proxy()->drawItemPixmap(p, QStyle::visualRect(opt->direction, rect, pr), Qt::AlignCenter, pm);
1627                         } else {
1628                             drawArrow(this, toolbutton, pr, p, widget);
1629                         }
1630                         alignment |= Qt::AlignLeft | Qt::AlignVCenter;
1631                     }
1632                     tr.translate(shiftX, shiftY);
1633                     proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
1634                                  toolbutton->state & State_Enabled, toolbutton->text,
1635                                  QPalette::ButtonText);
1636                 } else {
1637                     rect.translate(shiftX, shiftY);
1638                     if (hasArrow) {
1639                         drawArrow(this, toolbutton, rect, p, widget);
1640                     } else {
1641                         proxy()->drawItemPixmap(p, rect, Qt::AlignCenter, pm);
1642                     }
1643                 }
1644             }
1645         }
1646         break;
1647 #endif // QT_NO_TOOLBUTTON
1648 #ifndef QT_NO_TOOLBOX
1649     case CE_ToolBoxTab:
1650         if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1651             proxy()->drawControl(CE_ToolBoxTabShape, tb, p, widget);
1652             proxy()->drawControl(CE_ToolBoxTabLabel, tb, p, widget);
1653         }
1654         break;
1655     case CE_ToolBoxTabShape:
1656         if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1657             int d = 20 + tb->rect.height() - 3;
1658             QPolygon a(7);
1659             if (tb->direction != Qt::RightToLeft) {
1660                 a.setPoint(0, -1, tb->rect.height() + 1);
1661                 a.setPoint(1, -1, 1);
1662                 a.setPoint(2, tb->rect.width() - d, 1);
1663                 a.setPoint(3, tb->rect.width() - 20, tb->rect.height() - 2);
1664                 a.setPoint(4, tb->rect.width() - 1, tb->rect.height() - 2);
1665                 a.setPoint(5, tb->rect.width() - 1, tb->rect.height() + 1);
1666                 a.setPoint(6, -1, tb->rect.height() + 1);
1667             } else {
1668                 a.setPoint(0, tb->rect.width(), tb->rect.height() + 1);
1669                 a.setPoint(1, tb->rect.width(), 1);
1670                 a.setPoint(2, d - 1, 1);
1671                 a.setPoint(3, 20 - 1, tb->rect.height() - 2);
1672                 a.setPoint(4, 0, tb->rect.height() - 2);
1673                 a.setPoint(5, 0, tb->rect.height() + 1);
1674                 a.setPoint(6, tb->rect.width(), tb->rect.height() + 1);
1675             }
1676
1677             p->setPen(tb->palette.mid().color().darker(150));
1678             p->drawPolygon(a);
1679             p->setPen(tb->palette.light().color());
1680             if (tb->direction != Qt::RightToLeft) {
1681                 p->drawLine(0, 2, tb->rect.width() - d, 2);
1682                 p->drawLine(tb->rect.width() - d - 1, 2, tb->rect.width() - 21, tb->rect.height() - 1);
1683                 p->drawLine(tb->rect.width() - 20, tb->rect.height() - 1,
1684                             tb->rect.width(), tb->rect.height() - 1);
1685             } else {
1686                 p->drawLine(tb->rect.width() - 1, 2, d - 1, 2);
1687                 p->drawLine(d, 2, 20, tb->rect.height() - 1);
1688                 p->drawLine(19, tb->rect.height() - 1,
1689                             -1, tb->rect.height() - 1);
1690             }
1691             p->setBrush(Qt::NoBrush);
1692         }
1693         break;
1694 #endif // QT_NO_TOOLBOX
1695 #ifndef QT_NO_TABBAR
1696     case CE_TabBarTab:
1697         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1698             proxy()->drawControl(CE_TabBarTabShape, tab, p, widget);
1699             proxy()->drawControl(CE_TabBarTabLabel, tab, p, widget);
1700         }
1701         break;
1702     case CE_TabBarTabShape:
1703         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1704             p->save();
1705
1706             QRect rect(tab->rect);
1707             bool selected = tab->state & State_Selected;
1708             bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1709             int tabOverlap = onlyOne ? 0 : proxy()->pixelMetric(PM_TabBarTabOverlap, opt, widget);
1710
1711             if (!selected) {
1712                 switch (tab->shape) {
1713                 case QTabBar::TriangularNorth:
1714                     rect.adjust(0, 0, 0, -tabOverlap);
1715                     if(!selected)
1716                         rect.adjust(1, 1, -1, 0);
1717                     break;
1718                 case QTabBar::TriangularSouth:
1719                     rect.adjust(0, tabOverlap, 0, 0);
1720                     if(!selected)
1721                         rect.adjust(1, 0, -1, -1);
1722                     break;
1723                 case QTabBar::TriangularEast:
1724                     rect.adjust(tabOverlap, 0, 0, 0);
1725                     if(!selected)
1726                         rect.adjust(0, 1, -1, -1);
1727                     break;
1728                 case QTabBar::TriangularWest:
1729                     rect.adjust(0, 0, -tabOverlap, 0);
1730                     if(!selected)
1731                         rect.adjust(1, 1, 0, -1);
1732                     break;
1733                 default:
1734                     break;
1735                 }
1736             }
1737
1738             p->setPen(QPen(tab->palette.foreground(), 0));
1739             if (selected) {
1740                 p->setBrush(tab->palette.base());
1741             } else {
1742                 if (widget && widget->parentWidget())
1743                     p->setBrush(widget->parentWidget()->palette().background());
1744                 else
1745                     p->setBrush(tab->palette.background());
1746             }
1747
1748             int y;
1749             int x;
1750             QPolygon a(10);
1751             switch (tab->shape) {
1752             case QTabBar::TriangularNorth:
1753             case QTabBar::TriangularSouth: {
1754                 a.setPoint(0, 0, -1);
1755                 a.setPoint(1, 0, 0);
1756                 y = rect.height() - 2;
1757                 x = y / 3;
1758                 a.setPoint(2, x++, y - 1);
1759                 ++x;
1760                 a.setPoint(3, x++, y++);
1761                 a.setPoint(4, x, y);
1762
1763                 int i;
1764                 int right = rect.width() - 1;
1765                 for (i = 0; i < 5; ++i)
1766                     a.setPoint(9 - i, right - a.point(i).x(), a.point(i).y());
1767                 if (tab->shape == QTabBar::TriangularNorth)
1768                     for (i = 0; i < 10; ++i)
1769                         a.setPoint(i, a.point(i).x(), rect.height() - 1 - a.point(i).y());
1770
1771                 a.translate(rect.left(), rect.top());
1772                 p->setRenderHint(QPainter::Antialiasing);
1773                 p->translate(0, 0.5);
1774
1775                 QPainterPath path;
1776                 path.addPolygon(a);
1777                 p->drawPath(path);
1778                 break; }
1779             case QTabBar::TriangularEast:
1780             case QTabBar::TriangularWest: {
1781                 a.setPoint(0, -1, 0);
1782                 a.setPoint(1, 0, 0);
1783                 x = rect.width() - 2;
1784                 y = x / 3;
1785                 a.setPoint(2, x - 1, y++);
1786                 ++y;
1787                 a.setPoint(3, x++, y++);
1788                 a.setPoint(4, x, y);
1789                 int i;
1790                 int bottom = rect.height() - 1;
1791                 for (i = 0; i < 5; ++i)
1792                     a.setPoint(9 - i, a.point(i).x(), bottom - a.point(i).y());
1793                 if (tab->shape == QTabBar::TriangularWest)
1794                     for (i = 0; i < 10; ++i)
1795                         a.setPoint(i, rect.width() - 1 - a.point(i).x(), a.point(i).y());
1796                 a.translate(rect.left(), rect.top());
1797                 p->setRenderHint(QPainter::Antialiasing);
1798                 p->translate(0.5, 0);
1799                 QPainterPath path;
1800                 path.addPolygon(a);
1801                 p->drawPath(path);
1802                 break; }
1803             default:
1804                 break;
1805             }
1806             p->restore();
1807         }
1808         break;
1809     case CE_ToolBoxTabLabel:
1810         if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
1811             bool enabled = tb->state & State_Enabled;
1812             bool selected = tb->state & State_Selected;
1813             QPixmap pm = tb->icon.pixmap(proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb, widget),
1814                                          enabled ? QIcon::Normal : QIcon::Disabled);
1815
1816             QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget);
1817             QRect tr, ir;
1818             int ih = 0;
1819             if (pm.isNull()) {
1820                 tr = cr;
1821                 tr.adjust(4, 0, -8, 0);
1822             } else {
1823                 int iw = pm.width() + 4;
1824                 ih = pm.height();
1825                 ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
1826                 tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
1827             }
1828
1829             if (selected && proxy()->styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb, widget)) {
1830                 QFont f(p->font());
1831                 f.setBold(true);
1832                 p->setFont(f);
1833             }
1834
1835             QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width());
1836
1837             if (ih)
1838                 p->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm);
1839
1840             int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
1841             if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, tb, widget))
1842                 alignment |= Qt::TextHideMnemonic;
1843             proxy()->drawItemText(p, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText);
1844
1845             if (!txt.isEmpty() && opt->state & State_HasFocus) {
1846                 QStyleOptionFocusRect opt;
1847                 opt.rect = tr;
1848                 opt.palette = tb->palette;
1849                 opt.state = QStyle::State_None;
1850                 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, widget);
1851             }
1852         }
1853         break;
1854     case CE_TabBarTabLabel:
1855         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
1856             QStyleOptionTabV3 tabV2(*tab);
1857             QRect tr = tabV2.rect;
1858             bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
1859                                 || tabV2.shape == QTabBar::RoundedWest
1860                                 || tabV2.shape == QTabBar::TriangularEast
1861                                 || tabV2.shape == QTabBar::TriangularWest;
1862
1863             int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
1864             if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
1865                 alignment |= Qt::TextHideMnemonic;
1866
1867             if (verticalTabs) {
1868                 p->save();
1869                 int newX, newY, newRot;
1870                 if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
1871                     newX = tr.width() + tr.x();
1872                     newY = tr.y();
1873                     newRot = 90;
1874                 } else {
1875                     newX = tr.x();
1876                     newY = tr.y() + tr.height();
1877                     newRot = -90;
1878                 }
1879                 QTransform m = QTransform::fromTranslate(newX, newY);
1880                 m.rotate(newRot);
1881                 p->setTransform(m, true);
1882             }
1883             QRect iconRect;
1884             d->tabLayout(&tabV2, widget, &tr, &iconRect);
1885             tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect
1886
1887             if (!tabV2.icon.isNull()) {
1888                 QPixmap tabIcon = tabV2.icon.pixmap(tabV2.iconSize,
1889                                                     (tabV2.state & State_Enabled) ? QIcon::Normal
1890                                                                                   : QIcon::Disabled,
1891                                                     (tabV2.state & State_Selected) ? QIcon::On
1892                                                                                    : QIcon::Off);
1893                 p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
1894             }
1895
1896             proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
1897             if (verticalTabs)
1898                 p->restore();
1899
1900             if (tabV2.state & State_HasFocus) {
1901                 const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);
1902
1903                 int x1, x2;
1904                 x1 = tabV2.rect.left();
1905                 x2 = tabV2.rect.right() - 1;
1906
1907                 QStyleOptionFocusRect fropt;
1908                 fropt.QStyleOption::operator=(*tab);
1909                 fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
1910                                    x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
1911                 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
1912             }
1913         }
1914         break;
1915 #endif // QT_NO_TABBAR
1916 #ifndef QT_NO_SIZEGRIP
1917     case CE_SizeGrip: {
1918         p->save();
1919         int x, y, w, h;
1920         opt->rect.getRect(&x, &y, &w, &h);
1921
1922         int sw = qMin(h, w);
1923         if (h > w)
1924             p->translate(0, h - w);
1925         else
1926             p->translate(w - h, 0);
1927
1928         int sx = x;
1929         int sy = y;
1930         int s = sw / 3;
1931
1932         Qt::Corner corner;
1933         if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt))
1934             corner = sgOpt->corner;
1935         else if (opt->direction == Qt::RightToLeft)
1936             corner = Qt::BottomLeftCorner;
1937         else
1938             corner = Qt::BottomRightCorner;
1939
1940         if (corner == Qt::BottomLeftCorner) {
1941             sx = x + sw;
1942             for (int i = 0; i < 4; ++i) {
1943                 p->setPen(QPen(opt->palette.light().color(), 1));
1944                 p->drawLine(x, sy - 1 , sx + 1, sw);
1945                 p->setPen(QPen(opt->palette.dark().color(), 1));
1946                 p->drawLine(x, sy, sx, sw);
1947                 p->setPen(QPen(opt->palette.dark().color(), 1));
1948                 p->drawLine(x, sy + 1, sx - 1, sw);
1949                 sx -= s;
1950                 sy += s;
1951             }
1952         } else if (corner == Qt::BottomRightCorner) {
1953             for (int i = 0; i < 4; ++i) {
1954                 p->setPen(QPen(opt->palette.light().color(), 1));
1955                 p->drawLine(sx - 1, sw, sw, sy - 1);
1956                 p->setPen(QPen(opt->palette.dark().color(), 1));
1957                 p->drawLine(sx, sw, sw, sy);
1958                 p->setPen(QPen(opt->palette.dark().color(), 1));
1959                 p->drawLine(sx + 1, sw, sw, sy + 1);
1960                 sx += s;
1961                 sy += s;
1962             }
1963         } else if (corner == Qt::TopRightCorner) {
1964             sy = y + sw;
1965             for (int i = 0; i < 4; ++i) {
1966                 p->setPen(QPen(opt->palette.light().color(), 1));
1967                 p->drawLine(sx - 1, y, sw, sy + 1);
1968                 p->setPen(QPen(opt->palette.dark().color(), 1));
1969                 p->drawLine(sx, y, sw, sy);
1970                 p->setPen(QPen(opt->palette.dark().color(), 1));
1971                 p->drawLine(sx + 1, y, sw, sy - 1);
1972                 sx += s;
1973                 sy -= s;
1974             }
1975         } else if (corner == Qt::TopLeftCorner) {
1976             for (int i = 0; i < 4; ++i) {
1977                 p->setPen(QPen(opt->palette.light().color(), 1));
1978                 p->drawLine(x, sy - 1, sx - 1, y);
1979                 p->setPen(QPen(opt->palette.dark().color(), 1));
1980                 p->drawLine(x, sy, sx, y);
1981                 p->setPen(QPen(opt->palette.dark().color(), 1));
1982                 p->drawLine(x, sy + 1, sx + 1, y);
1983                 sx += s;
1984                 sy += s;
1985             }
1986         }
1987         p->restore();
1988         break; }
1989 #endif // QT_NO_SIZEGRIP
1990 #ifndef QT_NO_RUBBERBAND
1991     case CE_RubberBand: {
1992         if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
1993             QPixmap tiledPixmap(16, 16);
1994             QPainter pixmapPainter(&tiledPixmap);
1995             pixmapPainter.setPen(Qt::NoPen);
1996             pixmapPainter.setBrush(Qt::Dense4Pattern);
1997             pixmapPainter.setBackground(QBrush(opt->palette.base()));
1998             pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
1999             pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
2000             pixmapPainter.end();
2001             // ### workaround for borked XRENDER
2002             tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
2003
2004             p->save();
2005             QRect r = opt->rect;
2006             QStyleHintReturnMask mask;
2007             if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
2008                 p->setClipRegion(mask.region);
2009             p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
2010             p->setPen(opt->palette.color(QPalette::Active, QPalette::WindowText));
2011             p->setBrush(Qt::NoBrush);
2012             p->drawRect(r.adjusted(0, 0, -1, -1));
2013             if (rbOpt->shape == QRubberBand::Rectangle)
2014                 p->drawRect(r.adjusted(3, 3, -4, -4));
2015             p->restore();
2016         }
2017         break; }
2018 #endif // QT_NO_RUBBERBAND
2019 #ifndef QT_NO_DOCKWIDGET
2020     case CE_DockWidgetTitle:
2021         if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
2022             QRect r = dwOpt->rect.adjusted(0, 0, -1, -1);
2023             if (dwOpt->movable) {
2024                 p->setPen(dwOpt->palette.color(QPalette::Dark));
2025                 p->drawRect(r);
2026             }
2027
2028             if (!dwOpt->title.isEmpty()) {
2029                 const QStyleOptionDockWidgetV2 *v2
2030                     = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
2031                 bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
2032
2033                 if (verticalTitleBar) {
2034                     QSize s = r.size();
2035                     s.transpose();
2036                     r.setSize(s);
2037
2038                     p->save();
2039                     p->translate(r.left(), r.top() + r.width());
2040                     p->rotate(-90);
2041                     p->translate(-r.left(), -r.top());
2042                 }
2043
2044                 const int indent = p->fontMetrics().descent();
2045                 proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1),
2046                               Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
2047                               dwOpt->state & State_Enabled, dwOpt->title,
2048                               QPalette::WindowText);
2049
2050                 if (verticalTitleBar)
2051                     p->restore();
2052             }
2053         }
2054         break;
2055 #endif // QT_NO_DOCKWIDGET
2056     case CE_Header:
2057         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2058             QRegion clipRegion = p->clipRegion();
2059             p->setClipRect(opt->rect);
2060             proxy()->drawControl(CE_HeaderSection, header, p, widget);
2061             QStyleOptionHeader subopt = *header;
2062             subopt.rect = subElementRect(SE_HeaderLabel, header, widget);
2063             if (subopt.rect.isValid())
2064                 proxy()->drawControl(CE_HeaderLabel, &subopt, p, widget);
2065             if (header->sortIndicator != QStyleOptionHeader::None) {
2066                 subopt.rect = subElementRect(SE_HeaderArrow, opt, widget);
2067                 proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, p, widget);
2068             }
2069             p->setClipRegion(clipRegion);
2070         }
2071         break;
2072     case CE_FocusFrame:
2073             p->fillRect(opt->rect, opt->palette.foreground());
2074         break;
2075     case CE_HeaderSection:
2076             qDrawShadePanel(p, opt->rect, opt->palette,
2077                         opt->state & State_Sunken, 1,
2078                         &opt->palette.brush(QPalette::Button));
2079         break;
2080     case CE_HeaderEmptyArea:
2081             p->fillRect(opt->rect, opt->palette.background());
2082         break;
2083 #ifndef QT_NO_COMBOBOX
2084     case CE_ComboBoxLabel:
2085         if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2086             QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
2087             p->save();
2088             p->setClipRect(editRect);
2089             if (!cb->currentIcon.isNull()) {
2090                 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
2091                                                              : QIcon::Disabled;
2092                 QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
2093                 QRect iconRect(editRect);
2094                 iconRect.setWidth(cb->iconSize.width() + 4);
2095                 iconRect = alignedRect(cb->direction,
2096                                        Qt::AlignLeft | Qt::AlignVCenter,
2097                                        iconRect.size(), editRect);
2098                 if (cb->editable)
2099                     p->fillRect(iconRect, opt->palette.brush(QPalette::Base));
2100                 proxy()->drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
2101
2102                 if (cb->direction == Qt::RightToLeft)
2103                     editRect.translate(-4 - cb->iconSize.width(), 0);
2104                 else
2105                     editRect.translate(cb->iconSize.width() + 4, 0);
2106             }
2107             if (!cb->currentText.isEmpty() && !cb->editable) {
2108                 proxy()->drawItemText(p, editRect.adjusted(1, 0, -1, 0),
2109                              visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
2110                              cb->palette, cb->state & State_Enabled, cb->currentText);
2111             }
2112             p->restore();
2113         }
2114         break;
2115 #endif // QT_NO_COMBOBOX
2116 #ifndef QT_NO_TOOLBAR
2117     case CE_ToolBar:
2118         if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
2119             // Compatibility with styles that use PE_PanelToolBar
2120             QStyleOptionFrame frame;
2121             frame.QStyleOption::operator=(*toolBar);
2122             frame.lineWidth = toolBar->lineWidth;
2123             frame.midLineWidth = toolBar->midLineWidth;
2124             proxy()->drawPrimitive(PE_PanelToolBar, opt, p, widget);
2125
2126             if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
2127                 break;
2128             qDrawShadePanel(p, toolBar->rect, toolBar->palette, false, toolBar->lineWidth,
2129                             &toolBar->palette.brush(QPalette::Button));
2130         }
2131         break;
2132 #endif // QT_NO_TOOLBAR
2133     case CE_ColumnViewGrip: {
2134         // draw background gradients
2135         QLinearGradient g(0, 0, opt->rect.width(), 0);
2136         g.setColorAt(0, opt->palette.color(QPalette::Active, QPalette::Mid));
2137         g.setColorAt(0.5, Qt::white);
2138         p->fillRect(QRect(0, 0, opt->rect.width(), opt->rect.height()), g);
2139
2140         // draw the two lines
2141         QPen pen(p->pen());
2142         pen.setWidth(opt->rect.width()/20);
2143         pen.setColor(opt->palette.color(QPalette::Active, QPalette::Dark));
2144         p->setPen(pen);
2145
2146         int line1starting = opt->rect.width()*8 / 20;
2147         int line2starting = opt->rect.width()*13 / 20;
2148         int top = opt->rect.height()*20/75;
2149         int bottom = opt->rect.height() - 1 - top;
2150         p->drawLine(line1starting, top, line1starting, bottom);
2151         p->drawLine(line2starting, top, line2starting, bottom);
2152         }
2153         break;
2154
2155 #ifndef QT_NO_ITEMVIEWS
2156     case CE_ItemViewItem:
2157         if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
2158             p->save();
2159             p->setClipRect(opt->rect);
2160
2161             QRect checkRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
2162             QRect iconRect = subElementRect(SE_ItemViewItemDecoration, vopt, widget);
2163             QRect textRect = subElementRect(SE_ItemViewItemText, vopt, widget);
2164
2165             // draw the background
2166             proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);
2167
2168             // draw the check mark
2169             if (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) {
2170                 QStyleOptionViewItemV4 option(*vopt);
2171                 option.rect = checkRect;
2172                 option.state = option.state & ~QStyle::State_HasFocus;
2173
2174                 switch (vopt->checkState) {
2175                 case Qt::Unchecked:
2176                     option.state |= QStyle::State_Off;
2177                     break;
2178                 case Qt::PartiallyChecked:
2179                     option.state |= QStyle::State_NoChange;
2180                     break;
2181                 case Qt::Checked:
2182                     option.state |= QStyle::State_On;
2183                     break;
2184                 }
2185                 proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, p, widget);
2186             }
2187
2188             // draw the icon
2189             QIcon::Mode mode = QIcon::Normal;
2190             if (!(vopt->state & QStyle::State_Enabled))
2191                 mode = QIcon::Disabled;
2192             else if (vopt->state & QStyle::State_Selected)
2193                 mode = QIcon::Selected;
2194             QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
2195             vopt->icon.paint(p, iconRect, vopt->decorationAlignment, mode, state);
2196
2197             // draw the text
2198             if (!vopt->text.isEmpty()) {
2199                 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
2200                                       ? QPalette::Normal : QPalette::Disabled;
2201                 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
2202                     cg = QPalette::Inactive;
2203
2204                 if (vopt->state & QStyle::State_Selected) {
2205                     p->setPen(vopt->palette.color(cg, QPalette::HighlightedText));
2206                 } else {
2207                     p->setPen(vopt->palette.color(cg, QPalette::Text));
2208                 }
2209                 if (vopt->state & QStyle::State_Editing) {
2210                     p->setPen(vopt->palette.color(cg, QPalette::Text));
2211                     p->drawRect(textRect.adjusted(0, 0, -1, -1));
2212                 }
2213
2214                 d->viewItemDrawText(p, vopt, textRect);
2215             }
2216
2217             // draw the focus rect
2218              if (vopt->state & QStyle::State_HasFocus) {
2219                 QStyleOptionFocusRect o;
2220                 o.QStyleOption::operator=(*vopt);
2221                 o.rect = subElementRect(SE_ItemViewItemFocusRect, vopt, widget);
2222                 o.state |= QStyle::State_KeyboardFocusChange;
2223                 o.state |= QStyle::State_Item;
2224                 QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled)
2225                               ? QPalette::Normal : QPalette::Disabled;
2226                 o.backgroundColor = vopt->palette.color(cg, (vopt->state & QStyle::State_Selected)
2227                                              ? QPalette::Highlight : QPalette::Window);
2228                 proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, p, widget);
2229             }
2230
2231              p->restore();
2232         }
2233         break;
2234
2235 #endif // QT_NO_ITEMVIEWS
2236 #ifndef QT_NO_FRAME
2237     case CE_ShapedFrame:
2238         if (const QStyleOptionFrameV3 *f = qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) {
2239             int frameShape  = f->frameShape;
2240             int frameShadow = QFrame::Plain;
2241             if (f->state & QStyle::State_Sunken) {
2242                 frameShadow = QFrame::Sunken;
2243             } else if (f->state & QStyle::State_Raised) {
2244                 frameShadow = QFrame::Raised;
2245             }
2246
2247             int lw = f->lineWidth;
2248             int mlw = f->midLineWidth;
2249             QPalette::ColorRole foregroundRole = QPalette::WindowText;
2250             if (widget)
2251                 foregroundRole = widget->foregroundRole();
2252
2253             switch (frameShape) {
2254             case QFrame::Box:
2255                 if (frameShadow == QFrame::Plain) {
2256                     qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2257                 } else {
2258                     qDrawShadeRect(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
2259                 }
2260                 break;
2261             case QFrame::StyledPanel:
2262                 //keep the compatibility with Qt 4.4 if there is a proxy style.
2263                 //be sure to call drawPrimitive(QStyle::PE_Frame) on the proxy style
2264                 if (widget) {
2265                     widget->style()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
2266                 } else {
2267                     proxy()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
2268                 }
2269                 break;
2270             case QFrame::Panel:
2271                 if (frameShadow == QFrame::Plain) {
2272                     qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2273                 } else {
2274                     qDrawShadePanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw);
2275                 }
2276                 break;
2277             case QFrame::WinPanel:
2278                 if (frameShadow == QFrame::Plain) {
2279                     qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
2280                 } else {
2281                     qDrawWinPanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken);
2282                 }
2283                 break;
2284             case QFrame::HLine:
2285             case QFrame::VLine: {
2286                 QPoint p1, p2;
2287                 if (frameShape == QFrame::HLine) {
2288                     p1 = QPoint(opt->rect.x(), opt->rect.height() / 2);
2289                     p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y());
2290                 } else {
2291                     p1 = QPoint(opt->rect.x()+opt->rect.width() / 2, 0);
2292                     p2 = QPoint(p1.x(), opt->rect.height());
2293                 }
2294                 if (frameShadow == QFrame::Plain) {
2295                     QPen oldPen = p->pen();
2296                     p->setPen(QPen(opt->palette.brush(foregroundRole), lw));
2297                     p->drawLine(p1, p2);
2298                     p->setPen(oldPen);
2299                 } else {
2300                     qDrawShadeLine(p, p1, p2, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
2301                 }
2302                 break;
2303                 }
2304             }
2305         }
2306         break;
2307 #endif
2308     default:
2309         break;
2310     }
2311 }
2312
2313 /*!
2314   \reimp
2315 */
2316 QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
2317                                    const QWidget *widget) const
2318 {
2319     Q_D(const QCommonStyle);
2320     QRect r;
2321     switch (sr) {
2322     case SE_PushButtonContents:
2323         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2324             int dx1, dx2;
2325             dx1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
2326             if (btn->features & QStyleOptionButton::AutoDefaultButton)
2327                 dx1 += proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2328             dx2 = dx1 * 2;
2329             r.setRect(opt->rect.x() + dx1, opt->rect.y() + dx1, opt->rect.width() - dx2,
2330                       opt->rect.height() - dx2);
2331             r = visualRect(opt->direction, opt->rect, r);
2332         }
2333         break;
2334     case SE_PushButtonFocusRect:
2335         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2336             int dbw1 = 0, dbw2 = 0;
2337             if (btn->features & QStyleOptionButton::AutoDefaultButton){
2338                 dbw1 = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
2339                 dbw2 = dbw1 * 2;
2340             }
2341
2342             int dfw1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget) + 1,
2343                 dfw2 = dfw1 * 2;
2344
2345             r.setRect(btn->rect.x() + dfw1 + dbw1, btn->rect.y() + dfw1 + dbw1,
2346                       btn->rect.width() - dfw2 - dbw2, btn->rect.height()- dfw2 - dbw2);
2347             r = visualRect(opt->direction, opt->rect, r);
2348         }
2349         break;
2350     case SE_CheckBoxIndicator:
2351         {
2352             int h = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
2353             r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
2354                       proxy()->pixelMetric(PM_IndicatorWidth, opt, widget), h);
2355             r = visualRect(opt->direction, opt->rect, r);
2356         }
2357         break;
2358
2359     case SE_CheckBoxContents:
2360         {
2361             // Deal with the logical first, then convert it back to screen coords.
2362             QRect ir = visualRect(opt->direction, opt->rect,
2363                                   subElementRect(SE_CheckBoxIndicator, opt, widget));
2364             int spacing = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget);
2365             r.setRect(ir.right() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
2366                       opt->rect.height());
2367             r = visualRect(opt->direction, opt->rect, r);
2368         }
2369         break;
2370
2371     case SE_CheckBoxFocusRect:
2372         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2373             if (btn->icon.isNull() && btn->text.isEmpty()) {
2374                 r = subElementRect(SE_CheckBoxIndicator, opt, widget);
2375                 r.adjust(1, 1, -1, -1);
2376                 break;
2377             }
2378             // As above, deal with the logical first, then convert it back to screen coords.
2379             QRect cr = visualRect(btn->direction, btn->rect,
2380                                   subElementRect(SE_CheckBoxContents, btn, widget));
2381
2382             QRect iconRect, textRect;
2383             if (!btn->text.isEmpty()) {
2384                 textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft
2385                                         | Qt::AlignVCenter | Qt::TextShowMnemonic,
2386                                         btn->state & State_Enabled, btn->text);
2387             }
2388             if (!btn->icon.isNull()) {
2389                 iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2390                                         | Qt::TextShowMnemonic,
2391                                    btn->icon.pixmap(btn->iconSize, QIcon::Normal));
2392                 if (!textRect.isEmpty())
2393                     textRect.translate(iconRect.right() + 4, 0);
2394             }
2395             r = iconRect | textRect;
2396             r.adjust(-3, -2, 3, 2);
2397             r = r.intersected(btn->rect);
2398             r = visualRect(btn->direction, btn->rect, r);
2399         }
2400         break;
2401
2402     case SE_RadioButtonIndicator:
2403         {
2404             int h = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget);
2405             r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
2406                     proxy()->pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), h);
2407             r = visualRect(opt->direction, opt->rect, r);
2408         }
2409         break;
2410
2411     case SE_RadioButtonContents:
2412         {
2413             QRect ir = visualRect(opt->direction, opt->rect,
2414                                   subElementRect(SE_RadioButtonIndicator, opt, widget));
2415             int spacing = proxy()->pixelMetric(PM_RadioButtonLabelSpacing, opt, widget);
2416             r.setRect(ir.left() + ir.width() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
2417                       opt->rect.height());
2418             r = visualRect(opt->direction, opt->rect, r);
2419             break;
2420         }
2421
2422     case SE_RadioButtonFocusRect:
2423         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2424             if (btn->icon.isNull() && btn->text.isEmpty()) {
2425                 r = subElementRect(SE_RadioButtonIndicator, opt, widget);
2426                 r.adjust(1, 1, -1, -1);
2427                 break;
2428             }
2429             QRect cr = visualRect(btn->direction, btn->rect,
2430                                   subElementRect(SE_RadioButtonContents, opt, widget));
2431
2432             QRect iconRect, textRect;
2433             if (!btn->text.isEmpty()){
2434                 textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
2435                                  | Qt::TextShowMnemonic, btn->state & State_Enabled, btn->text);
2436             }
2437             if (!btn->icon.isNull()) {
2438                 iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic,
2439                                    btn->icon.pixmap(btn->iconSize, QIcon::Normal));
2440                 if (!textRect.isEmpty())
2441                     textRect.translate(iconRect.right() + 4, 0);
2442             }
2443             r = iconRect | textRect;
2444             r.adjust(-3, -2, 3, 2);
2445             r = r.intersected(btn->rect);
2446             r = visualRect(btn->direction, btn->rect, r);
2447         }
2448         break;
2449 #ifndef QT_NO_SLIDER
2450     case SE_SliderFocusRect:
2451         if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
2452             int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
2453             int thickness  = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
2454             if (slider->orientation == Qt::Horizontal)
2455                 r.setRect(0, tickOffset - 1, slider->rect.width(), thickness + 2);
2456             else
2457                 r.setRect(tickOffset - 1, 0, thickness + 2, slider->rect.height());
2458             r = r.intersected(slider->rect);
2459             r = visualRect(opt->direction, opt->rect, r);
2460         }
2461         break;
2462 #endif // QT_NO_SLIDER
2463 #ifndef QT_NO_PROGRESSBAR
2464     case SE_ProgressBarGroove:
2465     case SE_ProgressBarContents:
2466     case SE_ProgressBarLabel:
2467         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
2468             int textw = 0;
2469             bool vertical = false;
2470             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
2471                 vertical = (pb2->orientation == Qt::Vertical);
2472             }
2473             if (!vertical) {
2474                 if (pb->textVisible)
2475                     textw = qMax(pb->fontMetrics.width(pb->text), pb->fontMetrics.width(QLatin1String("100%"))) + 6;
2476             }
2477
2478             if ((pb->textAlignment & Qt::AlignCenter) == 0) {
2479                 if (sr != SE_ProgressBarLabel)
2480                     r.setCoords(pb->rect.left(), pb->rect.top(),
2481                                 pb->rect.right() - textw, pb->rect.bottom());
2482                 else
2483                     r.setCoords(pb->rect.right() - textw, pb->rect.top(),
2484                                 pb->rect.right(), pb->rect.bottom());
2485             } else {
2486                 r = pb->rect;
2487             }
2488             r = visualRect(pb->direction, pb->rect, r);
2489         }
2490         break;
2491 #endif // QT_NO_PROGRESSBAR
2492 #ifdef QT3_SUPPORT
2493     case SE_Q3DockWindowHandleRect:
2494         if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
2495             if (!dw->docked || !dw->closeEnabled)
2496                 r.setRect(0, 0, dw->rect.width(), dw->rect.height());
2497             else {
2498                 if (dw->state & State_Horizontal)
2499                     r.setRect(0, 15, dw->rect.width(), dw->rect.height() - 15);
2500                 else
2501                     r.setRect(0, 1, dw->rect.width() - 15, dw->rect.height() - 1);
2502             }
2503             r = visualRect(opt->direction, opt->rect, r);
2504         }
2505         break;
2506 #endif // QT3_SUPPORT
2507 #ifndef QT_NO_COMBOBOX
2508     case SE_ComboBoxFocusRect:
2509         if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
2510             int margin = cb->frame ? 3 : 0;
2511             r.setRect(opt->rect.left() + margin, opt->rect.top() + margin,
2512                       opt->rect.width() - 2*margin - 16, opt->rect.height() - 2*margin);
2513             r = visualRect(opt->direction, opt->rect, r);
2514         }
2515         break;
2516 #endif // QT_NO_COMBOBOX
2517 #ifndef QT_NO_TOOLBOX
2518     case SE_ToolBoxTabContents:
2519         r = opt->rect;
2520         r.adjust(0, 0, -30, 0);
2521         break;
2522 #endif // QT_NO_TOOLBOX
2523     case SE_HeaderLabel: {
2524         int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
2525         r.setRect(opt->rect.x() + margin, opt->rect.y() + margin,
2526                   opt->rect.width() - margin * 2, opt->rect.height() - margin * 2);
2527
2528         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2529             // Subtract width needed for arrow, if there is one
2530             if (header->sortIndicator != QStyleOptionHeader::None) {
2531                 if (opt->state & State_Horizontal)
2532                     r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2));
2533                 else
2534                     r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2));
2535             }
2536         }
2537         r = visualRect(opt->direction, opt->rect, r);
2538         break; }
2539     case SE_HeaderArrow: {
2540         int h = opt->rect.height();
2541         int w = opt->rect.width();
2542         int x = opt->rect.x();
2543         int y = opt->rect.y();
2544         int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
2545
2546         if (opt->state & State_Horizontal) {
2547             int horiz_size = h / 2;
2548             r.setRect(x + w - margin * 2 - horiz_size, y + 5,
2549                       horiz_size, h - margin * 2 - 5);
2550         } else {
2551             int vert_size = w / 2;
2552             r.setRect(x + 5, y + h - margin * 2 - vert_size,
2553                       w - margin * 2 - 5, vert_size);
2554         }
2555         r = visualRect(opt->direction, opt->rect, r);
2556         break; }
2557
2558     case SE_RadioButtonClickRect:
2559         r = subElementRect(SE_RadioButtonFocusRect, opt, widget);
2560         r |= subElementRect(SE_RadioButtonIndicator, opt, widget);
2561         break;
2562     case SE_CheckBoxClickRect:
2563         r = subElementRect(SE_CheckBoxFocusRect, opt, widget);
2564         r |= subElementRect(SE_CheckBoxIndicator, opt, widget);
2565         break;
2566 #ifndef QT_NO_TABWIDGET
2567     case SE_TabWidgetTabBar:
2568         if (const QStyleOptionTabWidgetFrame *twf
2569                 = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2570             r.setSize(twf->tabBarSize);
2571             const uint alingMask = Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter;
2572             switch (twf->shape) {
2573             case QTabBar::RoundedNorth:
2574             case QTabBar::TriangularNorth:
2575                 // Constrain the size now, otherwise, center could get off the page
2576                 // This of course repeated for all the other directions
2577                 r.setWidth(qMin(r.width(), twf->rect.width()
2578                                             - twf->leftCornerWidgetSize.width()
2579                                             - twf->rightCornerWidgetSize.width()));
2580                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2581                 default:
2582                 case Qt::AlignLeft:
2583                     r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0));
2584                     break;
2585                 case Qt::AlignHCenter:
2586                     r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
2587                                          + (twf->leftCornerWidgetSize.width() / 2)
2588                                          - (twf->rightCornerWidgetSize.width() / 2), 0));
2589                     break;
2590                 case Qt::AlignRight:
2591                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
2592                                          - twf->rightCornerWidgetSize.width(), 0));
2593                     break;
2594                 }
2595                 r = visualRect(twf->direction, twf->rect, r);
2596                 break;
2597             case QTabBar::RoundedSouth:
2598             case QTabBar::TriangularSouth:
2599                 r.setWidth(qMin(r.width(), twf->rect.width()
2600                                             - twf->leftCornerWidgetSize.width()
2601                                             - twf->rightCornerWidgetSize.width()));
2602                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2603                 default:
2604                 case Qt::AlignLeft:
2605                     r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(),
2606                                          twf->rect.height() - twf->tabBarSize.height()));
2607                     break;
2608                 case Qt::AlignHCenter:
2609                     r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
2610                                          + (twf->leftCornerWidgetSize.width() / 2)
2611                                          - (twf->rightCornerWidgetSize.width() / 2),
2612                                          twf->rect.height() - twf->tabBarSize.height()));
2613                     break;
2614                 case Qt::AlignRight:
2615                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
2616                                          - twf->rightCornerWidgetSize.width(),
2617                                          twf->rect.height() - twf->tabBarSize.height()));
2618                     break;
2619                 }
2620                 r = visualRect(twf->direction, twf->rect, r);
2621                 break;
2622             case QTabBar::RoundedEast:
2623             case QTabBar::TriangularEast:
2624                 r.setHeight(qMin(r.height(), twf->rect.height()
2625                                             - twf->leftCornerWidgetSize.height()
2626                                             - twf->rightCornerWidgetSize.height()));
2627                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2628                 default:
2629                 case Qt::AlignLeft:
2630                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2631                                          twf->leftCornerWidgetSize.height()));
2632                     break;
2633                 case Qt::AlignHCenter:
2634                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2635                                          twf->rect.center().y() - r.height() / 2));
2636                     break;
2637                 case Qt::AlignRight:
2638                     r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2639                                          twf->rect.height() - twf->tabBarSize.height()
2640                                          - twf->rightCornerWidgetSize.height()));
2641                     break;
2642                 }
2643                 break;
2644             case QTabBar::RoundedWest:
2645             case QTabBar::TriangularWest:
2646                 r.setHeight(qMin(r.height(), twf->rect.height()
2647                                              - twf->leftCornerWidgetSize.height()
2648                                              - twf->rightCornerWidgetSize.height()));
2649                 switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
2650                 default:
2651                 case Qt::AlignLeft:
2652                     r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height()));
2653                     break;
2654                 case Qt::AlignHCenter:
2655                     r.moveTopLeft(QPoint(0, twf->rect.center().y() - r.height() / 2));
2656                     break;
2657                 case Qt::AlignRight:
2658                     r.moveTopLeft(QPoint(0, twf->rect.height() - twf->tabBarSize.height()
2659                                          - twf->rightCornerWidgetSize.height()));
2660                     break;
2661                 }
2662                 break;
2663             }
2664         }
2665         break;
2666     case SE_TabWidgetTabPane:
2667     case SE_TabWidgetTabContents:
2668         if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2669             QStyleOptionTab tabopt;
2670             tabopt.shape = twf->shape;
2671             int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &tabopt, widget);
2672             if (twf->lineWidth == 0)
2673                 overlap = 0;
2674             switch (twf->shape) {
2675             case QTabBar::RoundedNorth:
2676             case QTabBar::TriangularNorth:
2677                 r = QRect(QPoint(0,qMax(twf->tabBarSize.height() - overlap, 0)),
2678                           QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
2679                 break;
2680             case QTabBar::RoundedSouth:
2681             case QTabBar::TriangularSouth:
2682                 r = QRect(QPoint(0,0), QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
2683                 break;
2684             case QTabBar::RoundedEast:
2685             case QTabBar::TriangularEast:
2686                 r = QRect(QPoint(0, 0), QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
2687                 break;
2688             case QTabBar::RoundedWest:
2689             case QTabBar::TriangularWest:
2690                 r = QRect(QPoint(qMax(twf->tabBarSize.width() - overlap, 0), 0),
2691                           QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
2692                 break;
2693             }
2694             if (sr == SE_TabWidgetTabContents && twf->lineWidth > 0)
2695                r.adjust(2, 2, -2, -2);
2696         }
2697         break;
2698     case SE_TabWidgetLeftCorner:
2699         if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2700             QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2701             switch (twf->shape) {
2702             case QTabBar::RoundedNorth:
2703             case QTabBar::TriangularNorth:
2704                 r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()),
2705                           twf->leftCornerWidgetSize);
2706                 break;
2707             case QTabBar::RoundedSouth:
2708             case QTabBar::TriangularSouth:
2709                 r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
2710                break;
2711             default:
2712                break;
2713             }
2714            r = visualRect(twf->direction, twf->rect, r);
2715         }
2716         break;
2717    case SE_TabWidgetRightCorner:
2718        if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
2719            QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2720            switch (twf->shape) {
2721            case QTabBar::RoundedNorth:
2722            case QTabBar::TriangularNorth:
2723                 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2724                                  paneRect.y() - twf->rightCornerWidgetSize.height()),
2725                           twf->rightCornerWidgetSize);
2726                break;
2727            case QTabBar::RoundedSouth:
2728            case QTabBar::TriangularSouth:
2729                 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
2730                                  paneRect.height()), twf->rightCornerWidgetSize);
2731                break;
2732            default:
2733                break;
2734            }
2735            r = visualRect(twf->direction, twf->rect, r);
2736         }
2737         break;
2738     case SE_TabBarTabText:
2739         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
2740             QStyleOptionTabV3 tabV3(*tab);
2741             QRect dummyIconRect;
2742             d->tabLayout(&tabV3, widget, &r, &dummyIconRect);
2743         }
2744         break;
2745     case SE_TabBarTabLeftButton:
2746     case SE_TabBarTabRightButton:
2747         if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
2748             bool selected = tab->state & State_Selected;
2749             int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
2750             int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
2751             int hpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
2752             hpadding = qMax(hpadding, 4); //workaround KStyle returning 0 because they workaround an old bug in Qt
2753
2754             bool verticalTabs = tab->shape == QTabBar::RoundedEast
2755                     || tab->shape == QTabBar::RoundedWest
2756                     || tab->shape == QTabBar::TriangularEast
2757                     || tab->shape == QTabBar::TriangularWest;
2758
2759             QRect tr = tab->rect;
2760             if (tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::TriangularSouth)
2761                 verticalShift = -verticalShift;
2762             if (verticalTabs) {
2763                 qSwap(horizontalShift, verticalShift);
2764                 horizontalShift *= -1;
2765                 verticalShift *= -1;
2766             }
2767             if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest)
2768                 horizontalShift = -horizontalShift;
2769
2770             tr.adjust(0, 0, horizontalShift, verticalShift);
2771             if (selected)
2772             {
2773                 tr.setBottom(tr.bottom() - verticalShift);
2774                 tr.setRight(tr.right() - horizontalShift);
2775             }
2776
2777             QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
2778             int w = size.width();
2779             int h = size.height();
2780             int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
2781             int midWidth = ((tr.width() - w) / 2);
2782
2783             bool atTheTop = true;
2784             switch (tab->shape) {
2785             case QTabBar::RoundedWest:
2786             case QTabBar::TriangularWest:
2787                 atTheTop = (sr == SE_TabBarTabLeftButton);