src/gui/styles/qwindowsxpstyle.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/styles/qwindowsxpstyle.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,4232 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qwindowsxpstyle.h"
+#include "qwindowsxpstyle_p.h"
+
+#if !defined(QT_NO_STYLE_WINDOWSXP) || defined(QT_PLUGIN)
+
+#include <private/qobject_p.h>
+#include <private/qpaintengine_raster_p.h>
+#include <private/qapplication_p.h>
+#include <private/qstylehelper_p.h>
+#include <qlibrary.h>
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <qwidget.h>
+#include <qapplication.h>
+#include <qpixmapcache.h>
+
+#include <qdesktopwidget.h>
+#include <qtoolbutton.h>
+#include <qtabbar.h>
+#include <qcombobox.h>
+#include <qscrollbar.h>
+#include <qheaderview.h>
+#include <qspinbox.h>
+#include <qlistview.h>
+#include <qstackedwidget.h>
+#include <qpushbutton.h>
+#include <qtoolbar.h>
+#include <qlabel.h>
+#include <qvarlengtharray.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+// Runtime resolved theme engine function calls
+typedef bool (WINAPI *PtrIsAppThemed)();
+typedef bool (WINAPI *PtrIsThemeActive)();
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+typedef HRESULT (WINAPI *PtrGetThemeDocumentationProperty)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, OUT LPWSTR pszValueBuff, int cchMaxValChars);
+typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
+typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
+typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
+typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
+typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
+typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
+typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeBackgroundRegion)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pRect, OUT HRGN *pRegion);
+typedef BOOL (WINAPI *PtrIsThemeBackgroundPartiallyTransparent)(HTHEME hTheme, int iPartId, int iStateId);
+
+static PtrIsAppThemed pIsAppThemed = 0;
+static PtrIsThemeActive pIsThemeActive = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+static PtrGetThemeBool pGetThemeBool = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
+static PtrGetThemeFilename pGetThemeFilename = 0;
+static PtrGetThemeFont pGetThemeFont = 0;
+static PtrGetThemeInt pGetThemeInt = 0;
+static PtrGetThemeIntList pGetThemeIntList = 0;
+static PtrGetThemeMargins pGetThemeMargins = 0;
+static PtrGetThemeMetric pGetThemeMetric = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemePosition pGetThemePosition = 0;
+static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
+static PtrGetThemeRect pGetThemeRect = 0;
+static PtrGetThemeString pGetThemeString = 0;
+static PtrGetThemeBackgroundRegion pGetThemeBackgroundRegion = 0;
+static PtrGetThemeDocumentationProperty pGetThemeDocumentationProperty = 0;
+static PtrIsThemeBackgroundPartiallyTransparent pIsThemeBackgroundPartiallyTransparent = 0;
+
+// General const values
+static const int windowsItemFrame        =  2; // menu item frame width
+static const int windowsItemHMargin      =  3; // menu item hor text margin
+static const int windowsItemVMargin      =  0; // menu item ver text margin
+static const int windowsArrowHMargin     =  6; // arrow horizontal margin
+static const int windowsRightBorder      = 12; // right border on windows
+
+// External function calls
+extern Q_GUI_EXPORT HDC qt_win_display_dc();
+extern QRegion qt_region_from_HRGN(HRGN rgn);
+
+
+
+// Theme data helper ------------------------------------------------------------------------------
+/* \internal
+    Returns true if the themedata is valid for use.
+*/
+bool XPThemeData::isValid()
+{
+    return QWindowsXPStylePrivate::useXP() && name.size() && handle();
+}
+
+
+/* \internal
+    Returns the theme engine handle to the specific class.
+    If the handle hasn't been opened before, it opens the data, and
+    adds it to a static map, for caching.
+*/
+HTHEME XPThemeData::handle()
+{
+    if (!QWindowsXPStylePrivate::useXP())
+        return 0;
+
+    if (!htheme && QWindowsXPStylePrivate::handleMap)
+        htheme = QWindowsXPStylePrivate::handleMap->operator[](name);
+
+    if (!htheme) {
+        htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16());
+        if (htheme) {
+            if (!QWindowsXPStylePrivate::handleMap)
+                QWindowsXPStylePrivate::handleMap = new QMap<QString, HTHEME>;
+            QWindowsXPStylePrivate::handleMap->operator[](name) = htheme;
+        }
+    }
+
+    return htheme;
+}
+
+/* \internal
+    Converts a QRect to the native RECT structure.
+*/
+RECT XPThemeData::toRECT(const QRect &qr)
+{
+    RECT r;
+    r.left = qr.x();
+    r.right = qr.x() + qr.width();
+    r.top = qr.y();
+    r.bottom = qr.y() + qr.height();
+    return r;
+}
+
+/* \internal
+    Returns the native region of a part, if the part is considered
+    transparent. The region is scaled to the parts size (rect).
+*/
+HRGN XPThemeData::mask()
+{
+    if (!pIsThemeBackgroundPartiallyTransparent(handle(), partId, stateId))
+        return 0;
+
+    HRGN hrgn;
+    HDC dc = painter == 0 ? 0 : painter->paintEngine()->getDC();
+    RECT nativeRect = toRECT(rect);
+    pGetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn);
+    if (dc)
+        painter->paintEngine()->releaseDC(dc);
+    return hrgn;
+}
+
+// QWindowsXPStylePrivate -------------------------------------------------------------------------
+// Static initializations
+QWidget *QWindowsXPStylePrivate::limboWidget = 0;
+QPixmap *QWindowsXPStylePrivate::tabbody = 0;
+QMap<QString,HTHEME> *QWindowsXPStylePrivate::handleMap = 0;
+bool QWindowsXPStylePrivate::use_xp = false;
+QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
+
+/* \internal
+    Checks if the theme engine can/should be used, or if we should
+    fall back to Windows style.
+*/
+bool QWindowsXPStylePrivate::useXP(bool update)
+{
+    if (!update)
+        return use_xp;
+    return (use_xp = resolveSymbols() && pIsThemeActive()
+            && (pIsAppThemed() || !QApplication::instance()));
+}
+
+/* \internal
+    Handles refcounting, and queries the theme engine for usage.
+*/
+void QWindowsXPStylePrivate::init(bool force)
+{
+    if (ref.ref() && !force)
+        return;
+    if (!force) // -1 based atomic refcounting
+        ref.ref();
+
+    useXP(true);
+}
+
+/* \internal
+    Cleans up all static data.
+*/
+void QWindowsXPStylePrivate::cleanup(bool force)
+{
+    if(bufferBitmap) {
+        if (bufferDC && nullBitmap)
+            SelectObject(bufferDC, nullBitmap);
+        DeleteObject(bufferBitmap);
+        bufferBitmap = 0;
+    }
+
+    if(bufferDC)
+        DeleteDC(bufferDC);
+    bufferDC = 0;
+
+    if (ref.deref() && !force)
+        return;
+    if (!force)  // -1 based atomic refcounting
+        ref.deref();
+
+    use_xp = false;
+    cleanupHandleMap();
+    if (limboWidget) {
+        if (QApplication::closingDown())
+            delete limboWidget;
+        else
+            limboWidget->deleteLater();
+    }
+    delete tabbody;
+    limboWidget = 0;
+    tabbody = 0;
+}
+
+/* \internal
+    Closes all open theme data handles to ensure that we don't leak
+    resources, and that we don't refere to old handles when for
+    example the user changes the theme style.
+*/
+void QWindowsXPStylePrivate::cleanupHandleMap()
+{
+    if (!handleMap)
+        return;
+
+    QMap<QString, HTHEME>::Iterator it;
+    for (it = handleMap->begin(); it != handleMap->end(); ++it)
+        pCloseThemeData(it.value());
+    delete handleMap;
+    handleMap = 0;
+}
+
+/*! \internal
+    This function will always return a valid window handle, and might
+    create a limbo widget to do so.
+    We often need a window handle to for example open theme data, so
+    this function ensures that we get one.
+*/
+HWND QWindowsXPStylePrivate::winId(const QWidget *widget)
+{
+    if (widget && widget->internalWinId())
+        return widget->internalWinId();
+
+    if (!limboWidget) {
+        limboWidget = new QWidget(0);
+        limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
+    }
+
+    return limboWidget->winId();
+}
+
+/*! \internal
+    Returns the pointer to a tab widgets body pixmap, scaled to the
+    height of the screen. This way the theme engine doesn't need to
+    scale the body for every time we ask for it. (Speed optimization)
+*/
+const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *)
+{
+    if (!tabbody) {
+        SIZE sz;
+        XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY);
+        pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
+
+        tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
+        QPainter painter(tabbody);
+        theme.rect = QRect(0, 0, sz.cx, sz.cy);
+        drawBackground(theme);
+        // We fill with the last line of the themedata, that
+        // way we don't get a tiled pixmap inside big tabs
+        QPixmap temp(sz.cx, 1);
+        painter.drawPixmap(0, 0, temp, 0, sz.cy-1, -1, -1);
+        painter.drawTiledPixmap(0, sz.cy, sz.cx, tabbody->height()-sz.cy, temp);
+    }
+    return tabbody;
+}
+
+/*! \internal
+    Returns true if all the necessary theme engine symbols were
+    resolved.
+*/
+bool QWindowsXPStylePrivate::resolveSymbols()
+{
+    static bool tried = false;
+    if (!tried) {
+        tried = true;
+        QLibrary themeLib(QLatin1String("uxtheme"));
+        pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
+        if (pIsAppThemed) {
+            pIsThemeActive          = (PtrIsThemeActive         )themeLib.resolve("IsThemeActive");
+            pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
+            pOpenThemeData          = (PtrOpenThemeData         )themeLib.resolve("OpenThemeData");
+            pCloseThemeData         = (PtrCloseThemeData        )themeLib.resolve("CloseThemeData");
+            pDrawThemeBackground    = (PtrDrawThemeBackground   )themeLib.resolve("DrawThemeBackground");
+            pDrawThemeBackgroundEx  = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
+            pGetCurrentThemeName    = (PtrGetCurrentThemeName   )themeLib.resolve("GetCurrentThemeName");
+            pGetThemeBool           = (PtrGetThemeBool          )themeLib.resolve("GetThemeBool");
+            pGetThemeColor          = (PtrGetThemeColor         )themeLib.resolve("GetThemeColor");
+            pGetThemeEnumValue      = (PtrGetThemeEnumValue     )themeLib.resolve("GetThemeEnumValue");
+            pGetThemeFilename       = (PtrGetThemeFilename      )themeLib.resolve("GetThemeFilename");
+            pGetThemeFont           = (PtrGetThemeFont          )themeLib.resolve("GetThemeFont");
+            pGetThemeInt            = (PtrGetThemeInt           )themeLib.resolve("GetThemeInt");
+            pGetThemeIntList        = (PtrGetThemeIntList       )themeLib.resolve("GetThemeIntList");
+            pGetThemeMargins        = (PtrGetThemeMargins       )themeLib.resolve("GetThemeMargins");
+            pGetThemeMetric         = (PtrGetThemeMetric        )themeLib.resolve("GetThemeMetric");
+            pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
+            pGetThemePosition       = (PtrGetThemePosition      )themeLib.resolve("GetThemePosition");
+            pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+            pGetThemeRect           = (PtrGetThemeRect          )themeLib.resolve("GetThemeRect");
+            pGetThemeString         = (PtrGetThemeString        )themeLib.resolve("GetThemeString");
+            pGetThemeBackgroundRegion              = (PtrGetThemeBackgroundRegion             )themeLib.resolve("GetThemeBackgroundRegion");
+            pGetThemeDocumentationProperty         = (PtrGetThemeDocumentationProperty        )themeLib.resolve("GetThemeDocumentationProperty");
+            pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
+        }
+    }
+
+    return pIsAppThemed != 0;
+}
+
+/*! \internal
+    Returns a native buffer (DIB section) of at least the size of
+    ( \a x , \a y ). The buffer has a 32 bit depth, to not lose
+    the alpha values on proper alpha-pixmaps.
+*/
+HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
+{
+    // If we already have a HBITMAP which is of adequate size, just return that
+    if (bufferBitmap) {
+        if (bufferW >= w && bufferH >= h)
+            return bufferBitmap;
+        // Not big enough, discard the old one
+        if (bufferDC && nullBitmap)
+            SelectObject(bufferDC, nullBitmap);
+        DeleteObject(bufferBitmap);
+        bufferBitmap = 0;
+    }
+
+    w = qMax(bufferW, w);
+    h = qMax(bufferH, h);
+
+    if (!bufferDC)
+        bufferDC = CreateCompatibleDC(qt_win_display_dc());
+
+    // Define the header
+    BITMAPINFO bmi;
+    memset(&bmi, 0, sizeof(bmi));
+    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
+    bmi.bmiHeader.biWidth       = w;
+    bmi.bmiHeader.biHeight      = -h;
+    bmi.bmiHeader.biPlanes      = 1;
+    bmi.bmiHeader.biBitCount    = 32;
+    bmi.bmiHeader.biCompression = BI_RGB;
+
+    // Create the pixmap
+    bufferPixels = 0;
+    bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
+    GdiFlush();
+    nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
+
+    if (!bufferBitmap) {
+        qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection");
+        bufferW = 0;
+        bufferH = 0;
+        return 0;
+    }
+    if (!bufferPixels) {
+        qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data");
+        bufferW = 0;
+        bufferH = 0;
+        return 0;
+    }
+    bufferW = w;
+    bufferH = h;
+#ifdef DEBUG_XP_STYLE
+    qDebug("Creating new dib section (%d, %d)", w, h);
+#endif
+    return bufferBitmap;
+}
+
+/*! \internal
+    Returns true if the part contains any transparency at all. This does
+    not indicate what kind of transparency we're dealing with. It can be
+        - Alpha transparency
+        - Masked transparency
+*/
+bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
+{
+    return pIsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId,
+                                                  themeData.stateId);
+}
+
+
+/*! \internal
+    Returns a QRegion of the region of the part
+*/
+QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
+{
+    HRGN hRgn = 0;
+    RECT rect = themeData.toRECT(themeData.rect);
+    if (!SUCCEEDED(pGetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
+                                             themeData.stateId, &rect, &hRgn)))
+        return QRegion();
+
+    HRGN dest = CreateRectRgn(0, 0, 0, 0);
+    const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
+
+    QRegion region;
+
+    if (success)
+        region = qt_region_from_HRGN(dest);
+
+    DeleteObject(hRgn);
+    DeleteObject(dest);
+
+    return region;
+}
+
+/*! \internal
+    Sets the parts region on a window.
+*/
+void QWindowsXPStylePrivate::setTransparency(QWidget *widget, XPThemeData &themeData)
+{
+    HRGN hrgn = themeData.mask();
+    if (hrgn && widget)
+        SetWindowRgn(winId(widget), hrgn, true);
+}
+
+/*! \internal
+    Returns true if the native doublebuffer contains a pixel which
+    has a non-0xFF alpha value. Should only be use when its
+    guaranteed that data painted into the buffer wasn't a proper
+    alpha pixmap.
+*/
+bool QWindowsXPStylePrivate::hasAnyData(const QRect &rect)
+{
+    const int startX = rect.left();
+    const int startY = rect.top();
+    const int w = rect.width();
+    const int h = rect.height();
+
+    for (int y = startY; y < h; ++y) {
+        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+        for (int x = startX; x < w; ++x, ++buffer) {
+            int alpha = (*buffer) >> 24;
+            if (alpha != 0xFF) // buffer has been touched
+                return true;
+        }
+    }
+    return false;
+}
+
+/*! \internal
+    Returns true if the native doublebuffer contains pixels with
+    varying alpha value.
+*/
+bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect)
+{
+    const int startX = rect.left();
+    const int startY = rect.top();
+    const int w = rect.width();
+    const int h = rect.height();
+
+    int firstAlpha = -1;
+    for (int y = startY; y < h/2; ++y) {
+        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+        for (int x = startX; x < w; ++x, ++buffer) {
+            int alpha = (*buffer) >> 24;
+            if (firstAlpha == -1)
+                firstAlpha = alpha;
+            else if (alpha != firstAlpha)
+                return true;
+        }
+    }
+    return false;
+}
+
+/*! \internal
+    When the theme engine paints both a true alpha pixmap and a glyph
+    into our buffer, the glyph might not contain a proper alpha value.
+    The rule of thumb for premultiplied pixmaps is that the color
+    values of a pixel can never be higher than the alpha values, so
+    we use this to our advantage here, and fix all instances where
+    this occures.
+*/
+bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect)
+{
+    const int startX = rect.left();
+    const int startY = rect.top();
+    const int w = rect.width();
+    const int h = rect.height();
+    bool hasFixedAlphaValue = false;
+
+    for (int y = startY; y < h; ++y) {
+        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+        for (register int x = startX; x < w; ++x, ++buffer) {
+            uint pixel = *buffer;
+            int alpha = qAlpha(pixel);
+            if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {
+                *buffer |= 0xff000000;
+                hasFixedAlphaValue = true;
+            }
+        }
+    }
+    return hasFixedAlphaValue;
+}
+
+/*! \internal
+    Swaps the alpha values on certain pixels:
+        0xFF?????? -> 0x00??????
+        0x00?????? -> 0xFF??????
+    Used to determin the mask of a non-alpha transparent pixmap in
+    the native doublebuffer, and swap the alphas so we may paint
+    the image as a Premultiplied QImage with drawImage(), and obtain
+    the mask transparency.
+*/
+bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
+{
+    const int startX = rect.left();
+    const int startY = rect.top();
+    const int w = rect.width();
+    const int h = rect.height();
+    bool valueChange = false;
+
+    // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
+    for (int y = startY; y < h; ++y) {
+        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+        for (register int x = startX; x < w; ++x, ++buffer) {
+            if (allPixels) {
+                *buffer |= 0xFF000000;
+                continue;
+            }
+            register unsigned int alphaValue = (*buffer) & 0xFF000000;
+            if (alphaValue == 0xFF000000) {
+                *buffer = 0;
+                valueChange = true;
+            } else if (alphaValue == 0) {
+                *buffer |= 0xFF000000;
+                valueChange = true;
+            }
+        }
+    }
+    return valueChange;
+}
+
+/*! \internal
+    Main theme drawing function.
+    Determines the correct lowlevel drawing method depending on several
+    factors.
+        Use drawBackgroundThruNativeBuffer() if:
+            - Painter does not have an HDC
+            - Theme part is flipped (mirrored horizontally)
+        else use drawBackgroundDirectly().
+*/
+void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
+{
+    if (themeData.rect.isEmpty())
+        return;
+
+    QPainter *painter = themeData.painter;
+    Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
+    if (!painter || !painter->isActive())
+        return;
+
+    painter->save();
+
+    QMatrix m = painter->matrix();
+    bool complexXForm = m.m11() != 1.0 || m.m22() != 1.0 || m.m12() != 0.0 || m.m21() != 0.0;
+
+    bool translucentToplevel = false;
+    QPaintDevice *pdev = painter->device();
+    if (pdev->devType() == QInternal::Widget) {
+        QWidget *win = ((QWidget *) pdev)->window();
+        translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground);
+    }
+
+    bool useFallback = painter->paintEngine()->getDC() == 0
+                       || painter->opacity() != 1.0
+                       || themeData.rotate
+                       || complexXForm
+                       || themeData.mirrorVertically
+                       || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0)
+                       || translucentToplevel;
+
+    if (!useFallback)
+        drawBackgroundDirectly(themeData);
+    else
+        drawBackgroundThruNativeBuffer(themeData);
+
+    painter->restore();
+}
+
+/*! \internal
+    This function draws the theme parts directly to the paintengines HDC.
+    Do not use this if you need to perform other transformations on the
+    resulting data.
+*/
+void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
+{
+    QPainter *painter = themeData.painter;
+    HDC dc = painter->paintEngine()->getDC();
+
+    QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
+                            int(painter->deviceMatrix().dy()));
+    QRect area = themeData.rect.translated(redirectionDelta);
+
+    QRegion sysRgn = painter->paintEngine()->systemClip();
+    if (sysRgn.isEmpty())
+        sysRgn = area;
+    else
+        sysRgn &= area;
+    if (painter->hasClipping())
+        sysRgn &= painter->clipRegion().translated(redirectionDelta);
+    SelectClipRgn(dc, sysRgn.handle());
+
+#ifdef DEBUG_XP_STYLE
+        printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",
+               qPrintable(themeData.name), themeData.partId, themeData.stateId);
+        showProperties(themeData);
+#endif
+
+    RECT drawRECT = themeData.toRECT(area);
+    DTBGOPTS drawOptions;
+    drawOptions.dwSize = sizeof(drawOptions);
+    drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
+    drawOptions.dwFlags = DTBG_CLIPRECT
+                          | (themeData.noBorder ? DTBG_OMITBORDER : 0)
+                          | (themeData.noContent ? DTBG_OMITCONTENT : 0)
+                          | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
+
+    if (pDrawThemeBackgroundEx != 0) {
+        pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
+    } else {
+        // We are running on a system where the uxtheme.dll does not have
+        // the DrawThemeBackgroundEx function, so we need to clip away
+        // borders or contents manually. All flips and mirrors uses the
+        // fallback implementation
+
+        int borderSize = 0;
+        PROPERTYORIGIN origin = PO_NOTFOUND;
+        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
+        pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
+
+        // Clip away border region
+        QRegion extraClip = sysRgn;
+        if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
+            if (themeData.noBorder) {
+                // extraClip &= area is already done
+                drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));
+            }
+
+            // Clip away content region
+            if (themeData.noContent) {
+                QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+                extraClip ^= content;
+            }
+
+            // Set the clip region, if used..
+            if (themeData.noBorder || themeData.noContent)
+                SelectClipRgn(dc, extraClip.handle());
+        }
+
+        pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
+    }
+    SelectClipRgn(dc, 0);
+}
+
+/*! \internal
+    This function uses a secondary Native doublebuffer for painting parts.
+    It should only be used when the painteengine doesn't provide a proper
+    HDC for direct painting (e.g. when doing a grabWidget(), painting to
+    other pixmaps etc), or when special transformations are needed (e.g.
+    flips (horizonal mirroring only, vertical are handled by the theme
+    engine).
+*/
+void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData)
+{
+    QPainter *painter = themeData.painter;
+    QRect rect = themeData.rect;
+
+    if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
+        rect = QRect(0, 0, rect.height(), rect.width());
+    }
+    rect.moveTo(0,0);
+    int partId = themeData.partId;
+    int stateId = themeData.stateId;
+    int w = rect.width();
+    int h = rect.height();
+
+    // Values initialized later, either from cached values, or from function calls
+    AlphaChannelType alphaType = UnknownAlpha;
+    bool stateHasData = true; // We assume so;
+    bool hasAlpha = false;
+    bool partIsTransparent;
+    bool inspectData;
+    bool potentialInvalidAlpha;
+
+    QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
+                             .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
+                             .arg(w).arg(h);
+    QPixmap cachedPixmap;
+    ThemeMapKey key(themeData);
+    ThemeMapData data = alphaCache.value(key);
+
+    bool haveCachedPixmap = false;
+    bool isCached = data.dataValid;
+    if (isCached) {
+        if (!(stateHasData = data.hasAnyData))
+            return; // Cached NOOP
+        inspectData = data.wasAlphaSwapped;
+        partIsTransparent = data.partIsTransparent;
+        hasAlpha = data.hasAlphaChannel;
+        alphaType = data.alphaType;
+        potentialInvalidAlpha = data.hadInvalidAlpha;
+
+        haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
+
+#ifdef DEBUG_XP_STYLE
+        char buf[25];
+        ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
+        printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
+               haveCachedPixmap ? buf : "]-------------------",
+               qPrintable(themeData.name), themeData.partId, themeData.stateId);
+#endif
+    } else {
+        // Not cached, so get values from Theme Engine
+        BOOL tmt_borderonly = false;
+        COLORREF tmt_transparentcolor = 0x0;
+        PROPERTYORIGIN proporigin = PO_NOTFOUND;
+        pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);
+        pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
+        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);
+        inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);
+
+        // ### This is a vista-specific workaround for broken alpha in titlebar pixmaps
+        if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+            if (themeData.partId == WP_CAPTION || themeData.partId == WP_SMALLCAPTION)
+                inspectData = false;
+        }
+
+        partIsTransparent = isTransparent(themeData);
+
+        potentialInvalidAlpha = false;
+        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);
+        if (proporigin == PO_PART || proporigin == PO_STATE) {
+            int tmt_glyphtype = GT_NONE;
+            pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
+            potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;
+        }
+
+#ifdef DEBUG_XP_STYLE
+        printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
+               qPrintable(themeData.name), themeData.partId, themeData.stateId);
+        printf("-->partIsTransparen      = %d\n", partIsTransparent);
+        printf("-->inspectData           = %d\n", inspectData);
+        printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
+        showProperties(themeData);
+#endif
+    }
+    bool wasAlphaSwapped = false;
+    bool wasAlphaFixed = false;
+
+    // OLD PSDK Workaround ------------------------------------------------------------------------
+    // See if we need extra clipping for the older PSDK, which does
+    // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER
+    // and DTGB_OMITCONTENT
+    bool addBorderContentClipping = false;
+    QRegion extraClip;
+    QRect area = rect;
+    if (themeData.noBorder || themeData.noContent) {
+        extraClip = area;
+        // We are running on a system where the uxtheme.dll does not have
+        // the DrawThemeBackgroundEx function, so we need to clip away
+        // borders or contents manually.
+
+        int borderSize = 0;
+        PROPERTYORIGIN origin = PO_NOTFOUND;
+        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
+        pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
+
+        // Clip away border region
+        if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
+            if (themeData.noBorder) {
+                extraClip &= area;
+                area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
+            }
+
+            // Clip away content region
+            if (themeData.noContent) {
+                QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+                extraClip ^= content;
+            }
+        }
+        addBorderContentClipping = (themeData.noBorder | themeData.noContent);
+    }
+
+    QImage img;
+    if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
+        buffer(w, h); // Ensure a buffer of at least (w, h) in size
+        HDC dc = bufferHDC();
+
+        // Clear the buffer
+        if (alphaType != NoAlpha) {
+            // Consider have separate "memset" function for small chunks for more speedup
+            memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);
+        }
+
+        // Difference between area and rect
+        int dx = area.x() - rect.x();
+        int dy = area.y() - rect.y();
+        int dr = area.right() - rect.right();
+        int db = area.bottom() - rect.bottom();
+
+        // Adjust so painting rect starts from Origo
+        rect.moveTo(0,0);
+        area.moveTo(dx,dy);
+        DTBGOPTS drawOptions;
+        drawOptions.dwSize = sizeof(drawOptions);
+        drawOptions.rcClip = themeData.toRECT(rect);
+        drawOptions.dwFlags = DTBG_CLIPRECT
+                            | (themeData.noBorder ? DTBG_OMITBORDER : 0)
+                            | (themeData.noContent ? DTBG_OMITCONTENT : 0);
+
+        // Drawing the part into the backing store
+        if (pDrawThemeBackgroundEx != 0) {
+            RECT rect(themeData.toRECT(area));
+            pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &rect, &drawOptions);
+        } else {
+            // Set the clip region, if used..
+            if (addBorderContentClipping) {
+                SelectClipRgn(dc, extraClip.handle());
+                // Compensate for the noBorder area difference (noContent has the same area)
+                drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));
+            }
+
+            pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);
+
+            if (addBorderContentClipping)
+                SelectClipRgn(dc, 0);
+        }
+
+        // If not cached, analyze the buffer data to figure
+        // out alpha type, and if it contains data
+        if (!isCached) {
+            if (inspectData)
+                stateHasData = hasAnyData(rect);
+            // SHORTCUT: If the part's state has no data, cache it for NOOP later
+            if (!stateHasData) {
+                memset(&data, 0, sizeof(data));
+                data.dataValid = true;
+                alphaCache.insert(key, data);
+                return;
+            }
+            hasAlpha = hasAlphaChannel(rect);
+            if (!hasAlpha && partIsTransparent)
+                potentialInvalidAlpha = true;
+#if defined(DEBUG_XP_STYLE) && 1
+            dumpNativeDIB(w, h);
+#endif
+        }
+
+        // Swap alpha values, if needed
+        if (inspectData)
+            wasAlphaSwapped = swapAlphaChannel(rect);
+
+        // Fix alpha values, if needed
+        if (potentialInvalidAlpha)
+            wasAlphaFixed = fixAlphaChannel(rect);
+
+        QImage::Format format;
+        if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
+            format = QImage::Format_ARGB32_Premultiplied;
+            alphaType = RealAlpha;
+        } else if (wasAlphaSwapped) {
+            format = QImage::Format_ARGB32_Premultiplied;
+            alphaType = MaskAlpha;
+        } else {
+            format = QImage::Format_RGB32;
+            // The image data we got from the theme engine does not have any transparency,
+            // thus the alpha channel is set to 0.
+            // However, Format_RGB32 requires the alpha part to be set to 0xff, thus
+            // we must flip it from 0x00 to 0xff
+            swapAlphaChannel(rect, true);
+            alphaType = NoAlpha;
+        }
+#if defined(DEBUG_XP_STYLE) && 1
+        printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
+#endif
+        img = QImage(bufferPixels, bufferW, bufferH, format);
+    }
+
+    // Blitting backing store
+    bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
+
+    QRegion newRegion;
+    QRegion oldRegion;
+    if (useRegion) {
+        newRegion = region(themeData);
+        oldRegion = painter->clipRegion();
+        painter->setClipRegion(newRegion);
+#if defined(DEBUG_XP_STYLE) && 0
+        printf("Using region:\n");
+        QVector<QRect> rects = newRegion.rects();
+        for (int i = 0; i < rects.count(); ++i) {
+            const QRect &r = rects.at(i);
+            printf("    (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
+        }
+#endif
+    }
+
+    if (addBorderContentClipping)
+        painter->setClipRegion(extraClip, Qt::IntersectClip);
+
+    if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
+        if (!haveCachedPixmap)
+            painter->drawImage(themeData.rect, img, rect);
+        else
+            painter->drawPixmap(themeData.rect, cachedPixmap);
+    } else {
+        // This is _slow_!
+        // Make a copy containing only the necessary data, and mirror
+        // on all wanted axes. Then draw the copy.
+        // If cached, the normal pixmap is cached, instead of caching
+        // all possible orientations for each part and state.
+        QImage imgCopy;
+        if (!haveCachedPixmap)
+            imgCopy = img.copy(rect);
+        else
+            imgCopy = cachedPixmap.toImage();
+
+        if (themeData.rotate) {
+            QMatrix rotMatrix;
+            rotMatrix.rotate(themeData.rotate);
+            imgCopy = imgCopy.transformed(rotMatrix);
+        }
+        if (themeData.mirrorHorizontally || themeData.mirrorVertically) {
+            imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);
+        }
+        painter->drawImage(themeData.rect,
+                           imgCopy);
+    }
+
+    if (useRegion || addBorderContentClipping) {
+        if (oldRegion.isEmpty())
+            painter->setClipping(false);
+        else
+            painter->setClipRegion(oldRegion);
+    }
+
+    // Cache the pixmap to avoid expensive swapAlphaChannel() calls
+    if (!haveCachedPixmap && w && h) {
+        QPixmap pix = QPixmap::fromImage(img).copy(rect);
+        QPixmapCache::insert(pixmapCacheKey, pix);
+#ifdef DEBUG_XP_STYLE
+        printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
+               w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
+#endif
+    }
+
+    // Add to theme part cache
+    if (!isCached) {
+        memset(&data, 0, sizeof(data));
+        data.dataValid = true;
+        data.partIsTransparent = partIsTransparent;
+        data.alphaType = alphaType;
+        data.hasAlphaChannel = hasAlpha;
+        data.hasAnyData = stateHasData;
+        data.wasAlphaSwapped = wasAlphaSwapped;
+        data.hadInvalidAlpha = wasAlphaFixed;
+        alphaCache.insert(key, data);
+    }
+}
+
+
+// ------------------------------------------------------------------------------------------------
+
+/*!
+    \class QWindowsXPStyle
+    \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel.
+
+    \ingroup appearance
+
+    \warning This style is only available on the Windows XP platform
+    because it makes use of Windows XP's style engine.
+
+    Most of the functions are documented in the base classes
+    QWindowsStyle, QCommonStyle, and QStyle, but the
+    QWindowsXPStyle overloads of drawComplexControl(), drawControl(),
+    drawControlMask(), drawPrimitive(), proxy()->subControlRect(), and
+    sizeFromContents(), are documented here.
+
+    \img qwindowsxpstyle.png
+    \sa QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
+*/
+
+/*!
+    Constructs a QWindowsStyle
+*/
+QWindowsXPStyle::QWindowsXPStyle()
+    : QWindowsStyle(*new QWindowsXPStylePrivate)
+{
+}
+
+/*!
+    Destroys the style.
+*/
+QWindowsXPStyle::~QWindowsXPStyle()
+{
+}
+
+/*! \reimp */
+void QWindowsXPStyle::unpolish(QApplication *app)
+{
+    QWindowsStyle::unpolish(app);
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QApplication *app)
+{
+    QWindowsStyle::polish(app);
+    if (!QWindowsXPStylePrivate::useXP())
+        return;
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QWidget *widget)
+{
+    QWindowsStyle::polish(widget);
+    if (!QWindowsXPStylePrivate::useXP())
+        return;
+
+    if (qobject_cast<QAbstractButton*>(widget)
+        || qobject_cast<QToolButton*>(widget)
+        || qobject_cast<QTabBar*>(widget)
+#ifndef QT_NO_COMBOBOX
+        || qobject_cast<QComboBox*>(widget)
+#endif // QT_NO_COMBOBOX
+        || qobject_cast<QScrollBar*>(widget)
+        || qobject_cast<QSlider*>(widget)
+        || qobject_cast<QHeaderView*>(widget)
+#ifndef QT_NO_SPINBOX
+        || qobject_cast<QAbstractSpinBox*>(widget)
+        || qobject_cast<QSpinBox*>(widget)
+#endif // QT_NO_SPINBOX
+        || widget->inherits("QWorkspaceChild")
+        || widget->inherits("Q3TitleBar"))
+        widget->setAttribute(Qt::WA_Hover);
+
+#ifndef QT_NO_RUBBERBAND
+    if (qobject_cast<QRubberBand*>(widget)) {
+        widget->setWindowOpacity(0.6);
+    }
+#endif
+    if (qobject_cast<QStackedWidget*>(widget) &&
+               qobject_cast<QTabWidget*>(widget->parent()))
+        widget->parentWidget()->setAttribute(Qt::WA_ContentsPropagated);
+
+    Q_D(QWindowsXPStyle);
+    if (!d->hasInitColors) {
+        // Get text color for group box labels
+        COLORREF cref;
+        XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0);
+        pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
+        d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+        pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
+        d->groupBoxTextColorDisabled = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+        // Where does this color come from?
+        //pGetThemeColor(theme.handle(), TKP_TICS, TSS_NORMAL, TMT_COLOR, &cref);
+        d->sliderTickColor = qRgb(165, 162, 148);
+        d->hasInitColors = true;
+    }
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QPalette &pal)
+{
+    QWindowsStyle::polish(pal);
+    pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110));
+}
+
+/*! \reimp */
+void QWindowsXPStyle::unpolish(QWidget *widget)
+{
+#ifndef QT_NO_RUBBERBAND
+    if (qobject_cast<QRubberBand*>(widget)) {
+        widget->setWindowOpacity(1.0);
+    }
+#endif
+    Q_D(QWindowsXPStyle);
+    // Unpolish of widgets is the first thing that
+    // happens when a theme changes, or the theme
+    // engine is turned off. So we detect it here.
+    bool oldState = QWindowsXPStylePrivate::useXP();
+    bool newState = QWindowsXPStylePrivate::useXP(true);
+    if ((oldState != newState) && newState) {
+        d->cleanup(true);
+        d->init(true);
+    } else {
+        // Cleanup handle map, if just changing style,
+        // or turning it on. In both cases the values
+        // already in the map might be old (other style).
+        d->cleanupHandleMap();
+    }
+    if (qobject_cast<QAbstractButton*>(widget)
+        || qobject_cast<QToolButton*>(widget)
+        || qobject_cast<QTabBar*>(widget)
+#ifndef QT_NO_COMBOBOX
+        || qobject_cast<QComboBox*>(widget)
+#endif // QT_NO_COMBOBOX
+        || qobject_cast<QScrollBar*>(widget)
+        || qobject_cast<QSlider*>(widget)
+        || qobject_cast<QHeaderView*>(widget)
+#ifndef QT_NO_SPINBOX
+        || qobject_cast<QAbstractSpinBox*>(widget)
+        || qobject_cast<QSpinBox*>(widget)
+#endif // QT_NO_SPINBOX
+        || widget->inherits("QWorkspaceChild")
+        || widget->inherits("Q3TitleBar"))
+        widget->setAttribute(Qt::WA_Hover, false);
+    QWindowsStyle::unpolish(widget);
+}
+
+/*! \reimp */
+QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, const QWidget *widget) const
+{
+    if (!QWindowsXPStylePrivate::useXP()) {
+        return QWindowsStyle::subElementRect(sr, option, widget);
+    }
+
+    QRect rect(option->rect);
+    switch(sr) {
+    case SE_DockWidgetCloseButton:
+    case SE_DockWidgetFloatButton:
+        rect = QWindowsStyle::subElementRect(sr, option, widget);
+        return rect.translated(0, 1);
+    break;
+    case SE_TabWidgetTabContents:
+        if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
+        {
+            rect = QWindowsStyle::subElementRect(sr, option, widget);
+            if (sr == SE_TabWidgetTabContents)
+                   rect.adjust(0, 0, -2, -2);
+        }
+        break;
+    case SE_TabWidgetTabBar: {
+        rect = QWindowsStyle::subElementRect(sr, option, widget);
+        const QStyleOptionTabWidgetFrame *twfOption =
+            qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option);
+        if (twfOption && twfOption->direction == Qt::RightToLeft
+            && (twfOption->shape == QTabBar::RoundedNorth
+                || twfOption->shape == QTabBar::RoundedSouth))
+        {
+            QStyleOptionTab otherOption;
+            otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth
+                                ? QTabBar::RoundedEast : QTabBar::RoundedSouth);
+            int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption, widget);
+            int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+            rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0);
+        }
+        break;}
+
+    case SE_PushButtonContents:
+        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+            MARGINS borderSize;
+            if (widget) {
+                XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+                HTHEME theme = buttontheme.handle();
+                if (theme) {
+                    int stateId;
+                    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;
+                    else
+                        stateId = PBS_NORMAL;
+
+                    int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+                    rect = option->rect.adjusted(border, border, -border, -border);
+
+                    int result = pGetThemeMargins(theme,
+                                                  NULL,
+                                                  BP_PUSHBUTTON,
+                                                  stateId,
+                                                  TMT_CONTENTMARGINS,
+                                                  NULL,
+                                                  &borderSize);
+
+                    if (result == S_OK) {
+                        rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
+                                    -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
+                        rect = visualRect(option->direction, option->rect, rect);
+                    }
+                }
+            }
+        }
+        break;
+    case SE_ProgressBarContents:
+        rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
+        if (option->state & QStyle::State_Horizontal)
+            rect.adjust(4, 3, -4, -3);
+        else
+            rect.adjust(3, 2, -3, -2);
+        break;
+    default:
+        rect = QWindowsStyle::subElementRect(sr, option, widget);
+    }
+    return rect;
+}
+
+/*!
+    \reimp
+*/
+void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
+                                    const QWidget *widget) const
+{
+    QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+
+    if (!QWindowsXPStylePrivate::useXP()) {
+        QWindowsStyle::drawPrimitive(pe, option, p, widget);
+        return;
+    }
+
+    QString name;
+    int partId = 0;
+    int stateId = 0;
+    QRect rect = option->rect;
+    State flags = option->state;
+    bool hMirrored = false;
+    bool vMirrored = false;
+    bool noBorder = false;
+    bool noContent = false;
+    int  rotate = 0;
+
+    switch (pe) {
+    case PE_FrameTabBarBase:
+        if (const QStyleOptionTabBarBase *tbb
+                = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+            p->save();
+            switch (tbb->shape) {
+            case QTabBar::RoundedNorth:
+                p->setPen(QPen(tbb->palette.dark(), 0));
+                p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
+                break;
+            case QTabBar::RoundedWest:
+                p->setPen(QPen(tbb->palette.dark(), 0));
+                p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
+                break;
+            case QTabBar::RoundedSouth:
+                p->setPen(QPen(tbb->palette.dark(), 0));
+                p->drawLine(tbb->rect.left(), tbb->rect.top(),
+                            tbb->rect.right(), tbb->rect.top());
+                break;
+            case QTabBar::RoundedEast:
+                p->setPen(QPen(tbb->palette.dark(), 0));
+                p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
+                break;
+            case QTabBar::TriangularNorth:
+            case QTabBar::TriangularEast:
+            case QTabBar::TriangularWest:
+            case QTabBar::TriangularSouth:
+                p->restore();
+                QWindowsStyle::drawPrimitive(pe, option, p, widget);
+                return;
+            }
+            p->restore();
+        }
+        return;
+    case PE_PanelButtonBevel:
+        name = QLatin1String("BUTTON");
+        partId = BP_PUSHBUTTON;
+        if (!(flags & State_Enabled))
+            stateId = PBS_DISABLED;
+        else if ((flags & State_Sunken) || (flags & State_On))
+            stateId = PBS_PRESSED;
+        else if (flags & State_MouseOver)
+            stateId = PBS_HOT;
+        //else if (flags & State_ButtonDefault)
+        //    stateId = PBS_DEFAULTED;
+        else
+            stateId = PBS_NORMAL;
+        break;
+
+    case PE_PanelButtonTool:
+        if (widget && widget->inherits("QDockWidgetTitleButton")) {
+            if (const QWidget *dw = widget->parentWidget())
+                if (dw->isWindow())
+                    return;
+        }
+        name = QLatin1String("TOOLBAR");
+        partId = TP_BUTTON;
+        if (!(flags & State_Enabled))
+            stateId = TS_DISABLED;
+        else if (flags & State_Sunken)
+            stateId = TS_PRESSED;
+        else if (flags & State_MouseOver)
+            stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+        else if (flags & State_On)
+            stateId = TS_CHECKED;
+        else if (!(flags & State_AutoRaise))
+            stateId = TS_HOT;
+        else
+            stateId = TS_NORMAL;
+        break;
+
+    case PE_IndicatorButtonDropDown:
+        name = QLatin1String("TOOLBAR");
+        partId = TP_SPLITBUTTONDROPDOWN;
+        if (!(flags & State_Enabled))
+            stateId = TS_DISABLED;
+        else if (flags & State_Sunken)
+            stateId = TS_PRESSED;
+        else if (flags & State_MouseOver)
+            stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+        else if (flags & State_On)
+            stateId = TS_CHECKED;
+        else if (!(flags & State_AutoRaise))
+            stateId = TS_HOT;
+        else
+            stateId = TS_NORMAL;
+        if (option->direction == Qt::RightToLeft)
+            hMirrored = true;
+        break;
+
+    case PE_IndicatorCheckBox:
+        name = QLatin1String("BUTTON");
+        partId = BP_CHECKBOX;
+        if (!(flags & State_Enabled))
+            stateId = CBS_UNCHECKEDDISABLED;
+        else if (flags & State_Sunken)
+            stateId = CBS_UNCHECKEDPRESSED;
+        else if (flags & State_MouseOver)
+            stateId = CBS_UNCHECKEDHOT;
+        else
+            stateId = CBS_UNCHECKEDNORMAL;
+
+        if (flags & State_On)
+            stateId += CBS_CHECKEDNORMAL-1;
+        else if (flags & State_NoChange)
+            stateId += CBS_MIXEDNORMAL-1;
+
+        break;
+
+    case PE_IndicatorRadioButton:
+        name = QLatin1String("BUTTON");
+        partId = BP_RADIOBUTTON;
+        if (!(flags & State_Enabled))
+            stateId = RBS_UNCHECKEDDISABLED;
+        else if (flags & State_Sunken)
+            stateId = RBS_UNCHECKEDPRESSED;
+        else if (flags & State_MouseOver)
+            stateId = RBS_UNCHECKEDHOT;
+        else
+            stateId = RBS_UNCHECKEDNORMAL;
+
+        if (flags & State_On)
+            stateId += RBS_CHECKEDNORMAL-1;
+        break;
+
+    case PE_IndicatorDockWidgetResizeHandle:
+        return;
+
+case PE_Frame:
+    {
+        if (flags & State_Raised)
+            return;
+        name = QLatin1String("LISTVIEW");
+        partId = LVP_LISTGROUP;
+        XPThemeData theme(0, 0, name, partId, 0);
+
+        if (!(flags & State_Enabled))
+            stateId = ETS_DISABLED;
+        else
+            stateId = ETS_NORMAL;
+        int fillType;
+        if (pGetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
+            if (fillType == BT_BORDERFILL) {
+                COLORREF bcRef;
+                pGetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
+                QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
+                QPen oldPen = p->pen();
+                // int borderSize = 1;
+                // pGetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize);
+
+                // 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(bordercolor, 1));
+                p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+                p->setPen(oldPen);
+                return;
+            } else if (fillType == BT_NONE) {
+                return;
+            } else {
+                break;
+            }
+        }
+    }
+    case PE_FrameLineEdit: {
+        // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
+        QWidget *parentWidget = 0;
+        if (widget)
+            parentWidget = widget->parentWidget();
+        if (parentWidget)
+            parentWidget = parentWidget->parentWidget();
+        if (widget && widget->inherits("QLineEdit")
+            && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+            QPen oldPen = p->pen();
+            // Inner white border
+            p->setPen(QPen(option->palette.base().color(), 1));
+            p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+            // Outer dark border
+            p->setPen(QPen(option->palette.shadow().color(), 1));
+            p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+            p->setPen(oldPen);
+            return;
+        } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+            name = QLatin1String("EDIT");
+            partId = EP_EDITTEXT;
+            noContent = true;
+            if (!(flags & State_Enabled))
+                stateId = ETS_DISABLED;
+            else
+                stateId = ETS_NORMAL;
+        }
+        break;
+    }
+
+    case PE_PanelLineEdit:
+        if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+            name = QLatin1String("EDIT");
+            partId = EP_EDITTEXT;
+            noBorder = true;
+            QBrush bg;
+            bool usePalette = false;
+            bool isEnabled = flags & State_Enabled;
+            uint resolve_mask = panel->palette.resolve();
+
+#ifndef QT_NO_SPINBOX
+            //Since spin box includes a line edit we need to resolve the palette on the spin box instead
+            if (widget) {
+                if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
+                    resolve_mask = spinbox->palette().resolve();
+            }
+#endif // QT_NO_SPINBOX
+            if (resolve_mask & (1 << QPalette::Base)) {
+                // Base color is set for this widget, so use it
+                bg = panel->palette.brush(QPalette::Base);
+                usePalette = true;
+            }
+
+            stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
+
+            if (usePalette) {
+                p->fillRect(panel->rect, bg);
+            } else {
+                XPThemeData theme(0, p, name, partId, stateId, rect);
+                if (!theme.isValid()) {
+                    QWindowsStyle::drawPrimitive(pe, option, p, widget);
+                    return;
+                }
+                int bgType;
+                pGetThemeEnumValue( theme.handle(),
+                                    partId,
+                                    stateId,
+                                    TMT_BGTYPE,
+                                    &bgType);
+                if( bgType == BT_IMAGEFILE ) {
+                    theme.mirrorHorizontally = hMirrored;
+                    theme.mirrorVertically = vMirrored;
+                    theme.noBorder = noBorder;
+                    theme.noContent = noContent;
+                    theme.rotate = rotate;
+                    d->drawBackground(theme);
+                } else {
+                    QBrush fillColor = option->palette.brush(QPalette::Base);
+
+                    if (!isEnabled) {
+                        PROPERTYORIGIN origin = PO_NOTFOUND;
+                        pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
+                        // Use only if the fill property comes from our part
+                        if ((origin == PO_PART || origin == PO_STATE)) {
+                            COLORREF bgRef;
+                            pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
+                            fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
+                        }
+                    }
+                    p->fillRect(option->rect, fillColor);
+                }
+            }
+
+            if (panel->lineWidth > 0)
+                proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
+            return;
+        }
+        break;
+
+    case PE_FrameTabWidget:
+        if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
+        {
+            name = QLatin1String("TAB");
+            partId = TABP_PANE;
+
+            if (widget) {
+                bool useGradient = true;
+                const int maxlength = 256;
+                wchar_t themeFileName[maxlength];
+                wchar_t themeColor[maxlength];
+                // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
+                if (pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
+                    wchar_t *offset = 0;
+                    if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
+                        offset++;
+                        if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
+                            useGradient = false;
+                        }
+                    }
+                }
+                // This should work, but currently there's an error in the ::drawBackgroundDirectly()
+                // code, when using the HDC directly..
+                if (useGradient) {
+                    QStyleOptionTabWidgetFrame frameOpt = *tab;
+                    frameOpt.rect = widget->rect();
+                    QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget);
+                    QRegion reg = option->rect;
+                    reg -= contentsRect;
+                    p->setClipRegion(reg);
+                    XPThemeData theme(widget, p, name, partId, stateId, rect);
+                    theme.mirrorHorizontally = hMirrored;
+                    theme.mirrorVertically = vMirrored;
+                    d->drawBackground(theme);
+                    p->setClipRect(contentsRect);
+                    partId = TABP_BODY;
+                }
+            }
+            switch (tab->shape) {
+            case QTabBar::RoundedNorth:
+            case QTabBar::TriangularNorth:
+                break;
+            case QTabBar::RoundedSouth:
+            case QTabBar::TriangularSouth:
+                vMirrored = true;
+                break;
+            case QTabBar::RoundedEast:
+            case QTabBar::TriangularEast:
+                rotate = 90;
+                break;
+            case QTabBar::RoundedWest:
+            case QTabBar::TriangularWest:
+                rotate = 90;
+                hMirrored = true;
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+
+    case PE_FrameMenu:
+        p->save();
+        p->setPen(option->palette.dark().color());
+        p->drawRect(rect.adjusted(0, 0, -1, -1));
+        p->restore();
+        return;
+
+    case PE_PanelMenuBar:
+        break;
+
+ case PE_FrameDockWidget:
+     if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
+        {
+            name = QLatin1String("WINDOW");
+            if (flags & State_Active)
+                stateId = FS_ACTIVE;
+            else
+                stateId = FS_INACTIVE;
+
+            int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget);
+
+            XPThemeData theme(widget, p, name, 0, stateId);
+            if (!theme.isValid())
+                break;
+            theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth);           theme.partId = WP_SMALLFRAMELEFT;
+            d->drawBackground(theme);
+            theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
+            theme.partId = WP_SMALLFRAMERIGHT;
+            d->drawBackground(theme);
+            theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
+            theme.partId = WP_SMALLFRAMEBOTTOM;
+            d->drawBackground(theme);
+            return;
+        }
+        break;
+
+    case PE_IndicatorHeaderArrow:
+        {
+#if 0 // XP theme engine doesn't know about this :(
+            name = QLatin1String("HEADER");
+            partId = HP_HEADERSORTARROW;
+            if (flags & State_Down)
+                stateId = HSAS_SORTEDDOWN;
+            else
+                stateId = HSAS_SORTEDUP;
+#else
+            if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+                p->save();
+                p->setPen(option->palette.dark().color());
+                p->translate(0, option->rect.height()/2 - 4);
+                if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide
+                    p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
+                    p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
+                    p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
+                    p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
+                    p->drawPoint(option->rect.x()+4, option->rect.y()+4);
+                } else if(header->sortIndicator & QStyleOptionHeader::SortDown) {
+                    p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
+                    p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
+                    p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
+                    p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
+                    p->drawPoint(option->rect.x()+4, option->rect.y());
+                }
+                p->restore();
+                return;
+            }
+#endif
+        }
+        break;
+
+    case PE_FrameStatusBarItem:
+        name = QLatin1String("STATUS");
+        partId = SP_PANE;
+        break;
+
+    case PE_FrameGroupBox:
+        name = QLatin1String("BUTTON");
+        partId = BP_GROUPBOX;
+        if (!(flags & State_Enabled))
+            stateId = GBS_DISABLED;
+        else
+            stateId = GBS_NORMAL;
+        if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+            const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option);
+            if (frame2->features & QStyleOptionFrameV2::Flat) {
+                // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style
+                QRect fr = frame->rect;
+                QPoint p1(fr.x(), fr.y() + 1);
+                QPoint p2(fr.x() + fr.width(), p1.y() + 1);
+                rect = QRect(p1, p2);
+                name = QLatin1String("");
+            }
+        }
+        break;
+
+    case PE_IndicatorProgressChunk:
+        {
+        Qt::Orientation orient = Qt::Horizontal;
+        bool inverted = false;
+        if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+            orient = pb2->orientation;
+            if (pb2->invertedAppearance)
+                inverted = true;
+        }
+        if (orient == Qt::Horizontal) {
+            partId = PP_CHUNK;
+            rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
+            if (inverted && option->direction == Qt::LeftToRight)
+                hMirrored = true;
+        } else {
+            partId = PP_CHUNKVERT;
+            rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
+        }
+        name = QLatin1String("PROGRESS");
+        stateId = 1;
+        }
+        break;
+
+    case PE_Q3DockWindowSeparator:
+        name = QLatin1String("TOOLBAR");
+        if (flags & State_Horizontal)
+            partId = TP_SEPARATOR;
+        else
+            partId = TP_SEPARATORVERT;
+        break;
+
+    case PE_FrameWindow:
+        if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
+        {
+            name = QLatin1String("WINDOW");
+            if (flags & State_Active)
+                stateId = FS_ACTIVE;
+            else
+                stateId = FS_INACTIVE;
+
+            int fwidth = frm->lineWidth + frm->midLineWidth;
+
+            XPThemeData theme(0, p, name, 0, stateId);
+            if (!theme.isValid())
+                break;
+
+            theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
+            theme.partId = WP_FRAMELEFT;
+            d->drawBackground(theme);
+            theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
+            theme.partId = WP_FRAMERIGHT;
+            d->drawBackground(theme);
+            theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
+            theme.partId = WP_FRAMEBOTTOM;
+            d->drawBackground(theme);
+            theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
+            theme.partId = WP_CAPTION;
+            d->drawBackground(theme);
+            return;
+        }
+        break;
+
+    case PE_IndicatorBranch:
+        {
+            static const int decoration_size = 9;
+            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;
+            QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+            if (option->state & State_Item) {
+                if (option->direction == Qt::RightToLeft)
+                    p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+                else
+                    p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+            }
+            if (option->state & State_Sibling)
+                p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+            if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
+                p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+            if (option->state & State_Children) {
+                int delta = decoration_size / 2;
+                bef_h -= delta;
+                bef_v -= delta;
+                aft_h += delta;
+                aft_v += delta;
+                XPThemeData theme(0, p, QLatin1String("TREEVIEW"));
+                theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
+                theme.partId = TVP_GLYPH;
+                theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
+                d->drawBackground(theme);
+            }
+        }
+        return;
+
+    case PE_IndicatorToolBarSeparator:
+        if (option->rect.height() < 3) {
+            // XP style requires a few pixels for the separator
+            // to be visible.
+            QWindowsStyle::drawPrimitive(pe, option, p, widget);
+            return;
+        }
+        name = QLatin1String("TOOLBAR");
+        partId = TP_SEPARATOR;
+
+        if (option->state & State_Horizontal)
+            partId = TP_SEPARATOR;
+        else
+            partId = TP_SEPARATORVERT;
+
+        break;
+
+    case PE_IndicatorToolBarHandle:
+
+        name = QLatin1String("REBAR");
+        partId = RP_GRIPPER;
+        if (option->state & State_Horizontal) {
+            partId = RP_GRIPPER;
+            rect.adjust(0, 0, -2, 0);
+        }
+        else {
+            partId = RP_GRIPPERVERT;
+            rect.adjust(0, 0, 0, -2);
+        }
+        break;
+
+    case PE_IndicatorItemViewItemCheck: {
+        QStyleOptionButton button;
+        button.QStyleOption::operator=(*option);
+        button.state &= ~State_MouseOver;
+        proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p, widget);
+        return;
+    }
+
+    default:
+        break;
+    }
+
+    XPThemeData theme(0, p, name, partId, stateId, rect);
+    if (!theme.isValid()) {
+        QWindowsStyle::drawPrimitive(pe, option, p, widget);
+        return;
+    }
+    theme.mirrorHorizontally = hMirrored;
+    theme.mirrorVertically = vMirrored;
+    theme.noBorder = noBorder;
+    theme.noContent = noContent;
+    theme.rotate = rotate;
+    d->drawBackground(theme);
+}
+
+/*!
+    \reimp
+*/
+void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
+                                  const QWidget *widget) const
+{
+  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+    if (!QWindowsXPStylePrivate::useXP()) {
+        QWindowsStyle::drawControl(element, option, p, widget);
+        return;
+    }
+
+    QRect rect(option->rect);
+    State flags = option->state;
+
+    int rotate = 0;
+    bool hMirrored = false;
+    bool vMirrored = false;
+
+    QString name;
+    int partId = 0;
+    int stateId = 0;
+    switch (element) {
+    case CE_SizeGrip:
+        {
+            name = QLatin1String("STATUS");
+            partId = SP_GRIPPER;
+            SIZE sz;
+            XPThemeData theme(0, p, name, partId, 0);
+            pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz);
+            --sz.cy;
+            if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
+                switch (sg->corner) {
+                    case Qt::BottomRightCorner:
+                        rect = QRect(rect.right() - sz.cx, rect.bottom() - sz.cy, sz.cx, sz.cy);
+                        break;
+                    case Qt::BottomLeftCorner:
+                        rect = QRect(rect.left() + 1, rect.bottom() - sz.cy, sz.cx, sz.cy);
+                        hMirrored = true;
+                        break;
+                    case Qt::TopRightCorner:
+                        rect = QRect(rect.right() - sz.cx, rect.top() + 1, sz.cx, sz.cy);
+                        vMirrored = true;
+                        break;
+                    case Qt::TopLeftCorner:
+                        rect = QRect(rect.left() + 1, rect.top() + 1, sz.cx, sz.cy);
+                        hMirrored = vMirrored = true;
+                }
+            }
+        }
+        break;
+
+    case CE_HeaderSection:
+        name = QLatin1String("HEADER");
+        partId = HP_HEADERITEM;
+        if (flags & State_Sunken)
+            stateId = HIS_PRESSED;
+        else if (flags & State_MouseOver)
+            stateId = HIS_HOT;
+        else
+            stateId = HIS_NORMAL;
+        break;
+
+    case CE_Splitter:
+        p->eraseRect(option->rect);
+        return;
+
+    case CE_PushButtonBevel:
+        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
+        {
+            name = QLatin1String("BUTTON");
+            partId = BP_PUSHBUTTON;
+            bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
+                || ((btn->features & QStyleOptionButton::CommandLinkButton)
+                    && !(flags & State_MouseOver)
+                    && !(btn->features & QStyleOptionButton::DefaultButton));
+            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)
+                stateId = PBS_DEFAULTED;
+            else
+                stateId = PBS_NORMAL;
+
+            if (!justFlat) {
+                XPThemeData theme(widget, p, name, partId, stateId, rect);
+                d->drawBackground(theme);
+            }
+
+            if (btn->features & QStyleOptionButton::HasMenu) {
+                int mbiw = 0, mbih = 0;
+                XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN);
+                if (theme.isValid()) {
+                    SIZE size;
+                    pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                    mbiw = size.cx;
+                    mbih = size.cy;
+                }
+
+                QRect ir = btn->rect;
+                QStyleOptionButton newBtn = *btn;
+                newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
+                proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+            }
+            return;
+        }
+        break;
+    case CE_TabBarTab:
+        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
+        {
+            stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
+        }
+    break;
+
+    case CE_TabBarTabShape:
+        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
+        {
+            name = QLatin1String("TAB");
+            bool isDisabled = !(tab->state & State_Enabled);
+            bool hasFocus = tab->state & State_HasFocus;
+            bool isHot = tab->state & State_MouseOver;
+            bool selected = tab->state & State_Selected;
+            bool lastTab = tab->position == QStyleOptionTab::End;
+            bool firstTab = tab->position == QStyleOptionTab::Beginning;
+            bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+            bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignLeft;
+            bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignCenter;
+            int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+            int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option, widget);
+
+            if (isDisabled)
+                stateId = TIS_DISABLED;
+            else if (selected)
+                stateId = TIS_SELECTED;
+            else if (hasFocus)
+                stateId = TIS_FOCUSED;
+            else if (isHot)
+                stateId = TIS_HOT;
+            else
+                stateId = TIS_NORMAL;
+
+            // Selecting proper part depending on position
+            if (firstTab || onlyOne) {
+                if (leftAligned) {
+                    partId = TABP_TABITEMLEFTEDGE;
+                } else if (centerAligned) {
+                    partId = TABP_TABITEM;
+                } else { // rightAligned
+                    partId = TABP_TABITEMRIGHTEDGE;
+                }
+            } else {
+                partId = TABP_TABITEM;
+            }
+
+            if (tab->direction == Qt::RightToLeft
+                && (tab->shape == QTabBar::RoundedNorth
+                    || tab->shape == QTabBar::RoundedSouth)) {
+                bool temp = firstTab;
+                firstTab = lastTab;
+                lastTab = temp;
+            }
+            bool begin = firstTab || onlyOne;
+            bool end = lastTab || onlyOne;
+            switch (tab->shape) {
+            case QTabBar::RoundedNorth:
+                if (selected)
+                    rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
+                else
+                    rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
+                break;
+            case QTabBar::RoundedSouth:
+                //vMirrored = true;
+                rotate = 180; // Not 100% correct, but works
+                if (selected)
+                    rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
+                else
+                    rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
+                break;
+            case QTabBar::RoundedEast:
+                rotate = 90;
+                if (selected) {
+                    rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
+                }else{
+                    rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
+                }
+                break;
+            case QTabBar::RoundedWest:
+                hMirrored = true;
+                rotate = 90;
+                if (selected) {
+                    rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
+                }else{
+                    rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
+                }
+                break;
+            default:
+                name = QLatin1String("");  // Do our own painting for triangular
+                break;
+            }
+
+            if (!selected) {
+                switch (tab->shape) {
+                case QTabBar::RoundedNorth:
+                    rect.adjust(0,0, 0,-1);
+                    break;
+                case QTabBar::RoundedSouth:
+                    rect.adjust(0,1, 0,0);
+                    break;
+                case QTabBar::RoundedEast:
+                    rect.adjust( 1,0, 0,0);
+                    break;
+                case QTabBar::RoundedWest:
+                    rect.adjust(0,0, -1,0);
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+        break;
+
+    case CE_ProgressBarGroove:
+        {
+        Qt::Orientation orient = Qt::Horizontal;
+        if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+            orient = pb2->orientation;
+        partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
+        name = QLatin1String("PROGRESS");
+        stateId = 1;
+        }
+        break;
+
+    case CE_MenuEmptyArea:
+    case CE_MenuItem:
+        if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+        {
+            int tab = menuitem->tabWidth;
+            bool dis = !(menuitem->state & State_Enabled);
+            bool act = menuitem->state & State_Selected;
+            bool checkable = menuitem->menuHasCheckableItems;
+            bool checked = checkable ? menuitem->checked : false;
+
+            // windows always has a check column, regardless whether we have an icon or not
+            int checkcol = qMax(menuitem->maxIconWidth, 12);
+
+            int x, y, w, h;
+            rect.getRect(&x, &y, &w, &h);
+
+            QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+            p->fillRect(rect, fill);
+
+            if (element == CE_MenuEmptyArea)
+                break;
+
+            // draw separator -------------------------------------------------
+            if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+                int yoff = y-1 + h / 2;
+                p->setPen(menuitem->palette.dark().color());
+                p->drawLine(x, yoff, x+w, yoff);
+                ++yoff;
+                p->setPen(menuitem->palette.light().color());
+                p->drawLine(x, yoff, x+w, yoff);
+                return;
+            }
+
+            int xpos = x;
+
+            // draw icon ------------------------------------------------------
+            if (!menuitem->icon.isNull()) {
+                QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+                if (act && !dis)
+                    mode = QIcon::Active;
+                QPixmap pixmap = checked ?
+                                 menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On) :
+                                 menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
+                int pixw = pixmap.width();
+                int pixh = pixmap.height();
+                QRect iconRect(0, 0, pixw, pixh);
+                iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
+                QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
+                p->setPen(menuitem->palette.text().color());
+                p->setBrush(Qt::NoBrush);
+                if (checked)
+                    p->drawRect(vIconRect.adjusted(-1, -2, 1, 1));
+                p->drawPixmap(vIconRect.topLeft(), pixmap);
+
+            // draw checkmark -------------------------------------------------
+            } else if (checked) {
+                QStyleOptionMenuItem newMi = *menuitem;
+                newMi.state = State_None;
+                if (!dis)
+                    newMi.state |= State_Enabled;
+                if (act)
+                    newMi.state |= State_On;
+
+                QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame,
+                                            menuitem->rect.y() + windowsItemFrame,
+                                            checkcol - 2 * windowsItemFrame,
+                                            menuitem->rect.height() - 2*windowsItemFrame);
+                newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
+                proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
+            }
+
+            QColor textColor = dis ? menuitem->palette.text().color() :
+                               act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
+            p->setPen(textColor);
+
+            // draw text ------------------------------------------------------
+            int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+            xpos = menuitem->rect.x() + xm;
+            QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+            QRect vTextRect = visualRect(option->direction, option->rect, textRect);
+            QString s = menuitem->text;
+            if (!s.isEmpty()) {
+                p->save();
+                int t = s.indexOf(QLatin1Char('\t'));
+                int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft;
+                if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+                    text_flags |= Qt::TextHideMnemonic;
+                // draw tab text ----------------
+                if (t >= 0) {
+                    QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
+                    if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+                        p->setPen(menuitem->palette.light().color());
+                        p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+                        p->setPen(textColor);
+                    }
+                    p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+                    s = s.left(t);
+                }
+                QFont font = menuitem->font;
+                if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+                    font.setBold(true);
+                p->setFont(font);
+                if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+                    p->setPen(menuitem->palette.light().color());
+                    p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+                    p->setPen(textColor);
+                }
+                p->drawText(vTextRect, text_flags, s);
+                p->restore();
+            }
+
+            // draw sub menu arrow --------------------------------------------
+            if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
+                int dim = (h - 2) / 2;
+                PrimitiveElement arrow;
+                arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+                xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+                QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+                QStyleOptionMenuItem newMI = *menuitem;
+                newMI.rect = vSubMenuRect;
+                newMI.state = dis ? State_None : State_Enabled;
+                if (act)
+                    newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color());
+                proxy()->drawPrimitive(arrow, &newMI, p, widget);
+            }
+        }
+        return;
+
+    case CE_MenuBarItem:
+        if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+        {
+            if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+                break;
+
+            bool act = mbi->state & State_Selected;
+            bool dis = !(mbi->state & State_Enabled);
+
+            QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+            QPalette::ColorRole textRole = dis ? QPalette::Text:
+                                           act ? QPalette::HighlightedText : QPalette::ButtonText;
+            QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
+
+            uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+            if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+                alignment |= Qt::TextHideMnemonic;
+
+            p->fillRect(rect, fill);
+            if (!pix.isNull())
+                drawItemPixmap(p, mbi->rect, alignment, pix);
+            else
+                drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+        }
+        return;
+#ifndef QT_NO_DOCKWIDGET
+    case CE_DockWidgetTitle:
+        if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+        {
+            int buttonMargin = 4;
+            int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+            int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
+            bool isFloating = widget && widget->isWindow();
+            bool isActive = dwOpt->state & State_Active;
+
+            const QStyleOptionDockWidgetV2 *v2
+                = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+            bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+            if (verticalTitleBar) {
+                QSize s = rect.size();
+                s.transpose();
+                rect.setSize(s);
+
+                p->translate(rect.left() - 1, rect.top() + rect.width());
+                p->rotate(-90);
+                p->translate(-rect.left() + 1, -rect.top());
+            }
+            QRect r = 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 != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+                    titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+            } else {
+                titleRect.adjust(mw, 0, 0, 0);
+                if (!dwOpt->floatable && !dwOpt->closable)
+                    titleRect.adjust(0, 0, -mw, 0);
+            }
+
+            if (!verticalTitleBar)
+                titleRect = visualRect(dwOpt->direction, r, titleRect);
+
+            if (!isFloating) {
+                QPen oldPen = p->pen();
+                QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+                p->setPen(dwOpt->palette.color(QPalette::Dark));
+                p->drawRect(r);
+
+                if (!titleText.isEmpty()) {
+                    drawItemText(p, titleRect,
+                                Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+                                dwOpt->state & State_Enabled, titleText,
+                                QPalette::WindowText);
+                }
+
+                p->setPen(oldPen);
+            } else {
+                name = QLatin1String("WINDOW");
+                if (isActive)
+                    stateId = CS_ACTIVE;
+                else
+                    stateId = CS_INACTIVE;
+
+                int titleHeight = rect.height() - 2;
+                rect = rect.adjusted(-fw, -fw, fw, 0);
+
+                XPThemeData theme(widget, p, name, 0, stateId);
+                if (!theme.isValid())
+                    break;
+
+                // Draw small type title bar
+                theme.rect = rect;
+                theme.partId = WP_SMALLCAPTION;
+                d->drawBackground(theme);
+
+                // Figure out maximal button space on title bar
+
+                QIcon ico = widget->windowIcon();
+                bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
+                if (hasIcon) {
+                    QPixmap pxIco = ico.pixmap(titleHeight);
+                    if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
+                        p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
+                    else
+                        p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
+                }
+                if (!dwOpt->title.isEmpty()) {
+                    QPen oldPen = p->pen();
+                    QFont oldFont = p->font();
+                    QFont titleFont = oldFont;
+                    titleFont.setBold(true);
+                    p->setFont(titleFont);
+                    QString titleText
+                        = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+
+                    int result = TST_NONE;
+                    pGetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
+                    if (result != TST_NONE) {
+                        COLORREF textShadowRef;
+                        pGetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
+                        QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
+                        p->setPen(textShadow);
+                        drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
+                                    Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
+                                    dwOpt->state & State_Enabled, titleText);
+                    }
+
+                    COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
+                    QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
+                    p->setPen(textColor);
+                    drawItemText(p, titleRect,
+                                Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
+                                dwOpt->state & State_Enabled, titleText);
+                    p->setFont(oldFont);
+                    p->setPen(oldPen);
+                }
+
+            }
+
+            return;
+        }
+        break;
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_RUBBERBAND
+    case CE_RubberBand:
+        if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
+            QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
+            p->save();
+            QRect r = option->rect;
+            p->setPen(highlight.darker(120));
+            QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
+                                qMin(highlight.green()/2 + 110, 255),
+                                qMin(highlight.blue()/2 + 110, 255),
+                                (widget && widget->isTopLevel())? 255 : 127);
+            p->setBrush(dimHighlight);
+            p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+            p->restore();
+            return;
+        }
+#endif // QT_NO_RUBBERBAND
+    case CE_HeaderEmptyArea:
+        if (option->state & State_Horizontal)
+        {
+            name = QLatin1String("HEADER");
+            stateId = HIS_NORMAL;
+        }
+        else {
+            QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p, widget);
+            return;
+        }
+        break;
+    default:
+        break;
+    }
+
+    XPThemeData theme(widget, p, name, partId, stateId, rect);
+    if (!theme.isValid()) {
+        QWindowsStyle::drawControl(element, option, p, widget);
+        return;
+    }
+
+    theme.rotate = rotate;
+    theme.mirrorHorizontally = hMirrored;
+    theme.mirrorVertically = vMirrored;
+    d->drawBackground(theme);
+}
+
+
+/*!
+    \reimp
+*/
+void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
+                                         QPainter *p, const QWidget *widget) const
+{
+    QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+
+    if (!QWindowsXPStylePrivate::useXP()) {
+        QWindowsStyle::drawComplexControl(cc, option, p, widget);
+        return;
+    }
+
+    State flags = option->state;
+    SubControls sub = option->subControls;
+    QRect r = option->rect;
+
+    int partId = 0;
+    int stateId = 0;
+    if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
+        flags |= State_MouseOver;
+
+    switch (cc) {
+#ifndef QT_NO_SPINBOX
+    case CC_SpinBox:
+        if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
+        {
+            XPThemeData theme(widget, p, QLatin1String("SPIN"));
+
+            if (sb->frame && (sub & SC_SpinBoxFrame)) {
+                partId = EP_EDITTEXT;
+                if (!(flags & State_Enabled))
+                    stateId = ETS_DISABLED;
+                else if (flags & State_HasFocus)
+                    stateId = ETS_FOCUSED;
+                else
+                    stateId = ETS_NORMAL;
+
+                XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+                ftheme.noContent = true;
+                d->drawBackground(ftheme);
+            }
+            if (sub & SC_SpinBoxUp) {
+                theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
+                partId = SPNP_UP;
+                if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
+                    stateId = UPS_DISABLED;
+                else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
+                    stateId = UPS_PRESSED;
+                else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
+                    stateId = UPS_HOT;
+                else
+                    stateId = UPS_NORMAL;
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+            if (sub & SC_SpinBoxDown) {
+                theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+                partId = SPNP_DOWN;
+                if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
+                    stateId = DNS_DISABLED;
+                else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
+                    stateId = DNS_PRESSED;
+                else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
+                    stateId = DNS_HOT;
+                else
+                    stateId = DNS_NORMAL;
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+        }
+        break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+    case CC_ComboBox:
+        if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+        {
+            if (sub & SC_ComboBoxEditField) {
+                if (cmb->frame) {
+                    partId = EP_EDITTEXT;
+                    if (!(flags & State_Enabled))
+                        stateId = ETS_DISABLED;
+                    else if (flags & State_HasFocus)
+                        stateId = ETS_FOCUSED;
+                    else
+                        stateId = ETS_NORMAL;
+                    XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+                    d->drawBackground(theme);
+                } else {
+                    QBrush editBrush = cmb->palette.brush(QPalette::Base);
+                    p->fillRect(option->rect, editBrush);
+                }
+                if (!cmb->editable) {
+                    QRect re = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
+                    if (option->state & State_HasFocus) {
+                        p->fillRect(re, option->palette.highlight());
+                        p->setPen(option->palette.highlightedText().color());
+                        p->setBackground(option->palette.highlight());
+                    } else {
+                        p->fillRect(re, option->palette.base());
+                        p->setPen(option->palette.text().color());
+                        p->setBackground(option->palette.base());
+                    }
+                }
+            }
+
+            if (sub & SC_ComboBoxArrow) {
+                XPThemeData theme(widget, p, QLatin1String("COMBOBOX"));
+                theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
+                partId = CP_DROPDOWNBUTTON;
+                if (!(flags & State_Enabled))
+                    stateId = CBXS_DISABLED;
+                else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_Sunken))
+                    stateId = CBXS_PRESSED;
+                else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_MouseOver))
+                    stateId = CBXS_HOT;
+                else
+                    stateId = CBXS_NORMAL;
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+        }
+        break;
+#endif // QT_NO_COMBOBOX
+    case CC_ScrollBar:
+        if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
+        {
+            XPThemeData theme(widget, p, QLatin1String("SCROLLBAR"));
+            bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
+            if (maxedOut)
+                flags &= ~State_Enabled;
+
+            bool isHorz = flags & State_Horizontal;
+            bool isRTL  = option->direction == Qt::RightToLeft;
+            if (sub & SC_ScrollBarAddLine) {
+                theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
+                partId = SBP_ARROWBTN;
+                if (!(flags & State_Enabled))
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
+                else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
+                else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
+                    stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
+                else
+                    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
+                    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 = scrollbar->orientation == Qt::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
+                        stateId = SCRBS_NORMAL;
+
+                    // Draw handle
+                    theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+                    theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+
+                    // Calculate rect of gripper
+                    const int swidth = theme.rect.width();
+                    const int sheight = theme.rect.height();
+
+                    MARGINS contentsMargin;
+                    RECT rect = theme.toRECT(theme.rect);
+                    pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
+
+                    SIZE size;
+                    theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
+                    pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                    int gw = size.cx, gh = size.cy;
+
+
+                    QRect gripperBounds;
+                    if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
+                        gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+                        gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+                        gripperBounds.setWidth(gw);
+                        gripperBounds.setHeight(gh);
+                    } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
+                        gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+                        gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+                        gripperBounds.setWidth(gw);
+                        gripperBounds.setHeight(gh);
+                    }
+
+                    // Draw gripper if there is enough space
+                    if (!gripperBounds.isEmpty()) {
+                        p->save();
+                        theme.rect = gripperBounds;
+                        p->setClipRegion(d->region(theme));// Only change inside the region of the gripper
+                        d->drawBackground(theme);          // Transparent gripper ontop of background
+                        p->restore();
+                    }
+                }
+            }
+        }
+        break;
+
+#ifndef QT_NO_SLIDER
+    case CC_Slider:
+        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option))
+        {
+            XPThemeData theme(widget, p, QLatin1String("TRACKBAR"));
+            QRect slrect = slider->rect;
+            QRegion tickreg = slrect;
+            if (sub & SC_SliderGroove) {
+                theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+                if (slider->orientation == Qt::Horizontal) {
+                    partId = TKP_TRACK;
+                    stateId = TRS_NORMAL;
+                    theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
+                } else {
+                    partId = TKP_TRACKVERT;
+                    stateId = TRVS_NORMAL;
+                    theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
+                }
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+                tickreg -= theme.rect;
+            }
+            if (sub & SC_SliderTickmarks) {
+                int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+                int ticks = slider->tickPosition;
+                int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+                int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+                int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+                int interval = slider->tickInterval;
+                if (interval <= 0) {
+                    interval = slider->singleStep;
+                    if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+                                                        available)
+                        - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+                                                          0, available) < 3)
+                        interval = slider->pageStep;
+                }
+                if (!interval)
+                    interval = 1;
+                int fudge = len / 2;
+                int pos;
+                int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0;
+                p->setPen(d->sliderTickColor);
+                QVarLengthArray<QLine, 32> lines;
+                int v = slider->minimum;
+                while (v <= slider->maximum + 1) {
+                    if (v == slider->maximum + 1 && interval == 1)
+                        break;
+                    const int v_ = qMin(v, slider->maximum);
+                    int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
+                    pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+                                                          v_, available) + fudge;
+                    if (slider->orientation == Qt::Horizontal) {
+                        if (ticks & QSlider::TicksAbove)
+                            lines.append(QLine(pos, tickOffset - 1 - bothOffset,
+                                               pos, tickOffset - 1 - bothOffset - tickLength));
+
+                        if (ticks & QSlider::TicksBelow)
+                            lines.append(QLine(pos, tickOffset + thickness + bothOffset,
+                                               pos, tickOffset + thickness + bothOffset + tickLength));
+                    } else {
+                        if (ticks & QSlider::TicksAbove)
+                            lines.append(QLine(tickOffset - 1 - bothOffset, pos,
+                                               tickOffset - 1 - bothOffset - tickLength, pos));
+
+                        if (ticks & QSlider::TicksBelow)
+                            lines.append(QLine(tickOffset + thickness + bothOffset, pos,
+                                               tickOffset + thickness + bothOffset + tickLength, pos));
+                    }
+                    // in the case where maximum is max int
+                    int nextInterval = v + interval;
+                    if (nextInterval < v)
+                        break;
+                    v = nextInterval;
+                }
+                if (lines.size() > 0) {
+                    p->save();
+                    p->translate(slrect.topLeft());
+                    p->drawLines(lines.constData(), lines.size());
+                    p->restore();
+                }
+            }
+            if (sub & SC_SliderHandle) {
+                theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+                if (slider->orientation == Qt::Horizontal) {
+                    if (slider->tickPosition == QSlider::TicksAbove)
+                        partId = TKP_THUMBTOP;
+                    else if (slider->tickPosition == QSlider::TicksBelow)
+                        partId = TKP_THUMBBOTTOM;
+                    else
+                        partId = TKP_THUMB;
+
+                    if (!(slider->state & State_Enabled))
+                        stateId = TUS_DISABLED;
+                    else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
+                        stateId = TUS_PRESSED;
+                    else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
+                        stateId = TUS_HOT;
+                    else if (flags & State_HasFocus)
+                        stateId = TUS_FOCUSED;
+                    else
+                        stateId = TUS_NORMAL;
+                } else {
+                    if (slider->tickPosition == QSlider::TicksLeft)
+                        partId = TKP_THUMBLEFT;
+                    else if (slider->tickPosition == QSlider::TicksRight)
+                        partId = TKP_THUMBRIGHT;
+                    else
+                        partId = TKP_THUMBVERT;
+
+                    if (!(slider->state & State_Enabled))
+                        stateId = TUVS_DISABLED;
+                    else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
+                        stateId = TUVS_PRESSED;
+                    else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
+                        stateId = TUVS_HOT;
+                    else if (flags & State_HasFocus)
+                        stateId = TUVS_FOCUSED;
+                    else
+                        stateId = TUVS_NORMAL;
+                }
+                theme.partId = partId;
+                theme.stateId = stateId;
+                d->drawBackground(theme);
+            }
+            if (slider->state & State_HasFocus) {
+                QStyleOptionFocusRect fropt;
+                fropt.QStyleOption::operator=(*slider);
+                fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+                proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+            }
+        }
+        break;
+#endif
+#ifndef QT_NO_TOOLBUTTON
+    case CC_ToolButton:
+        if (const QStyleOptionToolButton *toolbutton
+            = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+            QRect button, menuarea;
+            button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
+            menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
+
+            State bflags = toolbutton->state & ~State_Sunken;
+            State mflags = bflags;
+
+            if (bflags & State_AutoRaise) {
+                if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+                    bflags &= ~State_Raised;
+                }
+            }
+
+            if (toolbutton->state & State_Sunken) {
+                if (toolbutton->activeSubControls & SC_ToolButton) {
+                    bflags |= State_Sunken;
+                    mflags |= State_MouseOver | State_Sunken;
+                } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
+                    mflags |= State_Sunken;
+                    bflags |= State_MouseOver;
+                }
+            }
+
+            QStyleOption tool(0);
+            tool.palette = toolbutton->palette;
+            if (toolbutton->subControls & SC_ToolButton) {
+                if (flags & (State_Sunken | State_On | State_Raised) || !(flags & State_AutoRaise)) {
+                    if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) {
+                        XPThemeData theme(widget, p, QLatin1String("TOOLBAR"));
+                        theme.partId = TP_SPLITBUTTON;
+                        theme.rect = button;
+                        if (!(bflags & State_Enabled))
+                            stateId = TS_DISABLED;
+                        else if (bflags & State_Sunken)
+                            stateId = TS_PRESSED;
+                        else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
+                            stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+                        else if (bflags & State_On)
+                            stateId = TS_CHECKED;
+                        else
+                            stateId = TS_NORMAL;
+                        if (option->direction == Qt::RightToLeft)
+                            theme.mirrorHorizontally = true;
+                        theme.stateId = stateId;
+                        d->drawBackground(theme);
+                    } else {
+                        tool.rect = button;
+                        tool.state = bflags;
+                        if (widget && !qobject_cast<QToolBar*>(widget->parentWidget())
+                                   && !(bflags & State_AutoRaise))
+                            proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
+                        else
+                            proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+                    }
+                }
+            }
+
+            if (toolbutton->state & State_HasFocus) {
+                QStyleOptionFocusRect fr;
+                fr.QStyleOption::operator=(*toolbutton);
+                fr.rect.adjust(3, 3, -3, -3);
+                if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
+                    fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
+                                                      toolbutton, widget), 0);
+                proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
+            }
+            QStyleOptionToolButton label = *toolbutton;
+            label.state = bflags;
+            int fw = 2;
+            label.rect = button.adjusted(fw, fw, -fw, -fw);
+            proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+
+            if (toolbutton->subControls & SC_ToolButtonMenu) {
+                tool.rect = menuarea;
+                tool.state = mflags;
+                proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+            } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
+                int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
+                QRect ir = toolbutton->rect;
+                QStyleOptionToolButton newBtn = *toolbutton;
+                newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
+                proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+            }
+        }
+        break;
+#endif // QT_NO_TOOLBUTTON
+
+    case CC_TitleBar:
+        {
+            if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
+            {
+                bool isActive = tb->titleBarState & QStyle::State_Active;
+                XPThemeData theme(widget, p, QLatin1String("WINDOW"));
+                if (sub & SC_TitleBarLabel) {
+
+#ifdef QT3_SUPPORT
+                    if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+                        partId = WP_SMALLCAPTION;
+                    } else
+#endif
+                        partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
+                    theme.rect = option->rect;
+                    if (widget && !widget->isEnabled())
+                        stateId = CS_DISABLED;
+                    else if (isActive)
+                        stateId = CS_ACTIVE;
+                    else
+                        stateId = CS_INACTIVE;
+
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+
+                    QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
+
+                    int result = TST_NONE;
+                    pGetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
+                    if (result != TST_NONE) {
+                        COLORREF textShadowRef;
+                        pGetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
+                        QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
+                        p->setPen(textShadow);
+                        p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(),
+                                    Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+                    }
+                    COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
+                    QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
+                    p->setPen(textColor);
+                    p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(),
+                                Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+                }
+                if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu, widget);
+                    partId = WP_SYSBUTTON;
+                    if ((widget && !widget->isEnabled()) || !isActive)
+                        stateId = SBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
+                        stateId = SBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
+                        stateId = SBS_HOT;
+                    else
+                        stateId = SBS_NORMAL;
+                    if (!tb->icon.isNull()) {
+                        tb->icon.paint(p, theme.rect);
+                    } else {
+                        theme.partId = partId;
+                        theme.stateId = stateId;
+                        SIZE sz;
+                        pGetThemePartSize(theme.handle(), qt_win_display_dc(), theme.partId, theme.stateId, 0, TS_TRUE, &sz);
+                        if (sz.cx == 0 || sz.cy == 0) {
+                            int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
+                            QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb, widget).pixmap(iconSize, iconSize);
+                            p->save();
+                            drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
+                            p->restore();
+                        } else {
+                            d->drawBackground(theme);
+                        }
+                    }
+                }
+
+                if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
+                        && !(tb->titleBarState & Qt::WindowMinimized)) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget);
+                    partId = WP_MINBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = MINBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken))
+                        stateId = MINBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver))
+                        stateId = MINBS_HOT;
+                    else if (!isActive)
+                        stateId = MINBS_INACTIVE;
+                    else
+                        stateId = MINBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
+                        && !(tb->titleBarState & Qt::WindowMaximized)) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget);
+                    partId = WP_MAXBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = MAXBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken))
+                        stateId = MAXBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver))
+                        stateId = MAXBS_HOT;
+                    else if (!isActive)
+                        stateId = MAXBS_INACTIVE;
+                    else
+                        stateId = MAXBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_TitleBarContextHelpButton
+                    && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget);
+                    partId = WP_HELPBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = MINBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken))
+                        stateId = MINBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver))
+                        stateId = MINBS_HOT;
+                    else if (!isActive)
+                        stateId = MINBS_INACTIVE;
+                    else
+                        stateId = MINBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                bool drawNormalButton = (sub & SC_TitleBarNormalButton)
+                                        && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+                                        && (tb->titleBarState & Qt::WindowMinimized))
+                                        || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+                                        && (tb->titleBarState & Qt::WindowMaximized)));
+                if (drawNormalButton) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget);
+                    partId = WP_RESTOREBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = RBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken))
+                        stateId = RBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver))
+                        stateId = RBS_HOT;
+                    else if (!isActive)
+                        stateId = RBS_INACTIVE;
+                    else
+                        stateId = RBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
+                        && !(tb->titleBarState & Qt::WindowMinimized)) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget);
+                    partId = WP_MINBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = MINBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken))
+                        stateId = MINBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver))
+                        stateId = MINBS_HOT;
+                    else if (!isActive)
+                        stateId = MINBS_INACTIVE;
+                    else
+                        stateId = MINBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
+                        && tb->titleBarState & Qt::WindowMinimized) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget);
+                    partId = WP_RESTOREBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = RBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken))
+                        stateId = RBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver))
+                        stateId = RBS_HOT;
+                    else if (!isActive)
+                        stateId = RBS_INACTIVE;
+                    else
+                        stateId = RBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+                if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+                    theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget);
+                    //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
+                    partId = WP_CLOSEBUTTON;
+                    if (widget && !widget->isEnabled())
+                        stateId = CBS_DISABLED;
+                    else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken))
+                        stateId = CBS_PUSHED;
+                    else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver))
+                        stateId = CBS_HOT;
+                    else if (!isActive)
+                        stateId = CBS_INACTIVE;
+                    else
+                        stateId = CBS_NORMAL;
+                    theme.partId = partId;
+                    theme.stateId = stateId;
+                    d->drawBackground(theme);
+                }
+            }
+        }
+        break;
+
+#ifndef QT_NO_WORKSPACE
+    case CC_MdiControls:
+        {
+            QRect buttonRect;
+            XPThemeData theme(widget, p, QLatin1String("WINDOW"), WP_MDICLOSEBUTTON, CBS_NORMAL);
+
+            if (option->subControls & SC_MdiCloseButton) {
+                buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
+                if (theme.isValid()) {
+                    theme.partId = WP_MDICLOSEBUTTON;
+                    theme.rect = buttonRect;
+                    if (!(flags & State_Enabled))
+                        theme.stateId = CBS_INACTIVE;
+                    else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton))
+                        theme.stateId = CBS_PUSHED;
+                    else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton))
+                        theme.stateId = CBS_HOT;
+                    else
+                        theme.stateId = CBS_NORMAL;
+                    d->drawBackground(theme);
+                }
+            }
+            if (option->subControls & SC_MdiNormalButton) {
+                buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget);
+                if (theme.isValid()) {
+                    theme.partId = WP_MDIRESTOREBUTTON;
+                    theme.rect = buttonRect;
+                    if (!(flags & State_Enabled))
+                        theme.stateId = CBS_INACTIVE;
+                    else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton))
+                        theme.stateId = CBS_PUSHED;
+                    else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton))
+                        theme.stateId = CBS_HOT;
+                    else
+                        theme.stateId = CBS_NORMAL;
+                    d->drawBackground(theme);
+                }
+            }
+            if (option->subControls & QStyle::SC_MdiMinButton) {
+                buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget);
+                if (theme.isValid()) {
+                    theme.partId = WP_MDIMINBUTTON;
+                    theme.rect = buttonRect;
+                    if (!(flags & State_Enabled))
+                        theme.stateId = CBS_INACTIVE;
+                    else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton))
+                        theme.stateId = CBS_PUSHED;
+                    else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton))
+                        theme.stateId = CBS_HOT;
+                    else
+                        theme.stateId = CBS_NORMAL;
+                    d->drawBackground(theme);
+                }
+            }
+        }
+        break;
+#endif //QT_NO_WORKSPACE
+#ifndef QT_NO_DIAL
+    case CC_Dial:
+        if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
+            QStyleHelper::drawDial(dial, p);
+        break;
+#endif // QT_NO_DIAL
+    default:
+        QWindowsStyle::drawComplexControl(cc, option, p, widget);
+        break;
+    }
+}
+
+/*! \reimp */
+int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const
+{
+    if (!QWindowsXPStylePrivate::useXP())
+        return QWindowsStyle::pixelMetric(pm, option, widget);
+
+    int res = 0;
+    switch (pm) {
+    case PM_MenuBarPanelWidth:
+        res = 0;
+        break;
+
+    case PM_DefaultFrameWidth:
+        if (qobject_cast<const QListView*>(widget))
+            res = 2;
+        else
+            res = 1;
+        break;
+    case PM_MenuPanelWidth:
+    case PM_SpinBoxFrameWidth:
+        res = 1;
+        break;
+
+    case PM_TabBarTabOverlap:
+    case PM_MenuHMargin:
+    case PM_MenuVMargin:
+        res = 2;
+        break;
+
+    case PM_TabBarBaseOverlap:
+        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+            switch (tab->shape) {
+            case QTabBar::RoundedNorth:
+            case QTabBar::TriangularNorth:
+                res = 1;
+                break;
+            case QTabBar::RoundedSouth:
+            case QTabBar::TriangularSouth:
+                res = 2;
+                break;
+            case QTabBar::RoundedEast:
+            case QTabBar::TriangularEast:
+                res = 3;
+                break;
+            case QTabBar::RoundedWest:
+            case QTabBar::TriangularWest:
+                res = 1;
+                break;
+            }
+        }
+        break;
+
+    case PM_SplitterWidth:
+        res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width());
+        break;
+
+    case PM_IndicatorWidth:
+    case PM_IndicatorHeight:
+        {
+            XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
+            if (theme.isValid()) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                res = (pm == PM_IndicatorWidth) ? size.cx : size.cy;
+            }
+        }
+        break;
+
+    case PM_ExclusiveIndicatorWidth:
+    case PM_ExclusiveIndicatorHeight:
+        {
+            XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
+            if (theme.isValid()) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                res = (pm == PM_ExclusiveIndicatorWidth) ? size.cx : size.cy;
+            }
+        }
+        break;
+
+    case PM_ProgressBarChunkWidth:
+        {
+            Qt::Orientation orient = Qt::Horizontal;
+            if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+                orient = pb2->orientation;
+            XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
+            if (theme.isValid()) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                res = (orient == Qt::Horizontal) ? size.cx : size.cy;
+            }
+        }
+        break;
+
+    case PM_SliderThickness:
+        {
+            XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB);
+            if (theme.isValid()) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                res = size.cy;
+            }
+        }
+        break;
+
+    case PM_TitleBarHeight:
+        {
+#ifdef QT3_SUPPORT
+            if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+                res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+            } else
+#endif
+            if (widget && (widget->windowType() == Qt::Tool))
+                res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+            else
+                res = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+        }
+        break;
+
+    case PM_MdiSubWindowFrameWidth:
+        {
+            XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE);
+            if (theme.isValid()) {
+                SIZE size;
+                pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size);
+                res = size.cx-1;
+            }
+        }
+        break;
+
+    case PM_MdiSubWindowMinimizedWidth:
+        res = 160;
+        break;
+
+#ifndef QT_NO_TOOLBAR
+    case PM_ToolBarHandleExtent:
+        res = int(QStyleHelper::dpiScaled(8.));
+        break;
+
+#endif // QT_NO_TOOLBAR
+    case PM_DockWidgetFrameWidth:
+    {
+        XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE);
+        if (theme.isValid()) {
+            SIZE size;
+            pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+            res = size.cx;
+        }
+    }
+    break;
+    case PM_DockWidgetSeparatorExtent:
+        res = int(QStyleHelper::dpiScaled(4.));
+        break;
+    case PM_DockWidgetTitleMargin:
+        res = int(QStyleHelper::dpiScaled(4.));
+        break;
+
+    case PM_ButtonShiftHorizontal:
+    case PM_ButtonShiftVertical:
+        if (qstyleoption_cast<const QStyleOptionToolButton *>(option))
+            res = 1;
+        else
+            res = 0;
+        break;
+
+    case PM_ButtonDefaultIndicator:
+        res = 0;
+        break;
+
+    default:
+        res = QWindowsStyle::pixelMetric(pm, option, widget);
+    }
+
+    return res;
+}
+
+/*
+  This function is used by subControlRect to check if a button
+  should be drawn for the given subControl given a set of window flags.
+*/
+static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
+
+    bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+    bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+    const uint flags = tb->titleBarFlags;
+    bool retVal = false;
+    switch (sc) {
+    case QStyle::SC_TitleBarContextHelpButton:
+        if (flags & Qt::WindowContextHelpButtonHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarMinButton:
+        if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarNormalButton:
+        if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+            retVal = true;
+        else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarMaxButton:
+        if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarShadeButton:
+        if (!isMinimized &&  flags & Qt::WindowShadeButtonHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarUnshadeButton:
+        if (isMinimized && flags & Qt::WindowShadeButtonHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarCloseButton:
+        if (flags & Qt::WindowSystemMenuHint)
+            retVal = true;
+        break;
+    case QStyle::SC_TitleBarSysMenu:
+        if (flags & Qt::WindowSystemMenuHint)
+            retVal = true;
+        break;
+    default :
+        retVal = true;
+    }
+    return retVal;
+}
+
+/*!
+    \reimp
+*/
+QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
+                                      SubControl subControl, const QWidget *widget) const
+{
+    if (!QWindowsXPStylePrivate::useXP())
+        return QWindowsStyle::subControlRect(cc, option, subControl, widget);
+
+    QRect rect;
+
+    switch (cc) {
+    case CC_TitleBar:
+        if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+            if (!buttonVisible(subControl, tb))
+                return rect;
+            const bool isToolTitle = false;
+            const int height = tb->rect.height();
+            const int width = tb->rect.width();
+            int buttonHeight = GetSystemMetrics(SM_CYSIZE) - 4;
+            int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
+            const int delta = buttonWidth + 2;
+            int controlTop = option->rect.bottom() - buttonHeight - 2;
+            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;
+            bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+            bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+            int offset = 0;
+
+            switch (subControl) {
+            case SC_TitleBarLabel:
+                rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
+                if (isToolTitle) {
+                    if (sysmenuHint) {
+                        rect.adjust(0, 0, -buttonWidth - 3, 0);
+                    }
+                    if (minimizeHint || maximizeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                } else {
+                    if (sysmenuHint) {
+                        const int leftOffset = height - 8;
+                        rect.adjust(leftOffset, 0, 0, 0);
+                    }
+                    if (minimizeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                    if (maximizeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                    if (contextHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                    if (shadeHint)
+                        rect.adjust(0, 0, -buttonWidth - 2, 0);
+                }
+                break;
+
+            case SC_TitleBarContextHelpButton:
+                if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+                    offset += delta;
+                //fall through
+            case SC_TitleBarMinButton:
+                if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+                    offset += delta;
+                else if (subControl == SC_TitleBarMinButton)
+                    break;
+                //fall through
+            case SC_TitleBarNormalButton:
+                if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+                    offset += delta;
+                else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+                    offset += delta;
+                else if (subControl == SC_TitleBarNormalButton)
+                    break;
+                //fall through
+            case SC_TitleBarMaxButton:
+                if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+                    offset += delta;
+                else if (subControl == SC_TitleBarMaxButton)
+                    break;
+                //fall through
+            case SC_TitleBarShadeButton:
+                if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+                    offset += delta;
+                else if (subControl == SC_TitleBarShadeButton)
+                    break;
+                //fall through
+            case SC_TitleBarUnshadeButton:
+                if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+                    offset += delta;
+                else if (subControl == SC_TitleBarUnshadeButton)
+                    break;
+                //fall through
+            case SC_TitleBarCloseButton:
+                if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+                    offset += delta;
+                else if (subControl == SC_TitleBarCloseButton)
+                    break;
+
+                rect.setRect(width - offset - controlTop + 1, controlTop,
+                             buttonWidth, buttonHeight);
+                break;
+
+            case SC_TitleBarSysMenu:
+                {
+                    const int controlTop = 6;
+                    const int controlHeight = height - controlTop - 3;
+                    const 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());
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+
+    case CC_ComboBox:
+        if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+            int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
+            int xpos = x;
+            xpos += wi - 1 - 16;
+
+            switch (subControl) {
+            case SC_ComboBoxFrame:
+                rect = cmb->rect;
+                break;
+
+            case SC_ComboBoxArrow:
+                rect = QRect(xpos, y+1, 16, he-2);
+                break;
+
+            case SC_ComboBoxEditField:
+                rect = QRect(x+2, y+2, wi-3-16, he-4);
+                break;
+
+            case SC_ComboBoxListBoxPopup:
+                rect = cmb->rect;
+                break;
+
+            default:
+                break;
+            }
+        }
+        break;
+#ifndef QT_NO_WORKSPACE
+    case CC_MdiControls:
+    {
+        int numSubControls = 0;
+        if (option->subControls & SC_MdiCloseButton)
+            ++numSubControls;
+        if (option->subControls & SC_MdiMinButton)
+            ++numSubControls;
+        if (option->subControls & SC_MdiNormalButton)
+            ++numSubControls;
+        if (numSubControls == 0)
+            break;
+
+        int buttonWidth = option->rect.width()/ numSubControls;
+        int offset = 0;
+        switch (subControl) {
+        case SC_MdiCloseButton:
+            // Only one sub control, no offset needed.
+            if (numSubControls == 1)
+                break;
+            offset += buttonWidth;
+            //FALL THROUGH
+        case SC_MdiNormalButton:
+            // No offset needed if
+            // 1) There's only one sub control
+            // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
+            if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
+                break;
+            if (option->subControls & SC_MdiNormalButton)
+                offset += buttonWidth;
+            break;
+        default:
+            break;
+        }
+        rect = QRect(offset, 0, buttonWidth, option->rect.height());
+        break;
+    }
+#endif // QT_NO_WORKSPACE
+
+    default:
+        rect = visualRect(option->direction, option->rect,
+                          QWindowsStyle::subControlRect(cc, option, subControl, widget));
+        break;
+    }
+    return visualRect(option->direction, option->rect, rect);
+}
+
+/*!
+    \reimp
+*/
+QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *option,
+                                        const QSize &contentsSize, const QWidget *widget) const
+{
+    if (!QWindowsXPStylePrivate::useXP())
+        return QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
+
+    QSize sz(contentsSize);
+    switch (ct) {
+    case CT_LineEdit:
+    case CT_ComboBox:
+        {
+            XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+            HTHEME theme = buttontheme.handle();
+            MARGINS borderSize;
+            if (theme) {
+                int result = pGetThemeMargins(theme,
+                                              NULL,
+                                              BP_PUSHBUTTON,
+                                              PBS_NORMAL,
+                                              TMT_CONTENTMARGINS,
+                                              NULL,
+                                              &borderSize);
+                if (result == S_OK) {
+                    sz += QSize(borderSize.cxLeftWidth + borderSize.cxRightWidth - 2,
+                                borderSize.cyBottomHeight + borderSize.cyTopHeight - 2);
+                }
+                sz += QSize(23, 0); //arrow button
+            }
+        }
+        break;
+    case CT_SpinBox:
+        {
+            //Spinbox adds frame twice
+            sz = QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
+            int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+            sz -= QSize(2*border, 2*border);
+        }
+        break;
+    case CT_TabWidget:
+        sz += QSize(6, 6);
+        break;
+    case CT_Menu:
+        sz += QSize(1, 0);
+        break;
+#ifndef QT_NO_MENUBAR
+    case CT_MenuBarItem:
+        if (!sz.isEmpty())
+            sz += QSize(windowsItemHMargin * 5 + 1, 6);
+        break;
+#endif
+    case CT_MenuItem:
+        if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+        {
+            if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) {
+                sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+                sz.setHeight(sz.height() - 2);
+                return sz;
+            }
+        }
+        sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+        break;
+
+    case CT_MdiControls:
+        if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
+            int width = 0;
+            if (styleOpt->subControls & SC_MdiMinButton)
+                width += 17 + 1;
+            if (styleOpt->subControls & SC_MdiNormalButton)
+                width += 17 + 1;
+            if (styleOpt->subControls & SC_MdiCloseButton)
+                width += 17 + 1;
+            sz = QSize(width, 19);
+        } else {
+            sz = QSize(54, 19);
+        }
+        break;
+
+    default:
+        sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+        break;
+    }
+
+    return sz;
+}
+
+
+/*! \reimp */
+int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+                               QStyleHintReturn *returnData) const
+{
+  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+    if (!QWindowsXPStylePrivate::useXP())
+        return QWindowsStyle::styleHint(hint, option, widget, returnData);
+
+    int res = 0;
+    switch (hint) {
+
+    case SH_EtchDisabledText:
+        res = (qobject_cast<const QLabel*>(widget) != 0);
+        break;
+
+    case SH_SpinControls_DisableOnBounds:
+        res = 0;
+        break;
+
+    case SH_TitleBar_AutoRaise:
+    case SH_TitleBar_NoBorder:
+        res = 1;
+        break;
+
+    case SH_GroupBox_TextLabelColor:
+        if (!widget || (widget && widget->isEnabled()))
+            res = d->groupBoxTextColor;
+        else
+            res = d->groupBoxTextColorDisabled;
+        break;
+
+    case SH_Table_GridLineColor:
+        res = 0xC0C0C0;
+        break;
+
+    case SH_WindowFrame_Mask:
+        {
+            res = 1;
+            QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData);
+            const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
+            if (mask && titlebar) {
+                XPThemeData themeData;
+                if (titlebar->titleBarState & Qt::WindowMinimized) {
+                    themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, option->rect);
+                } else
+                    themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, option->rect);
+                mask->region = d->region(themeData);
+            }
+        }
+        break;
+#ifndef QT_NO_RUBBERBAND
+    case SH_RubberBand_Mask:
+        if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
+            res = 0;
+            break;
+        }
+#endif // QT_NO_RUBBERBAND
+
+    case SH_ItemView_DrawDelegateFrame:
+        res = 1;
+        break;
+
+    default:
+        res =QWindowsStyle::styleHint(hint, option, widget, returnData);
+    }
+
+    return res;
+}
+
+/*! \reimp */
+QPalette QWindowsXPStyle::standardPalette() const
+{
+    if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal)
+        return *QApplicationPrivate::sys_pal;
+    else
+        return QWindowsStyle::standardPalette();
+}
+
+/*!
+    \reimp
+*/
+QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
+                                        const QWidget *widget) const
+{
+    if (!QWindowsXPStylePrivate::useXP())
+        return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+
+    switch(standardPixmap) {
+    case SP_TitleBarMaxButton:
+    case SP_TitleBarCloseButton:
+        if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+        {
+            if (widget && widget->isWindow()) {
+                XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                if (theme.isValid()) {
+                    SIZE sz;
+                    pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz);
+                    return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(QSize(sz.cx, sz.cy));
+                }
+            }
+        }
+        break;
+    default:
+        break;
+    }
+    return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+/*!
+    \internal
+*/
+QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
+                                                  const QStyleOption *option,
+                                                  const QWidget *widget) const
+{
+    if (!QWindowsXPStylePrivate::useXP()) {
+        return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+    }
+
+    QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+    switch(standardIcon) {
+    case SP_TitleBarMaxButton:
+        if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+        {
+            if (d->dockFloat.isNull()) {
+                XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL);
+                if (theme.isValid()) {
+                    SIZE size;
+                    pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
+                    QPixmap pm = QPixmap(size.cx, size.cy);
+                    pm.fill(Qt::transparent);
+                    QPainter p(&pm);
+                    theme.painter = &p;
+                    theme.rect = QRect(0, 0, size.cx, size.cy);
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off);    // Normal
+                    pm.fill(Qt::transparent);
+                    theme.stateId = MAXBS_PUSHED;
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On);     // Pressed
+                    pm.fill(Qt::transparent);
+                    theme.stateId = MAXBS_HOT;
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off);    // Hover
+                    pm.fill(Qt::transparent);
+                    theme.stateId = MAXBS_INACTIVE;
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off);  // Disabled
+                }
+            }
+            if (widget && widget->isWindow())
+                return d->dockFloat;
+
+        }
+        break;
+    case SP_TitleBarCloseButton:
+        if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+        {
+            if (d->dockClose.isNull()) {
+                XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                if (theme.isValid()) {
+                    SIZE size;
+                    pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+                    QPixmap pm = QPixmap(size.cx, size.cy);
+                    pm.fill(Qt::transparent);
+                    QPainter p(&pm);
+                    theme.painter = &p;
+                    theme.partId = WP_CLOSEBUTTON; // ####
+                    theme.rect = QRect(0, 0, size.cx, size.cy);
+                    d->drawBackground(theme);
+                    d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off);    // Normal
+                    pm.fill(Qt::transparent);
+                    theme.stateId = CBS_PUSHED;
+                    d->drawBackground(theme);
+                    d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On);     // Pressed
+                    pm.fill(Qt::transparent);
+                    theme.stateId = CBS_HOT;
+                    d->drawBackground(theme);
+                    d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off);    // Hover
+                    pm.fill(Qt::transparent);
+                    theme.stateId = CBS_INACTIVE;
+                    d->drawBackground(theme);
+                    d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off);  // Disabled
+                }
+            }
+            if (widget && widget->isWindow())
+                return d->dockClose;
+        }
+        break;
+    case SP_TitleBarNormalButton:
+        if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+        {
+            if (d->dockFloat.isNull()) {
+                XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL);
+                if (theme.isValid()) {
+                    SIZE size;
+                    pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
+                    QPixmap pm = QPixmap(size.cx, size.cy);
+                    pm.fill(Qt::transparent);
+                    QPainter p(&pm);
+                    theme.painter = &p;
+                    theme.rect = QRect(0, 0, size.cx, size.cy);
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off);    // Normal
+                    pm.fill(Qt::transparent);
+                    theme.stateId = RBS_PUSHED;
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On);     // Pressed
+                    pm.fill(Qt::transparent);
+                    theme.stateId = RBS_HOT;
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off);    // Hover
+                    pm.fill(Qt::transparent);
+                    theme.stateId = RBS_INACTIVE;
+                    d->drawBackground(theme);
+                    d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off);  // Disabled
+                }
+            }
+            if (widget && widget->isWindow())
+                return d->dockFloat;
+
+        }
+        break;
+    default:
+        break;
+    }
+
+    return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+/*!
+    \internal
+
+    Constructs a QWindowsXPStyle object.
+*/
+QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd)
+{
+}
+
+
+// Debugging code ---------------------------------------------------------------------[ START ]---
+// The code for this point on is not compiled by default, but only used as assisting
+// debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file.
+
+#ifdef DEBUG_XP_STYLE
+// The schema file expects these to be defined by the user.
+#define TMT_ENUMDEF 8
+#define TMT_ENUMVAL TEXT('A')
+#define TMT_ENUM    TEXT('B')
+#define SCHEMA_STRINGS // For 2nd pass on schema file
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <tmschema.h>
+QT_END_INCLUDE_NAMESPACE
+
+// A property's value, type and name combo
+struct PropPair {
+    int propValue;
+    int propType;
+    LPCWSTR propName;
+};
+
+// Operator for sorting of PropPairs
+bool operator<(PropPair a, PropPair b) {
+    return wcscmp(a.propName, b.propName) < 0;
+}
+
+// Our list of all possible properties
+static QList<PropPair> all_props;
+
+
+/*! \internal
+    Dumps a portion of the full native DIB section double buffer.
+    The DIB section double buffer is only used when doing special
+    transformations to the theme part, or when the real double
+    buffer in the paintengine does not have an HDC we may use
+    directly.
+    Since we cannot rely on the pixel data we get from Microsoft
+    when drawing into the DIB section, we use this function to
+    see the actual data we got, and can determin the appropriate
+    action.
+*/
+void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
+{
+    if (w && h) {
+        static int pCount = 0;
+        DWORD *bufPix = (DWORD*)bufferPixels;
+
+        char *bufferDump = new char[bufferH * bufferW * 16];
+        char *bufferPos = bufferDump;
+
+        memset(bufferDump, 0, sizeof(bufferDump));
+        bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
+        bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
+        bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
+        for (int iy = 0; iy < h; ++iy) {
+            bufferPos += sprintf(bufferPos, "\n    ");
+            bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4));
+            for (int ix = 0; ix < w; ++ix) {
+                bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix);
+                ++bufPix;
+            }
+        }
+        bufferPos += sprintf(bufferPos, "\n};\n\n");
+        printf(bufferDump);
+
+        delete bufferDump;
+        ++pCount;
+    }
+}
+
+/*! \internal
+    Shows the value of a given property for a part.
+*/
+static void showProperty(XPThemeData &themeData, const PropPair &prop)
+{
+    PROPERTYORIGIN origin = PO_NOTFOUND;
+    pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+    const char *originStr;
+    switch(origin) {
+    case PO_STATE:
+        originStr = "State ";
+        break;
+    case PO_PART:
+        originStr = "Part  ";
+        break;
+    case PO_CLASS:
+        originStr = "Class ";
+        break;
+    case PO_GLOBAL:
+        originStr = "Globl ";
+        break;
+    case PO_NOTFOUND:
+    default:
+        originStr = "Unkwn ";
+        break;
+    }
+
+    switch(prop.propType) {
+    case TMT_STRING:
+        {
+            wchar_t buffer[512];
+            pGetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
+            printf("  (%sString)  %-20S: %S\n", originStr, prop.propName, buffer);
+        }
+        break;
+    case TMT_ENUM:
+        {
+            int result = -1;
+            pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sEnum)    %-20S: %d\n", originStr, prop.propName, result);
+        }
+        break;
+    case TMT_INT:
+        {
+            int result = -1;
+            pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sint)     %-20S: %d\n", originStr, prop.propName, result);
+        }
+        break;
+    case TMT_BOOL:
+        {
+            BOOL result = false;
+            pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sbool)    %-20S: %d\n", originStr, prop.propName, result);
+        }
+        break;
+    case TMT_COLOR:
+        {
+            COLORREF result = 0;
+            pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%scolor)   %-20S: 0x%08X\n", originStr, prop.propName, result);
+        }
+        break;
+    case TMT_MARGINS:
+        {
+            MARGINS result;
+            memset(&result, 0, sizeof(result));
+            pGetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result);
+            printf("  (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr,
+                   prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight);
+        }
+        break;
+    case TMT_FILENAME:
+        {
+            wchar_t buffer[512];
+            pGetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
+            printf("  (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer);
+        }
+        break;
+    case TMT_SIZE:
+        {
+            SIZE result1;
+            SIZE result2;
+            SIZE result3;
+            memset(&result1, 0, sizeof(result1));
+            memset(&result2, 0, sizeof(result2));
+            memset(&result3, 0, sizeof(result3));
+            pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN,  &result1);
+            pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2);
+            pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3);
+            printf("  (%ssize)    %-20S: Min (%d, %d),  True(%d, %d),  Draw(%d, %d)\n", originStr, prop.propName,
+                   result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy);
+        }
+        break;
+    case TMT_POSITION:
+        {
+            POINT result;
+            memset(&result, 0, sizeof(result));
+            pGetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y);
+        }
+        break;
+    case TMT_RECT:
+        {
+            RECT result;
+            memset(&result, 0, sizeof(result));
+            pGetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sRect)    %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom);
+        }
+        break;
+    case TMT_FONT:
+        {
+            LOGFONT result;
+            memset(&result, 0, sizeof(result));
+            pGetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sFont)    %-20S: %S  height(%d)  width(%d)  weight(%d)\n", originStr, prop.propName,
+                   result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight);
+        }
+        break;
+    case TMT_INTLIST:
+        {
+            INTLIST result;
+            memset(&result, 0, sizeof(result));
+            pGetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+            printf("  (%sInt list)%-20S: { ", originStr, prop.propName);
+            for (int i = 0; i < result.iValueCount; ++i)
+                printf("%d ", result.iValues[i]);
+            printf("}\n");
+        }
+        break;
+    default:
+        printf("    %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType);
+    }
+}
+
+/*! \internal
+    Dump all valid properties for a part.
+    If it's the first time this function is called, then the name,
+    enum value and documentation of all properties are shown, as
+    well as all global properties.
+*/
+void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData)
+{
+    if (!all_props.count()) {
+        const TMSCHEMAINFO *infoTable = GetSchemaInfo();
+        for (int i = 0; i < infoTable->iPropCount; ++i) {
+            int propType  = infoTable->pPropTable[i].bPrimVal;
+            int propValue = infoTable->pPropTable[i].sEnumVal;
+            LPCWSTR propName = infoTable->pPropTable[i].pszName;
+
+            switch(propType) {
+            case TMT_ENUMDEF:
+            case TMT_ENUMVAL:
+                continue;
+            default:
+                if (propType != propValue) {
+                    PropPair prop;
+                    prop.propValue = propValue;
+                    prop.propName  = propName;
+                    prop.propType  = propType;
+                    all_props.append(prop);
+                }
+            }
+        }
+        qSort(all_props);
+
+        {// List all properties
+            printf("part properties count = %d:\n", all_props.count());
+            printf("      Enum  Property Name        Description\n");
+            printf("-----------------------------------------------------------\n");
+            wchar_t themeName[256];
+            pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0);
+            for (int j = 0; j < all_props.count(); ++j) {
+                PropPair prop = all_props.at(j);
+                wchar_t buf[500];
+                pGetThemeDocumentationProperty(themeName, prop.propName, buf, 500);
+                printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf);
+            }
+        }
+
+        {// Show Global values
+            printf("Global Properties:\n");
+            for (int j = 0; j < all_props.count(); ++j) {
+                PropPair prop = all_props.at(j);
+                PROPERTYORIGIN origin = PO_NOTFOUND;
+                pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+                if (origin == PO_GLOBAL) {
+                    showProperty(themeData, prop);
+                }
+            }
+        }
+    }
+
+    for (int j = 0; j < all_props.count(); ++j) {
+        PropPair prop = all_props.at(j);
+        PROPERTYORIGIN origin = PO_NOTFOUND;
+        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+        if (origin != PO_NOTFOUND)
+        {
+            showProperty(themeData, prop);
+        }
+    }
+}
+#endif
+// Debugging code -----------------------------------------------------------------------[ END ]---
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_WINDOWSXP