QWindowVistaStyle: Always initialize text color of menu items.
[qt:qt.git] / src / gui / styles / qwindowsvistastyle.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qwindowsvistastyle.h"
43 #include "qwindowsvistastyle_p.h"
44 #include <private/qstylehelper_p.h>
45 #include <private/qsystemlibrary_p.h>
46
47 #if !defined(QT_NO_STYLE_WINDOWSVISTA) || defined(QT_PLUGIN)
48
49 QT_BEGIN_NAMESPACE
50
51 static const int windowsItemFrame        =  2; // menu item frame width
52 static const int windowsItemHMargin      =  3; // menu item hor text margin
53 static const int windowsItemVMargin      =  4; // menu item ver text margin
54 static const int windowsArrowHMargin     =  6; // arrow horizontal margin
55 static const int windowsRightBorder      = 15; // right border on windows
56
57 #ifndef TMT_CONTENTMARGINS
58 #  define TMT_CONTENTMARGINS 3602
59 #endif
60 #ifndef TMT_SIZINGMARGINS
61 #  define TMT_SIZINGMARGINS 3601
62 #endif
63 #ifndef LISS_NORMAL
64 #  define LISS_NORMAL 1
65 #  define LISS_HOT 2
66 #  define LISS_SELECTED 3
67 #  define LISS_DISABLED 4
68 #  define LISS_SELECTEDNOTFOCUS 5
69 #  define LISS_HOTSELECTED 6
70 #endif
71 #ifndef BP_COMMANDLINK
72 #  define BP_COMMANDLINK 6
73 #  define BP_COMMANDLINKGLYPH 7
74 #  define CMDLGS_NORMAL 1
75 #  define CMDLGS_HOT 2
76 #  define CMDLGS_PRESSED 3
77 #  define CMDLGS_DISABLED 4
78 #endif
79 #ifndef PP_TRANSPARENTBAR
80 #  define PP_TRANSPARENTBAR 11
81 #  define PP_TRANSPARENTBARVERT 12
82 #endif
83
84 // Runtime resolved theme engine function calls
85
86
87 typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
88 typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
89 typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
90 typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
91 typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
92 typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
93 typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
94 typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
95 typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
96 typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
97 typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
98 typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
99 typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
100 typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
101 typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
102 typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
103 typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
104 typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
105 typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
106 typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
107 typedef HRESULT (WINAPI *PtrGetThemeTransitionDuration)(HTHEME hTheme, int iPartId, int iStateFromId, int iStateToId, int iPropId, int *pDuration);
108 typedef HRESULT (WINAPI *PtrIsThemePartDefined)(HTHEME hTheme, int iPartId, int iStateId);
109 typedef HRESULT (WINAPI *PtrSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
110 typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
111
112 static PtrIsThemePartDefined pIsThemePartDefined = 0;
113 static PtrOpenThemeData pOpenThemeData = 0;
114 static PtrCloseThemeData pCloseThemeData = 0;
115 static PtrDrawThemeBackground pDrawThemeBackground = 0;
116 static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
117 static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
118 static PtrGetThemeBool pGetThemeBool = 0;
119 static PtrGetThemeColor pGetThemeColor = 0;
120 static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
121 static PtrGetThemeFilename pGetThemeFilename = 0;
122 static PtrGetThemeFont pGetThemeFont = 0;
123 static PtrGetThemeInt pGetThemeInt = 0;
124 static PtrGetThemeIntList pGetThemeIntList = 0;
125 static PtrGetThemeMargins pGetThemeMargins = 0;
126 static PtrGetThemeMetric pGetThemeMetric = 0;
127 static PtrGetThemePartSize pGetThemePartSize = 0;
128 static PtrGetThemePosition pGetThemePosition = 0;
129 static PtrGetThemeRect pGetThemeRect = 0;
130 static PtrGetThemeString pGetThemeString = 0;
131 static PtrGetThemeTransitionDuration pGetThemeTransitionDuration= 0;
132 static PtrSetWindowTheme pSetWindowTheme = 0;
133 static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
134
135 /* \internal
136     Checks if we should use Vista style , or if we should
137     fall back to Windows style.
138 */
139 bool QWindowsVistaStylePrivate::useVista()
140 {
141     return (QWindowsVistaStylePrivate::useXP() &&
142             (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA &&
143              (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)));
144 }
145
146 /*!
147   \class QWindowsVistaStyle
148   \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
149   \since 4.3
150   \ingroup appearance
151
152   \warning This style is only available on the Windows Vista platform
153   because it makes use of Windows Vista's style engine.
154
155   \sa QMacStyle, QWindowsXPStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
156 */
157
158 /*!
159   Constructs a QWindowsVistaStyle object.
160 */
161 QWindowsVistaStyle::QWindowsVistaStyle()
162     : QWindowsXPStyle(*new QWindowsVistaStylePrivate)
163 {
164 }
165
166 //convert Qt state flags to uxtheme button states
167 static int buttonStateId(int flags, int partId)
168 {
169     int stateId = 0;
170     if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) {
171         if (!(flags & QStyle::State_Enabled))
172             stateId = RBS_UNCHECKEDDISABLED;
173         else if (flags & QStyle::State_Sunken)
174             stateId = RBS_UNCHECKEDPRESSED;
175         else if (flags & QStyle::State_MouseOver)
176             stateId = RBS_UNCHECKEDHOT;
177         else
178             stateId = RBS_UNCHECKEDNORMAL;
179
180         if (flags & QStyle::State_On)
181             stateId += RBS_CHECKEDNORMAL-1;
182
183     } else if (partId == BP_PUSHBUTTON) {
184         if (!(flags & QStyle::State_Enabled))
185             stateId = PBS_DISABLED;
186         else if (flags & (QStyle::State_Sunken | QStyle::State_On))
187             stateId = PBS_PRESSED;
188         else if (flags & QStyle::State_MouseOver)
189             stateId = PBS_HOT;
190         else
191             stateId = PBS_NORMAL;
192     } else {
193         Q_ASSERT(1);
194     }
195     return stateId;
196 }
197
198 void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option)
199 {
200     Q_UNUSED(option);
201     Q_UNUSED(painter);
202 }
203
204 /*! \internal
205
206   Helperfunction to paint the current transition state between two
207   animation frames.
208
209   The result is a blended image consisting of ((alpha)*_primaryImage)
210   + ((1-alpha)*_secondaryImage)
211
212 */
213 void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
214     if (_secondaryImage.isNull() || _primaryImage.isNull())
215         return;
216
217     if (_tempImage.isNull())
218         _tempImage = _secondaryImage;
219
220     const int a = qRound(alpha*256);
221     const int ia = 256 - a;
222     const int sw = _primaryImage.width();
223     const int sh = _primaryImage.height();
224     const int bpl = _primaryImage.bytesPerLine();
225     switch(_primaryImage.depth()) {
226     case 32:
227         {
228             uchar *mixed_data = _tempImage.bits();
229             const uchar *back_data = _primaryImage.bits();
230             const uchar *front_data = _secondaryImage.bits();
231             for (int sy = 0; sy < sh; sy++) {
232                 quint32* mixed = (quint32*)mixed_data;
233                 const quint32* back = (const quint32*)back_data;
234                 const quint32* front = (const quint32*)front_data;
235                 for (int sx = 0; sx < sw; sx++) {
236                     quint32 bp = back[sx];
237                     quint32 fp = front[sx];
238                     mixed[sx] =  qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
239                                         (qGreen(bp)*ia + qGreen(fp)*a)>>8,
240                                         (qBlue(bp)*ia + qBlue(fp)*a)>>8,
241                                         (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
242                 }
243                 mixed_data += bpl;
244                 back_data += bpl;
245                 front_data += bpl;
246             }
247         }
248     default:
249         break;
250     }
251     painter->drawImage(rect, _tempImage);
252 }
253
254 /*! \internal
255   Paints a transition state. The result will be a mix between the
256   initial and final state of the transition, depending on the time
257   difference between _startTime and current time.
258 */
259 void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option)
260 {
261     float alpha = 1.0;
262     if (_duration > 0) {
263         QTime current = QTime::currentTime();
264
265         if (_startTime > current)
266             _startTime = current;
267
268         int timeDiff = _startTime.msecsTo(current);
269         alpha = timeDiff/(float)_duration;
270         if (timeDiff > _duration) {
271             _running = false;
272             alpha = 1.0;
273         }
274     }
275     else {
276         _running = false;
277     }
278     drawBlendedImage(painter, option->rect, alpha);
279 }
280
281 /*! \internal
282   Paints a pulse. The result will be a mix between the primary and
283   secondary pulse images depending on the time difference between
284   _startTime and current time.
285 */
286 void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option)
287 {
288     float alpha = 1.0;
289     if (_duration > 0) {
290         QTime current = QTime::currentTime();
291
292         if (_startTime > current)
293             _startTime = current;
294
295         int timeDiff = _startTime.msecsTo(current) % _duration*2;
296         if (timeDiff > _duration)
297             timeDiff = _duration*2 - timeDiff;
298         alpha = timeDiff/(float)_duration;
299     } else {
300         _running = false;
301     }
302     drawBlendedImage(painter, option->rect, alpha);
303 }
304
305
306 /*!
307  \internal
308  
309   Animations are used for some state transitions on specific widgets.
310  
311   Only one running animation can exist for a widget at any specific
312   time.  Animations can be added through
313   QWindowsVistaStylePrivate::startAnimation(Animation *) and any
314   existing animation on a widget can be retrieved with
315   QWindowsVistaStylePrivate::widgetAnimation(Widget *).
316  
317   Once an animation has been started,
318   QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will
319   continuously call update() on the widget until it is stopped,
320   meaning that drawPrimitive will be called many times until the
321   transition has completed. During this time, the result will be
322   retrieved by the Animation::paint(...) function and not by the style
323   itself.
324  
325   To determine if a transition should occur, the style needs to know
326   the previous state of the widget as well as the current one. This is
327   solved by updating dynamic properties on the widget every time the
328   function is called.
329  
330   Transitions interrupting existing transitions should always be
331   smooth, so whenever a hover-transition is started on a pulsating
332   button, it uses the current frame of the pulse-animation as the
333   starting image for the hover transition.
334  
335  */
336 void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
337                                        QPainter *painter, const QWidget *widget) const
338 {
339     QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
340
341     int state = option->state;
342     if (!QWindowsVistaStylePrivate::useVista()) {
343         QWindowsStyle::drawPrimitive(element, option, painter, widget);
344         return;
345     }
346
347     QRect oldRect;
348     QRect newRect;
349
350     if (widget && d->transitionsEnabled())
351     {
352         /* all widgets that supports state transitions : */
353         if (
354 #ifndef QT_NO_LINEEDIT
355             (qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) ||
356 #endif // QT_NO_LINEEDIT
357             (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) ||
358             (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) ||
359             (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) ||
360             (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel)
361         )
362         {
363             // Retrieve and update the dynamic properties tracking
364             // the previous state of the widget:
365             QWidget *w = const_cast<QWidget *> (widget);
366             int oldState = w->property("_q_stylestate").toInt();
367             oldRect = w->property("_q_stylerect").toRect();
368             newRect = w->rect();
369             w->setProperty("_q_stylestate", (int)option->state);
370             w->setProperty("_q_stylerect", w->rect());
371
372             bool doTransition = oldState && 
373                                 ((state & State_Sunken)     != (oldState & State_Sunken) ||
374                                  (state & State_On)         != (oldState & State_On)     ||
375                                  (state & State_MouseOver)  != (oldState & State_MouseOver));
376
377             if (oldRect != newRect ||
378                 (state & State_Enabled) != (oldState & State_Enabled) ||
379                 (state & State_Active)  != (oldState & State_Active))
380                     d->stopAnimation(widget);
381
382 #ifndef QT_NO_LINEEDIT
383             if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget))
384                 if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits
385                     doTransition = false;
386 #endif // QT_NO_LINEEDIT
387
388             if (doTransition) {
389
390                 // We create separate images for the initial and final transition states and store them in the
391                 // Transition object.
392                 QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
393                 QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
394                 QStyleOption opt = *option;
395
396                 opt.rect.setRect(0, 0, option->rect.width(), option->rect.height());
397                 opt.state = (QStyle::State)oldState;
398                 startImage.fill(0);
399                 QPainter startPainter(&startImage);
400
401                 QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
402                 QWindowsVistaTransition *t = new QWindowsVistaTransition;
403                 t->setWidget(w);
404
405                 // If we have a running animation on the widget already, we will use that to paint the initial
406                 // state of the new transition, this ensures a smooth transition from a current animation such as a
407                 // pulsating default button into the intended target state.
408
409                 if (!anim)
410                     proxy()->drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0
411                 else                                               // this ensures that we do not recurse in the animation logic above
412                     anim->paint(&startPainter, &opt);
413
414                 d->startAnimation(t);
415                 t->setStartImage(startImage);
416
417                 // The end state of the transition is simply the result we would have painted
418                 // if the style was not animated.
419
420                 QPainter endPainter(&endImage);
421                 endImage.fill(0);
422                 QStyleOption opt2 = opt;
423                 opt2.state = option->state;
424                 proxy()->drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0
425                                                               // this ensures that we do not recurse in the animation logic above
426                 t->setEndImage(endImage);
427
428                 HTHEME theme;
429                 int partId;
430                 int duration;
431                 int fromState = 0;
432                 int toState = 0;
433
434                 //translate state flags to UXTHEME states :
435                 if (element == PE_FrameLineEdit) {
436                     theme = pOpenThemeData(0, L"Edit");
437                     partId = EP_EDITBORDER_NOSCROLL;
438
439                     if (oldState & State_MouseOver)
440                         fromState = ETS_HOT;
441                     else if (oldState & State_HasFocus)
442                         fromState = ETS_FOCUSED;
443                     else
444                         fromState = ETS_NORMAL;
445
446                     if (state & State_MouseOver)
447                         toState = ETS_HOT;
448                     else if (state & State_HasFocus)
449                         toState = ETS_FOCUSED;
450                     else
451                         toState = ETS_NORMAL;
452
453                 } else {
454                     theme = pOpenThemeData(0, L"Button");
455                     if (element == PE_IndicatorRadioButton)
456                         partId = BP_RADIOBUTTON;
457                     else if (element == PE_IndicatorCheckBox)
458                         partId = BP_CHECKBOX;
459                     else
460                         partId = BP_PUSHBUTTON;
461
462                     fromState = buttonStateId(oldState, partId);
463                     toState = buttonStateId(option->state, partId);
464                 }
465
466                 // Retrieve the transition time between the states from the system.
467                 if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
468                     TMT_TRANSITIONDURATIONS, &duration) == S_OK)
469                 {
470                     t->setDuration(duration);
471                 }
472                 t->setStartTime(QTime::currentTime());
473             }
474         }
475     } // End of animation part
476
477
478     QRect rect = option->rect;
479
480     switch (element) {
481     case PE_IndicatorHeaderArrow:
482         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
483             int stateId = HSAS_SORTEDDOWN;
484             if (header->sortIndicator & QStyleOptionHeader::SortDown)
485                 stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours
486             XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect);
487             d->drawBackground(theme);
488         }
489         break;
490
491     case PE_IndicatorBranch:
492         {
493             XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW"));
494             static int decoration_size = 0;
495             if (theme.isValid() && !decoration_size) {
496                 SIZE size;
497                 pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size);
498                 decoration_size = qMax(size.cx, size.cy);
499             }
500             int mid_h = option->rect.x() + option->rect.width() / 2;
501             int mid_v = option->rect.y() + option->rect.height() / 2;
502             int bef_h = mid_h;
503             int bef_v = mid_v;
504             int aft_h = mid_h;
505             int aft_v = mid_v;
506             if (option->state & State_Children) {
507                 int delta = decoration_size / 2;
508                 theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size);
509                 theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH;
510                 theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
511                 if (option->direction == Qt::RightToLeft)
512                     theme.mirrorHorizontally = true;
513                 d->drawBackground(theme);
514                 bef_h -= delta + 2;
515                 bef_v -= delta + 2;
516                 aft_h += delta - 2;
517                 aft_v += delta - 2;
518             }
519 #if 0
520             QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
521             if (option->state & State_Item) {
522                 if (option->direction == Qt::RightToLeft)
523                     painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
524                 else
525                     painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
526             }
527             if (option->state & State_Sibling && option->rect.bottom() > aft_v)
528                 painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
529             if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y()))
530                 painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
531 #endif
532         }
533         break;
534
535     case PE_PanelButtonBevel:
536     case PE_IndicatorCheckBox:
537     case PE_IndicatorRadioButton:
538         {
539             if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
540                 a->paint(painter, option);
541             } else {
542                 QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
543             }
544         }
545         break;
546
547     case PE_FrameMenu:
548         {
549             int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE;
550             XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect);
551             d->drawBackground(theme);
552         }
553         break;
554     case PE_Frame:
555 #ifndef QT_NO_TEXTEDIT
556         if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) {
557             painter->save();
558             int stateId = ETS_NORMAL;
559             if (!(state & State_Enabled))
560                 stateId = ETS_DISABLED;
561             else if (edit->isReadOnly())
562                 stateId = ETS_READONLY;
563             else if (state & State_HasFocus)
564                 stateId = ETS_SELECTED;
565             XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect);
566             // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
567             int borderSize = 1;
568             pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
569             QRegion clipRegion = option->rect;
570             QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
571             clipRegion ^= content;
572             painter->setClipRegion(clipRegion);
573             d->drawBackground(theme);
574             painter->restore();
575         } else
576 #endif // QT_NO_TEXTEDIT
577             QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
578         break;
579
580     case PE_PanelLineEdit:
581         if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
582             QBrush bg;
583             bool usePalette = false;
584             bool isEnabled = option->state & State_Enabled;
585             uint resolve_mask = panel->palette.resolve();
586             if (widget) {
587             //Since spin box and combo box includes a line edit we need to resolve the palette on the parent instead
588 #ifndef QT_NO_SPINBOX
589                 if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
590                     resolve_mask = spinbox->palette().resolve();
591 #endif // QT_NO_SPINBOX
592             }
593             if (resolve_mask & (1 << QPalette::Base)) {
594                 // Base color is set for this widget, so use it
595                 bg = panel->palette.brush(QPalette::Base);
596                 usePalette = true;
597             }
598             if (usePalette) {
599                 painter->fillRect(panel->rect, bg);
600             } else {
601                 int partId = EP_BACKGROUND;
602                 int stateId = EBS_NORMAL;
603                 if (!isEnabled)
604                     stateId = EBS_DISABLED;
605                 else if (state & State_ReadOnly)
606                     stateId = EBS_READONLY;
607                 else if (state & State_MouseOver)
608                     stateId = EBS_HOT;
609
610                 XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect);
611                 if (!theme.isValid()) {
612                     QWindowsStyle::drawPrimitive(element, option, painter, widget);
613                     return;
614                 }
615                 int bgType;
616                 pGetThemeEnumValue( theme.handle(),
617                                     partId,
618                                     stateId,
619                                     TMT_BGTYPE,
620                                     &bgType);
621                 if( bgType == BT_IMAGEFILE ) {
622                     d->drawBackground(theme);
623                 } else {
624                     QBrush fillColor = option->palette.brush(QPalette::Base);
625                     if (!isEnabled) {
626                         PROPERTYORIGIN origin = PO_NOTFOUND;
627                         pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
628                         // Use only if the fill property comes from our part
629                         if ((origin == PO_PART || origin == PO_STATE)) {
630                             COLORREF bgRef;
631                             pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
632                             fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
633                         }
634                     }
635                     painter->fillRect(option->rect, fillColor);
636                 }
637             }
638             if (panel->lineWidth > 0)
639                 proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
640             return;
641         }
642         break;
643
644     case PE_FrameLineEdit:
645         if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
646             anim->paint(painter, option);
647         } else {
648             QPainter *p = painter;
649             QWidget *parentWidget = 0;
650             if (widget) {
651                 parentWidget = widget->parentWidget();
652                 if (parentWidget)
653                     parentWidget = parentWidget->parentWidget();
654             }
655             if (widget && widget->inherits("QLineEdit")
656                 && parentWidget && parentWidget->inherits("QAbstractItemView")) {
657                 // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
658                 QPen oldPen = p->pen();
659                 // Inner white border
660                 p->setPen(QPen(option->palette.base().color(), 1));
661                 p->drawRect(option->rect.adjusted(1, 1, -2, -2));
662                 // Outer dark border
663                 p->setPen(QPen(option->palette.shadow().color(), 1));
664                 p->drawRect(option->rect.adjusted(0, 0, -1, -1));
665                 p->setPen(oldPen);
666                 return;
667             } else {
668                 int stateId = ETS_NORMAL;
669                 if (!(state & State_Enabled))
670                     stateId = ETS_DISABLED;
671                 else if (state & State_ReadOnly)
672                     stateId = ETS_READONLY;
673                 else if (state & State_MouseOver)
674                     stateId = ETS_HOT;
675                 else if (state & State_HasFocus)
676                     stateId = ETS_SELECTED;
677                 XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect);
678                 painter->save();
679                 QRegion clipRegion = option->rect;
680                 clipRegion -= option->rect.adjusted(2, 2, -2, -2);
681                 painter->setClipRegion(clipRegion);
682                 d->drawBackground(theme);
683                 painter->restore();
684             }
685         }
686         break;
687
688     case PE_IndicatorToolBarHandle:
689         {
690             XPThemeData theme;
691             QRect rect;
692             if (option->state & State_Horizontal) {
693                 theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
694                 rect = option->rect.adjusted(0, 1, 0, -2);
695                 rect.setWidth(4);
696             } else {
697                 theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
698                 rect = option->rect.adjusted(1, 0, -1, 0);
699                 rect.setHeight(4);
700             }
701             theme.rect = rect;
702             d->drawBackground(theme);
703         }
704         break;
705
706     case PE_IndicatorToolBarSeparator:
707         {
708             QPen pen = painter->pen();
709             int margin = 3;
710             painter->setPen(option->palette.background().color().darker(114));
711             if (option->state & State_Horizontal) {
712                 int x1 = option->rect.center().x();
713                 painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin));
714             } else {
715                 int y1 = option->rect.center().y();
716                 painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1));
717             }
718             painter->setPen(pen);
719         }
720         break;
721
722     case PE_PanelTipLabel: {
723         XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
724         d->drawBackground(theme);
725         break;
726     }
727
728     case PE_PanelItemViewItem:
729         {
730             const QStyleOptionViewItemV4 *vopt;
731             const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
732             bool newStyle = true;
733
734             if (qobject_cast<const QTableView*>(widget))
735                 newStyle = false;
736
737             if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
738                 bool selected = vopt->state & QStyle::State_Selected;
739                 bool hover = vopt->state & QStyle::State_MouseOver;
740                 bool active = vopt->state & QStyle::State_Active;
741
742                 if (vopt->features & QStyleOptionViewItemV2::Alternate)
743                     painter->fillRect(vopt->rect, vopt->palette.alternateBase());
744
745                 QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
746                                           ? QPalette::Normal : QPalette::Disabled;
747                 if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
748                     cg = QPalette::Inactive;
749
750                 QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0);
751                 itemRect.setTop(vopt->rect.top());
752                 itemRect.setBottom(vopt->rect.bottom());
753
754                 QSize sectionSize = itemRect.size();
755                 if (vopt->showDecorationSelected)
756                     sectionSize = vopt->rect.size();
757
758                 if (view->selectionBehavior() == QAbstractItemView::SelectRows)
759                     sectionSize.setWidth(vopt->rect.width());
760                 if (view->selectionMode() == QAbstractItemView::NoSelection)
761                     hover = false;
762                 QPixmap pixmap;
763
764                 if (vopt->backgroundBrush.style() != Qt::NoBrush) {
765                     const QPointF oldBrushOrigin = painter->brushOrigin();
766                     painter->setBrushOrigin(vopt->rect.topLeft());
767                     painter->fillRect(vopt->rect, vopt->backgroundBrush);
768                     painter->setBrushOrigin(oldBrushOrigin);
769                 }
770
771                 if (hover || selected) {
772                     if (sectionSize.width() > 0 && sectionSize.height() > 0) {
773                         QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width())
774                                                             .arg(sectionSize.height()).arg(selected).arg(active).arg(hover);
775                         if (!QPixmapCache::find(key, pixmap)) {
776                             pixmap = QPixmap(sectionSize);
777                             pixmap.fill(Qt::transparent);
778
779                             int state;
780                             if (selected && hover)
781                                 state = LISS_HOTSELECTED;
782                             else if (selected && !active)
783                                 state = LISS_SELECTEDNOTFOCUS;
784                             else if (selected)
785                                 state = LISS_SELECTED;
786                             else
787                                 state = LISS_HOT;
788
789                             QPainter pixmapPainter(&pixmap);
790                             XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"),
791                                 LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
792                             if (theme.isValid()) {
793                                 d->drawBackground(theme);
794                             } else {
795                                 QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
796                                 break;;
797                             }
798                             QPixmapCache::insert(key, pixmap);
799                         }
800                     }
801
802                     if (vopt->showDecorationSelected) {
803                         const int frame = 2; //Assumes a 2 pixel pixmap border
804                         QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height());
805                         QRect pixmapRect = vopt->rect;
806                         bool reverse = vopt->direction == Qt::RightToLeft;
807                         bool leftSection = vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning;
808                         bool rightSection = vopt->viewItemPosition == QStyleOptionViewItemV4::End;
809                         if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne
810                             || vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid)
811                             painter->drawPixmap(pixmapRect.topLeft(), pixmap);
812                         else if (reverse ? rightSection : leftSection){
813                             painter->drawPixmap(QRect(pixmapRect.topLeft(), 
814                                                 QSize(frame, pixmapRect.height())), pixmap, 
815                                                 QRect(QPoint(0, 0), QSize(frame, pixmapRect.height())));
816                             painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0), 
817                                                 pixmap, srcRect.adjusted(frame, 0, -frame, 0));
818                         } else if (reverse ? leftSection : rightSection) {
819                             painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0), 
820                                                 QSize(frame, pixmapRect.height())), pixmap, 
821                                                 QRect(QPoint(pixmapRect.width() - frame, 0), 
822                                                 QSize(frame, pixmapRect.height())));
823                             painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0), 
824                                                 pixmap, srcRect.adjusted(frame, 0, -frame, 0));
825                         } else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle)
826                             painter->drawPixmap(pixmapRect, pixmap,
827                                                 srcRect.adjusted(frame, 0, -frame, 0));
828                     } else {
829                         if (vopt->text.isEmpty() && vopt->icon.isNull())
830                             break;
831                         painter->drawPixmap(itemRect.topLeft(), pixmap);
832                     }
833                 }
834             } else {
835                 QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
836             }
837             break;
838         }
839     case PE_Widget:
840         {
841             const QDialogButtonBox *buttonBox = 0;
842
843             if (qobject_cast<const QMessageBox *> (widget))
844                 buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
845 #ifndef QT_NO_INPUTDIALOG
846             else if (qobject_cast<const QInputDialog *> (widget))
847                 buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
848 #endif // QT_NO_INPUTDIALOG
849
850             if (buttonBox) {
851                 //draw white panel part
852                 XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect);
853                 QRect toprect = option->rect;
854                 toprect.setBottom(buttonBox->geometry().top());
855                 theme.rect = toprect;
856                 d->drawBackground(theme);
857
858                 //draw bottom panel part
859                 QRect buttonRect = option->rect;
860                 buttonRect.setTop(buttonBox->geometry().top());
861                 theme.rect = buttonRect;
862                 theme.partId = TDLG_SECONDARYPANEL;
863                 d->drawBackground(theme);
864             }
865         }
866         break;
867     default:
868         QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
869         break;
870     }
871 }
872
873
874 /*!
875  \internal
876
877  see drawPrimitive for comments on the animation support
878  */
879 void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option,
880                                   QPainter *painter, const QWidget *widget) const
881 {
882     QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
883
884     if (!QWindowsVistaStylePrivate::useVista()) {
885         QWindowsStyle::drawControl(element, option, painter, widget);
886         return;
887     }
888
889     bool selected = option->state & State_Selected;
890     bool pressed = option->state & State_Sunken;
891     bool disabled = !(option->state & State_Enabled);
892
893     int state = option->state;
894     QString name;
895
896     QRect rect(option->rect);
897     State flags = option->state;
898     int partId = 0;
899     int stateId = 0;
900
901     QRect oldRect;
902     QRect newRect;
903
904     if (d->transitionsEnabled() && widget) {
905         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
906             if ((qobject_cast<const QPushButton*>(widget) && element == CE_PushButtonBevel))
907             {
908                 QWidget *w = const_cast<QWidget *> (widget);
909                 int oldState = w->property("_q_stylestate").toInt();
910                 oldRect = w->property("_q_stylerect").toRect();
911                 newRect = w->rect();
912                 w->setProperty("_q_stylestate", (int)option->state);
913                 w->setProperty("_q_stylerect", w->rect());
914
915                 bool wasDefault = w->property("_q_isdefault").toBool();
916                 bool isDefault = button->features & QStyleOptionButton::DefaultButton;
917                 w->setProperty("_q_isdefault", isDefault);
918
919                 bool doTransition = ((state & State_Sunken)     != (oldState & State_Sunken) ||
920                                      (state & State_On)         != (oldState & State_On)     ||
921                                      (state & State_MouseOver)  != (oldState & State_MouseOver));
922
923                 if (oldRect != newRect || (wasDefault && !isDefault))
924                 {
925                     doTransition = false;
926                     d->stopAnimation(widget);
927                 }
928
929                 if (doTransition) {
930                     QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
931                     QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
932                     QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
933
934                     QStyleOptionButton opt = *button;
935                     opt.state = (QStyle::State)oldState;
936
937                     startImage.fill(0);
938                     QWindowsVistaTransition *t = new QWindowsVistaTransition;
939                     t->setWidget(w);
940                     QPainter startPainter(&startImage);
941
942                     if (!anim) {
943                         proxy()->drawControl(element, &opt, &startPainter, 0 /* Intentional */);
944                     } else {
945                         anim->paint(&startPainter, &opt);
946                         d->stopAnimation(widget);
947                     }
948
949                     t->setStartImage(startImage);
950                     d->startAnimation(t);
951
952                     endImage.fill(0);
953                     QPainter endPainter(&endImage);
954                     proxy()->drawControl(element, option, &endPainter, 0 /* Intentional */);
955                     t->setEndImage(endImage);
956                     int duration = 0;
957                     HTHEME theme = pOpenThemeData(0, L"Button");
958
959                     int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
960                     int toState = buttonStateId(option->state, BP_PUSHBUTTON);
961                     if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
962                         t->setDuration(duration);
963                     else
964                         t->setDuration(0);
965                     t->setStartTime(QTime::currentTime());
966                 }
967             }
968         }
969     }
970     switch (element) {
971     case CE_PushButtonBevel:
972         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
973         {
974
975             QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
976             if (anim && (btn->state & State_Enabled)) {
977                 anim->paint(painter, option);
978             } else {
979                 name = QLatin1String("BUTTON");
980                 partId = BP_PUSHBUTTON;
981                 if (btn->features & QStyleOptionButton::CommandLinkButton)
982                     partId = BP_COMMANDLINK;
983                 bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
984                 if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
985                     stateId = PBS_DISABLED;
986                 else if (justFlat)
987                     ;
988                 else if (flags & (State_Sunken | State_On))
989                     stateId = PBS_PRESSED;
990                 else if (flags & State_MouseOver)
991                     stateId = PBS_HOT;
992                 else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
993                     stateId = PBS_DEFAULTED;
994                 else
995                     stateId = PBS_NORMAL;
996
997                 if (!justFlat) {
998
999                     if (widget && d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
1000                         !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
1001                          (state & State_Enabled) && (state & State_Active))
1002                         {
1003                         if (!anim && widget) {
1004                             QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
1005                             startImage.fill(0);
1006                             QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
1007                             alternateImage.fill(0);
1008
1009                             QWindowsVistaPulse *pulse = new QWindowsVistaPulse;
1010                             pulse->setWidget(const_cast<QWidget*>(widget));
1011
1012                             QPainter startPainter(&startImage);
1013                             stateId = PBS_DEFAULTED;
1014                             XPThemeData theme(widget, &startPainter, name, partId, stateId, rect);
1015                             d->drawBackground(theme);
1016
1017                             QPainter alternatePainter(&alternateImage);
1018                             theme.stateId = PBS_DEFAULTED_ANIMATING;
1019                             theme.painter = &alternatePainter;
1020                             d->drawBackground(theme);
1021                             pulse->setPrimaryImage(startImage);
1022                             pulse->setAlternateImage(alternateImage);
1023                             pulse->setStartTime(QTime::currentTime());
1024                             pulse->setDuration(2000);
1025                             d->startAnimation(pulse);
1026                             anim = pulse;
1027                         }
1028
1029                         if (anim)
1030                             anim->paint(painter, option);
1031                         else {
1032                             XPThemeData theme(widget, painter, name, partId, stateId, rect);
1033                             d->drawBackground(theme);
1034                         }
1035                     }
1036                     else {
1037                         d->stopAnimation(widget);
1038                         XPThemeData theme(widget, painter, name, partId, stateId, rect);
1039                         d->drawBackground(theme);
1040                     }
1041                 }
1042             }
1043             if (btn->features & QStyleOptionButton::HasMenu) {
1044                 int mbiw = 0, mbih = 0;
1045                 XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON);
1046                 if (theme.isValid()) {
1047                     SIZE size;
1048                     if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
1049                         mbiw = size.cx;
1050                         mbih = size.cy;
1051                     }
1052                 }
1053                 QRect ir = subElementRect(SE_PushButtonContents, option, 0);
1054                 QStyleOptionButton newBtn = *btn;
1055                 newBtn.rect = QStyle::visualRect(option->direction, option->rect,
1056                                                 QRect(ir.right() - mbiw - 2,
1057                                                       option->rect.top() + (option->rect.height()/2) - (mbih/2),
1058                                                       mbiw + 1, mbih + 1));
1059                 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
1060             }
1061             return;
1062         }
1063         break;
1064 #ifndef QT_NO_PROGRESSBAR
1065     case CE_ProgressBarGroove:
1066         {
1067             Qt::Orientation orient = Qt::Horizontal;
1068             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
1069                 orient = pb2->orientation;
1070             partId = (orient == Qt::Horizontal) ? PP_TRANSPARENTBAR : PP_TRANSPARENTBARVERT;
1071             name = QLatin1String("PROGRESS");
1072             stateId = 1;
1073
1074             XPThemeData theme(widget, painter, name, partId, stateId, rect);
1075             d->drawBackground(theme);
1076         }
1077         break;
1078     case CE_ProgressBarContents:
1079         if (const QStyleOptionProgressBar *bar
1080                 = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1081             bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0);
1082             bool vertical = false;
1083             bool inverted = false;
1084             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
1085                 vertical = (pb2->orientation == Qt::Vertical);
1086                 inverted = pb2->invertedAppearance;
1087             }
1088
1089             if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) {
1090                 if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) {
1091                     if (!d->widgetAnimation(progressbar)) {
1092                         QWindowsVistaAnimation *a = new QWindowsVistaAnimation;
1093                         a->setWidget(const_cast<QWidget*>(widget));
1094                         a->setStartTime(QTime::currentTime());
1095                         d->startAnimation(a);
1096                     }
1097                 } else {
1098                     d->stopAnimation(progressbar);
1099                 }
1100             }
1101
1102             XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL);
1103             theme.rect = option->rect;
1104             bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted);
1105             QTime current = QTime::currentTime();
1106
1107             if (isIndeterminate) {
1108                 if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
1109                     int glowSize = 120;
1110                     int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
1111                     int animOffset = a->startTime().msecsTo(current) / 4;
1112                     if (animOffset > animationWidth)
1113                         a->setStartTime(QTime::currentTime());
1114                     painter->save();
1115                     painter->setClipRect(theme.rect);
1116                     QRect animRect;
1117                     QSize pixmapSize(14, 14);
1118                     if (vertical) {
1119                         animRect = QRect(theme.rect.left(),
1120                                          inverted ? rect.top() - glowSize + animOffset :
1121                                                     rect.bottom() + glowSize - animOffset,
1122                                          rect.width(), glowSize);
1123                          pixmapSize.setHeight(animRect.height());
1124                     } else {
1125                         animRect = QRect(rect.left() - glowSize + animOffset,
1126                                          rect.top(), glowSize, rect.height());
1127                         animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, 
1128                                                                 option->rect, animRect);
1129                         pixmapSize.setWidth(animRect.width());
1130                     }
1131                     QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height());
1132                     QPixmap pixmap;
1133                     if (!QPixmapCache::find(name, pixmap)) {
1134                         QImage image(pixmapSize, QImage::Format_ARGB32);
1135                         image.fill(Qt::transparent);
1136                         QPainter imagePainter(&image);
1137                         theme.painter = &imagePainter;
1138                         theme.partId = vertical ? PP_FILLVERT : PP_FILL;
1139                         theme.rect = QRect(QPoint(0,0), theme.rect.size());
1140                         QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(),
1141                                                       vertical ? image.height() : 0);
1142                         alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
1143                         alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220));
1144                         alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
1145                         imagePainter.fillRect(image.rect(), alphaGradient);
1146                         imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
1147                         d->drawBackground(theme);
1148                         imagePainter.end();
1149                         pixmap = QPixmap::fromImage(image);
1150                         QPixmapCache::insert(name, pixmap);
1151                     }
1152                     painter->drawPixmap(animRect, pixmap);
1153                     painter->restore();
1154                 }
1155             }
1156             else {
1157                 qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar
1158
1159                 if (vertical) {
1160                     int maxHeight = option->rect.height();
1161                     int minHeight = 0;
1162                     double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight);
1163                     int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight);
1164                     theme.rect.setHeight(height);
1165                     if (!inverted)
1166                         theme.rect.moveTop(rect.height() - theme.rect.height());
1167                 } else {
1168                     int maxWidth = option->rect.width();
1169                     int minWidth = 0;
1170                     double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth);
1171                     int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth);
1172                     theme.rect.setWidth(width);
1173                     theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, 
1174                                                               option->rect, theme.rect);
1175                 }
1176                 d->drawBackground(theme);
1177
1178                 if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
1179                     int glowSize = 140;
1180                     int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
1181                     int animOffset = a->startTime().msecsTo(current) / 4;
1182                     theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
1183                     if (animOffset > animationWidth) {
1184                         if (bar->progress < bar->maximum)
1185                             a->setStartTime(QTime::currentTime());
1186                         else
1187                             d->stopAnimation(widget); //we stop the glow motion only after it has
1188                                                       //moved out of view
1189                     }
1190                     painter->save();
1191                     painter->setClipRect(theme.rect);
1192                     if (vertical) {
1193                         theme.rect = QRect(theme.rect.left(),
1194                                            inverted ? rect.top() - glowSize + animOffset :
1195                                                       rect.bottom() + glowSize - animOffset,
1196                                            rect.width(), glowSize);
1197                     } else {
1198                         theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height());
1199                         theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect);
1200                     }
1201                     d->drawBackground(theme);
1202                     painter->restore();
1203                 }
1204             }
1205         }
1206         break;
1207 #endif // QT_NO_PROGRESSBAR
1208     case CE_MenuBarItem:
1209         {
1210
1211         if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
1212         {
1213             if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
1214                 break;
1215
1216             QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
1217             QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
1218
1219             uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1220             if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
1221                 alignment |= Qt::TextHideMnemonic;
1222
1223             //The rect adjustment is a workaround for the menu not really filling its background.
1224             XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
1225             d->drawBackground(theme);
1226
1227             int stateId = MBI_NORMAL;
1228             if (disabled)
1229                 stateId = MBI_DISABLED;
1230             else if (pressed)
1231                 stateId = MBI_PUSHED;
1232             else if (selected)
1233                 stateId = MBI_HOT;
1234
1235             XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect);
1236             d->drawBackground(theme2);
1237
1238             if (!pix.isNull())
1239                 drawItemPixmap(painter, mbi->rect, alignment, pix);
1240             else
1241                 drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
1242         }
1243     }
1244     break;
1245 #ifndef QT_NO_MENU
1246     case CE_MenuItem:
1247         if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1248             // windows always has a check column, regardless whether we have an icon or not
1249             int checkcol = 25;
1250             {
1251                 SIZE    size;
1252                 MARGINS margins;
1253                 XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
1254                 pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
1255                 pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
1256                 checkcol = qMax(menuitem->maxIconWidth, int(3 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
1257             }
1258             QRect rect = option->rect;
1259
1260             //draw vertical menu line
1261             if (option->direction == Qt::LeftToRight)
1262                 checkcol += rect.x();
1263             QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
1264             QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
1265             QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
1266             XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect);
1267             d->drawBackground(theme2);
1268
1269             int x, y, w, h;
1270             menuitem->rect.getRect(&x, &y, &w, &h);
1271             int tab = menuitem->tabWidth;
1272             bool dis = !(menuitem->state & State_Enabled);
1273             bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
1274                             ? menuitem->checked : false;
1275             bool act = menuitem->state & State_Selected;
1276
1277             if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
1278                 int yoff = y-2 + h / 2;
1279                 QPoint p1 = QPoint(x + checkcol, yoff);
1280                 QPoint p2 = QPoint(x + w + 6 , yoff);
1281                 stateId = MBI_HOT;
1282                 QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
1283                 subRect  = QStyle::visualRect(option->direction, option->rect, subRect );
1284                 XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect);
1285                 d->drawBackground(theme2);
1286                 return;
1287             }
1288
1289             QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
1290                                           menuitem->rect.y(), checkcol - 6, menuitem->rect.height()));
1291
1292             if (act) {
1293                 stateId = dis ? MBI_DISABLED : MBI_HOT;
1294                 XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect);
1295                 d->drawBackground(theme2);
1296             }
1297
1298             if (checked) {
1299                 XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND,
1300                                   menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
1301                 SIZE    size;
1302                 MARGINS margins;
1303                 pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
1304                 pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0,
1305                                 TMT_CONTENTMARGINS, NULL, &margins);
1306                 QRect checkRect(0, 0, size.cx + margins.cxLeftWidth + margins.cxRightWidth ,
1307                                 size.cy + margins.cyBottomHeight + margins.cyTopHeight);
1308                 checkRect.moveCenter(vCheckRect.center());
1309                 theme.rect = checkRect;
1310
1311                 d->drawBackground(theme);
1312
1313                 if (menuitem->icon.isNull()) {
1314                     checkRect = QRect(0, 0, size.cx, size.cy);
1315                     checkRect.moveCenter(theme.rect.center());
1316                     theme.rect = checkRect;
1317
1318                     theme.partId = MENU_POPUPCHECK;
1319                     bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive;
1320                     if (dis)
1321                         theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED;
1322                     else
1323                         theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL;
1324                     d->drawBackground(theme);
1325                 }
1326             }
1327
1328             if (!menuitem->icon.isNull()) {
1329                 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1330                 if (act && !dis)
1331                     mode = QIcon::Active;
1332                 QPixmap pixmap;
1333                 if (checked)
1334                     pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
1335                 else
1336                     pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
1337                 int pixw = pixmap.width();
1338                 int pixh = pixmap.height();
1339                 QRect pmr(0, 0, pixw, pixh);
1340                 pmr.moveCenter(vCheckRect.center());
1341                 painter->setPen(menuitem->palette.text().color());
1342                 painter->drawPixmap(pmr.topLeft(), pixmap);
1343             }
1344
1345             painter->setPen(menuitem->palette.buttonText().color());
1346
1347             const QColor textColor = menuitem->palette.text().color();
1348             if (dis)
1349                 painter->setPen(textColor);
1350
1351             int xm = windowsItemFrame + checkcol + windowsItemHMargin;
1352             int xpos = menuitem->rect.x() + xm;
1353             QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
1354             QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
1355             QString s = menuitem->text;
1356             if (!s.isEmpty()) {    // draw text
1357                 painter->save();
1358                 int t = s.indexOf(QLatin1Char('\t'));
1359                 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1360                 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
1361                     text_flags |= Qt::TextHideMnemonic;
1362                 text_flags |= Qt::AlignLeft;
1363                 if (t >= 0) {
1364                     QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
1365                     QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
1366                     painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
1367                     s = s.left(t);
1368                 }
1369                 QFont font = menuitem->font;
1370                 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
1371                     font.setBold(true);
1372                 painter->setFont(font);
1373                 painter->setPen(textColor);
1374                 painter->drawText(vTextRect, text_flags, s.left(t));
1375                 painter->restore();
1376             }
1377             if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
1378                 int dim = (h - 2 * windowsItemFrame) / 2;
1379                 PrimitiveElement arrow;
1380                 arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
1381                 xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
1382                 QRect  vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
1383                 QStyleOptionMenuItem newMI = *menuitem;
1384                 newMI.rect = vSubMenuRect;
1385                 newMI.state = dis ? State_None : State_Enabled;
1386                 proxy()->drawPrimitive(arrow, &newMI, painter, widget);
1387             }
1388         }
1389         break;
1390 #endif // QT_NO_MENU
1391     case CE_HeaderSection:
1392         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
1393             name = QLatin1String("HEADER");
1394             partId = HP_HEADERITEM;
1395             if (flags & State_Sunken)
1396                 stateId = HIS_PRESSED;
1397             else if (flags & State_MouseOver)
1398                 stateId = HIS_HOT;
1399             else
1400                 stateId = HIS_NORMAL;
1401
1402             if (header->sortIndicator != QStyleOptionHeader::None)
1403                 stateId += 3;
1404
1405             XPThemeData theme(widget, painter, name, partId, stateId, option->rect);
1406             d->drawBackground(theme);
1407         }
1408         break;
1409     case CE_MenuBarEmptyArea:
1410         {
1411             stateId = MBI_NORMAL;
1412             if (!(state & State_Enabled))
1413                 stateId = MBI_DISABLED;
1414             XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect);
1415             d->drawBackground(theme);
1416         }
1417         break;
1418     case CE_ToolBar:
1419         if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
1420             QPalette pal = option->palette;
1421             pal.setColor(QPalette::Dark, option->palette.background().color().darker(130));
1422             QStyleOptionToolBar copyOpt = *toolbar;
1423             copyOpt.palette = pal;
1424             QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
1425         }
1426         break;
1427     case CE_DockWidgetTitle:
1428         if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
1429             QRect rect = option->rect;
1430             if (dockWidget->isFloating()) {
1431                 QWindowsXPStyle::drawControl(element, option, painter, widget);
1432                 break; //otherwise fall through
1433             }
1434
1435             if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
1436
1437             const QStyleOptionDockWidgetV2 *v2
1438                 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
1439             bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
1440
1441             if (verticalTitleBar) {
1442                 QSize s = rect.size();
1443                 s.transpose();
1444                 rect.setSize(s);
1445
1446                 painter->translate(rect.left() - 1, rect.top() + rect.width());
1447                 painter->rotate(-90);
1448                 painter->translate(-rect.left() + 1, -rect.top());
1449             }
1450
1451             painter->setBrush(option->palette.background().color().darker(110));
1452             painter->setPen(option->palette.background().color().darker(130));
1453             painter->drawRect(rect.adjusted(0, 1, -1, -3));
1454
1455             int buttonMargin = 4;
1456             int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
1457             int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
1458             const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
1459             bool isFloating = dw != 0 && dw->isFloating();
1460
1461             QRect r = option->rect.adjusted(0, 2, -1, -3);
1462             QRect titleRect = r;
1463
1464             if (dwOpt->closable) {
1465                 QSize sz = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
1466                 titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
1467             }
1468
1469             if (dwOpt->floatable) {
1470                 QSize sz = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
1471                 titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
1472             }
1473
1474             if (isFloating) {
1475                 titleRect.adjust(0, -fw, 0, 0);
1476                 if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
1477                     titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
1478             } else {
1479                 titleRect.adjust(mw, 0, 0, 0);
1480                 if (!dwOpt->floatable && !dwOpt->closable)
1481                     titleRect.adjust(0, 0, -mw, 0);
1482             }
1483             if (!verticalTitleBar)
1484                 titleRect = visualRect(dwOpt->direction, r, titleRect);
1485
1486             if (!dwOpt->title.isEmpty()) {
1487                 QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
1488                                                                       verticalTitleBar ? titleRect.height() : titleRect.width());
1489                 const int indent = painter->fontMetrics().descent();
1490                 drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1),
1491                                 Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
1492                                 dwOpt->state & State_Enabled, titleText,
1493                                 QPalette::WindowText);
1494                 }
1495             }
1496             break;
1497         }
1498 #ifndef QT_NO_ITEMVIEWS
1499     case CE_ItemViewItem:
1500         {
1501             const QStyleOptionViewItemV4 *vopt;
1502             const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
1503             bool newStyle = true;
1504
1505             if (qobject_cast<const QTableView*>(widget))
1506                 newStyle = false;
1507
1508             if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
1509                 /*
1510                 // We cannot currently get the correct selection color for "explorer style" views
1511                 COLORREF cref = 0;
1512                 XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0);
1513                 unsigned int res = pGetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref);
1514                 QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
1515                 */
1516                 QPalette palette = vopt->palette;
1517                 palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text));
1518                 // Note that setting a saturated color here results in ugly XOR colors in the focus rect
1519                 palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108));
1520                 QStyleOptionViewItemV4 adjustedOption = *vopt;
1521                 adjustedOption.palette = palette;
1522                 // We hide the  focusrect in singleselection as it is not required
1523                 if ((view->selectionMode() == QAbstractItemView::SingleSelection) 
1524                     && !(vopt->state & State_KeyboardFocusChange))
1525                 adjustedOption.state &= ~State_HasFocus;
1526                 QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget);
1527             } else {
1528                 QWindowsXPStyle::drawControl(element, option, painter, widget);
1529             }
1530             break;
1531         }
1532 #endif // QT_NO_ITEMVIEWS
1533
1534     default:
1535         QWindowsXPStyle::drawControl(element, option, painter, widget);
1536         break;
1537     }
1538 }
1539
1540 /*!
1541   \internal
1542
1543   see drawPrimitive for comments on the animation support
1544
1545  */
1546 void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
1547                                          QPainter *painter, const QWidget *widget) const
1548 {
1549     QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
1550     if (!QWindowsVistaStylePrivate::useVista()) {
1551         QWindowsStyle::drawComplexControl(control, option, painter, widget);
1552         return;
1553     }
1554
1555     State state = option->state;
1556     SubControls sub = option->subControls;
1557     QRect r = option->rect;
1558
1559     int partId = 0;
1560     int stateId = 0;
1561
1562     State flags = option->state;
1563     if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
1564         flags |= State_MouseOver;
1565
1566     if (d->transitionsEnabled() && widget) {
1567         if ((qobject_cast<const QScrollBar *>(widget) && control == CC_ScrollBar)
1568 #ifndef QT_NO_SPINBOX
1569             || (qobject_cast<const QAbstractSpinBox*>(widget) && control == CC_SpinBox)
1570 #endif // QT_NO_SPINBOX
1571 #ifndef QT_NO_COMBOBOX
1572             || (qobject_cast<const QComboBox*>(widget) && control == CC_ComboBox)
1573 #endif // QT_NO_COMBOBOX
1574             )
1575         {
1576             QWidget *w = const_cast<QWidget *> (widget);
1577
1578             int oldState = w->property("_q_stylestate").toInt();
1579             int oldActiveControls = w->property("_q_stylecontrols").toInt();
1580             QRect oldRect = w->property("_q_stylerect").toRect();
1581             w->setProperty("_q_stylestate", (int)option->state);
1582             w->setProperty("_q_stylecontrols", (int)option->activeSubControls);
1583             w->setProperty("_q_stylerect", w->rect());
1584
1585             bool doTransition = ((state & State_Sunken)     != (oldState & State_Sunken)    ||
1586                                  (state & State_On)         != (oldState & State_On)        ||
1587                                  (state & State_MouseOver)  != (oldState & State_MouseOver) ||
1588                                   oldActiveControls            != option->activeSubControls);
1589
1590
1591             if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
1592                 QRect oldSliderPos = w->property("_q_stylesliderpos").toRect();
1593                 QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
1594                 w->setProperty("_q_stylesliderpos", currentPos);
1595                 if (oldSliderPos != currentPos) {
1596                     doTransition = false;
1597                     d->stopAnimation(widget);
1598                 }
1599             } else if (control == CC_SpinBox) {
1600                 //spinboxes have a transition when focus changes
1601                 if (!doTransition)
1602                     doTransition = (state & State_HasFocus) != (oldState & State_HasFocus);
1603             }
1604
1605             if (oldRect != option->rect) {
1606                 doTransition = false;
1607                 d->stopAnimation(widget);
1608             }
1609
1610             if (doTransition) {
1611                 QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
1612                 QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
1613                 QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
1614                 QWindowsVistaTransition *t = new QWindowsVistaTransition;
1615                 t->setWidget(w);
1616                 if (!anim) {
1617                     if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
1618                         //Combo boxes are special cased to avoid cleartype issues
1619                         startImage.fill(0);
1620                         QPainter startPainter(&startImage);
1621                         QStyleOptionComboBox startCombo = *combo;
1622                         startCombo.state = (QStyle::State)oldState;
1623                         startCombo.activeSubControls = (QStyle::SubControl)oldActiveControls;
1624                         proxy()->drawComplexControl(control, &startCombo, &startPainter, 0 /* Intentional */);
1625                         t->setStartImage(startImage);
1626                     } else if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
1627                         //This is a workaround for the direct3d engine as it currently has some issues with grabWindow
1628                         startImage.fill(0);
1629                         QPainter startPainter(&startImage);
1630                         QStyleOptionSlider startSlider = *slider;
1631                         startSlider.state = (QStyle::State)oldState;
1632                         startSlider.activeSubControls = (QStyle::SubControl)oldActiveControls;
1633                         proxy()->drawComplexControl(control, &startSlider, &startPainter, 0 /* Intentional */);
1634                         t->setStartImage(startImage);
1635                     } else {
1636                         QPoint offset(0, 0);
1637                         if (!widget->internalWinId())
1638                             offset = widget->mapTo(widget->nativeParentWidget(), offset);
1639                         t->setStartImage(QPixmap::grabWindow(widget->effectiveWinId(), offset.x(), offset.y(),
1640                                          option->rect.width(), option->rect.height()).toImage());
1641                     }
1642                 } else {
1643                     startImage.fill(0);
1644                     QPainter startPainter(&startImage);
1645                     anim->paint(&startPainter, option);
1646                     t->setStartImage(startImage);
1647                 }
1648                 d->startAnimation(t);
1649                 endImage.fill(0);
1650                 QPainter endPainter(&endImage);
1651                 proxy()->drawComplexControl(control, option, &endPainter, 0 /* Intentional */);
1652                 t->setEndImage(endImage);
1653                 t->setStartTime(QTime::currentTime());
1654
1655                 if (option->state & State_MouseOver || option->state & State_Sunken)
1656                     t->setDuration(150);
1657                 else
1658                     t->setDuration(500);
1659             }
1660
1661             if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
1662                 anim->paint(painter, option);
1663                 return;
1664             }
1665
1666         }
1667     }
1668
1669     switch (control) {
1670     case CC_ComboBox:
1671         if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
1672         {
1673             if (cmb->editable) {
1674                 if (sub & SC_ComboBoxEditField) {
1675                     partId = EP_EDITBORDER_NOSCROLL;
1676                     if (!(flags & State_Enabled))
1677                         stateId = ETS_DISABLED;
1678                     else if (flags & State_MouseOver)
1679                         stateId = ETS_HOT;
1680                     else if (flags & State_HasFocus)
1681                         stateId = ETS_FOCUSED;
1682                     else
1683                         stateId = ETS_NORMAL;
1684
1685                     XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
1686
1687                     d->drawBackground(theme);
1688                 }
1689                 if (sub & SC_ComboBoxArrow) {
1690                     QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
1691                     XPThemeData theme(widget, painter, QLatin1String("COMBOBOX"));
1692                     theme.rect = subRect;
1693                     partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
1694
1695                     if (!(cmb->state & State_Enabled))
1696                         stateId = CBXS_DISABLED;
1697                     else if (cmb->state & State_Sunken || cmb->state & State_On)
1698                         stateId = CBXS_PRESSED;
1699                     else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
1700                         stateId = CBXS_HOT;
1701                     else
1702                         stateId = CBXS_NORMAL;
1703
1704                     theme.partId = partId;
1705                     theme.stateId = stateId;
1706                     d->drawBackground(theme);
1707                 }
1708
1709             } else {
1710                 if (sub & SC_ComboBoxFrame) {
1711                     QStyleOptionButton btn;
1712                     btn.QStyleOption::operator=(*option);
1713                     btn.rect = option->rect.adjusted(-1, -1, 1, 1);
1714                     if (sub & SC_ComboBoxArrow)
1715                         btn.features = QStyleOptionButton::HasMenu;
1716                     proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget);
1717                 }
1718             }
1719        }
1720        break;
1721     case CC_ScrollBar:
1722         if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
1723         {
1724             XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR"));
1725
1726             bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
1727             if (maxedOut)
1728                 flags &= ~State_Enabled;
1729
1730             bool isHorz = flags & State_Horizontal;
1731             bool isRTL  = option->direction == Qt::RightToLeft;
1732             if (sub & SC_ScrollBarAddLine) {
1733                 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
1734                 partId = SBP_ARROWBTN;
1735                 if (!(flags & State_Enabled))
1736                     stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
1737                 else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
1738                     stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
1739                 else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
1740                     stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
1741                 else if (scrollbar->state & State_MouseOver)
1742                     stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER);
1743                 else
1744                     stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
1745                 theme.partId = partId;
1746                 theme.stateId = stateId;
1747                 d->drawBackground(theme);
1748             }
1749             if (sub & SC_ScrollBarSubLine) {
1750                 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
1751                 partId = SBP_ARROWBTN;
1752                 if (!(flags & State_Enabled))
1753                     stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
1754                 else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
1755                     stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
1756                 else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
1757                     stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
1758                 else if (scrollbar->state & State_MouseOver)
1759                     stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER);
1760                 else
1761                     stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
1762                 theme.partId = partId;
1763                 theme.stateId = stateId;
1764                 d->drawBackground(theme);
1765             }
1766             if (maxedOut) {
1767                 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
1768                 theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
1769                 theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
1770                 partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
1771                 stateId = SCRBS_DISABLED;
1772                 theme.partId = partId;
1773                 theme.stateId = stateId;
1774                 d->drawBackground(theme);
1775             } else {
1776                 if (sub & SC_ScrollBarSubPage) {
1777                     theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
1778                     partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
1779                     if (!(flags & State_Enabled))
1780                         stateId = SCRBS_DISABLED;
1781                     else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
1782                         stateId = SCRBS_PRESSED;
1783                     else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
1784                         stateId = SCRBS_HOT;
1785                     else
1786                         stateId = SCRBS_NORMAL;
1787                     theme.partId = partId;
1788                     theme.stateId = stateId;
1789                     d->drawBackground(theme);
1790                 }
1791                 if (sub & SC_ScrollBarAddPage) {
1792                     theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
1793                     partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
1794                     if (!(flags & State_Enabled))
1795                         stateId = SCRBS_DISABLED;
1796                     else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
1797                         stateId = SCRBS_PRESSED;
1798                     else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
1799                         stateId = SCRBS_HOT;
1800                     else
1801                         stateId = SCRBS_NORMAL;
1802                     theme.partId = partId;
1803                     theme.stateId = stateId;
1804                     d->drawBackground(theme);
1805                 }
1806                 if (sub & SC_ScrollBarSlider) {
1807                     theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
1808                     if (!(flags & State_Enabled))
1809                         stateId = SCRBS_DISABLED;
1810                     else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
1811                         stateId = SCRBS_PRESSED;
1812                     else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
1813                         stateId = SCRBS_HOT;
1814                     else if (option->state & State_MouseOver)
1815                         stateId = SCRBS_HOVER;
1816                     else
1817                         stateId = SCRBS_NORMAL;
1818
1819                     // Draw handle
1820                     theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
1821                     theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
1822                     theme.stateId = stateId;
1823                     d->drawBackground(theme);
1824
1825                     // Calculate rect of gripper
1826                     const int swidth = theme.rect.width();
1827                     const int sheight = theme.rect.height();
1828
1829                     MARGINS contentsMargin;
1830                     RECT rect = theme.toRECT(theme.rect);
1831                     pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
1832
1833                     SIZE size;
1834                     theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
1835                     pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
1836                     int gw = size.cx, gh = size.cy;
1837
1838                     if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) {
1839                         QRect gripperBounds;
1840                         if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
1841                             gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
1842                             gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
1843                             gripperBounds.setWidth(gw);
1844                             gripperBounds.setHeight(gh);
1845                         } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
1846                             gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
1847                             gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
1848                             gripperBounds.setWidth(gw);
1849                             gripperBounds.setHeight(gh);
1850                         }
1851
1852                         // Draw gripper if there is enough space
1853                         if (!gripperBounds.isEmpty() && flags & State_Enabled) {
1854                             painter->save();
1855                             XPThemeData grippBackground = theme;
1856                             grippBackground.partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
1857                             theme.rect = gripperBounds;
1858                             painter->setClipRegion(d->region(theme));// Only change inside the region of the gripper
1859                             d->drawBackground(grippBackground);// The gutter is the grippers background
1860                             d->drawBackground(theme);          // Transparent gripper ontop of background
1861                             painter->restore();
1862                         }
1863                     }
1864                 }
1865             }
1866         }
1867         break;
1868 #ifndef QT_NO_SPINBOX
1869     case CC_SpinBox:
1870         if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
1871         {
1872             XPThemeData theme(widget, painter, QLatin1String("SPIN"));
1873             if (sb->frame && (sub & SC_SpinBoxFrame)) {
1874                 partId = EP_EDITBORDER_NOSCROLL;
1875                 if (!(flags & State_Enabled))
1876                     stateId = ETS_DISABLED;
1877                 else if (flags & State_MouseOver)
1878                     stateId = ETS_HOT;
1879                 else if (flags & State_HasFocus)
1880                     stateId = ETS_SELECTED;
1881                 else
1882                     stateId = ETS_NORMAL;
1883
1884                 XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
1885                 ftheme.noContent = true;
1886                 d->drawBackground(ftheme);
1887             }
1888             if (sub & SC_SpinBoxUp) {
1889                 theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1);
1890                 partId = SPNP_UP;
1891                 if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
1892                     stateId = UPS_DISABLED;
1893                 else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
1894                     stateId = UPS_PRESSED;
1895                 else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
1896                     stateId = UPS_HOT;
1897                 else
1898                     stateId = UPS_NORMAL;
1899                 theme.partId = partId;
1900                 theme.stateId = stateId;
1901                 d->drawBackground(theme);
1902             }
1903             if (sub & SC_SpinBoxDown) {
1904                 theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
1905                 partId = SPNP_DOWN;
1906                 if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
1907                     stateId = DNS_DISABLED;
1908                 else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
1909                     stateId = DNS_PRESSED;
1910                 else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
1911                     stateId = DNS_HOT;
1912                 else
1913                     stateId = DNS_NORMAL;
1914                 theme.partId = partId;
1915                 theme.stateId = stateId;
1916                 d->drawBackground(theme);
1917             }
1918         }
1919         break;
1920 #endif // QT_NO_SPINBOX
1921     default:
1922         QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
1923         break;
1924     }
1925 }
1926
1927 /*!
1928  \internal
1929  */
1930 QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
1931                                         const QSize &size, const QWidget *widget) const
1932 {
1933     if (!QWindowsVistaStylePrivate::useVista())
1934         return QWindowsStyle::sizeFromContents(type, option, size, widget);
1935
1936     QSize sz(size);
1937     switch (type) {
1938     case CT_MenuItem:
1939         sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
1940         int minimumHeight;
1941         {
1942             SIZE    size;
1943             MARGINS margins;
1944             XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
1945             pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
1946             pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
1947             minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height());
1948             sz.rwidth() += size.cx + margins.cxLeftWidth + margins.cxRightWidth;
1949         }
1950         
1951         if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1952             if (menuitem->menuItemType != QStyleOptionMenuItem::Separator)
1953                 sz.setHeight(minimumHeight);
1954         }
1955         return sz;
1956 #ifndef QT_NO_MENUBAR
1957     case CT_MenuBarItem:
1958         if (!sz.isEmpty())
1959             sz += QSize(windowsItemHMargin * 5 + 1, 5);
1960             return sz;
1961         break;
1962 #endif
1963     case CT_ItemViewItem:
1964         sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
1965         sz.rheight() += 2;
1966         return sz;
1967     case CT_SpinBox:
1968         {
1969             //Spinbox adds frame twice
1970             sz = QWindowsStyle::sizeFromContents(type, option, size, widget);
1971             int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
1972             sz -= QSize(2*border, 2*border);
1973         }
1974         return sz;
1975     default:
1976         break;
1977     }
1978     return QWindowsXPStyle::sizeFromContents(type, option, size, widget);
1979 }
1980
1981 /*!
1982  \internal
1983  */
1984 QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
1985 {
1986    if (!QWindowsVistaStylePrivate::useVista())
1987         return QWindowsStyle::subElementRect(element, option, widget);
1988
1989    QRect rect = QWindowsXPStyle::subElementRect(element, option, widget);
1990     switch (element) {
1991
1992     case SE_PushButtonContents:
1993         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1994             MARGINS borderSize;
1995             HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
1996             if (theme) {
1997                 int stateId = PBS_NORMAL;
1998                 if (!(option->state & State_Enabled))
1999                     stateId = PBS_DISABLED;
2000                 else if (option->state & State_Sunken)
2001                     stateId = PBS_PRESSED;
2002                 else if (option->state & State_MouseOver)
2003                     stateId = PBS_HOT;
2004                 else if (btn->features & QStyleOptionButton::DefaultButton)
2005                     stateId = PBS_DEFAULTED;
2006
2007                 int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
2008                 rect = option->rect.adjusted(border, border, -border, -border);
2009
2010                 int result = pGetThemeMargins(theme,
2011                                               NULL,
2012                                               BP_PUSHBUTTON,
2013                                               stateId,
2014                                               TMT_CONTENTMARGINS,
2015                                               NULL,
2016                                               &borderSize);
2017
2018                 if (result == S_OK) {
2019                     rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
2020                                 -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
2021                     rect = visualRect(option->direction, option->rect, rect);
2022                 }
2023             }
2024         }
2025         break;
2026
2027     case SE_HeaderArrow:
2028         {
2029             QRect r = rect;
2030             int h = option->rect.height();
2031             int w = option->rect.width();
2032             int x = option->rect.x();
2033             int y = option->rect.y();
2034             int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
2035
2036             XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
2037
2038             int arrowWidth = 13;
2039             int arrowHeight = 5;
2040             if (theme.isValid()) {
2041                 SIZE size;
2042                 if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
2043                     arrowWidth = size.cx;
2044                     arrowHeight = size.cy;
2045                 }
2046             }
2047             if (option->state & State_Horizontal) {
2048                 r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight);
2049             } else {
2050                 int vert_size = w / 2;
2051                 r.setRect(x + 5, y + h - margin * 2 - vert_size,
2052                           w - margin * 2 - 5, vert_size);
2053             }
2054             rect = visualRect(option->direction, option->rect, r);
2055         }
2056         break;
2057
2058     case SE_HeaderLabel:
2059         {
2060             int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
2061             QRect r = option->rect;
2062             r.setRect(option->rect.x() + margin, option->rect.y() + margin,
2063                       option->rect.width() - margin * 2, option->rect.height() - margin * 2);
2064             if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
2065                 // Subtract width needed for arrow, if there is one
2066                 if (header->sortIndicator != QStyleOptionHeader::None) {
2067                     if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top
2068                         r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2));
2069                 }
2070             }
2071             rect = visualRect(option->direction, option->rect, r);
2072         }
2073         break;
2074     case SE_ProgressBarContents:
2075         rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
2076         break;
2077     case SE_ItemViewItemDecoration:
2078         if (qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))
2079             rect.adjust(-2, 0, 2, 0);
2080         break;
2081     case SE_ItemViewItemFocusRect:
2082         if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
2083             QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
2084             QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget);
2085             if (!vopt->icon.isNull())
2086                 rect = textRect.united(displayRect);
2087             else
2088                 rect = textRect;
2089             rect = rect.adjusted(1, 0, -1, 0);
2090         }
2091         break;
2092     default:
2093         break;
2094     }
2095     return rect;
2096 }
2097
2098
2099 /*
2100   This function is used by subControlRect to check if a button
2101   should be drawn for the given subControl given a set of window flags.
2102 */
2103 static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
2104
2105     bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
2106     bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
2107     const uint flags = tb->titleBarFlags;
2108     bool retVal = false;
2109     switch (sc) {
2110     case QStyle::SC_TitleBarContextHelpButton:
2111         if (flags & Qt::WindowContextHelpButtonHint)
2112             retVal = true;
2113         break;
2114     case QStyle::SC_TitleBarMinButton:
2115         if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
2116             retVal = true;
2117         break;
2118     case QStyle::SC_TitleBarNormalButton:
2119         if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
2120             retVal = true;
2121         else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
2122             retVal = true;
2123         break;
2124     case QStyle::SC_TitleBarMaxButton:
2125         if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
2126             retVal = true;
2127         break;
2128     case QStyle::SC_TitleBarShadeButton:
2129         if (!isMinimized &&  flags & Qt::WindowShadeButtonHint)
2130             retVal = true;
2131         break;
2132     case QStyle::SC_TitleBarUnshadeButton:
2133         if (isMinimized && flags & Qt::WindowShadeButtonHint)
2134             retVal = true;
2135         break;
2136     case QStyle::SC_TitleBarCloseButton:
2137         if (flags & Qt::WindowSystemMenuHint)
2138             retVal = true;
2139         break;
2140     case QStyle::SC_TitleBarSysMenu:
2141         if (flags & Qt::WindowSystemMenuHint)
2142             retVal = true;
2143         break;
2144     default :
2145         retVal = true;
2146     }
2147     return retVal;
2148 }
2149
2150
2151 /*! \internal */
2152 int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
2153                              QStyleHintReturn *returnData) const
2154 {
2155     QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
2156     int ret = 0;
2157     switch (hint) {
2158     case SH_MessageBox_CenterButtons:
2159         ret = false;
2160         break;
2161     case SH_ToolTip_Mask:
2162         if (option) {
2163             if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
2164                 ret = true;
2165                 XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
2166                 mask->region = d->region(themeData);
2167             }
2168         }
2169         break;
2170      case SH_Table_GridLineColor:
2171         if (option)
2172             ret = option->palette.color(QPalette::Base).darker(118).rgb();
2173         else
2174             ret = -1;
2175         break;
2176     default:
2177         ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
2178         break;
2179     }
2180     return ret;
2181 }
2182
2183
2184 /*!
2185  \internal
2186  */
2187 QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
2188                                   SubControl subControl, const QWidget *widget) const
2189 {
2190    if (!QWindowsVistaStylePrivate::useVista())
2191         return QWindowsStyle::subControlRect(control, option, subControl, widget);
2192
2193     QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
2194     switch (control) {
2195 #ifndef QT_NO_COMBOBOX
2196     case CC_ComboBox:
2197         if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
2198             int x = cb->rect.x(),
2199                 y = cb->rect.y(),
2200                 wi = cb->rect.width(),
2201                 he = cb->rect.height();
2202             int xpos = x;
2203             int margin = cb->frame ? 3 : 0;
2204             int bmarg = cb->frame ? 2 : 0;
2205             int arrowButtonWidth = bmarg + 16;
2206             xpos += wi - arrowButtonWidth;
2207
2208             switch (subControl) {
2209             case SC_ComboBoxFrame:
2210                 rect = cb->rect;
2211                 break;
2212             case SC_ComboBoxArrow:
2213                 rect.setRect(xpos, y , arrowButtonWidth, he);
2214                 break;
2215             case SC_ComboBoxEditField:
2216                 rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
2217                 break;
2218             case SC_ComboBoxListBoxPopup:
2219                 rect = cb->rect;
2220                 break;
2221             default:
2222                 break;
2223             }
2224             rect = visualRect(cb->direction, cb->rect, rect);
2225             return rect;
2226         }
2227 #endif // QT_NO_COMBOBOX
2228     case CC_TitleBar:
2229         if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
2230             if (!buttonVisible(subControl, tb))
2231                 return rect;
2232             const bool isToolTitle = false;
2233             const int height = tb->rect.height();
2234             const int width = tb->rect.width();
2235             int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
2236
2237             const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
2238             const bool sysmenuHint  = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
2239             const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
2240             const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
2241             const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
2242             const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
2243
2244             switch (subControl) {
2245             case SC_TitleBarLabel:
2246                 rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
2247                 if (isToolTitle) {
2248                     if (sysmenuHint) {
2249                         rect.adjust(0, 0, -buttonWidth - 3, 0);
2250                     }
2251                     if (minimizeHint || maximizeHint)
2252                         rect.adjust(0, 0, -buttonWidth - 2, 0);
2253                 } else {
2254                     if (sysmenuHint) {
2255                         const int leftOffset = height - 8;
2256                         rect.adjust(leftOffset, 0, 0, 4);
2257                     }
2258                     if (minimizeHint)
2259                         rect.adjust(0, 0, -buttonWidth - 2, 0);
2260                     if (maximizeHint)
2261                         rect.adjust(0, 0, -buttonWidth - 2, 0);
2262                     if (contextHint)
2263                         rect.adjust(0, 0, -buttonWidth - 2, 0);
2264                     if (shadeHint)
2265                         rect.adjust(0, 0, -buttonWidth - 2, 0);
2266                 }
2267                 rect.translate(0, 2);
2268                 rect = visualRect(option->direction, option->rect, rect);
2269                 break;
2270             case SC_TitleBarSysMenu:
2271                 {
2272                     const int controlTop = 6;
2273                     const int controlHeight = height - controlTop - 3;
2274                     int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
2275                     QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
2276                     if (tb->icon.isNull())
2277                         iconSize = QSize(controlHeight, controlHeight);
2278                     int hPad = (controlHeight - iconSize.height())/2;
2279                     int vPad = (controlHeight - iconSize.width())/2;
2280                     rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
2281                     rect.translate(0, 3);
2282                     rect = visualRect(option->direction, option->rect, rect);
2283                 }
2284                 break;
2285             default:
2286                 break;
2287             }
2288         }
2289         break;
2290     default:
2291         break;
2292     }
2293     return rect;
2294 }
2295
2296 /*!
2297  \internal
2298  */
2299 bool QWindowsVistaStyle::event(QEvent *e)
2300 {
2301     Q_D(QWindowsVistaStyle);
2302     switch (e->type()) {
2303     case QEvent::Timer:
2304         {
2305             QTimerEvent *timerEvent = (QTimerEvent *)e;
2306             if (d->animationTimer.timerId() == timerEvent->timerId()) {
2307                 d->timerEvent();
2308                 e->accept();
2309                 return true;
2310             }
2311         }
2312         break;
2313     default:
2314         break;
2315     }
2316     return QWindowsXPStyle::event(e);
2317 }
2318
2319 /*!
2320  \internal
2321  */
2322 QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
2323                                                           const QPoint &pos, const QWidget *widget) const
2324 {
2325     if (!QWindowsVistaStylePrivate::useVista()) {
2326         return QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
2327     }
2328     return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
2329 }
2330
2331 /*!
2332  \internal
2333  */
2334 int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
2335 {
2336     if (!QWindowsVistaStylePrivate::useVista()) {
2337         return QWindowsStyle::pixelMetric(metric, option, widget);
2338     }
2339     switch (metric) {
2340
2341     case PM_DockWidgetTitleBarButtonMargin:
2342         return int(QStyleHelper::dpiScaled(5.));
2343     case PM_ScrollBarSliderMin:
2344         return int(QStyleHelper::dpiScaled(18.));
2345     case PM_MenuHMargin:
2346     case PM_MenuVMargin:
2347         return 0;
2348     case PM_MenuPanelWidth:
2349         return 3;
2350     default:
2351         break;
2352     }
2353     return QWindowsXPStyle::pixelMetric(metric, option, widget);
2354 }
2355
2356 /*!
2357  \internal
2358  */
2359 QPalette QWindowsVistaStyle::standardPalette() const
2360 {
2361     return QWindowsXPStyle::standardPalette();
2362 }
2363
2364 /*!
2365  \internal
2366  */
2367 void QWindowsVistaStyle::polish(QApplication *app)
2368 {
2369     QWindowsXPStyle::polish(app);
2370 }
2371
2372 /*!
2373  \internal
2374  */
2375 void QWindowsVistaStyle::polish(QWidget *widget)
2376 {
2377     QWindowsXPStyle::polish(widget);
2378 #ifndef QT_NO_LINEEDIT
2379     if (qobject_cast<QLineEdit*>(widget))
2380         widget->setAttribute(Qt::WA_Hover);
2381     else
2382 #endif // QT_NO_LINEEDIT
2383     if (qobject_cast<QGroupBox*>(widget))
2384         widget->setAttribute(Qt::WA_Hover);
2385     else if (qobject_cast<QCommandLinkButton*>(widget)) {
2386         QFont buttonFont = widget->font();
2387         buttonFont.setFamily(QLatin1String("Segoe UI"));
2388         widget->setFont(buttonFont);
2389     }
2390     else if (widget->inherits("QTipLabel")){
2391         //note that since tooltips are not reused
2392         //we do not have to care about unpolishing
2393         widget->setContentsMargins(3, 0, 4, 0);
2394         COLORREF bgRef;
2395         HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
2396         if (theme) {
2397             if (pGetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef) == S_OK) {
2398                 QColor textColor = QColor::fromRgb(bgRef);
2399                 QPalette pal;
2400                 pal.setColor(QPalette::All, QPalette::ToolTipText, textColor);
2401                 widget->setPalette(pal);
2402             }
2403         }
2404     } else if (qobject_cast<QMessageBox *> (widget)) {
2405         widget->setAttribute(Qt::WA_StyledBackground);
2406         QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
2407         if (buttonBox)
2408             buttonBox->setContentsMargins(0, 9, 0, 0);
2409     }
2410 #ifndef QT_NO_INPUTDIALOG
2411     else if (qobject_cast<QInputDialog *> (widget)) {
2412         widget->setAttribute(Qt::WA_StyledBackground);
2413         QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
2414         if (buttonBox)
2415             buttonBox->setContentsMargins(0, 9, 0, 0);
2416     }
2417 #endif // QT_NO_INPUTDIALOG
2418     else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
2419         tree->viewport()->setAttribute(Qt::WA_Hover);
2420     }
2421     else if (QListView *list = qobject_cast<QListView *> (widget)) {
2422         list->viewport()->setAttribute(Qt::WA_Hover);
2423     }
2424 }
2425
2426 /*!
2427  \internal
2428  */
2429 void QWindowsVistaStyle::unpolish(QWidget *widget)
2430 {
2431     QWindowsXPStyle::unpolish(widget);
2432
2433     QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
2434     d->stopAnimation(widget);
2435
2436 #ifndef QT_NO_LINEEDIT
2437     if (qobject_cast<QLineEdit*>(widget))
2438         widget->setAttribute(Qt::WA_Hover, false);
2439     else
2440 #endif // QT_NO_LINEEDIT
2441     if (qobject_cast<QGroupBox*>(widget))
2442         widget->setAttribute(Qt::WA_Hover, false);
2443     else if (qobject_cast<QMessageBox *> (widget)) {
2444         widget->setAttribute(Qt::WA_StyledBackground, false);
2445         QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
2446         if (buttonBox)
2447             buttonBox->setContentsMargins(0, 0, 0, 0);
2448     }
2449 #ifndef QT_NO_INPUTDIALOG
2450     else if (qobject_cast<QInputDialog *> (widget)) {
2451         widget->setAttribute(Qt::WA_StyledBackground, false);
2452         QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
2453         if (buttonBox)
2454             buttonBox->setContentsMargins(0, 0, 0, 0);
2455     }
2456 #endif // QT_NO_INPUTDIALOG
2457     else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
2458         tree->viewport()->setAttribute(Qt::WA_Hover, false);
2459     } else if (qobject_cast<QCommandLinkButton*>(widget)) {
2460         QFont font = QApplication::font("QCommandLinkButton");
2461         QFont widgetFont = widget->font();
2462         widgetFont.setFamily(font.family()); //Only family set by polish
2463         widget->setFont(widgetFont);
2464     }
2465 }
2466
2467
2468 /*!
2469  \internal
2470  */
2471 void QWindowsVistaStyle::unpolish(QApplication *app)
2472 {
2473     QWindowsXPStyle::unpolish(app);
2474 }
2475
2476 /*!
2477  \internal
2478  */
2479 void QWindowsVistaStyle::polish(QPalette &pal)
2480 {
2481     QWindowsStyle::polish(pal);
2482     pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104));
2483 }
2484
2485 /*!
2486  \internal
2487  */
2488 QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
2489                                       const QWidget *widget) const
2490 {
2491     if (!QWindowsVistaStylePrivate::useVista()) {
2492         return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
2493     }
2494     return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget);
2495 }
2496
2497 QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() :
2498     QWindowsXPStylePrivate(), m_treeViewHelper(0)
2499 {
2500     resolveSymbols();
2501 }
2502
2503 QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate()
2504 {
2505     qDeleteAll(animations);
2506     delete m_treeViewHelper;
2507 }
2508
2509 void QWindowsVistaStylePrivate::timerEvent()
2510 {
2511     for (int i = animations.size() - 1 ; i >= 0 ; --i) {
2512
2513         if (animations[i]->widget())
2514             animations[i]->widget()->update();
2515
2516         if (!animations[i]->widget() ||
2517             !animations[i]->widget()->isVisible() ||
2518             animations[i]->widget()->window()->isMinimized() ||
2519             !animations[i]->running() ||
2520             !QWindowsVistaStylePrivate::useVista())
2521         {
2522             QWindowsVistaAnimation *a = animations.takeAt(i);
2523             delete a;
2524         }
2525     }
2526     if (animations.size() == 0 && animationTimer.isActive()) {
2527         animationTimer.stop();
2528     }
2529 }
2530
2531 void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w)
2532 {
2533     for (int i = animations.size() - 1 ; i >= 0 ; --i) {
2534         if (animations[i]->widget() == w) {
2535             QWindowsVistaAnimation *a = animations.takeAt(i);
2536             delete a;
2537             break;
2538         }
2539     }
2540 }
2541
2542 void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t)
2543 {
2544     Q_Q(QWindowsVistaStyle);
2545     stopAnimation(t->widget());
2546     animations.append(t);
2547     if (animations.size() > 0 && !animationTimer.isActive()) {
2548         animationTimer.start(45, q);
2549     }
2550 }
2551
2552 bool QWindowsVistaStylePrivate::transitionsEnabled() const
2553 {
2554     BOOL animEnabled = false;
2555     if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0))
2556     {
2557         if (animEnabled)
2558             return true;
2559     }
2560     return false;
2561 }
2562
2563
2564 QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
2565 {
2566     if (!widget)
2567         return 0;
2568     foreach (QWindowsVistaAnimation *a, animations) {
2569         if (a->widget() == widget)
2570             return a;
2571     }
2572     return 0;
2573 }
2574
2575
2576 /*! \internal
2577     Returns true if all the necessary theme engine symbols were
2578     resolved.
2579 */
2580 bool QWindowsVistaStylePrivate::resolveSymbols()
2581 {
2582     static bool tried = false;
2583     if (!tried) {
2584         QSystemLibrary themeLib(QLatin1String("uxtheme"));
2585         pSetWindowTheme         = (PtrSetWindowTheme        )themeLib.resolve("SetWindowTheme");
2586         pIsThemePartDefined     = (PtrIsThemePartDefined    )themeLib.resolve("IsThemePartDefined");
2587         pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
2588         pOpenThemeData          = (PtrOpenThemeData         )themeLib.resolve("OpenThemeData");
2589         pCloseThemeData         = (PtrCloseThemeData        )themeLib.resolve("CloseThemeData");
2590         pDrawThemeBackground    = (PtrDrawThemeBackground   )themeLib.resolve("DrawThemeBackground");
2591         pDrawThemeBackgroundEx  = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
2592         pGetCurrentThemeName    = (PtrGetCurrentThemeName   )themeLib.resolve("GetCurrentThemeName");
2593         pGetThemeBool           = (PtrGetThemeBool          )themeLib.resolve("GetThemeBool");
2594         pGetThemeColor          = (PtrGetThemeColor         )themeLib.resolve("GetThemeColor");
2595         pGetThemeEnumValue      = (PtrGetThemeEnumValue     )themeLib.resolve("GetThemeEnumValue");
2596         pGetThemeFilename       = (PtrGetThemeFilename      )themeLib.resolve("GetThemeFilename");
2597         pGetThemeFont           = (PtrGetThemeFont          )themeLib.resolve("GetThemeFont");
2598         pGetThemeInt            = (PtrGetThemeInt           )themeLib.resolve("GetThemeInt");
2599         pGetThemeIntList        = (PtrGetThemeIntList       )themeLib.resolve("GetThemeIntList");
2600         pGetThemeMargins        = (PtrGetThemeMargins       )themeLib.resolve("GetThemeMargins");
2601         pGetThemeMetric         = (PtrGetThemeMetric        )themeLib.resolve("GetThemeMetric");
2602         pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
2603         pGetThemePosition       = (PtrGetThemePosition      )themeLib.resolve("GetThemePosition");
2604         pGetThemeRect           = (PtrGetThemeRect          )themeLib.resolve("GetThemeRect");
2605         pGetThemeString         = (PtrGetThemeString        )themeLib.resolve("GetThemeString");
2606         pGetThemeTransitionDuration = (PtrGetThemeTransitionDuration)themeLib.resolve("GetThemeTransitionDuration");
2607         pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
2608         tried = true;
2609     }
2610     return pGetThemeTransitionDuration != 0;
2611 }
2612
2613 /*
2614  * We need to set the windows explorer theme explicitly on a native widget
2615  * in order to get Vista-style item view themes
2616  */
2617 QWidget *QWindowsVistaStylePrivate::treeViewHelper()
2618 {
2619     if (!m_treeViewHelper) {
2620         m_treeViewHelper = new QWidget(0);
2621         pSetWindowTheme(m_treeViewHelper->winId(), L"explorer", NULL);
2622     }
2623     return m_treeViewHelper;
2624 }
2625
2626
2627 /*!
2628 \internal
2629 */
2630 QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon,
2631                                                   const QStyleOption *option,
2632                                                   const QWidget *widget) const
2633 {
2634     if (!QWindowsVistaStylePrivate::useVista()) {
2635         return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
2636     }
2637
2638     QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func());
2639     switch(standardIcon) {
2640     case SP_CommandLink:
2641         {
2642             XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
2643             if (theme.isValid()) {
2644                 SIZE size;
2645                 pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
2646                 QIcon linkGlyph;
2647                 QPixmap pm = QPixmap(size.cx, size.cy);
2648                 pm.fill(Qt::transparent);
2649                 QPainter p(&pm);
2650                 theme.painter = &p;
2651                 theme.rect = QRect(0, 0, size.cx, size.cy);
2652                 d->drawBackground(theme);
2653                 linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off);    // Normal
2654                 pm.fill(Qt::transparent);
2655
2656                 theme.stateId = CMDLGS_PRESSED;
2657                 d->drawBackground(theme);
2658                 linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On);     // Pressed
2659                 pm.fill(Qt::transparent);
2660
2661                 theme.stateId = CMDLGS_HOT;
2662                 d->drawBackground(theme);
2663                 linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off);    // Hover
2664                 pm.fill(Qt::transparent);
2665
2666                 theme.stateId = CMDLGS_DISABLED;
2667                 d->drawBackground(theme);
2668                 linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off);  // Disabled
2669                 return linkGlyph;
2670             }
2671         }
2672         break;
2673     default:
2674         break;
2675     }
2676     return QWindowsXPStyle::standardIconImplementation(standardIcon, option, widget);
2677 }
2678
2679 QT_END_NAMESPACE
2680
2681 #endif //QT_NO_WINDOWSVISTA