/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwindowsvistastyle_p.h"
#include "qwindowsvistastyle_p_p.h"
#include <qoperatingsystemversion.h>
#include <qscreen.h>
#include <qwindow.h>
#include <private/qstyleanimation_p.h>
#include <private/qstylehelper_p.h>
#include <qpa/qplatformnativeinterface.h>

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

/* \internal
    Checks if we should use Vista style , or if we should
    fall back to Windows style.
*/
bool QWindowsVistaStylePrivate::useVista()
{
    return QWindowsVistaStylePrivate::useXP();
}

/* \internal
    Checks and returns the style object
*/
inline QObject *styleObject(const QStyleOption *option) {
    return option ? option->styleObject : nullptr;
}

/* \internal
    Checks if we can animate on a style option
*/
bool canAnimate(const QStyleOption *option) {
    return option
            && option->styleObject
            && !option->styleObject->property("_q_no_animation").toBool();
}

static inline QImage createAnimationBuffer(const QStyleOption *option, const QWidget *widget)
{
    const int devicePixelRatio = widget ? widget->devicePixelRatio() : 1;
    QImage result(option->rect.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
    result.setDevicePixelRatio(devicePixelRatio);
    result.fill(0);
    return result;
}

/* \internal
    Used by animations to clone a styleoption and shift its offset
*/
QStyleOption *clonedAnimationStyleOption(const QStyleOption*option) {
    QStyleOption *styleOption = nullptr;
    if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option))
        styleOption = new QStyleOptionSlider(*slider);
    else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option))
        styleOption = new QStyleOptionSpinBox(*spinbox);
    else if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option))
        styleOption = new QStyleOptionGroupBox(*groupBox);
    else if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option))
        styleOption = new QStyleOptionComboBox(*combo);
    else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option))
        styleOption = new QStyleOptionButton(*button);
    else
        styleOption = new QStyleOption(*option);
    styleOption->rect = QRect(QPoint(0,0), option->rect.size());
    return styleOption;
}

/* \internal
    Used by animations to delete cloned styleoption
*/
void deleteClonedAnimationStyleOption(const QStyleOption *option)
{
    if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option))
        delete slider;
    else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option))
        delete spinbox;
    else if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option))
        delete groupBox;
    else if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option))
        delete combo;
    else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option))
        delete button;
    else
        delete option;
}

/*!
  \class QWindowsVistaStyle
  \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
  \since 4.3
  \ingroup appearance
  \inmodule QtWidgets
  \internal

  \warning This style is only available on the Windows Vista platform
  because it makes use of Windows Vista's style engine.

  \sa QMacStyle, QWindowsXPStyle, QFusionStyle
*/

/*!
  Constructs a QWindowsVistaStyle object.
*/
QWindowsVistaStyle::QWindowsVistaStyle()
    : QWindowsXPStyle(*new QWindowsVistaStylePrivate)
{
}

/*!
  Destructor.
*/
QWindowsVistaStyle::~QWindowsVistaStyle() = default;

//convert Qt state flags to uxtheme button states
static 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;
}

bool QWindowsVistaAnimation::isUpdateNeeded() const
{
    return QWindowsVistaStylePrivate::useVista();
}

void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option)
{
    painter->drawImage(option->rect, currentImage());
}

static inline bool supportsStateTransition(QStyle::PrimitiveElement element,
                                           const QStyleOption *option,
                                           const QWidget *widget)
{
    bool result = false;
    switch (element) {
    case QStyle::PE_IndicatorRadioButton:
    case QStyle::PE_IndicatorCheckBox:
        result = true;
        break;
    // QTBUG-40634, do not animate when color is set in palette for PE_PanelLineEdit.
    case QStyle::PE_FrameLineEdit:
        result = !QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget);
        break;
    default:
        break;
    }
    return result;
}

