src/gui/styles/qwindowsvistastyle.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/styles/qwindowsvistastyle.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,2695 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsvistastyle.h"
+#include "qwindowsvistastyle_p.h"
+#include <private/qstylehelper_p.h>
+
+#if !defined(QT_NO_STYLE_WINDOWSVISTA) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+static const int windowsItemFrame        =  2; // menu item frame width
+static const int windowsItemHMargin      =  3; // menu item hor text margin
+static const int windowsItemVMargin      =  4; // menu item ver text margin
+static const int windowsArrowHMargin     =  6; // arrow horizontal margin
+static const int windowsRightBorder      = 15; // right border on windows
+
+#ifndef TMT_CONTENTMARGINS
+#  define TMT_CONTENTMARGINS 3602
+#endif
+#ifndef TMT_SIZINGMARGINS
+#  define TMT_SIZINGMARGINS 3601
+#endif
+#ifndef LISS_NORMAL
+#  define LISS_NORMAL 1
+#  define LISS_HOT 2
+#  define LISS_SELECTED 3
+#  define LISS_DISABLED 4
+#  define LISS_SELECTEDNOTFOCUS 5
+#  define LISS_HOTSELECTED 6
+#endif
+#ifndef BP_COMMANDLINK
+#  define BP_COMMANDLINK 6
+#  define BP_COMMANDLINKGLYPH 7
+#  define CMDLGS_NORMAL 1
+#  define CMDLGS_HOT 2
+#  define CMDLGS_PRESSED 3
+#  define CMDLGS_DISABLED 4
+#endif
+
+// Runtime resolved theme engine function calls
+
+
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
+typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
+typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
+typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
+typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
+typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeTransitionDuration)(HTHEME hTheme, int iPartId, int iStateFromId, int iStateToId, int iPropId, int *pDuration);
+typedef HRESULT (WINAPI *PtrIsThemePartDefined)(HTHEME hTheme, int iPartId, int iStateId);
+typedef HRESULT (WINAPI *PtrSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
+
+static PtrIsThemePartDefined pIsThemePartDefined = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+static PtrGetThemeBool pGetThemeBool = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
+static PtrGetThemeFilename pGetThemeFilename = 0;
+static PtrGetThemeFont pGetThemeFont = 0;
+static PtrGetThemeInt pGetThemeInt = 0;
+static PtrGetThemeIntList pGetThemeIntList = 0;
+static PtrGetThemeMargins pGetThemeMargins = 0;
+static PtrGetThemeMetric pGetThemeMetric = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemePosition pGetThemePosition = 0;
+static PtrGetThemeRect pGetThemeRect = 0;
+static PtrGetThemeString pGetThemeString = 0;
+static PtrGetThemeTransitionDuration pGetThemeTransitionDuration= 0;
+static PtrSetWindowTheme pSetWindowTheme = 0;
+static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
+
+/* \internal
+    Checks if we should use Vista style , or if we should
+    fall back to Windows style.
+*/
+bool QWindowsVistaStylePrivate::useVista()
+{
+    return (QWindowsVistaStylePrivate::useXP() &&
+            (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA &&
+             QSysInfo::WindowsVersion < QSysInfo::WV_NT_based));
+}
+
+/*!
+  \class QWindowsVistaStyle
+  \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
+  \since 4.3
+  \ingroup appearance
+
+  \warning This style is only available on the Windows Vista platform
+  because it makes use of Windows Vista's style engine.
+
+  \sa QMacStyle, QWindowsXPStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
+*/
+
+/*!
+  Constructs a QWindowsVistaStyle object.
+*/
+QWindowsVistaStyle::QWindowsVistaStyle()
+    : QWindowsXPStyle(*new QWindowsVistaStylePrivate)
+{
+}
+
+//convert Qt state flags to uxtheme button states
+int buttonStateId(int flags, int partId)
+{
+    int stateId = 0;
+    if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) {
+        if (!(flags & QStyle::State_Enabled))
+            stateId = RBS_UNCHECKEDDISABLED;
+        else if (flags & QStyle::State_Sunken)
+            stateId = RBS_UNCHECKEDPRESSED;
+        else if (flags & QStyle::State_MouseOver)
+            stateId = RBS_UNCHECKEDHOT;
+        else
+            stateId = RBS_UNCHECKEDNORMAL;
+
+        if (flags & QStyle::State_On)
+            stateId += RBS_CHECKEDNORMAL-1;
+
+    } else if (partId == BP_PUSHBUTTON) {
+        if (!(flags & QStyle::State_Enabled))
+            stateId = PBS_DISABLED;
+        else if (flags & (QStyle::State_Sunken | QStyle::State_On))
+            stateId = PBS_PRESSED;
+        else if (flags & QStyle::State_MouseOver)
+            stateId = PBS_HOT;
+        else
+            stateId = PBS_NORMAL;
+    } else {
+        Q_ASSERT(1);
+    }
+    return stateId;
+}
+
+void Animation::paint(QPainter *painter, const QStyleOption *option)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(painter);
+}
+
+/*! \internal
+
+  Helperfunction to paint the current transition state between two
+  animation frames.
+
+  The result is a blended image consisting of ((alpha)*_primaryImage)
+  + ((1-alpha)*_secondaryImage)
+
+*/
+void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
+    if (_secondaryImage.isNull() || _primaryImage.isNull())
+        return;
+
+    if (_tempImage.isNull())
+        _tempImage = _secondaryImage;
+
+    const int a = qRound(alpha*256);
+    const int ia = 256 - a;
+    const int sw = _primaryImage.width();
+    const int sh = _primaryImage.height();
+    const int bpl = _primaryImage.bytesPerLine();
+    switch(_primaryImage.depth()) {
+    case 32:
+        {
+            uchar *mixed_data = _tempImage.bits();
+            const uchar *back_data = _primaryImage.bits();
+            const uchar *front_data = _secondaryImage.bits();
+            for (int sy = 0; sy < sh; sy++) {
+                quint32* mixed = (quint32*)mixed_data;
+                const quint32* back = (const quint32*)back_data;
+                const quint32* front = (const quint32*)front_data;
+                for (int sx = 0; sx < sw; sx++) {
+                    quint32 bp = back[sx];
+                    quint32 fp = front[sx];
+                    mixed[sx] =  qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
+                                        (qGreen(bp)*ia + qGreen(fp)*a)>>8,
+                                        (qBlue(bp)*ia + qBlue(fp)*a)>>8,
+                                        (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
+                }
+                mixed_data += bpl;
+                back_data += bpl;
+                front_data += bpl;
+            }
+        }
+    default:
+        break;
+    }
+    painter->drawImage(rect, _tempImage);
+}
+
+/*! \internal
+  Paints a transition state. The result will be a mix between the
+  initial and final state of the transition, depending on the time
+  difference between _startTime and current time.
+*/
+void Transition::paint(QPainter *painter, const QStyleOption *option)
+{
+    float alpha = 1.0;
+    if (_duration > 0) {
+        QTime current = QTime::currentTime();
+
+        if (_startTime > current)
+            _startTime = current;
+
+        int timeDiff = _startTime.msecsTo(current);
+        alpha = timeDiff/(float)_duration;
+        if (timeDiff > _duration) {
+            _running = false;
+            alpha = 1.0;
+        }
+    }
+    else {
+        _running = false;
+    }
+    drawBlendedImage(painter, option->rect, alpha);
+}
+
+/*! \internal
+  Paints a pulse. The result will be a mix between the primary and
+  secondary pulse images depending on the time difference between
+  _startTime and current time.
+*/
+void Pulse::paint(QPainter *painter, const QStyleOption *option)
+{
+    float alpha = 1.0;
+    if (_duration > 0) {
+        QTime current = QTime::currentTime();
+
+        if (_startTime > current)
+            _startTime = current;
+
+        int timeDiff = _startTime.msecsTo(current) % _duration*2;
+        if (timeDiff > _duration)
+            timeDiff = _duration*2 - timeDiff;
+        alpha = timeDiff/(float)_duration;
+    } else {
+        _running = false;
+    }
+    drawBlendedImage(painter, option->rect, alpha);
+}
+
+
+/*!
+ \internal
+ 
+  Animations are used for some state transitions on specific widgets.
+ 
+  Only one running animation can exist for a widget at any specific
+  time.  Animations can be added through
+  QWindowsVistaStylePrivate::startAnimation(Animation *) and any
+  existing animation on a widget can be retrieved with
+  QWindowsVistaStylePrivate::widgetAnimation(Widget *).
+ 
+  Once an animation has been started,
+  QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will
+  continuously call update() on the widget until it is stopped,
+  meaning that drawPrimitive will be called many times until the
+  transition has completed. During this time, the result will be
+  retrieved by the Animation::paint(...) function and not by the style
+  itself.
+ 
+  To determine if a transition should occur, the style needs to know
+  the previous state of the widget as well as the current one. This is
+  solved by updating dynamic properties on the widget every time the
+  function is called.
+ 
+  Transitions interrupting existing transitions should always be
+  smooth, so whenever a hover-transition is started on a pulsating
+  button, it uses the current frame of the pulse-animation as the
+  starting image for the hover transition.
+ 
+ */
+void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+                                       QPainter *painter, const QWidget *widget) const
+{
+    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+
+    int state = option->state;
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        QWindowsStyle::drawPrimitive(element, option, painter, widget);
+        return;
+    }
+
+    QRect oldRect;
+    QRect newRect;
+
+    if (widget && d->transitionsEnabled())
+    {
+        /* all widgets that supports state transitions : */
+        if (
+#ifndef QT_NO_LINEEDIT
+            (qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) ||
+#endif // QT_NO_LINEEDIT
+            (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) ||
+            (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) ||
+            (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) ||
+            (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel)
+        )
+        {
+            // Retrieve and update the dynamic properties tracking
+            // the previous state of the widget:
+            QWidget *w = const_cast<QWidget *> (widget);
+            int oldState = w->property("_q_stylestate").toInt();
+            oldRect = w->property("_q_stylerect").toRect();
+            newRect = w->rect();
+            w->setProperty("_q_stylestate", (int)option->state);
+            w->setProperty("_q_stylerect", w->rect());
+
+            bool doTransition = oldState && 
+                                ((state & State_Sunken)     != (oldState & State_Sunken) ||
+                                 (state & State_On)         != (oldState & State_On)     ||
+                                 (state & State_MouseOver)  != (oldState & State_MouseOver));
+
+            if (oldRect != newRect ||
+                (state & State_Enabled) != (oldState & State_Enabled) ||
+                (state & State_Active)  != (oldState & State_Active))
+                    d->stopAnimation(widget);
+
+#ifndef QT_NO_LINEEDIT
+            if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget))
+                if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits
+                    doTransition = false;
+#endif // QT_NO_LINEEDIT
+
+            if (doTransition) {
+
+                // We create separate images for the initial and final transition states and store them in the
+                // Transition object.
+                QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                QStyleOption opt = *option;
+
+                opt.rect.setRect(0, 0, option->rect.width(), option->rect.height());
+                opt.state = (QStyle::State)oldState;
+                startImage.fill(0);
+                QPainter startPainter(&startImage);
+
+                Animation *anim = d->widgetAnimation(widget);
+                Transition *t = new Transition;
+                t->setWidget(w);
+
+                // If we have a running animation on the widget already, we will use that to paint the initial
+                // state of the new transition, this ensures a smooth transition from a current animation such as a
+                // pulsating default button into the intended target state.
+
+                if (!anim)
+                    proxy()->drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0
+                else                                               // this ensures that we do not recurse in the animation logic above
+                    anim->paint(&startPainter, &opt);
+
+                d->startAnimation(t);
+                t->setStartImage(startImage);
+
+                // The end state of the transition is simply the result we would have painted
+                // if the style was not animated.
+
+                QPainter endPainter(&endImage);
+                endImage.fill(0);
+                QStyleOption opt2 = opt;
+                opt2.state = option->state;
+                proxy()->drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0
+                                                              // this ensures that we do not recurse in the animation logic above
+                t->setEndImage(endImage);
+
+                HTHEME theme;
+                int partId;
+                int duration;
+                int fromState = 0;
+                int toState = 0;
+
+                //translate state flags to UXTHEME states :
+                if (element == PE_FrameLineEdit) {
+                    theme = pOpenThemeData(0, L"Edit");
+                    partId = EP_EDITBORDER_NOSCROLL;
+
+                    if (oldState & State_MouseOver)
+                        fromState = ETS_HOT;
+                    else if (oldState & State_HasFocus)
+                        fromState = ETS_FOCUSED;
+                    else
+                        fromState = ETS_NORMAL;
+
+                    if (state & State_MouseOver)
+                        toState = ETS_HOT;
+                    else if (state & State_HasFocus)
+                        toState = ETS_FOCUSED;
+                    else
+                        toState = ETS_NORMAL;
+
+                } else {
+                    theme = pOpenThemeData(0, L"Button");
+                    if (element == PE_IndicatorRadioButton)
+                        partId = BP_RADIOBUTTON;
+                    else if (element == PE_IndicatorCheckBox)
+                        partId = BP_CHECKBOX;
+                    else
+                        partId = BP_PUSHBUTTON;
+
+                    fromState = buttonStateId(oldState, partId);
+                    toState = buttonStateId(option->state, partId);
+                }
+
+                // Retrieve the transition time between the states from the system.
+                if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
+                    TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+                {
+                    t->setDuration(duration);
+                }
+                t->setStartTime(QTime::currentTime());
+            }
+        }
+    } // End of animation part
+
+
+    QRect rect = option->rect;
+
+    switch (element) {
+    case PE_IndicatorHeaderArrow:
+        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+            int stateId = HSAS_SORTEDDOWN;
+            if (header->sortIndicator & QStyleOptionHeader::SortDown)
+                stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours
+            XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect);
+            d->drawBackground(theme);
+        }
+        break;
+
+    case PE_IndicatorBranch:
+        {
+            XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW"));
+            static int decoration_size = 0;
+            if (theme.isValid() && !decoration_size) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size);
+                decoration_size = qMax(size.cx, size.cy);
+            }
+            int mid_h = option->rect.x() + option->rect.width() / 2;
+            int mid_v = option->rect.y() + option->rect.height() / 2;
+            int bef_h = mid_h;
+            int bef_v = mid_v;
+            int aft_h = mid_h;
+            int aft_v = mid_v;
+            if (option->state & State_Children) {
+                int delta = decoration_size / 2;
+                theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size);
+                theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH;
+                theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
+                if (option->direction == Qt::RightToLeft)
+                    theme.mirrorHorizontally = true;
+                d->drawBackground(theme);
+                bef_h -= delta + 2;
+                bef_v -= delta + 2;
+                aft_h += delta - 2;
+                aft_v += delta - 2;
+            }
+#if 0
+            QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+            if (option->state & State_Item) {
+                if (option->direction == Qt::RightToLeft)
+                    painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+                else
+                    painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+            }
+            if (option->state & State_Sibling && option->rect.bottom() > aft_v)
+                painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+            if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y()))
+                painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+#endif
+        }
+        break;
+
+    case PE_PanelButtonBevel:
+    case PE_IndicatorCheckBox:
+    case PE_IndicatorRadioButton:
+        {
+            if (Animation *a = d->widgetAnimation(widget)) {
+                a->paint(painter, option);
+            } else {
+                QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+            }
+        }
+        break;
+
+    case PE_FrameMenu:
+        {
+            int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE;
+            XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect);
+            d->drawBackground(theme);
+        }
+        break;
+    case PE_Frame:
+#ifndef QT_NO_TEXTEDIT
+        if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) {
+            painter->save();
+            int stateId = ETS_NORMAL;
+            if (!(state & State_Enabled))
+                stateId = ETS_DISABLED;
+            else if (edit->isReadOnly())
+                stateId = ETS_READONLY;
+            else if (state & State_HasFocus)
+                stateId = ETS_SELECTED;
+            XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect);
+            uint resolve_mask = option->palette.resolve();
+            if (resolve_mask & (1 << QPalette::Base)) {
+                // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
+                int borderSize = 1;
+                pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
+                QRegion clipRegion = option->rect;
+                QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+                clipRegion ^= content;
+                painter->setClipRegion(clipRegion);
+            }
+            d->drawBackground(theme);
+            painter->restore();
+        } else
+#endif // QT_NO_TEXTEDIT
+            QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+        break;
+
+    case PE_PanelLineEdit:
+        if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+            QBrush bg;
+            bool usePalette = false;
+            bool isEnabled = option->state & State_Enabled;
+            uint resolve_mask = panel->palette.resolve();
+            if (widget) {
+            //Since spin box and combo box includes a line edit we need to resolve the palette on the parent instead
+#ifndef QT_NO_SPINBOX
+                if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
+                    resolve_mask = spinbox->palette().resolve();
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+                if (QComboBox *combobox = qobject_cast<QComboBox*>(widget->parentWidget()))
+                    resolve_mask = combobox->palette().resolve();
+#endif // QT_NO_COMBOBOX
+            }
+            if (resolve_mask & (1 << QPalette::Base)) {
+                // Base color is set for this widget, so use it
+                bg = panel->palette.brush(QPalette::Base);
+                usePalette = true;
+            }
+            if (usePalette) {
+                painter->fillRect(panel->rect, bg);
+            } else {
+                int partId = EP_BACKGROUND;
+                int stateId = EBS_NORMAL;
+                if (!isEnabled)
+                    stateId = EBS_DISABLED;
+                else if (state & State_ReadOnly)
+                    stateId = EBS_READONLY;
+                else if (state & State_MouseOver)
+                    stateId = EBS_HOT;
+
+                XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect);
+                if (!theme.isValid()) {
+                    QWindowsStyle::drawPrimitive(element, option, painter, widget);
+                    return;
+                }
+                int bgType;
+                pGetThemeEnumValue( theme.handle(),
+                                    partId,
+                                    stateId,
+                                    TMT_BGTYPE,
+                                    &bgType);
+                if( bgType == BT_IMAGEFILE ) {
+                    d->drawBackground(theme);
+                } else {
+                    QBrush fillColor = option->palette.brush(QPalette::Base);
+                    if (!isEnabled) {
+                        PROPERTYORIGIN origin = PO_NOTFOUND;
+                        pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
+                        // Use only if the fill property comes from our part
+                        if ((origin == PO_PART || origin == PO_STATE)) {
+                            COLORREF bgRef;
+                            pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
+                            fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
+                        }
+                    }
+                    painter->fillRect(option->rect, fillColor);
+                }
+            }
+            if (panel->lineWidth > 0)
+                proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
+            return;
+        }
+        break;
+
+    case PE_FrameLineEdit:
+        if (Animation *anim = d->widgetAnimation(widget)) {
+            anim->paint(painter, option);
+        } else {
+            QPainter *p = painter;
+            QWidget *parentWidget = 0;
+            if (widget) {
+                parentWidget = widget->parentWidget();
+                if (parentWidget)
+                    parentWidget = parentWidget->parentWidget();
+            }
+            if (widget && widget->inherits("QLineEdit")
+                && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+                // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
+                QPen oldPen = p->pen();
+                // Inner white border
+                p->setPen(QPen(option->palette.base().color(), 1));
+                p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+                // Outer dark border
+                p->setPen(QPen(option->palette.shadow().color(), 1));
+                p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+                p->setPen(oldPen);
+                return;
+            } else {
+                int stateId = ETS_NORMAL;
+                if (!(state & State_Enabled))
+                    stateId = ETS_DISABLED;
+                else if (state & State_ReadOnly)
+                    stateId = ETS_READONLY;
+                else if (state & State_MouseOver)
+                    stateId = ETS_HOT;
+                else if (state & State_HasFocus)
+                    stateId = ETS_SELECTED;
+                XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect);
+                painter->save();
+                QRegion clipRegion = option->rect;
+                clipRegion -= option->rect.adjusted(2, 2, -2, -2);
+                painter->setClipRegion(clipRegion);
+                d->drawBackground(theme);
+                painter->restore();
+            }
+        }
+        break;
+
+    case PE_IndicatorToolBarHandle:
+        {
+            XPThemeData theme;
+            QRect rect;
+            if (option->state & State_Horizontal) {
+                theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+                rect = option->rect.adjusted(0, 1, 0, -2);
+                rect.setWidth(4);
+            } else {
+                theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+                rect = option->rect.adjusted(1, 0, -1, 0);
+                rect.setHeight(4);
+            }
+            theme.rect = rect;
+            d->drawBackground(theme);
+        }
+        break;
+
+    case PE_IndicatorToolBarSeparator:
+        {
+            QPen pen = painter->pen();
+            int margin = 3;
+            painter->setPen(option->palette.background().color().darker(114));
+            if (option->state & State_Horizontal) {
+                int x1 = option->rect.center().x();
+                painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin));
+            } else {
+                int y1 = option->rect.center().y();
+                painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1));
+            }
+            painter->setPen(pen);
+        }
+        break;
+
+    case PE_PanelTipLabel: {
+        XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+        d->drawBackground(theme);
+        break;
+    }
+
+    case PE_PanelItemViewItem:
+        {
+            const QStyleOptionViewItemV4 *vopt;
+            const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+            bool newStyle = true;
+
+            if (qobject_cast<const QTableView*>(widget))
+                newStyle = false;
+
+            if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
+                bool selected = vopt->state & QStyle::State_Selected;
+                bool hover = vopt->state & QStyle::State_MouseOver;
+                bool active = vopt->state & QStyle::State_Active;
+
+                if (vopt->features & QStyleOptionViewItemV2::Alternate)
+                    painter->fillRect(vopt->rect, vopt->palette.alternateBase());
+
+                QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
+                                          ? QPalette::Normal : QPalette::Disabled;
+                if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+                    cg = QPalette::Inactive;
+
+                QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+                QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0);
+                itemRect.setTop(vopt->rect.top());
+                itemRect.setBottom(vopt->rect.bottom());
+
+                QSize sectionSize = itemRect.size();
+                if (vopt->showDecorationSelected)
+                    sectionSize = vopt->rect.size();
+
+                if (view->selectionBehavior() == QAbstractItemView::SelectRows)
+                    sectionSize.setWidth(vopt->rect.width());
+                if (view->selectionMode() == QAbstractItemView::NoSelection)
+                    hover = false;
+                QPixmap pixmap;
+
+                if (vopt->backgroundBrush.style() != Qt::NoBrush) {
+                    QPointF oldBO = painter->brushOrigin();
+                    painter->setBrushOrigin(vopt->rect.topLeft());
+                    painter->fillRect(vopt->rect, vopt->backgroundBrush);
+                }
+
+                if (hover || selected) {
+                    QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width())
+                                                        .arg(sectionSize.height()).arg(selected).arg(active).arg(hover);
+                    if (!QPixmapCache::find(key, pixmap)) {
+                        pixmap = QPixmap(sectionSize);
+                        pixmap.fill(Qt::transparent);
+
+                        int state;
+                        if (selected && hover)
+                            state = LISS_HOTSELECTED;
+                        else if (selected && !active)
+                            state = LISS_SELECTEDNOTFOCUS;
+                        else if (selected)
+                            state = LISS_SELECTED;
+                        else
+                            state = LISS_HOT;
+
+                        QPainter pixmapPainter(&pixmap);
+                        XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"),
+                            LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
+                        if (theme.isValid()) {
+                            d->drawBackground(theme);
+                        } else {
+                            QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
+                            break;;
+                        }
+                        QPixmapCache::insert(key, pixmap);
+                    }
+
+                    if (vopt->showDecorationSelected) {
+                        const int frame = 2; //Assumes a 2 pixel pixmap border
+                        QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height());
+                        QRect pixmapRect = vopt->rect;
+                        bool reverse = vopt->direction == Qt::RightToLeft;
+                        bool leftSection = vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning;
+                        bool rightSection = vopt->viewItemPosition == QStyleOptionViewItemV4::End;
+                        if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne
+                            || vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid)
+                            painter->drawPixmap(pixmapRect.topLeft(), pixmap);
+                        else if (reverse ? rightSection : leftSection){
+                            painter->drawPixmap(QRect(pixmapRect.topLeft(), 
+                                                QSize(frame, pixmapRect.height())), pixmap, 
+                                                QRect(QPoint(0, 0), QSize(frame, pixmapRect.height())));
+                            painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0), 
+                                                pixmap, srcRect.adjusted(frame, 0, -frame, 0));
+                        } else if (reverse ? leftSection : rightSection) {
+                            painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0), 
+                                                QSize(frame, pixmapRect.height())), pixmap, 
+                                                QRect(QPoint(pixmapRect.width() - frame, 0), 
+                                                QSize(frame, pixmapRect.height())));
+                            painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0), 
+                                                pixmap, srcRect.adjusted(frame, 0, -frame, 0));
+                        } else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle)
+                            painter->drawPixmap(pixmapRect, pixmap,
+                                                srcRect.adjusted(frame, 0, -frame, 0));
+                    } else {
+                        if (vopt->text.isEmpty() && vopt->icon.isNull())
+                            break;
+                        painter->drawPixmap(itemRect.topLeft(), pixmap);
+                    }
+                }
+            } else {
+                QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+            }
+            break;
+        }
+    case PE_Widget:
+        {
+            const QDialogButtonBox *buttonBox = 0;
+
+            if (qobject_cast<const QMessageBox *> (widget))
+                buttonBox = qFindChild<const QDialogButtonBox *>(widget,QLatin1String("qt_msgbox_buttonbox"));
+#ifndef QT_NO_INPUTDIALOG
+            else if (qobject_cast<const QInputDialog *> (widget))
+                buttonBox = qFindChild<const QDialogButtonBox *>(widget,QLatin1String("qt_inputdlg_buttonbox"));
+#endif // QT_NO_INPUTDIALOG
+
+            if (buttonBox) {
+                //draw white panel part
+                XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect);
+                QRect toprect = option->rect;
+                toprect.setBottom(buttonBox->geometry().top());
+                theme.rect = toprect;
+                d->drawBackground(theme);
+
+                //draw bottom panel part
+                QRect buttonRect = option->rect;
+                buttonRect.setTop(buttonBox->geometry().top());
+                theme.rect = buttonRect;
+                theme.partId = TDLG_SECONDARYPANEL;
+                d->drawBackground(theme);
+            }
+        }
+        break;
+    default:
+        QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+        break;
+    }
+}
+
+
+/*!
+ \internal
+
+ see drawPrimitive for comments on the animation support
+ */
+void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option,
+                                  QPainter *painter, const QWidget *widget) const
+{
+    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        QWindowsStyle::drawControl(element, option, painter, widget);
+        return;
+    }
+
+    bool selected = option->state & State_Selected;
+    bool pressed = option->state & State_Sunken;
+    bool disabled = !(option->state & State_Enabled);
+
+    int state = option->state;
+    QString name;
+
+    QRect rect(option->rect);
+    State flags = option->state;
+    int partId = 0;
+    int stateId = 0;
+
+    QRect oldRect;
+    QRect newRect;
+
+    if (d->transitionsEnabled() && widget) {
+        if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+            if ((qobject_cast<const QPushButton*>(widget) && element == CE_PushButtonBevel))
+            {
+                QWidget *w = const_cast<QWidget *> (widget);
+                int oldState = w->property("_q_stylestate").toInt();
+                oldRect = w->property("_q_stylerect").toRect();
+                newRect = w->rect();
+                w->setProperty("_q_stylestate", (int)option->state);
+                w->setProperty("_q_stylerect", w->rect());
+
+                bool wasDefault = w->property("_q_isdefault").toBool();
+                bool isDefault = button->features & QStyleOptionButton::DefaultButton;
+                w->setProperty("_q_isdefault", isDefault);
+
+                bool doTransition = ((state & State_Sunken)     != (oldState & State_Sunken) ||
+                                     (state & State_On)         != (oldState & State_On)     ||
+                                     (state & State_MouseOver)  != (oldState & State_MouseOver));
+
+                if (oldRect != newRect || (wasDefault && !isDefault))
+                {
+                    doTransition = false;
+                    d->stopAnimation(widget);
+                }
+
+                if (doTransition) {
+                    QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                    QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                    Animation *anim = d->widgetAnimation(widget);
+
+                    QStyleOptionButton opt = *button;
+                    opt.state = (QStyle::State)oldState;
+
+                    startImage.fill(0);
+                    Transition *t = new Transition;
+                    t->setWidget(w);
+                    QPainter startPainter(&startImage);
+
+                    if (!anim) {
+                        proxy()->drawControl(element, &opt, &startPainter, 0 /* Intentional */);
+                    } else {
+                        anim->paint(&startPainter, &opt);
+                        d->stopAnimation(widget);
+                    }
+
+                    t->setStartImage(startImage);
+                    d->startAnimation(t);
+
+                    endImage.fill(0);
+                    QPainter endPainter(&endImage);
+                    proxy()->drawControl(element, option, &endPainter, 0 /* Intentional */);
+                    t->setEndImage(endImage);
+                    int duration = 0;
+                    HTHEME theme = pOpenThemeData(0, L"Button");
+
+                    int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
+                    int toState = buttonStateId(option->state, BP_PUSHBUTTON);
+                    if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+                        t->setDuration(duration);
+                    else
+                        t->setDuration(0);
+                    t->setStartTime(QTime::currentTime());
+                }
+            }
+        }
+    }
+    switch (element) {
+    case CE_PushButtonBevel:
+        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
+        {
+
+            if (Animation *anim = d->widgetAnimation(widget)) {
+                anim->paint(painter, option);
+            } else {
+                name = QLatin1String("BUTTON");
+                partId = BP_PUSHBUTTON;
+                if (btn->features & QStyleOptionButton::CommandLinkButton)
+                    partId = BP_COMMANDLINK;
+                bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
+                if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
+                    stateId = PBS_DISABLED;
+                else if (justFlat)
+                    ;
+                else if (flags & (State_Sunken | State_On))
+                    stateId = PBS_PRESSED;
+                else if (flags & State_MouseOver)
+                    stateId = PBS_HOT;
+                else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
+                    stateId = PBS_DEFAULTED;
+                else
+                    stateId = PBS_NORMAL;
+
+                if (!justFlat) {
+
+                    if (widget && d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
+                        !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
+                         (state & State_Enabled) && (state & State_Active))
+                        {
+                        Animation *anim = d->widgetAnimation(widget);
+                        if (!anim && widget) {
+                            QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                            startImage.fill(0);
+                            QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                            alternateImage.fill(0);
+
+                            Pulse *pulse = new Pulse;
+                            pulse->setWidget(const_cast<QWidget*>(widget));
+
+                            QPainter startPainter(&startImage);
+                            stateId = PBS_DEFAULTED;
+                            XPThemeData theme(widget, &startPainter, name, partId, stateId, rect);
+                            d->drawBackground(theme);
+
+                            QPainter alternatePainter(&alternateImage);
+                            theme.stateId = PBS_DEFAULTED_ANIMATING;
+                            theme.painter = &alternatePainter;
+                            d->drawBackground(theme);
+                            pulse->setPrimaryImage(startImage);
+                            pulse->setAlternateImage(alternateImage);
+                            pulse->setStartTime(QTime::currentTime());
+                            pulse->setDuration(2000);
+                            d->startAnimation(pulse);
+                            anim = pulse;
+                        }
+
+                        if (anim)
+                            anim->paint(painter, option);
+                        else {
+                            XPThemeData theme(widget, painter, name, partId, stateId, rect);
+                            d->drawBackground(theme);
+                        }
+                    }
+                    else {
+                        d->stopAnimation(widget);
+                        XPThemeData theme(widget, painter, name, partId, stateId, rect);
+                        d->drawBackground(theme);
+                    }
+                }
+            }
+            if (btn->features & QStyleOptionButton::HasMenu) {
+                int mbiw = 0, mbih = 0;
+                XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON);
+                if (theme.isValid()) {
+                    SIZE size;
+                    if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
+                        mbiw = size.cx;
+                        mbih = size.cy;
+                    }
+                }
+                QRect ir = subElementRect(SE_PushButtonContents, option, 0);
+                QStyleOptionButton newBtn = *btn;
+                newBtn.rect = QStyle::visualRect(option->direction, option->rect,
+                                                QRect(ir.right() - mbiw - 2,
+                                                      option->rect.top() + (option->rect.height()/2) - (mbih/2),
+                                                      mbiw + 1, mbih + 1));
+                proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
+            }
+            return;
+        }
+        break;
+#ifndef QT_NO_PROGRESSBAR
+    case CE_ProgressBarContents:
+        if (const QStyleOptionProgressBar *bar
+                = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+            int stateId = MBI_NORMAL;
+            if (disabled)
+                stateId = MBI_DISABLED;
+            bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0);
+            bool vertical = false;
+            bool inverted = false;
+            if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+                vertical = (pb2->orientation == Qt::Vertical);
+                inverted = pb2->invertedAppearance;
+            }
+
+            if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) {
+                if (((progressbar->value() > 0  && d->transitionsEnabled()) || isIndeterminate)) {
+                    if (!d->widgetAnimation(progressbar) && progressbar->value() < progressbar->maximum()) {
+                        Animation *a = new Animation;
+                        a->setWidget(const_cast<QWidget*>(widget));
+                        a->setStartTime(QTime::currentTime());
+                        d->startAnimation(a);
+                    }
+                } else {
+                    d->stopAnimation(progressbar);
+                }
+            }
+
+            XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL);
+            theme.rect = option->rect;
+            bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted);
+            QTime current = QTime::currentTime();
+
+            if (isIndeterminate) {
+                if (Animation *a = d->widgetAnimation(widget)) {
+                    int glowSize = 120;
+                    int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
+                    int animOffset = a->startTime().msecsTo(current) / 4;
+                    if (animOffset > animationWidth)
+                        a->setStartTime(QTime::currentTime());
+                    painter->save();
+                    painter->setClipRect(theme.rect);
+                    QRect animRect;
+                    QSize pixmapSize(14, 14);
+                    if (vertical) {
+                        animRect = QRect(theme.rect.left(),
+                                         inverted ? rect.top() - glowSize + animOffset :
+                                                    rect.bottom() + glowSize - animOffset,
+                                         rect.width(), glowSize);
+                         pixmapSize.setHeight(animRect.height());
+                    } else {
+                        animRect = QRect(rect.left() - glowSize + animOffset,
+                                         rect.top(), glowSize, rect.height());
+                        animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, 
+                                                                option->rect, animRect);
+                        pixmapSize.setWidth(animRect.width());
+                    }
+                    QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height());
+                    QPixmap pixmap;
+                    if (!QPixmapCache::find(name, pixmap)) {
+                        QImage image(pixmapSize, QImage::Format_ARGB32);
+                        image.fill(Qt::transparent);
+                        QPainter imagePainter(&image);
+                        theme.painter = &imagePainter;
+                        theme.partId = vertical ? PP_FILLVERT : PP_FILL;
+                        theme.rect = QRect(QPoint(0,0), theme.rect.size());
+                        QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(),
+                                                      vertical ? image.height() : 0);
+                        alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
+                        alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220));
+                        alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
+                        imagePainter.fillRect(image.rect(), alphaGradient);
+                        imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+                        d->drawBackground(theme);
+                        imagePainter.end();
+                        pixmap = QPixmap::fromImage(image);
+                        QPixmapCache::insert(name, pixmap);
+                    }
+                    painter->drawPixmap(animRect, pixmap);
+                    painter->restore();
+                }
+            }
+            else {
+                qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar
+
+                if (vertical) {
+                    int maxHeight = option->rect.height();
+                    int minHeight = 0;
+                    double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight);
+                    int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight);
+                    theme.rect.setHeight(height);
+                    if (!inverted)
+                        theme.rect.moveTop(rect.height() - theme.rect.height());
+                } else {
+                    int maxWidth = option->rect.width();
+                    int minWidth = 0;
+                    double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth);
+                    int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth);
+                    theme.rect.setWidth(width);
+                    theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, 
+                                                              option->rect, theme.rect);
+                }
+                d->drawBackground(theme);
+
+                if (Animation *a = d->widgetAnimation(widget)) {
+                    int glowSize = 140;
+                    int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
+                    int animOffset = a->startTime().msecsTo(current) / 4;
+                    theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
+                    if (animOffset > animationWidth) {
+                        if (bar->progress < bar->maximum)
+                            a->setStartTime(QTime::currentTime());
+                        else
+                            d->stopAnimation(widget); //we stop the glow motion only after it has
+                                                      //moved out of view
+                    }
+                    painter->save();
+                    painter->setClipRect(theme.rect);
+                    if (vertical) {
+                        theme.rect = QRect(theme.rect.left(),
+                                           inverted ? rect.top() - glowSize + animOffset :
+                                                      rect.bottom() + glowSize - animOffset,
+                                           rect.width(), glowSize);
+                    } else {
+                        theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height());
+                        theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect);
+                    }
+                    d->drawBackground(theme);
+                    painter->restore();
+                }
+            }
+        }
+        break;
+#endif // QT_NO_PROGRESSBAR
+    case CE_MenuBarItem:
+        {
+
+        if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+        {
+            if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+                break;
+
+            QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
+            QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
+
+            uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+            if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+                alignment |= Qt::TextHideMnemonic;
+
+            //The rect adjustment is a workaround for the menu not really filling its background.
+            XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
+            d->drawBackground(theme);
+
+            int stateId = MBI_NORMAL;
+            if (disabled)
+                stateId = MBI_DISABLED;
+            else if (pressed)
+                stateId = MBI_PUSHED;
+            else if (selected)
+                stateId = MBI_HOT;
+
+            XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect);
+            d->drawBackground(theme2);
+
+            if (!pix.isNull())
+                drawItemPixmap(painter, mbi->rect, alignment, pix);
+            else
+                drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+        }
+    }
+    break;
+#ifndef QT_NO_MENU
+    case CE_MenuItem:
+        if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+            // windows always has a check column, regardless whether we have an icon or not
+            int checkcol = 28;
+            {
+                SIZE    size;
+                MARGINS margins;
+                XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+                pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+                pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
+                checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
+            }
+            QColor darkLine = option->palette.background().color().darker(108);
+            QColor lightLine = option->palette.background().color().lighter(107);
+            QRect rect = option->rect;
+            QStyleOptionMenuItem mbiCopy = *menuitem;
+
+            //draw vertical menu line
+            QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
+            QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
+            QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
+            XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect);
+            d->drawBackground(theme2);
+
+            int x, y, w, h;
+            menuitem->rect.getRect(&x, &y, &w, &h);
+            int tab = menuitem->tabWidth;
+            bool dis = !(menuitem->state & State_Enabled);
+            bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+                            ? menuitem->checked : false;
+            bool act = menuitem->state & State_Selected;
+
+            if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+                int yoff = y-2 + h / 2;
+                QPoint p1 = QPoint(x + checkcol, yoff);
+                QPoint p2 = QPoint(x + w + 6 , yoff);
+                stateId = MBI_HOT;
+                QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
+                subRect  = QStyle::visualRect(option->direction, option->rect, subRect );
+                XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect);
+                d->drawBackground(theme2);
+                return;
+            }
+
+            QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
+                                          menuitem->rect.y(), checkcol - 6, menuitem->rect.height()));
+
+            if (act) {
+                stateId = MBI_HOT;
+                XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect);
+                d->drawBackground(theme2);
+            }
+
+            if (checked) {
+                XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND,
+                                  menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
+                SIZE    size;
+                MARGINS margins;
+                pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+                pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0,
+                                TMT_CONTENTMARGINS, NULL, &margins);
+                QRect checkRect(0, 0, size.cx + margins.cxLeftWidth + margins.cxRightWidth ,
+                                size.cy + margins.cyBottomHeight + margins.cyTopHeight);
+                checkRect.moveCenter(vCheckRect.center());
+                theme.rect = checkRect;
+
+                d->drawBackground(theme);
+
+                if (menuitem->icon.isNull()) {
+                    checkRect = QRect(0, 0, size.cx, size.cy);
+                    checkRect.moveCenter(theme.rect.center());
+                    theme.rect = checkRect;
+
+                    theme.partId = MENU_POPUPCHECK;
+                    bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive;
+                    if (dis)
+                        theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED;
+                    else
+                        theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL;
+                    d->drawBackground(theme);
+                }
+            }
+
+            if (!menuitem->icon.isNull()) {
+                QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+                if (act && !dis)
+                    mode = QIcon::Active;
+                QPixmap pixmap;
+                if (checked)
+                    pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
+                else
+                    pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
+                int pixw = pixmap.width();
+                int pixh = pixmap.height();
+                QRect pmr(0, 0, pixw, pixh);
+                pmr.moveCenter(vCheckRect.center());
+                painter->setPen(menuitem->palette.text().color());
+                painter->drawPixmap(pmr.topLeft(), pixmap);
+            }
+
+            painter->setPen(menuitem->palette.buttonText().color());
+
+            QColor discol;
+            if (dis) {
+                discol = menuitem->palette.text().color();
+                painter->setPen(discol);
+            }
+
+            int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+            int xpos = menuitem->rect.x() + xm;
+            QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+            QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
+            QString s = menuitem->text;
+            if (!s.isEmpty()) {    // draw text
+                painter->save();
+                int t = s.indexOf(QLatin1Char('\t'));
+                int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+                if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+                    text_flags |= Qt::TextHideMnemonic;
+                text_flags |= Qt::AlignLeft;
+                if (t >= 0) {
+                    QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
+                    QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+                    painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+                    s = s.left(t);
+                }
+                QFont font = menuitem->font;
+                if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+                    font.setBold(true);
+                painter->setFont(font);
+                painter->setPen(discol);
+                painter->drawText(vTextRect, text_flags, s.left(t));
+                painter->restore();
+            }
+            if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+                int dim = (h - 2 * windowsItemFrame) / 2;
+                PrimitiveElement arrow;
+                arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+                xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+                QRect  vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+                QStyleOptionMenuItem newMI = *menuitem;
+                newMI.rect = vSubMenuRect;
+                newMI.state = dis ? State_None : State_Enabled;
+                proxy()->drawPrimitive(arrow, &newMI, painter, widget);
+            }
+        }
+        break;
+#endif // QT_NO_MENU
+    case CE_HeaderSection:
+        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+            name = QLatin1String("HEADER");
+            partId = HP_HEADERITEM;
+            if (flags & State_Sunken)
+                stateId = HIS_PRESSED;
+            else if (flags & State_MouseOver)
+                stateId = HIS_HOT;
+            else
+                stateId = HIS_NORMAL;
+
+            if (header->sortIndicator != QStyleOptionHeader::None)
+                stateId += 3;
+
+            XPThemeData theme(widget, painter, name, partId, stateId, option->rect);
+            d->drawBackground(theme);
+        }
+        break;
+    case CE_MenuBarEmptyArea:
+        {
+            stateId = MBI_NORMAL;
+            if (!(state & State_Enabled))
+                stateId = MBI_DISABLED;
+            XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect);
+            d->drawBackground(theme);
+        }
+        break;
+    case CE_ToolBar:
+        if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+            QPalette pal = option->palette;
+            pal.setColor(QPalette::Dark, option->palette.background().color().darker(130));
+            QStyleOptionToolBar copyOpt = *toolbar;
+            copyOpt.palette = pal;
+            QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
+        }
+        break;
+    case CE_DockWidgetTitle:
+        if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
+            QRect rect = option->rect;
+            if (dockWidget->isFloating()) {
+                QWindowsXPStyle::drawControl(element, option, painter, widget);
+                break; //otherwise fall through
+            }
+
+            if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+
+            const QStyleOptionDockWidgetV2 *v2
+                = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+            bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+            if (verticalTitleBar) {
+                QSize s = rect.size();
+                s.transpose();
+                rect.setSize(s);
+
+                painter->translate(rect.left() - 1, rect.top() + rect.width());
+                painter->rotate(-90);
+                painter->translate(-rect.left() + 1, -rect.top());
+            }
+
+            painter->setBrush(option->palette.background().color().darker(110));
+            painter->setPen(option->palette.background().color().darker(130));
+            painter->drawRect(rect.adjusted(0, 1, -1, -3));
+
+            int buttonMargin = 4;
+            int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+            int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
+            const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
+            bool isFloating = dw != 0 && dw->isFloating();
+
+            QRect r = option->rect.adjusted(0, 2, -1, -3);
+            QRect titleRect = r;
+
+            if (dwOpt->closable) {
+                QSize sz = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
+                titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+            }
+
+            if (dwOpt->floatable) {
+                QSize sz = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
+                titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+            }
+
+            if (isFloating) {
+                titleRect.adjust(0, -fw, 0, 0);
+                if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+                    titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+            } else {
+                titleRect.adjust(mw, 0, 0, 0);
+                if (!dwOpt->floatable && !dwOpt->closable)
+                    titleRect.adjust(0, 0, -mw, 0);
+            }
+            if (!verticalTitleBar)
+                titleRect = visualRect(dwOpt->direction, r, titleRect);
+
+            if (!dwOpt->title.isEmpty()) {
+                QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
+                                                                      verticalTitleBar ? titleRect.height() : titleRect.width());
+                const int indent = painter->fontMetrics().descent();
+                drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1),
+                                Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
+                                dwOpt->state & State_Enabled, titleText,
+                                QPalette::WindowText);
+                }
+            }
+            break;
+        }
+#ifndef QT_NO_ITEMVIEWS
+    case CE_ItemViewItem:
+        {
+            const QStyleOptionViewItemV4 *vopt;
+            const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+            bool newStyle = true;
+
+            if (qobject_cast<const QTableView*>(widget))
+                newStyle = false;
+
+            if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
+                /*
+                // We cannot currently get the correct selection color for "explorer style" views
+                COLORREF cref = 0;
+                XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0);
+                unsigned int res = pGetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref);
+                QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+                */
+                QPalette palette = vopt->palette;
+                palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text));
+                // Note that setting a saturated color here results in ugly XOR colors in the focus rect
+                palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108));
+                QStyleOptionViewItemV4 adjustedOption = *vopt;
+                adjustedOption.palette = palette;
+                // We hide the  focusrect in singleselection as it is not required
+                if ((view->selectionMode() == QAbstractItemView::SingleSelection) 
+                    && !(vopt->state & State_KeyboardFocusChange))
+                adjustedOption.state &= ~State_HasFocus;
+                QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget);
+            } else {
+                QWindowsXPStyle::drawControl(element, option, painter, widget);
+            }
+            break;
+        }
+#endif // QT_NO_ITEMVIEWS
+
+    default:
+        QWindowsXPStyle::drawControl(element, option, painter, widget);
+        break;
+    }
+}
+
+/*!
+  \internal
+
+  see drawPrimitive for comments on the animation support
+
+ */
+void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+                                         QPainter *painter, const QWidget *widget) const
+{
+    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        QWindowsStyle::drawComplexControl(control, option, painter, widget);
+        return;
+    }
+
+    State state = option->state;
+    SubControls sub = option->subControls;
+    QRect r = option->rect;
+
+    int partId = 0;
+    int stateId = 0;
+
+    State flags = option->state;
+    if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
+        flags |= State_MouseOver;
+
+    if (d->transitionsEnabled() && widget) {
+        if ((qobject_cast<const QScrollBar *>(widget) && control == CC_ScrollBar)
+#ifndef QT_NO_SPINBOX
+            || (qobject_cast<const QAbstractSpinBox*>(widget) && control == CC_SpinBox)
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+            || (qobject_cast<const QComboBox*>(widget) && control == CC_ComboBox)
+#endif // QT_NO_COMBOBOX
+            )
+        {
+            QWidget *w = const_cast<QWidget *> (widget);
+
+            int oldState = w->property("_q_stylestate").toInt();
+            int oldActiveControls = w->property("_q_stylecontrols").toInt();
+            QRect oldRect = w->property("_q_stylerect").toRect();
+            w->setProperty("_q_stylestate", (int)option->state);
+            w->setProperty("_q_stylecontrols", (int)option->activeSubControls);
+            w->setProperty("_q_stylerect", w->rect());
+
+            bool doTransition = ((state & State_Sunken)     != (oldState & State_Sunken)    ||
+                                 (state & State_On)         != (oldState & State_On)        ||
+                                 (state & State_MouseOver)  != (oldState & State_MouseOver) ||
+                                  oldActiveControls            != option->activeSubControls);
+
+
+            if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+                QRect oldSliderPos = w->property("_q_stylesliderpos").toRect();
+                QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+                w->setProperty("_q_stylesliderpos", currentPos);
+                if (oldSliderPos != currentPos) {
+                    doTransition = false;
+                    d->stopAnimation(widget);
+                }
+            } else if (control == CC_SpinBox) {
+                //spinboxes have a transition when focus changes
+                if (!doTransition)
+                    doTransition = (state & State_HasFocus) != (oldState & State_HasFocus);
+            }
+
+            if (oldRect != option->rect) {
+                doTransition = false;
+                d->stopAnimation(widget);
+            }
+
+            if (doTransition) {
+                QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+                Animation *anim = d->widgetAnimation(widget);
+                Transition *t = new Transition;
+                t->setWidget(w);
+                if (!anim) {
+                    if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
+                        //Combo boxes are special cased to avoid cleartype issues
+                        startImage.fill(0);
+                        QPainter startPainter(&startImage);
+                        QStyleOptionComboBox startCombo = *combo;
+                        startCombo.state = (QStyle::State)oldState;
+                        startCombo.activeSubControls = (QStyle::SubControl)oldActiveControls;
+                        proxy()->drawComplexControl(control, &startCombo, &startPainter, 0 /* Intentional */);
+                        t->setStartImage(startImage);
+                    } else if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
+                        //This is a workaround for the direct3d engine as it currently has some issues with grabWindow
+                        startImage.fill(0);
+                        QPainter startPainter(&startImage);
+                        QStyleOptionSlider startSlider = *slider;
+                        startSlider.state = (QStyle::State)oldState;
+                        startSlider.activeSubControls = (QStyle::SubControl)oldActiveControls;
+                        proxy()->drawComplexControl(control, &startSlider, &startPainter, 0 /* Intentional */);
+                        t->setStartImage(startImage);
+                    } else {
+                        QPoint offset(0, 0);
+                        if (!widget->internalWinId())
+                            offset = widget->mapTo(widget->nativeParentWidget(), offset);
+                        t->setStartImage(QPixmap::grabWindow(widget->effectiveWinId(), offset.x(), offset.y(),
+                                         option->rect.width(), option->rect.height()).toImage());
+                    }
+                } else {
+                    startImage.fill(0);
+                    QPainter startPainter(&startImage);
+                    anim->paint(&startPainter, option);
+                    t->setStartImage(startImage);
+                }
+                d->startAnimation(t);
+                endImage.fill(0);
+                QPainter endPainter(&endImage);
+                proxy()->drawComplexControl(control, option, &endPainter, 0 /* Intentional */);
+                t->setEndImage(endImage);
+                t->setStartTime(QTime::currentTime());
+
+                if (option->state & State_MouseOver || option->state & State_Sunken)
+                    t->setDuration(150);
+                else
+                    t->setDuration(500);
+            }
+
+            if (Animation *anim = d->widgetAnimation(widget)) {
+                anim->paint(painter, option);
+                return;
+            }
+
+        }
+    }
+
+    switch (control) {
+    case CC_ComboBox:
+        if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+        {
+            if (cmb->editable) {
+                if (sub & SC_ComboBoxEditField) {
+                    partId = EP_EDITBORDER_NOSCROLL;
+                    if (!(flags & State_Enabled))
+                        stateId = ETS_DISABLED;
+                    else if (flags & State_MouseOver)
+                        stateId = ETS_HOT;
+                    else if (flags & State_HasFocus)
+                        stateId = ETS_FOCUSED;
+                    else
+                        stateId = ETS_NORMAL;
+
+                    XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_ComboBoxArrow) {
+                    QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
+                    XPThemeData theme(widget, painter, QLatin1String("COMBOBOX"));
+                    theme.rect = subRect;
+                    partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
+
+                    if (!(cmb->state & State_Enabled))
+                        stateId = CBXS_DISABLED;
+                    else if (cmb->state & State_Sunken || cmb->state & State_On)
+                        stateId = CBXS_PRESSED;
+                    else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
+                        stateId = CBXS_HOT;
+                    else
+                        stateId = CBXS_NORMAL;
+
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+
+            } else {
+                if (sub & SC_ComboBoxFrame) {
+                    QStyleOptionButton btn;
+                    btn.QStyleOption::operator=(*option);
+                    btn.rect = option->rect.adjusted(-1, -1, 1, 1);
+                    if (sub & SC_ComboBoxArrow)
+                        btn.features = QStyleOptionButton::HasMenu;
+                    proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget);
+                }
+            }
+       }
+       break;
+    case CC_ScrollBar:
+        if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
+        {
+            XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR"));
+
+            bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
+            if (maxedOut)
+                flags &= ~State_Enabled;
+
+            bool isHorz = flags & State_Horizontal;
+            bool isRTL  = option->direction == Qt::RightToLeft;
+            if (sub & SC_ScrollBarAddLine) {
+                theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
+                partId = SBP_ARROWBTN;
+                if (!(flags & State_Enabled))
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
+                else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
+                else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
+                else if (scrollbar->state & State_MouseOver)
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER);
+                else
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+            if (sub & SC_ScrollBarSubLine) {
+                theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
+                partId = SBP_ARROWBTN;
+                if (!(flags & State_Enabled))
+                    stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
+                else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
+                    stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
+                else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
+                    stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
+                else if (scrollbar->state & State_MouseOver)
+                    stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER);
+                else
+                    stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+            if (maxedOut) {
+                theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+                theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
+                theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
+                partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+                stateId = SCRBS_DISABLED;
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            } else {
+                if (sub & SC_ScrollBarSubPage) {
+                    theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
+                    partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
+                    if (!(flags & State_Enabled))
+                        stateId = SCRBS_DISABLED;
+                    else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
+                        stateId = SCRBS_PRESSED;
+                    else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
+                        stateId = SCRBS_HOT;
+                    else
+                        stateId = SCRBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_ScrollBarAddPage) {
+                    theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
+                    partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+                    if (!(flags & State_Enabled))
+                        stateId = SCRBS_DISABLED;
+                    else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
+                        stateId = SCRBS_PRESSED;
+                    else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
+                        stateId = SCRBS_HOT;
+                    else
+                        stateId = SCRBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_ScrollBarSlider) {
+                    theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+                    if (!(flags & State_Enabled))
+                        stateId = SCRBS_DISABLED;
+                    else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
+                        stateId = SCRBS_PRESSED;
+                    else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
+                        stateId = SCRBS_HOT;
+                    else if (option->state & State_MouseOver)
+                        stateId = SCRBS_HOVER;
+                    else
+                        stateId = SCRBS_NORMAL;
+
+                    // Draw handle
+                    theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+                    theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+
+                    // Calculate rect of gripper
+                    const int swidth = theme.rect.width();
+                    const int sheight = theme.rect.height();
+
+                    MARGINS contentsMargin;
+                    RECT rect = theme.toRECT(theme.rect);
+                    pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
+
+                    SIZE size;
+                    theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
+                    pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                    int gw = size.cx, gh = size.cy;
+
+
+                    QRect gripperBounds;
+                    if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
+                        gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+                        gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+                        gripperBounds.setWidth(gw);
+                        gripperBounds.setHeight(gh);
+                    } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
+                        gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+                        gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+                        gripperBounds.setWidth(gw);
+                        gripperBounds.setHeight(gh);
+                    }
+
+                    // Draw gripper if there is enough space
+                    if (!gripperBounds.isEmpty() && flags & State_Enabled) {
+                        painter->save();
+                        XPThemeData grippBackground = theme;
+                        grippBackground.partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+                        theme.rect = gripperBounds;
+                        painter->setClipRegion(d->region(theme));// Only change inside the region of the gripper
+                        d->drawBackground(grippBackground);// The gutter is the grippers background
+                        d->drawBackground(theme);          // Transparent gripper ontop of background
+                        painter->restore();
+                    }
+                }
+            }
+        }
+        break;
+#ifndef QT_NO_SPINBOX
+    case CC_SpinBox:
+        if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
+        {
+            XPThemeData theme(widget, painter, QLatin1String("SPIN"));
+            if (sb->frame && (sub & SC_SpinBoxFrame)) {
+                partId = EP_EDITBORDER_NOSCROLL;
+                if (!(flags & State_Enabled))
+                    stateId = ETS_DISABLED;
+                else if (flags & State_MouseOver)
+                    stateId = ETS_HOT;
+                else if (flags & State_HasFocus)
+                    stateId = ETS_SELECTED;
+                else
+                    stateId = ETS_NORMAL;
+
+                XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+                ftheme.noContent = true;
+                d->drawBackground(ftheme);
+            }
+            if (sub & SC_SpinBoxUp) {
+                theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1);
+                partId = SPNP_UP;
+                if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
+                    stateId = UPS_DISABLED;
+                else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
+                    stateId = UPS_PRESSED;
+                else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
+                    stateId = UPS_HOT;
+                else
+                    stateId = UPS_NORMAL;
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+            if (sub & SC_SpinBoxDown) {
+                theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+                partId = SPNP_DOWN;
+                if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
+                    stateId = DNS_DISABLED;
+                else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
+                    stateId = DNS_PRESSED;
+                else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
+                    stateId = DNS_HOT;
+                else
+                    stateId = DNS_NORMAL;
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+        }
+        break;
+#endif // QT_NO_SPINBOX
+    default:
+        QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+        break;
+    }
+}
+
+/*!
+ \internal
+ */
+QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+                                        const QSize &size, const QWidget *widget) const
+{
+    if (!QWindowsVistaStylePrivate::useVista())
+        return QWindowsStyle::sizeFromContents(type, option, size, widget);
+
+    QSize sz(size);
+
+    QSize newSize = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+    switch (type) {
+    case CT_LineEdit:
+    case CT_ComboBox:
+        {
+            HTHEME theme = pOpenThemeData(0, L"Button");
+            MARGINS borderSize;
+            if (theme) {
+                int result = pGetThemeMargins(theme,
+                                              NULL,
+                                              BP_PUSHBUTTON,
+                                              PBS_NORMAL,
+                                              TMT_CONTENTMARGINS,
+                                              NULL,
+                                              &borderSize);
+                if (result == S_OK) {
+                    sz += QSize(borderSize.cxLeftWidth + borderSize.cxRightWidth - 2,
+                                borderSize.cyBottomHeight + borderSize.cyTopHeight - 2);
+                }
+                sz += QSize(23, 0); //arrow button
+            }
+        }
+        return sz;
+    case CT_MenuItem:
+        sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+        int minimumHeight;
+        {
+            SIZE    size;
+            MARGINS margins;
+            XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+            pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+            pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
+            minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height());
+            sz.rwidth() += size.cx + margins.cxLeftWidth + margins.cxRightWidth;
+        }
+        
+        if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+            if (menuitem->menuItemType != QStyleOptionMenuItem::Separator)
+                sz.setHeight(minimumHeight);
+        }
+        return sz;
+#ifndef QT_NO_MENUBAR
+    case CT_MenuBarItem:
+        if (!sz.isEmpty())
+            sz += QSize(windowsItemHMargin * 5 + 1, 5);
+            return sz;
+        break;
+#endif
+    case CT_ItemViewItem:
+        sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+        sz.rheight() += 2;
+        return sz;
+    case CT_SpinBox:
+        {
+            //Spinbox adds frame twice
+            sz = QWindowsStyle::sizeFromContents(type, option, size, widget);
+            int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+            sz -= QSize(2*border, 2*border);
+        }
+        return sz;
+    default:
+        break;
+    }
+    return newSize;
+}
+
+/*!
+ \internal
+ */
+QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+   if (!QWindowsVistaStylePrivate::useVista())
+        return QWindowsStyle::subElementRect(element, option, widget);
+
+   QRect rect = QWindowsXPStyle::subElementRect(element, option, widget);
+    switch (element) {
+
+    case SE_PushButtonContents:
+        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+            MARGINS borderSize;
+            HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
+            if (theme) {
+                int stateId = PBS_NORMAL;
+                if (!(option->state & State_Enabled))
+                    stateId = PBS_DISABLED;
+                else if (option->state & State_Sunken)
+                    stateId = PBS_PRESSED;
+                else if (option->state & State_MouseOver)
+                    stateId = PBS_HOT;
+                else if (btn->features & QStyleOptionButton::DefaultButton)
+                    stateId = PBS_DEFAULTED;
+
+                int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+                rect = option->rect.adjusted(border, border, -border, -border);
+
+                int result = pGetThemeMargins(theme,
+                                              NULL,
+                                              BP_PUSHBUTTON,
+                                              stateId,
+                                              TMT_CONTENTMARGINS,
+                                              NULL,
+                                              &borderSize);
+
+                if (result == S_OK) {
+                    rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
+                                -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
+                    rect = visualRect(option->direction, option->rect, rect);
+                }
+            }
+        }
+        break;
+
+    case SE_HeaderArrow:
+        {
+            QRect r = rect;
+            int h = option->rect.height();
+            int w = option->rect.width();
+            int x = option->rect.x();
+            int y = option->rect.y();
+            int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
+
+            XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
+
+            int arrowWidth = 13;
+            int arrowHeight = 5;
+            if (theme.isValid()) {
+                SIZE size;
+                if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
+                    arrowWidth = size.cx;
+                    arrowHeight = size.cy;
+                }
+            }
+            if (option->state & State_Horizontal) {
+                r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight);
+            } else {
+                int vert_size = w / 2;
+                r.setRect(x + 5, y + h - margin * 2 - vert_size,
+                          w - margin * 2 - 5, vert_size);
+            }
+            rect = visualRect(option->direction, option->rect, r);
+        }
+        break;
+
+    case SE_HeaderLabel:
+        {
+            int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
+            QRect r = option->rect;
+            r.setRect(option->rect.x() + margin, option->rect.y() + margin,
+                      option->rect.width() - margin * 2, option->rect.height() - margin * 2);
+            if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+                // Subtract width needed for arrow, if there is one
+                if (header->sortIndicator != QStyleOptionHeader::None) {
+                    if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top
+                        r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2));
+                }
+            }
+            rect = visualRect(option->direction, option->rect, r);
+        }
+        break;
+    case SE_ProgressBarContents:
+        rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
+        break;
+    case SE_ItemViewItemDecoration:
+        if (qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))
+            rect.adjust(-2, 0, 2, 0);
+        break;
+    case SE_ItemViewItemFocusRect:
+        if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+            QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+            QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget);
+            if (!vopt->icon.isNull())
+                rect = textRect.united(displayRect);
+            else
+                rect = textRect;
+            rect = rect.adjusted(1, 0, -1, 0);
+        }
+        break;
+    default:
+        break;
+    }
+    return rect;
+}
+
+
+/*
+  This function is used by subControlRect to check if a button
+  should be drawn for the given subControl given a set of window flags.
+*/
+static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
+
+    bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+    bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+    const uint flags = tb->titleBarFlags;
+    bool retVal = false;
+    switch (sc) {
+    case QStyle::SC_TitleBarContextHelpButton:
+        if (flags & Qt::WindowContextHelpButtonHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarMinButton:
+        if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarNormalButton:
+        if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+            retVal = true;
+        else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarMaxButton:
+        if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarShadeButton:
+        if (!isMinimized &&  flags & Qt::WindowShadeButtonHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarUnshadeButton:
+        if (isMinimized && flags & Qt::WindowShadeButtonHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarCloseButton:
+        if (flags & Qt::WindowSystemMenuHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarSysMenu:
+        if (flags & Qt::WindowSystemMenuHint)
+            retVal = true;
+        break;
+    default :
+        retVal = true;
+    }
+    return retVal;
+}
+
+
+/*! \internal */
+int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+                             QStyleHintReturn *returnData) const
+{
+    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+    int ret = 0;
+    switch (hint) {
+    case SH_MessageBox_CenterButtons:
+        ret = false;
+        break;
+    case SH_ToolTip_Mask:
+        if (option) {
+            if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
+                ret = true;
+                XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+                mask->region = d->region(themeData);
+            }
+        }
+        break;
+     case SH_Table_GridLineColor:
+        if (option)
+            ret = option->palette.color(QPalette::Base).darker(118).rgb();
+        else
+            ret = -1;
+        break;
+    default:
+        ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
+        break;
+    }
+    return ret;
+}
+
+
+/*!
+ \internal
+ */
+QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+                                  SubControl subControl, const QWidget *widget) const
+{
+   if (!QWindowsVistaStylePrivate::useVista())
+        return QWindowsStyle::subControlRect(control, option, subControl, widget);
+
+    QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
+    switch (control) {
+#ifndef QT_NO_COMBOBOX
+    case CC_ComboBox:
+        if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+            int x = cb->rect.x(),
+                y = cb->rect.y(),
+                wi = cb->rect.width(),
+                he = cb->rect.height();
+            int xpos = x;
+            int margin = cb->frame ? 3 : 0;
+            int bmarg = cb->frame ? 2 : 0;
+            xpos += wi - bmarg - 16;
+
+            switch (subControl) {
+            case SC_ComboBoxFrame:
+                rect = cb->rect;
+                break;
+            case SC_ComboBoxArrow:
+                rect.setRect(xpos, y , wi - xpos, he);
+                break;
+            case SC_ComboBoxEditField:
+                rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
+                break;
+            case SC_ComboBoxListBoxPopup:
+                rect = cb->rect;
+                break;
+            default:
+                break;
+            }
+            rect = visualRect(cb->direction, cb->rect, rect);
+            return rect;
+        }
+#endif // QT_NO_COMBOBOX
+    case CC_TitleBar:
+        if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+            if (!buttonVisible(subControl, tb))
+                return rect;
+            const bool isToolTitle = false;
+            const int height = tb->rect.height();
+            const int width = tb->rect.width();
+            int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
+
+            const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
+            const bool sysmenuHint  = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
+            const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
+            const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
+            const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
+            const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
+
+            switch (subControl) {
+            case SC_TitleBarLabel:
+                rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
+                if (isToolTitle) {
+                    if (sysmenuHint) {
+                        rect.adjust(0, 0, -buttonWidth - 3, 0);
+                    }
+                    if (minimizeHint || maximizeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                } else {
+                    if (sysmenuHint) {
+                        const int leftOffset = height - 8;
+                        rect.adjust(leftOffset, 0, 0, 4);
+                    }
+                    if (minimizeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                    if (maximizeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                    if (contextHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                    if (shadeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                }
+                rect.translate(0, 2);
+                rect = visualRect(option->direction, option->rect, rect);
+                break;
+            case SC_TitleBarSysMenu:
+                {
+                    const int controlTop = 6;
+                    const int controlHeight = height - controlTop - 3;
+                    int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+                    QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
+                    if (tb->icon.isNull())
+                        iconSize = QSize(controlHeight, controlHeight);
+                    int hPad = (controlHeight - iconSize.height())/2;
+                    int vPad = (controlHeight - iconSize.width())/2;
+                    rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
+                    rect.translate(0, 3);
+                    rect = visualRect(option->direction, option->rect, rect);
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+    return rect;
+}
+
+/*!
+ \internal
+ */
+bool QWindowsVistaStyle::event(QEvent *e)
+{
+    Q_D(QWindowsVistaStyle);
+    switch (e->type()) {
+    case QEvent::Timer:
+        {
+            QTimerEvent *timerEvent = (QTimerEvent *)e;
+            if (d->animationTimer.timerId() == timerEvent->timerId()) {
+                d->timerEvent();
+                e->accept();
+                return true;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+    return QWindowsXPStyle::event(e);
+}
+
+/*!
+ \internal
+ */
+QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+                                                          const QPoint &pos, const QWidget *widget) const
+{
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        return QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
+    }
+    return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+/*!
+ \internal
+ */
+int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        return QWindowsStyle::pixelMetric(metric, option, widget);
+    }
+    switch (metric) {
+
+    case PM_DockWidgetTitleBarButtonMargin:
+        return int(QStyleHelper::dpiScaled(5.));
+    case PM_ScrollBarSliderMin:
+        return int(QStyleHelper::dpiScaled(18.));
+    case PM_MenuHMargin:
+    case PM_MenuVMargin:
+        return 0;
+    case PM_MenuPanelWidth:
+        return 3;
+    default:
+        break;
+    }
+    return QWindowsXPStyle::pixelMetric(metric, option, widget);
+}
+
+/*!
+ \internal
+ */
+QPalette QWindowsVistaStyle::standardPalette() const
+{
+    return QWindowsXPStyle::standardPalette();
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QApplication *app)
+{
+    QWindowsXPStyle::polish(app);
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QWidget *widget)
+{
+    QWindowsXPStyle::polish(widget);
+#ifndef QT_NO_LINEEDIT
+    if (qobject_cast<QLineEdit*>(widget))
+        widget->setAttribute(Qt::WA_Hover);
+    else
+#endif // QT_NO_LINEEDIT
+    if (qobject_cast<QGroupBox*>(widget))
+        widget->setAttribute(Qt::WA_Hover);
+    else if (qobject_cast<QCommandLinkButton*>(widget)) {
+        QFont buttonFont = widget->font();
+        buttonFont.setFamily(QLatin1String("Segoe UI"));
+        widget->setFont(buttonFont);
+    }
+    else if (widget->inherits("QTipLabel")){
+        //note that since tooltips are not reused
+        //we do not have to care about unpolishing
+        widget->setContentsMargins(3, 0, 4, 0);
+        COLORREF bgRef;
+        HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
+        if (theme) {
+            if (pGetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef) == S_OK) {
+                QColor textColor = QColor::fromRgb(bgRef);
+                QPalette pal;
+                pal.setColor(QPalette::All, QPalette::ToolTipText, textColor);
+                widget->setPalette(pal);
+            }
+        }
+    } else if (qobject_cast<QMessageBox *> (widget)) {
+        widget->setAttribute(Qt::WA_StyledBackground);
+        QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_msgbox_buttonbox"));
+        if (buttonBox)
+            buttonBox->setContentsMargins(0, 9, 0, 0);
+    }
+#ifndef QT_NO_INPUTDIALOG
+    else if (qobject_cast<QInputDialog *> (widget)) {
+        widget->setAttribute(Qt::WA_StyledBackground);
+        QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_inputdlg_buttonbox"));
+        if (buttonBox)
+            buttonBox->setContentsMargins(0, 9, 0, 0);
+    }
+#endif // QT_NO_INPUTDIALOG
+    else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
+        tree->viewport()->setAttribute(Qt::WA_Hover);
+    }
+    else if (QListView *list = qobject_cast<QListView *> (widget)) {
+        list->viewport()->setAttribute(Qt::WA_Hover);
+    }
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::unpolish(QWidget *widget)
+{
+    QWindowsXPStyle::unpolish(widget);
+
+    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+    d->stopAnimation(widget);
+
+#ifndef QT_NO_LINEEDIT
+    if (qobject_cast<QLineEdit*>(widget))
+        widget->setAttribute(Qt::WA_Hover, false);
+    else
+#endif // QT_NO_LINEEDIT
+    if (qobject_cast<QGroupBox*>(widget))
+        widget->setAttribute(Qt::WA_Hover, false);
+    else if (qobject_cast<QMessageBox *> (widget)) {
+        widget->setAttribute(Qt::WA_StyledBackground, false);
+        QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_msgbox_buttonbox"));
+        if (buttonBox)
+            buttonBox->setContentsMargins(0, 0, 0, 0);
+    }
+#ifndef QT_NO_INPUTDIALOG
+    else if (qobject_cast<QInputDialog *> (widget)) {
+        widget->setAttribute(Qt::WA_StyledBackground, false);
+        QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox *>(widget,QLatin1String("qt_inputdlg_buttonbox"));
+        if (buttonBox)
+            buttonBox->setContentsMargins(0, 0, 0, 0);
+    }
+#endif // QT_NO_INPUTDIALOG
+    else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
+        tree->viewport()->setAttribute(Qt::WA_Hover, false);
+    } else if (qobject_cast<QCommandLinkButton*>(widget)) {
+        QFont font = QApplication::font("QCommandLinkButton");
+        QFont widgetFont = widget->font();
+        widgetFont.setFamily(font.family()); //Only family set by polish
+        widget->setFont(widgetFont);
+    }
+}
+
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::unpolish(QApplication *app)
+{
+    QWindowsXPStyle::unpolish(app);
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QPalette &pal)
+{
+    QWindowsStyle::polish(pal);
+    pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104));
+}
+
+/*!
+ \internal
+ */
+QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
+                                      const QWidget *widget) const
+{
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+    }
+    return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() :
+    QWindowsXPStylePrivate(), m_treeViewHelper(0)
+{
+    resolveSymbols();
+}
+
+QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate()
+{
+    delete m_treeViewHelper;
+}
+
+void QWindowsVistaStylePrivate::timerEvent()
+{
+    for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+
+        if (animations[i]->widget())
+            animations[i]->widget()->update();
+
+        if (!animations[i]->widget() ||
+            !animations[i]->widget()->isEnabled() ||
+            !animations[i]->widget()->isVisible() ||
+            animations[i]->widget()->window()->isMinimized() ||
+            !animations[i]->running() ||
+            !QWindowsVistaStylePrivate::useVista())
+        {
+            Animation *a = animations.takeAt(i);
+            delete a;
+        }
+    }
+    if (animations.size() == 0 && animationTimer.isActive()) {
+        animationTimer.stop();
+    }
+}
+
+void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w)
+{
+    for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+        if (animations[i]->widget() == w) {
+            Animation *a = animations.takeAt(i);
+            delete a;
+            break;
+        }
+    }
+}
+
+void QWindowsVistaStylePrivate::startAnimation(Animation *t)
+{
+    Q_Q(QWindowsVistaStyle);
+    stopAnimation(t->widget());
+    animations.append(t);
+    if (animations.size() > 0 && !animationTimer.isActive()) {
+        animationTimer.start(45, q);
+    }
+}
+
+bool QWindowsVistaStylePrivate::transitionsEnabled() const
+{
+    BOOL animEnabled = false;
+    if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0))
+    {
+        if (animEnabled)
+            return true;
+    }
+    return false;
+}
+
+
+Animation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
+{
+    if (!widget)
+        return 0;
+    foreach (Animation *a, animations) {
+        if (a->widget() == widget)
+            return a;
+    }
+    return 0;
+}
+
+
+/*! \internal
+    Returns true if all the necessary theme engine symbols were
+    resolved.
+*/
+bool QWindowsVistaStylePrivate::resolveSymbols()
+{
+    static bool tried = false;
+    if (!tried) {
+        tried = true;
+        QLibrary themeLib(QLatin1String("uxtheme"));
+        pSetWindowTheme         = (PtrSetWindowTheme        )themeLib.resolve("SetWindowTheme");
+        pIsThemePartDefined     = (PtrIsThemePartDefined    )themeLib.resolve("IsThemePartDefined");
+        pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
+        pOpenThemeData          = (PtrOpenThemeData         )themeLib.resolve("OpenThemeData");
+        pCloseThemeData         = (PtrCloseThemeData        )themeLib.resolve("CloseThemeData");
+        pDrawThemeBackground    = (PtrDrawThemeBackground   )themeLib.resolve("DrawThemeBackground");
+        pDrawThemeBackgroundEx  = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
+        pGetCurrentThemeName    = (PtrGetCurrentThemeName   )themeLib.resolve("GetCurrentThemeName");
+        pGetThemeBool           = (PtrGetThemeBool          )themeLib.resolve("GetThemeBool");
+        pGetThemeColor          = (PtrGetThemeColor         )themeLib.resolve("GetThemeColor");
+        pGetThemeEnumValue      = (PtrGetThemeEnumValue     )themeLib.resolve("GetThemeEnumValue");
+        pGetThemeFilename       = (PtrGetThemeFilename      )themeLib.resolve("GetThemeFilename");
+        pGetThemeFont           = (PtrGetThemeFont          )themeLib.resolve("GetThemeFont");
+        pGetThemeInt            = (PtrGetThemeInt           )themeLib.resolve("GetThemeInt");
+        pGetThemeIntList        = (PtrGetThemeIntList       )themeLib.resolve("GetThemeIntList");
+        pGetThemeMargins        = (PtrGetThemeMargins       )themeLib.resolve("GetThemeMargins");
+        pGetThemeMetric         = (PtrGetThemeMetric        )themeLib.resolve("GetThemeMetric");
+        pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
+        pGetThemePosition       = (PtrGetThemePosition      )themeLib.resolve("GetThemePosition");
+        pGetThemeRect           = (PtrGetThemeRect          )themeLib.resolve("GetThemeRect");
+        pGetThemeString         = (PtrGetThemeString        )themeLib.resolve("GetThemeString");
+        pGetThemeTransitionDuration = (PtrGetThemeTransitionDuration)themeLib.resolve("GetThemeTransitionDuration");
+        pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+    }
+    return pGetThemeTransitionDuration != 0;
+}
+
+/*
+ * We need to set the windows explorer theme explicitly on a native widget
+ * in order to get Vista-style item view themes
+ */
+QWidget *QWindowsVistaStylePrivate::treeViewHelper()
+{
+    if (!m_treeViewHelper) {
+        m_treeViewHelper = new QWidget(0);
+        pSetWindowTheme(m_treeViewHelper->winId(), L"explorer", NULL);
+    }
+    return m_treeViewHelper;
+}
+
+
+/*!
+\internal
+*/
+QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon,
+                                                  const QStyleOption *option,
+                                                  const QWidget *widget) const
+{
+    if (!QWindowsVistaStylePrivate::useVista()) {
+        return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+    }
+
+    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func());
+    switch(standardIcon) {
+    case SP_CommandLink:
+        {
+            XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
+            if (theme.isValid()) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                QIcon linkGlyph;
+                QPixmap pm = QPixmap(size.cx, size.cy);
+                pm.fill(Qt::transparent);
+                QPainter p(&pm);
+                theme.painter = &p;
+                theme.rect = QRect(0, 0, size.cx, size.cy);
+                d->drawBackground(theme);
+                linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off);    // Normal
+                pm.fill(Qt::transparent);
+
+                theme.stateId = CMDLGS_PRESSED;
+                d->drawBackground(theme);
+                linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On);     // Pressed
+                pm.fill(Qt::transparent);
+
+                theme.stateId = CMDLGS_HOT;
+                d->drawBackground(theme);
+                linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off);    // Hover
+                pm.fill(Qt::transparent);
+
+                theme.stateId = CMDLGS_DISABLED;
+                d->drawBackground(theme);
+                linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off);  // Disabled
+                return linkGlyph;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+    return QWindowsXPStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_WINDOWSVISTA