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