/*!
 \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;
    }

    if ((option->state & State_Enabled) && d->transitionsEnabled() && canAnimate(option)) {
        {
            QRect oldRect;
            QRect newRect;

            if (supportsStateTransition(element, option, widget)) {
                // Retrieve and update the dynamic properties tracking
                // the previous state of the widget:
                QObject *styleObject = option->styleObject;
                styleObject->setProperty("_q_no_animation", true);

                int oldState = styleObject->property("_q_stylestate").toInt();
                oldRect = styleObject->property("_q_stylerect").toRect();
                newRect = option->rect;
                styleObject->setProperty("_q_stylestate", int(option->state));
                styleObject->setProperty("_q_stylerect", option->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(styleObject);

                if (option->state & State_ReadOnly && element == PE_FrameLineEdit) // Do not animate read only line edits
                    doTransition = false;

                if (doTransition) {
                    QStyleOption *styleOption = clonedAnimationStyleOption(option);
                    styleOption->state = QStyle::State(oldState);

                    QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
                    QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);

                    // We create separate images for the initial and final transition states and store them in the
                    // Transition object.
                    QImage startImage = createAnimationBuffer(option, widget);
                    QPainter startPainter(&startImage);

                    QImage endImage = createAnimationBuffer(option, widget);
                    QPainter endPainter(&endImage);

                    // 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, styleOption, &startPainter, widget);
                    else
                        anim->paint(&startPainter, styleOption);

                    t->setStartImage(startImage);

                    // The end state of the transition is simply the result we would have painted
                    // if the style was not animated.
                    styleOption->styleObject = nullptr;
                    styleOption->state = option->state;
                    proxy()->drawPrimitive(element, styleOption, &endPainter, widget);


                    t->setEndImage(endImage);

                    HTHEME theme;
                    int partId;
                    DWORD duration;
                    int fromState = 0;
                    int toState = 0;

                    //translate state flags to UXTHEME states :
                    if (element == PE_FrameLineEdit) {
                        theme = OpenThemeData(nullptr, 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 = OpenThemeData(nullptr, 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
                        && SUCCEEDED(GetThemeTransitionDuration(theme, partId, fromState, toState,
                                                                TMT_TRANSITIONDURATIONS, &duration))) {
                        t->setDuration(int(duration));
                    }
                    t->setStartTime(QTime::currentTime());

                    deleteClonedAnimationStyleOption(styleOption);
                    d->startAnimation(t);
                }
                styleObject->setProperty("_q_no_animation", false);
            }

        } // 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,
                              QWindowsXPStylePrivate::HeaderTheme,
                              HP_HEADERSORTARROW, stateId, option->rect);
            d->drawBackground(theme);
        }
        break;

    case PE_IndicatorBranch:
        {
            XPThemeData theme(widget, painter, QWindowsXPStylePrivate::VistaTreeViewTheme);
            static int decoration_size = 0;
            if (!decoration_size && theme.isValid()) {
                XPThemeData themeSize = theme;
                themeSize.partId = TVP_HOTGLYPH;
                themeSize.stateId = GLPS_OPENED;
                const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
                decoration_size = qRound(qMax(size.width(), size.height()));
            }
            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 (QWindowsVistaAnimation *a =
                    qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))){
                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,
                              QWindowsXPStylePrivate::MenuTheme,
                              MENU_POPUPBORDERS, stateId, option->rect);
            d->drawBackground(theme);
        }
        break;
    case PE_Frame: {
#ifndef QT_NO_ACCESSIBILITY
        if (QStyleHelper::isInstanceOf(option->styleObject, QAccessible::EditableText)
                || QStyleHelper::isInstanceOf(option->styleObject, QAccessible::StaticText) ||
#else
        if (
#endif
            (widget && widget->inherits("QTextEdit"))) {
            painter->save();
            int stateId = ETS_NORMAL;
            if (!(state & State_Enabled))
                stateId = ETS_DISABLED;
            else if (state & State_ReadOnly)
                stateId = ETS_READONLY;
            else if (state & State_HasFocus)
                stateId = ETS_SELECTED;
            XPThemeData theme(widget, painter,
                              QWindowsXPStylePrivate::EditTheme,
                              EP_EDITBORDER_HVSCROLL, stateId, option->rect);
            // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
            int borderSize = 1;
            GetThemeInt(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 {
            QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
        }
    }
    break;

    case PE_PanelLineEdit:
        if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
            bool isEnabled = option->state & State_Enabled;
            if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) {
                painter->fillRect(panel->rect, panel->palette.brush(QPalette::Base));
            } 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(nullptr, painter, QWindowsXPStylePrivate::EditTheme,
                                  partId, stateId, rect);
                if (!theme.isValid()) {
                    QWindowsStyle::drawPrimitive(element, option, painter, widget);
                    return;
                }
                int bgType;
                GetThemeEnumValue(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;
                        GetThemePropertyOrigin(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;
                            GetThemeColor(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 (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))) {
            anim->paint(painter, option);
        } else {
            QPainter *p = painter;
            if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) {
                // 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;
            }
            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,
                              QWindowsXPStylePrivate::EditTheme,
                              EP_EDITBORDER_NOSCROLL, stateId, option->rect);
            theme.noContent = true;
            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,
                                    QWindowsXPStylePrivate::RebarTheme,
                                    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, QWindowsXPStylePrivate::RebarTheme,
                                    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.window().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,
                          QWindowsXPStylePrivate::ToolTipTheme,
                          TTP_STANDARD, TTSS_NORMAL, option->rect);
        d->drawBackground(theme);
        break;
    }

    case PE_PanelItemViewItem:
        {
            const QStyleOptionViewItem *vopt;
            bool newStyle = true;
            QAbstractItemView::SelectionBehavior selectionBehavior = QAbstractItemView::SelectRows;
            QAbstractItemView::SelectionMode selectionMode = QAbstractItemView::NoSelection;
            if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) {
                newStyle = !qobject_cast<const QTableView*>(view);
                selectionBehavior = view->selectionBehavior();
                selectionMode = view->selectionMode();
#ifndef QT_NO_ACCESSIBILITY
            } else if (!widget) {
                newStyle = !QStyleHelper::hasAncestor(option->styleObject, QAccessible::MenuItem) ;
#endif
            }

            if (newStyle && (vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option))) {
                bool selected = vopt->state & QStyle::State_Selected;
                const bool hover = selectionMode != QAbstractItemView::NoSelection && (vopt->state & QStyle::State_MouseOver);
                bool active = vopt->state & QStyle::State_Active;

                if (vopt->features & QStyleOptionViewItem::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 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 (selectionBehavior == QAbstractItemView::SelectRows)
                    sectionSize.setWidth(vopt->rect.width());
                QPixmap pixmap;

                if (vopt->backgroundBrush.style() != Qt::NoBrush) {
                    const QPointF oldBrushOrigin = painter->brushOrigin();
                    painter->setBrushOrigin(vopt->rect.topLeft());
                    painter->fillRect(vopt->rect, vopt->backgroundBrush);
                    painter->setBrushOrigin(oldBrushOrigin);
                }

                if (hover || selected) {
                    if (sectionSize.width() > 0 && sectionSize.height() > 0) {
                        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(widget, &pixmapPainter,
                                              QWindowsXPStylePrivate::VistaTreeViewTheme,
                                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 == QStyleOptionViewItem::Beginning;
                        bool rightSection = vopt->viewItemPosition == QStyleOptionViewItem::End;
                        if (vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne
                            || vopt->viewItemPosition == QStyleOptionViewItem::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 == QStyleOptionViewItem::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:
        {
#if QT_CONFIG(dialogbuttonbox)
            const QDialogButtonBox *buttonBox = nullptr;

            if (qobject_cast<const QMessageBox *> (widget))
                buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
#if QT_CONFIG(inputdialog)
            else if (qobject_cast<const QInputDialog *> (widget))
                buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
#endif // QT_CONFIG(inputdialog)

            if (buttonBox) {
                //draw white panel part
                XPThemeData theme(widget, painter,
                                  QWindowsXPStylePrivate::TaskDialogTheme,
                                  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);
            }
#endif
        }
        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;
    int themeNumber  = -1;

    QRect rect(option->rect);
    State flags = option->state;
    int partId = 0;
    int stateId = 0;

    if (d->transitionsEnabled() && canAnimate(option))
    {
        if (element == CE_PushButtonBevel) {
            QRect oldRect;
            QRect newRect;

            QObject *styleObject = option->styleObject;

            int oldState = styleObject->property("_q_stylestate").toInt();
            oldRect = styleObject->property("_q_stylerect").toRect();
            newRect = option->rect;
            styleObject->setProperty("_q_stylestate", int(option->state));
            styleObject->setProperty("_q_stylerect", option->rect);

            bool wasDefault = false;
            bool isDefault = false;
            if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
                wasDefault = styleObject->property("_q_isdefault").toBool();
                isDefault = button->features & QStyleOptionButton::DefaultButton;
                styleObject->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(styleObject);
            }

            if (doTransition) {
                styleObject->setProperty("_q_no_animation", true);

                QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
                QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
                QStyleOption *styleOption = clonedAnimationStyleOption(option);
                styleOption->state = QStyle::State(oldState);

                QImage startImage = createAnimationBuffer(option, widget);
                QPainter startPainter(&startImage);

                // Use current state of existing animation if already one is running
                if (!anim) {
                    proxy()->drawControl(element, styleOption, &startPainter, widget);
                } else {
                    anim->paint(&startPainter, styleOption);
                    d->stopAnimation(styleObject);
                }

                t->setStartImage(startImage);
                QImage endImage = createAnimationBuffer(option, widget);
                QPainter endPainter(&endImage);
                styleOption->state = option->state;
                proxy()->drawControl(element, styleOption, &endPainter, widget);
                t->setEndImage(endImage);


                DWORD duration = 0;
                const HTHEME theme = OpenThemeData(nullptr, L"Button");

                int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
                int toState = buttonStateId(option->state, BP_PUSHBUTTON);
                if (GetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
                    t->setDuration(int(duration));
                else
                    t->setDuration(0);
                t->setStartTime(QTime::currentTime());
                styleObject->setProperty("_q_no_animation", false);

                deleteClonedAnimationStyleOption(styleOption);
                d->startAnimation(t);
            }

            QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
            if (anim) {
                anim->paint(painter, option);
                return;
            }

        }
    }
    switch (element) {
    case CE_PushButtonBevel:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
        {
            themeNumber = QWindowsXPStylePrivate::ButtonTheme;
            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 (d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
                        !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
                        (state & State_Enabled) && (state & State_Active))
                {
                    QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)));

                    if (!anim) {
                        QImage startImage = createAnimationBuffer(option, widget);
                        QImage alternateImage = createAnimationBuffer(option, widget);

                        QWindowsVistaPulse *pulse = new QWindowsVistaPulse(styleObject(option));

                        QPainter startPainter(&startImage);
                        stateId = PBS_DEFAULTED;
                        XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect);
                        d->drawBackground(theme);

                        QPainter alternatePainter(&alternateImage);
                        theme.stateId = PBS_DEFAULTED_ANIMATING;
                        theme.painter = &alternatePainter;
                        d->drawBackground(theme);
                        pulse->setStartImage(startImage);
                        pulse->setEndImage(alternateImage);
                        pulse->setStartTime(QTime::currentTime());
                        pulse->setDuration(2000);
                        d->startAnimation(pulse);
                        anim = pulse;
                    }

                    if (anim)
                        anim->paint(painter, option);
                    else {
                        XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
                        d->drawBackground(theme);
                    }
                }
                else {
                    XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
                    d->drawBackground(theme);
                }
            }

            if (btn->features & QStyleOptionButton::HasMenu) {
                int mbiw = 0, mbih = 0;
                XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ToolBarTheme,
                                  TP_DROPDOWNBUTTON);
                if (theme.isValid()) {
                    const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1, option);
                    if (!size.isEmpty()) {
                        mbiw = qRound(size.width());
                        mbih = qRound(size.height());
                    }
                }
                QRect ir = subElementRect(SE_PushButtonContents, option, nullptr);
                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;

    case CE_ProgressBarContents:
        if (const QStyleOptionProgressBar *bar
                = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
            bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0);
            const bool vertical = bar->orientation == Qt::Vertical;
            const bool inverted = bar->invertedAppearance;

            if (isIndeterminate || (bar->progress > 0 && (bar->progress < bar->maximum) && d->transitionsEnabled())) {
                if (!d->animation(styleObject(option)))
                    d->startAnimation(new QProgressStyleAnimation(d->animationFps, styleObject(option)));
            } else {
                d->stopAnimation(styleObject(option));
            }

            XPThemeData theme(widget, painter,
                              QWindowsXPStylePrivate::ProgressTheme,
                              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 (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) {
                    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), animRect.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 (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) {
                    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(styleObject(option)); //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;

    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);

            int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
            if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
                alignment |= Qt::TextHideMnemonic;

            if (widget && mbi->palette.color(QPalette::Window) != Qt::transparent) { // Not needed for QtQuick Controls
                //The rect adjustment is a workaround for the menu not really filling its background.
                XPThemeData theme(widget, painter,
                                  QWindowsXPStylePrivate::MenuTheme,
                                  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,
                               QWindowsXPStylePrivate::MenuTheme,
                               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;
#if QT_CONFIG(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
            const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget);
            int checkcol = qRound(qreal(25) * factor);
            const int gutterWidth = qRound(qreal(3) * factor);
            {
                XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::MenuTheme,
                                  MENU_POPUPCHECKBACKGROUND, MBI_HOT);
                XPThemeData themeSize = theme;
                themeSize.partId = MENU_POPUPCHECK;
                themeSize.stateId = 0;
                const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
                const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
                checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right()));
            }
            QRect rect = option->rect;

            //draw vertical menu line
            if (option->direction == Qt::LeftToRight)
                checkcol += rect.x();
            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(), gutterWidth, p2.y() - p1.y() + 1);
            XPThemeData theme2(widget, painter, QWindowsXPStylePrivate::MenuTheme,
                               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;
                const int separatorSize = qRound(qreal(6) * QWindowsStylePrivate::nativeMetricScaleFactor(widget));
                QPoint p1 = QPoint(x + checkcol, yoff);
                QPoint p2 = QPoint(x + w + separatorSize, yoff);
                stateId = MBI_HOT;
                QRect subRect(p1.x() + (gutterWidth - menuitem->rect.x()), p1.y(),
                              p2.x() - p1.x(), separatorSize);
                subRect  = QStyle::visualRect(option->direction, option->rect, subRect );
                XPThemeData theme2(widget, painter,
                                   QWindowsXPStylePrivate::MenuTheme,
                                   MENU_POPUPSEPARATOR, stateId, subRect);
                d->drawBackground(theme2);
                return;
            }

            QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
                                          menuitem->rect.y(), checkcol - (gutterWidth + menuitem->rect.x()), menuitem->rect.height()));

            if (act) {
                stateId = dis ? MBI_DISABLED : MBI_HOT;
                XPThemeData theme2(widget, painter,
                                   QWindowsXPStylePrivate::MenuTheme,
                                   MENU_POPUPITEM, stateId, option->rect);
                d->drawBackground(theme2);
            }

            if (checked) {
                XPThemeData theme(widget, painter,
                                  QWindowsXPStylePrivate::MenuTheme,
                                  MENU_POPUPCHECKBACKGROUND,
                                  menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
                XPThemeData themeSize = theme;
                themeSize.partId = MENU_POPUPCHECK;
                themeSize.stateId = 0;
                const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
                const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
                QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()),
                                qRound(size.height() + margins.bottom() + margins.top()));
                checkRect.moveCenter(vCheckRect.center());
                theme.rect = checkRect;

                d->drawBackground(theme);

                if (menuitem->icon.isNull()) {
                    checkRect = QRect(QPoint(0, 0), size.toSize());
                    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);
                const int pixw = pixmap.width() / pixmap.devicePixelRatio();
                const int pixh = pixmap.height() / pixmap.devicePixelRatio();
                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());

            const QColor textColor = menuitem->palette.text().color();
            if (dis)
                painter->setPen(textColor);

            int xm = windowsItemFrame + checkcol + windowsItemHMargin + (gutterWidth - menuitem->rect.x()) - 1;
            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(textColor);
                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_CONFIG(menu)
    case CE_HeaderSection:
        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
            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,
                              QWindowsXPStylePrivate::HeaderTheme,
                              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,
                              QWindowsXPStylePrivate::MenuTheme,
                              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.window().color().darker(130));
            QStyleOptionToolBar copyOpt = *toolbar;
            copyOpt.palette = pal;
            QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
        }
        break;
    case CE_DockWidgetTitle:
        if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
            const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget);
            QRect rect = option->rect;
            if (dockWidget && dockWidget->isFloating()) {
                QWindowsXPStyle::drawControl(element, option, painter, widget);
                break; //otherwise fall through
            }

            const bool verticalTitleBar = dwOpt->verticalTitleBar;

            if (verticalTitleBar) {
                rect = rect.transposed();

                painter->translate(rect.left() - 1, rect.top() + rect.width());
                painter->rotate(-90);
                painter->translate(-rect.left() + 1, -rect.top());
            }

            painter->setBrush(option->palette.window().color().darker(110));
            painter->setPen(option->palette.window().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 && dw->isFloating();

            QRect r = option->rect.adjusted(0, 2, -1, -3);
            QRect titleRect = r;

            if (dwOpt->closable) {
                QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
                titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
            }

            if (dwOpt->floatable) {
                QSize sz = proxy()->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 && 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 = 4;
                drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1),
                                Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic,
                                dwOpt->palette,
                                dwOpt->state & State_Enabled, titleText,
                                QPalette::WindowText);
                }
            }
            break;
#if QT_CONFIG(itemviews)
    case CE_ItemViewItem:
        {
            const QStyleOptionViewItem *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 QStyleOptionViewItem *>(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 = GetThemeColor(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));
                QStyleOptionViewItem 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_CONFIG(itemviews)
#if QT_CONFIG(combobox)
    case CE_ComboBoxLabel:
        QCommonStyle::drawControl(element, option, painter, widget);
        break;
#endif // QT_CONFIG(combobox)
    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() && canAnimate(option))
    {

        if (control == CC_ScrollBar || control == CC_SpinBox || control == CC_ComboBox) {

            QObject *styleObject = option->styleObject; // Can be widget or qquickitem

            int oldState = styleObject->property("_q_stylestate").toInt();
            int oldActiveControls = styleObject->property("_q_stylecontrols").toInt();

            QRect oldRect = styleObject->property("_q_stylerect").toRect();
            styleObject->setProperty("_q_stylestate", int(option->state));
            styleObject->setProperty("_q_stylecontrols", int(option->activeSubControls));
            styleObject->setProperty("_q_stylerect", option->rect);

            bool doTransition = ((state & State_Sunken)     != (oldState & State_Sunken)    ||
                                 (state & State_On)         != (oldState & State_On)        ||
                                 (state & State_MouseOver)  != (oldState & State_MouseOver) ||
                                  oldActiveControls         != int(option->activeSubControls));

            if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
                QRect oldSliderPos = styleObject->property("_q_stylesliderpos").toRect();
                QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
                styleObject->setProperty("_q_stylesliderpos", currentPos);
                if (oldSliderPos != currentPos) {
                    doTransition = false;
                    d->stopAnimation(styleObject);
                }
            } 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(styleObject);
            }

            if (doTransition) {
                QImage startImage = createAnimationBuffer(option, widget);
                QPainter startPainter(&startImage);

                QImage endImage = createAnimationBuffer(option, widget);
                QPainter endPainter(&endImage);

                QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
                QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);

                // Draw the image that ends the animation by using the current styleoption
                QStyleOptionComplex *styleOption = qstyleoption_cast<QStyleOptionComplex*>(clonedAnimationStyleOption(option));

                styleObject->setProperty("_q_no_animation", true);

                // Draw transition source
                if (!anim) {
                    styleOption->state = QStyle::State(oldState);
                    styleOption->activeSubControls = QStyle::SubControl(oldActiveControls);
                    proxy()->drawComplexControl(control, styleOption, &startPainter, widget);
                } else {
                    anim->paint(&startPainter, option);
                }
                t->setStartImage(startImage);

                // Draw transition target
                styleOption->state = option->state;
                styleOption->activeSubControls = option->activeSubControls;
                proxy()->drawComplexControl(control, styleOption, &endPainter, widget);

                styleObject->setProperty("_q_no_animation", false);

                t->setEndImage(endImage);
                t->setStartTime(QTime::currentTime());

                if (option->state & State_MouseOver || option->state & State_Sunken)
                    t->setDuration(150);
                else
                    t->setDuration(500);

                deleteClonedAnimationStyleOption(styleOption);
                d->startAnimation(t);
            }
            if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject))) {
                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,
                                      QWindowsXPStylePrivate::EditTheme,
                                      partId, stateId, r);

                    d->drawBackground(theme);
                }
                if (sub & SC_ComboBoxArrow) {
                    QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
                    XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
                    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) {
                    XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
                    theme.rect = option->rect;
                    theme.partId = CP_READONLY;
                    if (!(cmb->state & State_Enabled))
                        theme.stateId = CBXS_DISABLED;
                    else if (cmb->state & State_Sunken || cmb->state & State_On)
                        theme.stateId = CBXS_PRESSED;
                    else if (cmb->state & State_MouseOver)
                        theme.stateId = CBXS_HOT;
                    else
                        theme.stateId = CBXS_NORMAL;
                    d->drawBackground(theme);
                }
                if (sub & SC_ComboBoxArrow) {
                    XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
                    theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
                    theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
                    if (!(cmb->state & State_Enabled))
                        theme.stateId = CBXS_DISABLED;
                    else
                        theme.stateId = CBXS_NORMAL;
                    d->drawBackground(theme);
                }
                if ((sub & SC_ComboBoxEditField) && (flags & State_HasFocus)) {
                    QStyleOptionFocusRect fropt;
                    fropt.QStyleOption::operator=(*cmb);
                    fropt.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
                    proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
                }
            }
        }
        break;
    case CC_ScrollBar:
        if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
        {
            XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ScrollBarTheme);
            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.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
                    theme.stateId = stateId;
                    d->drawBackground(theme);

                    if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) {
                        const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, widget, &theme);
                        // 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;
#if QT_CONFIG(spinbox)
    case CC_SpinBox:
        if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
        {
            XPThemeData theme(widget, painter, QWindowsXPStylePrivate::SpinTheme);
            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,
                                   QWindowsXPStylePrivate::EditTheme,
                                   partId, stateId, r);
                // The spinbox in Windows QStyle is drawn with frameless QLineEdit inside it
                // That however breaks with QtQuickControls where this results in transparent
                // spinbox background, so if there's no "widget" passed (QtQuickControls case),
                // let ftheme.noContent be false, which fixes the spinbox rendering in QQC
                ftheme.noContent = (widget != nullptr);
                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_CONFIG(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);
    switch (type) {
    case CT_MenuItem:
        sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
        int minimumHeight;
        {
            XPThemeData theme(widget, nullptr,
                              QWindowsXPStylePrivate::MenuTheme,
                              MENU_POPUPCHECKBACKGROUND, MBI_HOT);
            XPThemeData themeSize = theme;
            themeSize.partId = MENU_POPUPCHECK;
            themeSize.stateId = 0;
            const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
            const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
            minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height());
            sz.rwidth() += qRound(size.width() + margins.left() + margins.right());
        }

        if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
            if (menuitem->menuItemType != QStyleOptionMenuItem::Separator)
                sz.setHeight(minimumHeight);
        }
        return sz;
#if QT_CONFIG(menubar)
    case CT_MenuBarItem:
        if (!sz.isEmpty())
            sz += QSize(windowsItemHMargin * 5 + 1, 5);
        return sz;
#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;
    case CT_HeaderSection:
        {
            // When there is a sort indicator it adds to the width but it is shown
            // above the text natively and not on the side
            if (QStyleOptionHeader *hdr = qstyleoption_cast<QStyleOptionHeader *>(const_cast<QStyleOption *>(option))) {
                QStyleOptionHeader::SortIndicator sortInd = hdr->sortIndicator;
                hdr->sortIndicator = QStyleOptionHeader::None;
                sz = QWindowsXPStyle::sizeFromContents(type, hdr, size, widget);
                hdr->sortIndicator = sortInd;
                return sz;
            }
            break;
        }
    default:
        break;
    }
    return QWindowsXPStyle::sizeFromContents(type, option, size, widget);
}

/*!
 \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;
            const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, 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);

                if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) {
                    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, nullptr,
                              QWindowsXPStylePrivate::HeaderTheme,
                              HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);

            int arrowWidth = 13;
            int arrowHeight = 5;
            if (theme.isValid()) {
                const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
                if (!size.isEmpty()) {
                    arrowWidth = qRound(size.width());
                    arrowHeight = qRound(size.height());
                }
            }
            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 QStyleOptionViewItem *>(option))
            rect.adjust(-2, 0, 2, 0);
        break;
    case SE_ItemViewItemFocusRect:
        if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(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 auto 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, nullptr,
                                      QWindowsXPStylePrivate::ToolTipTheme,
                                      TTP_STANDARD, TTSS_NORMAL, option->rect);
                mask->region = d->region(themeData);
            }
        }
        break;
     case SH_Table_GridLineColor:
        if (option)
            ret = int(option->palette.color(QPalette::Base).darker(118).rgb());
        else
            ret = -1;
        break;
    case SH_Header_ArrowAlignment:
        ret = Qt::AlignTop | Qt::AlignHCenter;
        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) {
#if QT_CONFIG(combobox)
    case CC_ComboBox:
        if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
            const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height();
            const int margin = cb->frame ? 3 : 0;
            const int bmarg = cb->frame ? 2 : 0;
            const int arrowWidth = qRound(QStyleHelper::dpiScaled(16, option));
            const int arrowButtonWidth = bmarg + arrowWidth;
            const int xpos = x + wi - arrowButtonWidth;

            switch (subControl) {
            case SC_ComboBoxFrame:
                rect = cb->rect;
                break;
            case SC_ComboBoxArrow:
                rect.setRect(xpos, y , arrowButtonWidth, he);
                break;
            case SC_ComboBoxEditField:
                rect.setRect(x + margin, y + margin, wi - 2 * margin - arrowWidth, he - 2 * margin);
                break;
            case SC_ComboBoxListBoxPopup:
                rect = cb->rect;
                break;
            default:
                break;
            }
            rect = visualRect(cb->direction, cb->rect, rect);
            return rect;
        }
        break;
#endif // QT_CONFIG(combobox)
    case CC_TitleBar:
        if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
            if (!buttonVisible(subControl, tb))
                return rect;
            const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget);
            const bool isToolTitle = false;
            const int height = tb->rect.height();
            const int width = tb->rect.width();
            const int buttonWidth =
                qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4, option));

            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, int(-buttonWidth - 3 * factor), 0);
                    }
                    if (minimizeHint || maximizeHint)
                        rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
                } else {
                    if (sysmenuHint) {
                        const int leftOffset = int(height - 8 * factor);
                        rect.adjust(leftOffset, 0, 0, int(4 * factor));
                    }
                    if (minimizeHint)
                        rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
                    if (maximizeHint)
                        rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
                    if (contextHint)
                        rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
                    if (shadeHint)
                        rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
                }
                rect.translate(0, int(2 * factor));
                rect = visualRect(option->direction, option->rect, rect);
                break;
            case SC_TitleBarSysMenu:
                {
                    const int controlTop = int(6 * factor);
                    const int controlHeight = int(height - controlTop - 3 * factor);
                    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, int(3 * factor));
                    rect = visualRect(option->direction, option->rect, rect);
                }
                break;
            default:
                break;
            }
        }
        break;
    default:
        break;
    }
    return rect;
}

/*!
 \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);
}

int QWindowsVistaStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
{
    switch (pm) {
    case QStyle::PM_DockWidgetTitleBarButtonMargin:
        return 5;
    case QStyle::PM_ScrollBarSliderMin:
        return 18;
    case QStyle::PM_MenuHMargin:
    case QStyle::PM_MenuVMargin:
        return 0;
    case QStyle::PM_MenuPanelWidth:
        return 3;
    default:
        break;
    }
    return QWindowsVistaStylePrivate::InvalidMetric;
}

/*!
 \internal
 */
int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
{
    if (!QWindowsVistaStylePrivate::useVista())
        return QWindowsStyle::pixelMetric(metric, option, widget);

    int ret = QWindowsVistaStylePrivate::fixedPixelMetric(metric);
    if (ret != QWindowsStylePrivate::InvalidMetric)
        return int(QStyleHelper::dpiScaled(ret, option));

    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);
#if QT_CONFIG(lineedit)
    if (qobject_cast<QLineEdit*>(widget))
        widget->setAttribute(Qt::WA_Hover);
    else
#endif // QT_CONFIG(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 = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"TOOLTIP");
        if (theme && SUCCEEDED(GetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef))) {
            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);
#if QT_CONFIG(dialogbuttonbox)
        QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
        if (buttonBox)
            buttonBox->setContentsMargins(0, 9, 0, 0);
#endif
    }
#if QT_CONFIG(inputdialog)
    else if (qobject_cast<QInputDialog *> (widget)) {
        widget->setAttribute(Qt::WA_StyledBackground);
#if QT_CONFIG(dialogbuttonbox)
        QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
        if (buttonBox)
            buttonBox->setContentsMargins(0, 9, 0, 0);
#endif
    }
#endif // QT_CONFIG(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 = d_func();

    d->stopAnimation(widget);

#if QT_CONFIG(lineedit)
    if (qobject_cast<QLineEdit*>(widget))
        widget->setAttribute(Qt::WA_Hover, false);
    else
#endif // QT_CONFIG(lineedit)
    if (qobject_cast<QGroupBox*>(widget))
        widget->setAttribute(Qt::WA_Hover, false);
    else if (qobject_cast<QMessageBox *> (widget)) {
        widget->setAttribute(Qt::WA_StyledBackground, false);
#if QT_CONFIG(dialogbuttonbox)
        QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
        if (buttonBox)
            buttonBox->setContentsMargins(0, 0, 0, 0);
#endif
    }
#if QT_CONFIG(inputdialog)
    else if (qobject_cast<QInputDialog *> (widget)) {
        widget->setAttribute(Qt::WA_StyledBackground, false);
#if QT_CONFIG(dialogbuttonbox)
        QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
        if (buttonBox)
            buttonBox->setContentsMargins(0, 0, 0, 0);
#endif
    }
#endif // QT_CONFIG(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()
{
}

bool QWindowsVistaStylePrivate::transitionsEnabled() const
{
    BOOL animEnabled = false;
    if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0))
    {
        if (animEnabled)
            return true;
    }
    return false;
}

/*!
\reimp
*/
QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon,
                                       const QStyleOption *option,
                                       const QWidget *widget) const
{
    if (!QWindowsVistaStylePrivate::useVista()) {
        return QWindowsStyle::standardIcon(standardIcon, option, widget);
    }

    QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func());
    switch(standardIcon) {
    case SP_CommandLink:
        {
            XPThemeData theme(nullptr, nullptr,
                              QWindowsXPStylePrivate::ButtonTheme,
                              BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
            if (theme.isValid()) {
                const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
                QIcon linkGlyph;
                QPixmap pm(size);
                pm.fill(Qt::transparent);
                QPainter p(&pm);
                theme.painter = &p;
                theme.rect = QRect(QPoint(0, 0), size);
                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::standardIcon(standardIcon, option, widget);
}

QT_END_NAMESPACE
