Qt 4.8
qwindowsxpstyle.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "qwindowsxpstyle.h"
42 #include "qwindowsxpstyle_p.h"
43 
44 #if !defined(QT_NO_STYLE_WINDOWSXP) || defined(QT_PLUGIN)
45 
46 #include <private/qobject_p.h>
47 #include <private/qpaintengine_raster_p.h>
48 #include <private/qapplication_p.h>
49 #include <private/qstylehelper_p.h>
50 #include <private/qwidget_p.h>
51 #include <private/qsystemlibrary_p.h>
52 #include <qpainter.h>
53 #include <qpaintengine.h>
54 #include <qwidget.h>
55 #include <qapplication.h>
56 #include <qpixmapcache.h>
57 
58 #include <qdesktopwidget.h>
59 #include <qtoolbutton.h>
60 #include <qtabbar.h>
61 #include <qcombobox.h>
62 #include <qscrollbar.h>
63 #include <qheaderview.h>
64 #include <qspinbox.h>
65 #include <qlistview.h>
66 #include <qstackedwidget.h>
67 #include <qpushbutton.h>
68 #include <qtoolbar.h>
69 #include <qlabel.h>
70 #include <qvarlengtharray.h>
71 #include <qdebug.h>
72 
74 
75 // Runtime resolved theme engine function calls
76 typedef bool (WINAPI *PtrIsAppThemed)();
77 typedef bool (WINAPI *PtrIsThemeActive)();
78 typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
79 typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
80 typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
81 typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
82 typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
83 typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
84 typedef HRESULT (WINAPI *PtrGetThemeDocumentationProperty)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, OUT LPWSTR pszValueBuff, int cchMaxValChars);
85 typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
86 typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
87 typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
88 typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
89 typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
90 typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
91 typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
92 typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
93 typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
94 typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
95 typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
96 typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
97 typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
98 typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
99 typedef HRESULT (WINAPI *PtrGetThemeBackgroundRegion)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pRect, OUT HRGN *pRegion);
100 typedef BOOL (WINAPI *PtrIsThemeBackgroundPartiallyTransparent)(HTHEME hTheme, int iPartId, int iStateId);
101 
126 
127 // General const values
128 static const int windowsItemFrame = 2; // menu item frame width
129 static const int windowsItemHMargin = 3; // menu item hor text margin
130 static const int windowsItemVMargin = 0; // menu item ver text margin
131 static const int windowsArrowHMargin = 6; // arrow horizontal margin
132 static const int windowsRightBorder = 12; // right border on windows
133 
134 // External function calls
135 extern Q_GUI_EXPORT HDC qt_win_display_dc();
136 extern QRegion qt_region_from_HRGN(HRGN rgn);
137 
138 
139 
140 // Theme data helper ------------------------------------------------------------------------------
141 /* \internal
142  Returns true if the themedata is valid for use.
143 */
145 {
146  return QWindowsXPStylePrivate::useXP() && name.size() && handle();
147 }
148 
149 
150 /* \internal
151  Returns the theme engine handle to the specific class.
152  If the handle hasn't been opened before, it opens the data, and
153  adds it to a static map, for caching.
154 */
156 {
158  return 0;
159 
162 
163  if (!htheme) {
165  if (htheme) {
169  }
170  }
171 
172  return htheme;
173 }
174 
175 /* \internal
176  Converts a QRect to the native RECT structure.
177 */
178 RECT XPThemeData::toRECT(const QRect &qr)
179 {
180  RECT r;
181  r.left = qr.x();
182  r.right = qr.x() + qr.width();
183  r.top = qr.y();
184  r.bottom = qr.y() + qr.height();
185  return r;
186 }
187 
188 /* \internal
189  Returns the native region of a part, if the part is considered
190  transparent. The region is scaled to the parts size (rect).
191 */
193 {
195  return 0;
196 
197  HRGN hrgn;
198  HDC dc = painter == 0 ? 0 : painter->paintEngine()->getDC();
199  RECT nativeRect = toRECT(rect);
200  pGetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn);
201  if (dc)
202  painter->paintEngine()->releaseDC(dc);
203  return hrgn;
204 }
205 
206 // QWindowsXPStylePrivate -------------------------------------------------------------------------
207 // Static initializations
211 bool QWindowsXPStylePrivate::use_xp = false;
213 
214 /* \internal
215  Checks if the theme engine can/should be used, or if we should
216  fall back to Windows style.
217 */
219 {
220  if (!update)
221  return use_xp;
222  return (use_xp = resolveSymbols() && pIsThemeActive()
223  && (pIsAppThemed() || !QApplication::instance()));
224 }
225 
226 /* \internal
227  Handles refcounting, and queries the theme engine for usage.
228 */
230 {
231  if (ref.ref() && !force)
232  return;
233  if (!force) // -1 based atomic refcounting
234  ref.ref();
235 
236  useXP(true);
237 }
238 
239 /* \internal
240  Cleans up all static data.
241 */
243 {
244  if(bufferBitmap) {
245  if (bufferDC && nullBitmap)
246  SelectObject(bufferDC, nullBitmap);
247  DeleteObject(bufferBitmap);
248  bufferBitmap = 0;
249  }
250 
251  if(bufferDC)
252  DeleteDC(bufferDC);
253  bufferDC = 0;
254 
255  if (ref.deref() && !force)
256  return;
257  if (!force) // -1 based atomic refcounting
258  ref.deref();
259 
260  use_xp = false;
261  cleanupHandleMap();
262  if (limboWidget) {
264  delete limboWidget;
265  else
266  limboWidget->deleteLater();
267  }
268  delete tabbody;
269  limboWidget = 0;
270  tabbody = 0;
271 }
272 
273 /* \internal
274  Closes all open theme data handles to ensure that we don't leak
275  resources, and that we don't refere to old handles when for
276  example the user changes the theme style.
277 */
279 {
280  if (!handleMap)
281  return;
282 
284  for (it = handleMap->begin(); it != handleMap->end(); ++it)
285  pCloseThemeData(it.value());
286  delete handleMap;
287  handleMap = 0;
288 }
289 
291 {
292  if (!widget)
293  return false;
294  const QWidget *parent1 = widget->parentWidget();
295  // Exlude dialogs or other toplevels parented on item views.
296  if (!parent1 || parent1->isWindow())
297  return false;
298  const QWidget *parent2 = parent1->parentWidget();
299  return parent2 && widget->inherits("QLineEdit")
300  && parent2->inherits("QAbstractItemView");
301 }
302 
313 {
314  if (widget && widget->internalWinId())
315  return widget->internalWinId();
316 
317  if (!limboWidget) {
318  limboWidget = new QWidget(0);
319  limboWidget->createWinId();
320  limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
321  // We don't need this internal widget to appear in QApplication::topLevelWidgets()
323  QWidgetPrivate::allWidgets->remove(limboWidget);
324  }
325 
326  return limboWidget->winId();
327 }
328 
338 {
339  if (!tabbody) {
340  SIZE sz;
341  XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY);
342  pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
343 
344  tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
345  QPainter painter(tabbody);
346  theme.rect = QRect(0, 0, sz.cx, sz.cy);
347  drawBackground(theme);
348  // We fill with the last line of the themedata, that
349  // way we don't get a tiled pixmap inside big tabs
350  QPixmap temp(sz.cx, 1);
351  painter.drawPixmap(0, 0, temp, 0, sz.cy-1, -1, -1);
352  painter.drawTiledPixmap(0, sz.cy, sz.cx, tabbody->height()-sz.cy, temp);
353  }
354  return tabbody;
355 }
356 
365 {
366  static bool tried = false;
367  if (!tried) {
368  QSystemLibrary themeLib(QLatin1String("uxtheme"));
369  pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
370  if (pIsAppThemed) {
371  pIsThemeActive = (PtrIsThemeActive )themeLib.resolve("IsThemeActive");
372  pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
373  pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
374  pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
375  pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
376  pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
377  pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
378  pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
379  pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
380  pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
381  pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
382  pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
383  pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
384  pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
385  pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
386  pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
387  pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
388  pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
389  pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
390  pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
391  pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
392  pGetThemeBackgroundRegion = (PtrGetThemeBackgroundRegion )themeLib.resolve("GetThemeBackgroundRegion");
393  pGetThemeDocumentationProperty = (PtrGetThemeDocumentationProperty )themeLib.resolve("GetThemeDocumentationProperty");
394  pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
395  }
396  tried = true;
397  }
398 
399  return pIsAppThemed != 0;
400 }
401 
410 HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
411 {
412  // If we already have a HBITMAP which is of adequate size, just return that
413  if (bufferBitmap) {
414  if (bufferW >= w && bufferH >= h)
415  return bufferBitmap;
416  // Not big enough, discard the old one
417  if (bufferDC && nullBitmap)
418  SelectObject(bufferDC, nullBitmap);
419  DeleteObject(bufferBitmap);
420  bufferBitmap = 0;
421  }
422 
423  w = qMax(bufferW, w);
424  h = qMax(bufferH, h);
425 
426  if (!bufferDC)
427  bufferDC = CreateCompatibleDC(qt_win_display_dc());
428 
429  // Define the header
430  BITMAPINFO bmi;
431  memset(&bmi, 0, sizeof(bmi));
432  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
433  bmi.bmiHeader.biWidth = w;
434  bmi.bmiHeader.biHeight = -h;
435  bmi.bmiHeader.biPlanes = 1;
436  bmi.bmiHeader.biBitCount = 32;
437  bmi.bmiHeader.biCompression = BI_RGB;
438 
439  // Create the pixmap
440  bufferPixels = 0;
441  bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
442  GdiFlush();
443  nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
444 
445  if (!bufferBitmap) {
446  qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection");
447  bufferW = 0;
448  bufferH = 0;
449  return 0;
450  }
451  if (!bufferPixels) {
452  qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data");
453  bufferW = 0;
454  bufferH = 0;
455  return 0;
456  }
457  bufferW = w;
458  bufferH = h;
459 #ifdef DEBUG_XP_STYLE
460  qDebug("Creating new dib section (%d, %d)", w, h);
461 #endif
462  return bufferBitmap;
463 }
464 
475 {
476  return pIsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId,
477  themeData.stateId);
478 }
479 
480 
485 {
486  HRGN hRgn = 0;
487  RECT rect = themeData.toRECT(themeData.rect);
488  if (!SUCCEEDED(pGetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
489  themeData.stateId, &rect, &hRgn)))
490  return QRegion();
491 
492  HRGN dest = CreateRectRgn(0, 0, 0, 0);
493  const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
494 
495  QRegion region;
496 
497  if (success)
498  region = qt_region_from_HRGN(dest);
499 
500  DeleteObject(hRgn);
501  DeleteObject(dest);
502 
503  return region;
504 }
505 
513 {
514  HRGN hrgn = themeData.mask();
515  if (hrgn && widget)
516  SetWindowRgn(winId(widget), hrgn, true);
517 }
518 
529 {
530  const int startX = rect.left();
531  const int startY = rect.top();
532  const int w = rect.width();
533  const int h = rect.height();
534 
535  for (int y = startY; y < h; ++y) {
536  register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
537  for (int x = startX; x < w; ++x, ++buffer) {
538  int alpha = (*buffer) >> 24;
539  if (alpha != 0xFF) // buffer has been touched
540  return true;
541  }
542  }
543  return false;
544 }
545 
554 {
555  const int startX = rect.left();
556  const int startY = rect.top();
557  const int w = rect.width();
558  const int h = rect.height();
559 
560  int firstAlpha = -1;
561  for (int y = startY; y < h/2; ++y) {
562  register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
563  for (int x = startX; x < w; ++x, ++buffer) {
564  int alpha = (*buffer) >> 24;
565  if (firstAlpha == -1)
566  firstAlpha = alpha;
567  else if (alpha != firstAlpha)
568  return true;
569  }
570  }
571  return false;
572 }
573 
586 {
587  const int startX = rect.left();
588  const int startY = rect.top();
589  const int w = rect.width();
590  const int h = rect.height();
591  bool hasFixedAlphaValue = false;
592 
593  for (int y = startY; y < h; ++y) {
594  register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
595  for (register int x = startX; x < w; ++x, ++buffer) {
596  uint pixel = *buffer;
597  int alpha = qAlpha(pixel);
598  if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {
599  *buffer |= 0xff000000;
600  hasFixedAlphaValue = true;
601  }
602  }
603  }
604  return hasFixedAlphaValue;
605 }
606 
620 {
621  const int startX = rect.left();
622  const int startY = rect.top();
623  const int w = rect.width();
624  const int h = rect.height();
625  bool valueChange = false;
626 
627  // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
628  for (int y = startY; y < h; ++y) {
629  register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
630  for (register int x = startX; x < w; ++x, ++buffer) {
631  if (allPixels) {
632  *buffer |= 0xFF000000;
633  continue;
634  }
635  register unsigned int alphaValue = (*buffer) & 0xFF000000;
636  if (alphaValue == 0xFF000000) {
637  *buffer = 0;
638  valueChange = true;
639  } else if (alphaValue == 0) {
640  *buffer |= 0xFF000000;
641  valueChange = true;
642  }
643  }
644  }
645  return valueChange;
646 }
647 
661 {
662  if (themeData.rect.isEmpty())
663  return;
664 
665  QPainter *painter = themeData.painter;
666  Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
667  if (!painter || !painter->isActive())
668  return;
669 
670  painter->save();
671 
672  bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate;
673 
674  bool translucentToplevel = false;
675  QPaintDevice *pdev = painter->device();
676  if (pdev->devType() == QInternal::Widget) {
677  QWidget *win = ((QWidget *) pdev)->window();
678  translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground);
679  }
680 
681  bool useFallback = painter->paintEngine()->getDC() == 0
682  || painter->opacity() != 1.0
683  || themeData.rotate
684  || complexXForm
685  || themeData.mirrorVertically
686  || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0)
687  || translucentToplevel;
688 
689  if (!useFallback)
690  drawBackgroundDirectly(themeData);
691  else
692  drawBackgroundThruNativeBuffer(themeData);
693 
694  painter->restore();
695 }
696 
706 {
707  QPainter *painter = themeData.painter;
708  HDC dc = painter->paintEngine()->getDC();
709 
710  QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
711  int(painter->deviceMatrix().dy()));
712  QRect area = themeData.rect.translated(redirectionDelta);
713 
714  QRegion sysRgn = painter->paintEngine()->systemClip();
715  if (sysRgn.isEmpty())
716  sysRgn = area;
717  else
718  sysRgn &= area;
719  if (painter->hasClipping())
720  sysRgn &= painter->clipRegion().translated(redirectionDelta);
721  SelectClipRgn(dc, sysRgn.handle());
722 
723 #ifdef DEBUG_XP_STYLE
724  printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",
725  qPrintable(themeData.name), themeData.partId, themeData.stateId);
726  showProperties(themeData);
727 #endif
728 
729  RECT drawRECT = themeData.toRECT(area);
730  DTBGOPTS drawOptions;
731  drawOptions.dwSize = sizeof(drawOptions);
732  drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
733  drawOptions.dwFlags = DTBG_CLIPRECT
734  | (themeData.noBorder ? DTBG_OMITBORDER : 0)
735  | (themeData.noContent ? DTBG_OMITCONTENT : 0)
736  | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
737 
738  if (pDrawThemeBackgroundEx != 0) {
739  pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
740  } else {
741  // We are running on a system where the uxtheme.dll does not have
742  // the DrawThemeBackgroundEx function, so we need to clip away
743  // borders or contents manually. All flips and mirrors uses the
744  // fallback implementation
745 
746  int borderSize = 0;
747  PROPERTYORIGIN origin = PO_NOTFOUND;
748  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
749  pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
750 
751  // Clip away border region
752  QRegion extraClip = sysRgn;
753  if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
754  if (themeData.noBorder) {
755  // extraClip &= area is already done
756  drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));
757  }
758 
759  // Clip away content region
760  if (themeData.noContent) {
761  QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
762  extraClip ^= content;
763  }
764 
765  // Set the clip region, if used..
766  if (themeData.noBorder || themeData.noContent)
767  SelectClipRgn(dc, extraClip.handle());
768  }
769 
770  pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
771  }
772  SelectClipRgn(dc, 0);
773 }
774 
787 {
788  QPainter *painter = themeData.painter;
789  QRect rect = themeData.rect;
790 
791  if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
792  rect = QRect(0, 0, rect.height(), rect.width());
793  }
794  rect.moveTo(0,0);
795  int partId = themeData.partId;
796  int stateId = themeData.stateId;
797  int w = rect.width();
798  int h = rect.height();
799 
800  // Values initialized later, either from cached values, or from function calls
801  AlphaChannelType alphaType = UnknownAlpha;
802  bool stateHasData = true; // We assume so;
803  bool hasAlpha = false;
804  bool partIsTransparent;
805  bool inspectData;
806  bool potentialInvalidAlpha;
807 
808  QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
809  .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
810  .arg(w).arg(h);
811  QPixmap cachedPixmap;
812  ThemeMapKey key(themeData);
813  ThemeMapData data = alphaCache.value(key);
814 
815  bool haveCachedPixmap = false;
816  bool isCached = data.dataValid;
817  if (isCached) {
818  if (!(stateHasData = data.hasAnyData))
819  return; // Cached NOOP
820  inspectData = data.wasAlphaSwapped;
821  partIsTransparent = data.partIsTransparent;
822  hasAlpha = data.hasAlphaChannel;
823  alphaType = data.alphaType;
824  potentialInvalidAlpha = data.hadInvalidAlpha;
825 
826  haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
827 
828 #ifdef DEBUG_XP_STYLE
829  char buf[25];
830  ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
831  printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
832  haveCachedPixmap ? buf : "]-------------------",
833  qPrintable(themeData.name), themeData.partId, themeData.stateId);
834 #endif
835  } else {
836  // Not cached, so get values from Theme Engine
837  BOOL tmt_borderonly = false;
838  COLORREF tmt_transparentcolor = 0x0;
839  PROPERTYORIGIN proporigin = PO_NOTFOUND;
840  pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);
841  pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
842  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);
843  inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);
844 
845  // ### This is a vista-specific workaround for broken alpha in titlebar pixmaps
847  if (themeData.partId == WP_CAPTION || themeData.partId == WP_SMALLCAPTION)
848  inspectData = false;
849  }
850 
851  partIsTransparent = isTransparent(themeData);
852 
853  potentialInvalidAlpha = false;
854  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);
855  if (proporigin == PO_PART || proporigin == PO_STATE) {
856  int tmt_glyphtype = GT_NONE;
857  pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
858  potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;
859  }
860 
861 #ifdef DEBUG_XP_STYLE
862  printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
863  qPrintable(themeData.name), themeData.partId, themeData.stateId);
864  printf("-->partIsTransparen = %d\n", partIsTransparent);
865  printf("-->inspectData = %d\n", inspectData);
866  printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
867  showProperties(themeData);
868 #endif
869  }
870  bool wasAlphaSwapped = false;
871  bool wasAlphaFixed = false;
872 
873  // OLD PSDK Workaround ------------------------------------------------------------------------
874  // See if we need extra clipping for the older PSDK, which does
875  // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER
876  // and DTGB_OMITCONTENT
877  bool addBorderContentClipping = false;
878  QRegion extraClip;
879  QRect area = rect;
880  if (themeData.noBorder || themeData.noContent) {
881  extraClip = area;
882  // We are running on a system where the uxtheme.dll does not have
883  // the DrawThemeBackgroundEx function, so we need to clip away
884  // borders or contents manually.
885 
886  int borderSize = 0;
887  PROPERTYORIGIN origin = PO_NOTFOUND;
888  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
889  pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
890 
891  // Clip away border region
892  if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
893  if (themeData.noBorder) {
894  extraClip &= area;
895  area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
896  }
897 
898  // Clip away content region
899  if (themeData.noContent) {
900  QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
901  extraClip ^= content;
902  }
903  }
904  addBorderContentClipping = (themeData.noBorder | themeData.noContent);
905  }
906 
907  QImage img;
908  if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
909  buffer(w, h); // Ensure a buffer of at least (w, h) in size
910  HDC dc = bufferHDC();
911 
912  // Clear the buffer
913  if (alphaType != NoAlpha) {
914  // Consider have separate "memset" function for small chunks for more speedup
915  memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);
916  }
917 
918  // Difference between area and rect
919  int dx = area.x() - rect.x();
920  int dy = area.y() - rect.y();
921  int dr = area.right() - rect.right();
922  int db = area.bottom() - rect.bottom();
923 
924  // Adjust so painting rect starts from Origo
925  rect.moveTo(0,0);
926  area.moveTo(dx,dy);
927  DTBGOPTS drawOptions;
928  drawOptions.dwSize = sizeof(drawOptions);
929  drawOptions.rcClip = themeData.toRECT(rect);
930  drawOptions.dwFlags = DTBG_CLIPRECT
931  | (themeData.noBorder ? DTBG_OMITBORDER : 0)
932  | (themeData.noContent ? DTBG_OMITCONTENT : 0);
933 
934  // Drawing the part into the backing store
935  if (pDrawThemeBackgroundEx != 0) {
936  RECT rect(themeData.toRECT(area));
937  pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &rect, &drawOptions);
938  } else {
939  // Set the clip region, if used..
940  if (addBorderContentClipping) {
941  SelectClipRgn(dc, extraClip.handle());
942  // Compensate for the noBorder area difference (noContent has the same area)
943  drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));
944  }
945 
946  pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);
947 
948  if (addBorderContentClipping)
949  SelectClipRgn(dc, 0);
950  }
951 
952  // If not cached, analyze the buffer data to figure
953  // out alpha type, and if it contains data
954  if (!isCached) {
955  if (inspectData)
956  stateHasData = hasAnyData(rect);
957  // SHORTCUT: If the part's state has no data, cache it for NOOP later
958  if (!stateHasData) {
959  memset(&data, 0, sizeof(data));
960  data.dataValid = true;
961  alphaCache.insert(key, data);
962  return;
963  }
964  hasAlpha = hasAlphaChannel(rect);
965  if (!hasAlpha && partIsTransparent)
966  potentialInvalidAlpha = true;
967 #if defined(DEBUG_XP_STYLE) && 1
968  dumpNativeDIB(w, h);
969 #endif
970  }
971 
972  // Swap alpha values, if needed
973  if (inspectData)
974  wasAlphaSwapped = swapAlphaChannel(rect);
975 
976  // Fix alpha values, if needed
977  if (potentialInvalidAlpha)
978  wasAlphaFixed = fixAlphaChannel(rect);
979 
981  if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
983  alphaType = RealAlpha;
984  } else if (wasAlphaSwapped) {
986  alphaType = MaskAlpha;
987  } else {
988  format = QImage::Format_RGB32;
989  // The image data we got from the theme engine does not have any transparency,
990  // thus the alpha channel is set to 0.
991  // However, Format_RGB32 requires the alpha part to be set to 0xff, thus
992  // we must flip it from 0x00 to 0xff
993  swapAlphaChannel(rect, true);
994  alphaType = NoAlpha;
995  }
996 #if defined(DEBUG_XP_STYLE) && 1
997  printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
998 #endif
999  img = QImage(bufferPixels, bufferW, bufferH, format);
1000  }
1001 
1002  // Blitting backing store
1003  bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
1004 
1005  QRegion newRegion;
1006  QRegion oldRegion;
1007  if (useRegion) {
1008  newRegion = region(themeData);
1009  oldRegion = painter->clipRegion();
1010  painter->setClipRegion(newRegion);
1011 #if defined(DEBUG_XP_STYLE) && 0
1012  printf("Using region:\n");
1013  QVector<QRect> rects = newRegion.rects();
1014  for (int i = 0; i < rects.count(); ++i) {
1015  const QRect &r = rects.at(i);
1016  printf(" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
1017  }
1018 #endif
1019  }
1020 
1021  if (addBorderContentClipping)
1022  painter->setClipRegion(extraClip, Qt::IntersectClip);
1023 
1024  if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
1025  if (!haveCachedPixmap)
1026  painter->drawImage(themeData.rect, img, rect);
1027  else
1028  painter->drawPixmap(themeData.rect, cachedPixmap);
1029  } else {
1030  // This is _slow_!
1031  // Make a copy containing only the necessary data, and mirror
1032  // on all wanted axes. Then draw the copy.
1033  // If cached, the normal pixmap is cached, instead of caching
1034  // all possible orientations for each part and state.
1035  QImage imgCopy;
1036  if (!haveCachedPixmap)
1037  imgCopy = img.copy(rect);
1038  else
1039  imgCopy = cachedPixmap.toImage();
1040 
1041  if (themeData.rotate) {
1042  QMatrix rotMatrix;
1043  rotMatrix.rotate(themeData.rotate);
1044  imgCopy = imgCopy.transformed(rotMatrix);
1045  }
1046  if (themeData.mirrorHorizontally || themeData.mirrorVertically) {
1047  imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);
1048  }
1049  painter->drawImage(themeData.rect,
1050  imgCopy);
1051  }
1052 
1053  if (useRegion || addBorderContentClipping) {
1054  if (oldRegion.isEmpty())
1055  painter->setClipping(false);
1056  else
1057  painter->setClipRegion(oldRegion);
1058  }
1059 
1060  // Cache the pixmap to avoid expensive swapAlphaChannel() calls
1061  if (!haveCachedPixmap && w && h) {
1062  QPixmap pix = QPixmap::fromImage(img).copy(rect);
1063  QPixmapCache::insert(pixmapCacheKey, pix);
1064 #ifdef DEBUG_XP_STYLE
1065  printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
1066  w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
1067 #endif
1068  }
1069 
1070  // Add to theme part cache
1071  if (!isCached) {
1072  memset(&data, 0, sizeof(data));
1073  data.dataValid = true;
1074  data.partIsTransparent = partIsTransparent;
1075  data.alphaType = alphaType;
1076  data.hasAlphaChannel = hasAlpha;
1077  data.hasAnyData = stateHasData;
1078  data.wasAlphaSwapped = wasAlphaSwapped;
1079  data.hadInvalidAlpha = wasAlphaFixed;
1080  alphaCache.insert(key, data);
1081  }
1082 }
1083 
1084 
1085 // ------------------------------------------------------------------------------------------------
1086 
1114 {
1115 }
1116 
1121 {
1122 }
1123 
1126 {
1128 }
1129 
1132 {
1133  QWindowsStyle::polish(app);
1135  return;
1136 }
1137 
1140 {
1141  QWindowsStyle::polish(widget);
1143  return;
1144 
1145  if (qobject_cast<QAbstractButton*>(widget)
1146  || qobject_cast<QToolButton*>(widget)
1147  || qobject_cast<QTabBar*>(widget)
1148 #ifndef QT_NO_COMBOBOX
1149  || qobject_cast<QComboBox*>(widget)
1150 #endif // QT_NO_COMBOBOX
1151  || qobject_cast<QScrollBar*>(widget)
1152  || qobject_cast<QSlider*>(widget)
1153  || qobject_cast<QHeaderView*>(widget)
1154 #ifndef QT_NO_SPINBOX
1155  || qobject_cast<QAbstractSpinBox*>(widget)
1156  || qobject_cast<QSpinBox*>(widget)
1157 #endif // QT_NO_SPINBOX
1158  || widget->inherits("QWorkspaceChild")
1159  || widget->inherits("Q3TitleBar"))
1160  widget->setAttribute(Qt::WA_Hover);
1161 
1162 #ifndef QT_NO_RUBBERBAND
1163  if (qobject_cast<QRubberBand*>(widget)) {
1164  widget->setWindowOpacity(0.6);
1165  }
1166 #endif
1167  if (qobject_cast<QStackedWidget*>(widget) &&
1168  qobject_cast<QTabWidget*>(widget->parent()))
1170 
1172  if (!d->hasInitColors) {
1173  // Get text color for group box labels
1174  COLORREF cref;
1175  XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0);
1176  pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
1177  d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
1178  pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
1179  d->groupBoxTextColorDisabled = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
1180  // Where does this color come from?
1181  //pGetThemeColor(theme.handle(), TKP_TICS, TSS_NORMAL, TMT_COLOR, &cref);
1182  d->sliderTickColor = qRgb(165, 162, 148);
1183  d->hasInitColors = true;
1184  }
1185 }
1186 
1189 {
1190  QWindowsStyle::polish(pal);
1191  pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110));
1192 }
1193 
1196 {
1197 #ifndef QT_NO_RUBBERBAND
1198  if (qobject_cast<QRubberBand*>(widget)) {
1199  widget->setWindowOpacity(1.0);
1200  }
1201 #endif
1203  // Unpolish of widgets is the first thing that
1204  // happens when a theme changes, or the theme
1205  // engine is turned off. So we detect it here.
1206  bool oldState = QWindowsXPStylePrivate::useXP();
1207  bool newState = QWindowsXPStylePrivate::useXP(true);
1208  if ((oldState != newState) && newState) {
1209  d->cleanup(true);
1210  d->init(true);
1211  } else {
1212  // Cleanup handle map, if just changing style,
1213  // or turning it on. In both cases the values
1214  // already in the map might be old (other style).
1215  d->cleanupHandleMap();
1216  }
1217  if (qobject_cast<QAbstractButton*>(widget)
1218  || qobject_cast<QToolButton*>(widget)
1219  || qobject_cast<QTabBar*>(widget)
1220 #ifndef QT_NO_COMBOBOX
1221  || qobject_cast<QComboBox*>(widget)
1222 #endif // QT_NO_COMBOBOX
1223  || qobject_cast<QScrollBar*>(widget)
1224  || qobject_cast<QSlider*>(widget)
1225  || qobject_cast<QHeaderView*>(widget)
1226 #ifndef QT_NO_SPINBOX
1227  || qobject_cast<QAbstractSpinBox*>(widget)
1228  || qobject_cast<QSpinBox*>(widget)
1229 #endif // QT_NO_SPINBOX
1230  || widget->inherits("QWorkspaceChild")
1231  || widget->inherits("Q3TitleBar"))
1232  widget->setAttribute(Qt::WA_Hover, false);
1233  QWindowsStyle::unpolish(widget);
1234 }
1235 
1238 {
1240  return QWindowsStyle::subElementRect(sr, option, widget);
1241  }
1242 
1243  QRect rect(option->rect);
1244  switch(sr) {
1247  rect = QWindowsStyle::subElementRect(sr, option, widget);
1248  return rect.translated(0, 1);
1249  break;
1251  if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
1252  {
1253  rect = QWindowsStyle::subElementRect(sr, option, widget);
1254  if (sr == SE_TabWidgetTabContents) {
1255  if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) {
1256  if (tabWidget->documentMode())
1257  break;
1258  }
1259 
1260  rect.adjust(0, 0, -2, -2);
1261  }
1262  }
1263  break;
1264  case SE_TabWidgetTabBar: {
1265  rect = QWindowsStyle::subElementRect(sr, option, widget);
1266  const QStyleOptionTabWidgetFrame *twfOption =
1268  if (twfOption && twfOption->direction == Qt::RightToLeft
1269  && (twfOption->shape == QTabBar::RoundedNorth
1270  || twfOption->shape == QTabBar::RoundedSouth))
1271  {
1272  QStyleOptionTab otherOption;
1273  otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth
1275  int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption, widget);
1276  int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
1277  rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0);
1278  }
1279  break;}
1280 
1281  case SE_PushButtonContents:
1282  if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
1283  MARGINS borderSize;
1284  if (widget) {
1285  XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
1286  HTHEME theme = buttontheme.handle();
1287  if (theme) {
1288  int stateId;
1289  if (!(option->state & State_Enabled))
1290  stateId = PBS_DISABLED;
1291  else if (option->state & State_Sunken)
1292  stateId = PBS_PRESSED;
1293  else if (option->state & State_MouseOver)
1294  stateId = PBS_HOT;
1295  else if (btn->features & QStyleOptionButton::DefaultButton)
1296  stateId = PBS_DEFAULTED;
1297  else
1298  stateId = PBS_NORMAL;
1299 
1300  int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
1301  rect = option->rect.adjusted(border, border, -border, -border);
1302 
1303  int result = pGetThemeMargins(theme,
1304  NULL,
1305  BP_PUSHBUTTON,
1306  stateId,
1308  NULL,
1309  &borderSize);
1310 
1311  if (result == S_OK) {
1312  rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
1313  -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
1314  rect = visualRect(option->direction, option->rect, rect);
1315  }
1316  }
1317  }
1318  }
1319  break;
1321  rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
1322  if (option->state & QStyle::State_Horizontal)
1323  rect.adjust(4, 3, -4, -3);
1324  else
1325  rect.adjust(3, 2, -3, -2);
1326  break;
1327  default:
1328  rect = QWindowsStyle::subElementRect(sr, option, widget);
1329  }
1330  return rect;
1331 }
1332 
1337  const QWidget *widget) const
1338 {
1339  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
1340 
1342  QWindowsStyle::drawPrimitive(pe, option, p, widget);
1343  return;
1344  }
1345 
1346  QString name;
1347  int partId = 0;
1348  int stateId = 0;
1349  QRect rect = option->rect;
1350  State flags = option->state;
1351  bool hMirrored = false;
1352  bool vMirrored = false;
1353  bool noBorder = false;
1354  bool noContent = false;
1355  int rotate = 0;
1356 
1357  switch (pe) {
1358  case PE_FrameTabBarBase:
1359  if (const QStyleOptionTabBarBase *tbb
1360  = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
1361  p->save();
1362  switch (tbb->shape) {
1363  case QTabBar::RoundedNorth:
1364  p->setPen(QPen(tbb->palette.dark(), 0));
1365  p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
1366  break;
1367  case QTabBar::RoundedWest:
1368  p->setPen(QPen(tbb->palette.dark(), 0));
1369  p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
1370  break;
1371  case QTabBar::RoundedSouth:
1372  p->setPen(QPen(tbb->palette.dark(), 0));
1373  p->drawLine(tbb->rect.left(), tbb->rect.top(),
1374  tbb->rect.right(), tbb->rect.top());
1375  break;
1376  case QTabBar::RoundedEast:
1377  p->setPen(QPen(tbb->palette.dark(), 0));
1378  p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
1379  break;
1384  p->restore();
1385  QWindowsStyle::drawPrimitive(pe, option, p, widget);
1386  return;
1387  }
1388  p->restore();
1389  }
1390  return;
1391  case PE_PanelButtonBevel:
1392  name = QLatin1String("BUTTON");
1393  partId = BP_PUSHBUTTON;
1394  if (!(flags & State_Enabled))
1395  stateId = PBS_DISABLED;
1396  else if ((flags & State_Sunken) || (flags & State_On))
1397  stateId = PBS_PRESSED;
1398  else if (flags & State_MouseOver)
1399  stateId = PBS_HOT;
1400  //else if (flags & State_ButtonDefault)
1401  // stateId = PBS_DEFAULTED;
1402  else
1403  stateId = PBS_NORMAL;
1404  break;
1405 
1406  case PE_PanelButtonTool:
1407  if (widget && widget->inherits("QDockWidgetTitleButton")) {
1408  if (const QWidget *dw = widget->parentWidget())
1409  if (dw->isWindow())
1410  return;
1411  }
1412  name = QLatin1String("TOOLBAR");
1413  partId = TP_BUTTON;
1414  if (!(flags & State_Enabled))
1415  stateId = TS_DISABLED;
1416  else if (flags & State_Sunken)
1417  stateId = TS_PRESSED;
1418  else if (flags & State_MouseOver)
1419  stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
1420  else if (flags & State_On)
1421  stateId = TS_CHECKED;
1422  else if (!(flags & State_AutoRaise))
1423  stateId = TS_HOT;
1424  else
1425  stateId = TS_NORMAL;
1426  break;
1427 
1429  name = QLatin1String("TOOLBAR");
1430  partId = TP_SPLITBUTTONDROPDOWN;
1431  if (!(flags & State_Enabled))
1432  stateId = TS_DISABLED;
1433  else if (flags & State_Sunken)
1434  stateId = TS_PRESSED;
1435  else if (flags & State_MouseOver)
1436  stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
1437  else if (flags & State_On)
1438  stateId = TS_CHECKED;
1439  else if (!(flags & State_AutoRaise))
1440  stateId = TS_HOT;
1441  else
1442  stateId = TS_NORMAL;
1443  if (option->direction == Qt::RightToLeft)
1444  hMirrored = true;
1445  break;
1446 
1447  case PE_IndicatorCheckBox:
1448  name = QLatin1String("BUTTON");
1449  partId = BP_CHECKBOX;
1450  if (!(flags & State_Enabled))
1451  stateId = CBS_UNCHECKEDDISABLED;
1452  else if (flags & State_Sunken)
1453  stateId = CBS_UNCHECKEDPRESSED;
1454  else if (flags & State_MouseOver)
1455  stateId = CBS_UNCHECKEDHOT;
1456  else
1457  stateId = CBS_UNCHECKEDNORMAL;
1458 
1459  if (flags & State_On)
1460  stateId += CBS_CHECKEDNORMAL-1;
1461  else if (flags & State_NoChange)
1462  stateId += CBS_MIXEDNORMAL-1;
1463 
1464  break;
1465 
1467  name = QLatin1String("BUTTON");
1468  partId = BP_RADIOBUTTON;
1469  if (!(flags & State_Enabled))
1470  stateId = RBS_UNCHECKEDDISABLED;
1471  else if (flags & State_Sunken)
1472  stateId = RBS_UNCHECKEDPRESSED;
1473  else if (flags & State_MouseOver)
1474  stateId = RBS_UNCHECKEDHOT;
1475  else
1476  stateId = RBS_UNCHECKEDNORMAL;
1477 
1478  if (flags & State_On)
1479  stateId += RBS_CHECKEDNORMAL-1;
1480  break;
1481 
1483  return;
1484 
1485 case PE_Frame:
1486  {
1487  if (flags & State_Raised)
1488  return;
1489  name = QLatin1String("LISTVIEW");
1490  partId = LVP_LISTGROUP;
1491  XPThemeData theme(0, 0, name, partId, 0);
1492 
1493  if (!(flags & State_Enabled))
1494  stateId = ETS_DISABLED;
1495  else
1496  stateId = ETS_NORMAL;
1497  int fillType;
1498  if (pGetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
1499  if (fillType == BT_BORDERFILL) {
1500  COLORREF bcRef;
1501  pGetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
1502  QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
1503  QPen oldPen = p->pen();
1504  // int borderSize = 1;
1505  // pGetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize);
1506 
1507  // Inner white border
1508  p->setPen(QPen(option->palette.base().color(), 1));
1509  p->drawRect(option->rect.adjusted(1, 1, -2, -2));
1510  // Outer dark border
1511  p->setPen(QPen(bordercolor, 1));
1512  p->drawRect(option->rect.adjusted(0, 0, -1, -1));
1513  p->setPen(oldPen);
1514  return;
1515  } else if (fillType == BT_NONE) {
1516  return;
1517  } else {
1518  break;
1519  }
1520  }
1521  }
1522  case PE_FrameLineEdit: {
1523  // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
1525  QPen oldPen = p->pen();
1526  // Inner white border
1527  p->setPen(QPen(option->palette.base().color(), 1));
1528  p->drawRect(option->rect.adjusted(1, 1, -2, -2));
1529  // Outer dark border
1530  p->setPen(QPen(option->palette.shadow().color(), 1));
1531  p->drawRect(option->rect.adjusted(0, 0, -1, -1));
1532  p->setPen(oldPen);
1533  return;
1534  } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
1535  name = QLatin1String("EDIT");
1536  partId = EP_EDITTEXT;
1537  noContent = true;
1538  if (!(flags & State_Enabled))
1539  stateId = ETS_DISABLED;
1540  else
1541  stateId = ETS_NORMAL;
1542  }
1543  break;
1544  }
1545 
1546  case PE_PanelLineEdit:
1547  if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
1548  name = QLatin1String("EDIT");
1549  partId = EP_EDITTEXT;
1550  noBorder = true;
1551  QBrush bg;
1552  bool usePalette = false;
1553  bool isEnabled = flags & State_Enabled;
1554  uint resolve_mask = panel->palette.resolve();
1555 
1556 #ifndef QT_NO_SPINBOX
1557  //Since spin box includes a line edit we need to resolve the palette on the spin box instead
1558  if (widget) {
1559  if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
1560  resolve_mask = spinbox->palette().resolve();
1561  }
1562 #endif // QT_NO_SPINBOX
1563  if (resolve_mask & (1 << QPalette::Base)) {
1564  // Base color is set for this widget, so use it
1565  bg = panel->palette.brush(QPalette::Base);
1566  usePalette = true;
1567  }
1568 
1569  stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
1570 
1571  if (usePalette) {
1572  p->fillRect(panel->rect, bg);
1573  } else {
1574  XPThemeData theme(0, p, name, partId, stateId, rect);
1575  if (!theme.isValid()) {
1576  QWindowsStyle::drawPrimitive(pe, option, p, widget);
1577  return;
1578  }
1579  int bgType;
1580  pGetThemeEnumValue( theme.handle(),
1581  partId,
1582  stateId,
1583  TMT_BGTYPE,
1584  &bgType);
1585  if( bgType == BT_IMAGEFILE ) {
1586  theme.mirrorHorizontally = hMirrored;
1587  theme.mirrorVertically = vMirrored;
1588  theme.noBorder = noBorder;
1589  theme.noContent = noContent;
1590  theme.rotate = rotate;
1591  d->drawBackground(theme);
1592  } else {
1593  QBrush fillColor = option->palette.brush(QPalette::Base);
1594 
1595  if (!isEnabled) {
1596  PROPERTYORIGIN origin = PO_NOTFOUND;
1597  pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
1598  // Use only if the fill property comes from our part
1599  if ((origin == PO_PART || origin == PO_STATE)) {
1600  COLORREF bgRef;
1601  pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
1602  fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
1603  }
1604  }
1605  p->fillRect(option->rect, fillColor);
1606  }
1607  }
1608 
1609  if (panel->lineWidth > 0)
1610  proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
1611  return;
1612  }
1613  break;
1614 
1615  case PE_FrameTabWidget:
1616  if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
1617  {
1618  name = QLatin1String("TAB");
1619  partId = TABP_PANE;
1620 
1621  if (widget) {
1622  bool useGradient = true;
1623  const int maxlength = 256;
1624  wchar_t themeFileName[maxlength];
1625  wchar_t themeColor[maxlength];
1626  // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
1627  if (pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
1628  wchar_t *offset = 0;
1629  if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
1630  offset++;
1631  if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
1632  useGradient = false;
1633  }
1634  }
1635  }
1636  // This should work, but currently there's an error in the ::drawBackgroundDirectly()
1637  // code, when using the HDC directly..
1638  if (useGradient) {
1639  QStyleOptionTabWidgetFrameV2 frameOpt = *tab;
1640  frameOpt.rect = widget->rect();
1641  QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget);
1642  QRegion reg = option->rect;
1643  reg -= contentsRect;
1644  p->setClipRegion(reg);
1645  XPThemeData theme(widget, p, name, partId, stateId, rect);
1646  theme.mirrorHorizontally = hMirrored;
1647  theme.mirrorVertically = vMirrored;
1648  d->drawBackground(theme);
1649  p->setClipRect(contentsRect);
1650  partId = TABP_BODY;
1651  }
1652  }
1653  switch (tab->shape) {
1654  case QTabBar::RoundedNorth:
1656  break;
1657  case QTabBar::RoundedSouth:
1659  vMirrored = true;
1660  break;
1661  case QTabBar::RoundedEast:
1663  rotate = 90;
1664  break;
1665  case QTabBar::RoundedWest:
1667  rotate = 90;
1668  hMirrored = true;
1669  break;
1670  default:
1671  break;
1672  }
1673  }
1674  break;
1675 
1676  case PE_FrameMenu:
1677  p->save();
1678  p->setPen(option->palette.dark().color());
1679  p->drawRect(rect.adjusted(0, 0, -1, -1));
1680  p->restore();
1681  return;
1682 
1683  case PE_PanelMenuBar:
1684  break;
1685 
1686  case PE_FrameDockWidget:
1687  if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
1688  {
1689  name = QLatin1String("WINDOW");
1690  if (flags & State_Active)
1691  stateId = FS_ACTIVE;
1692  else
1693  stateId = FS_INACTIVE;
1694 
1695  int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget);
1696 
1697  XPThemeData theme(widget, p, name, 0, stateId);
1698  if (!theme.isValid())
1699  break;
1700  theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT;
1701  d->drawBackground(theme);
1702  theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
1703  theme.partId = WP_SMALLFRAMERIGHT;
1704  d->drawBackground(theme);
1705  theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
1706  theme.partId = WP_SMALLFRAMEBOTTOM;
1707  d->drawBackground(theme);
1708  return;
1709  }
1710  break;
1711 
1713  {
1714 #if 0 // XP theme engine doesn't know about this :(
1715  name = QLatin1String("HEADER");
1716  partId = HP_HEADERSORTARROW;
1717  if (flags & State_Down)
1718  stateId = HSAS_SORTEDDOWN;
1719  else
1720  stateId = HSAS_SORTEDUP;
1721 #else
1722  if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
1723  p->save();
1724  p->setPen(option->palette.dark().color());
1725  p->translate(0, option->rect.height()/2 - 4);
1726  if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide
1727  p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
1728  p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
1729  p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
1730  p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
1731  p->drawPoint(option->rect.x()+4, option->rect.y()+4);
1732  } else if(header->sortIndicator & QStyleOptionHeader::SortDown) {
1733  p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
1734  p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
1735  p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
1736  p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
1737  p->drawPoint(option->rect.x()+4, option->rect.y());
1738  }
1739  p->restore();
1740  return;
1741  }
1742 #endif
1743  }
1744  break;
1745 
1746  case PE_FrameStatusBarItem:
1747  name = QLatin1String("STATUS");
1748  partId = SP_PANE;
1749  break;
1750 
1751  case PE_FrameGroupBox:
1752  name = QLatin1String("BUTTON");
1753  partId = BP_GROUPBOX;
1754  if (!(flags & State_Enabled))
1755  stateId = GBS_DISABLED;
1756  else
1757  stateId = GBS_NORMAL;
1758  if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
1759  const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option);
1760  if (frame2->features & QStyleOptionFrameV2::Flat) {
1761  // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style
1762  QRect fr = frame->rect;
1763  QPoint p1(fr.x(), fr.y() + 1);
1764  QPoint p2(fr.x() + fr.width(), p1.y() + 1);
1765  rect = QRect(p1, p2);
1766  name = QLatin1String("");
1767  }
1768  }
1769  break;
1770 
1772  {
1774  bool inverted = false;
1775  if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
1776  orient = pb2->orientation;
1777  if (pb2->invertedAppearance)
1778  inverted = true;
1779  }
1780  if (orient == Qt::Horizontal) {
1781  partId = PP_CHUNK;
1782  rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
1783  if (inverted && option->direction == Qt::LeftToRight)
1784  hMirrored = true;
1785  } else {
1786  partId = PP_CHUNKVERT;
1787  rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
1788  }
1789  name = QLatin1String("PROGRESS");
1790  stateId = 1;
1791  }
1792  break;
1793 
1795  name = QLatin1String("TOOLBAR");
1796  if (flags & State_Horizontal)
1797  partId = TP_SEPARATOR;
1798  else
1799  partId = TP_SEPARATORVERT;
1800  break;
1801 
1802  case PE_FrameWindow:
1803  if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
1804  {
1805  name = QLatin1String("WINDOW");
1806  if (flags & State_Active)
1807  stateId = FS_ACTIVE;
1808  else
1809  stateId = FS_INACTIVE;
1810 
1811  int fwidth = frm->lineWidth + frm->midLineWidth;
1812 
1813  XPThemeData theme(0, p, name, 0, stateId);
1814  if (!theme.isValid())
1815  break;
1816 
1817  theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
1818  theme.partId = WP_FRAMELEFT;
1819  d->drawBackground(theme);
1820  theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
1821  theme.partId = WP_FRAMERIGHT;
1822  d->drawBackground(theme);
1823  theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
1824  theme.partId = WP_FRAMEBOTTOM;
1825  d->drawBackground(theme);
1826  theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
1827  theme.partId = WP_CAPTION;
1828  d->drawBackground(theme);
1829  return;
1830  }
1831  break;
1832 
1833  case PE_IndicatorBranch:
1834  {
1835  static const int decoration_size = 9;
1836  int mid_h = option->rect.x() + option->rect.width() / 2;
1837  int mid_v = option->rect.y() + option->rect.height() / 2;
1838  int bef_h = mid_h;
1839  int bef_v = mid_v;
1840  int aft_h = mid_h;
1841  int aft_v = mid_v;
1842  QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
1843  if (option->state & State_Item) {
1844  if (option->direction == Qt::RightToLeft)
1845  p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
1846  else
1847  p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
1848  }
1849  if (option->state & State_Sibling)
1850  p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
1851  if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
1852  p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
1853  if (option->state & State_Children) {
1854  int delta = decoration_size / 2;
1855  bef_h -= delta;
1856  bef_v -= delta;
1857  aft_h += delta;
1858  aft_v += delta;
1859  XPThemeData theme(0, p, QLatin1String("TREEVIEW"));
1860  theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
1861  theme.partId = TVP_GLYPH;
1862  theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
1863  d->drawBackground(theme);
1864  }
1865  }
1866  return;
1867 
1869  if (option->rect.height() < 3) {
1870  // XP style requires a few pixels for the separator
1871  // to be visible.
1872  QWindowsStyle::drawPrimitive(pe, option, p, widget);
1873  return;
1874  }
1875  name = QLatin1String("TOOLBAR");
1876  partId = TP_SEPARATOR;
1877 
1878  if (option->state & State_Horizontal)
1879  partId = TP_SEPARATOR;
1880  else
1881  partId = TP_SEPARATORVERT;
1882 
1883  break;
1884 
1886 
1887  name = QLatin1String("REBAR");
1888  partId = RP_GRIPPER;
1889  if (option->state & State_Horizontal) {
1890  partId = RP_GRIPPER;
1891  rect.adjust(0, 0, -2, 0);
1892  }
1893  else {
1894  partId = RP_GRIPPERVERT;
1895  rect.adjust(0, 0, 0, -2);
1896  }
1897  break;
1898 
1900  QStyleOptionButton button;
1901  button.QStyleOption::operator=(*option);
1902  button.state &= ~State_MouseOver;
1903  proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p, widget);
1904  return;
1905  }
1906 
1907  default:
1908  break;
1909  }
1910 
1911  XPThemeData theme(0, p, name, partId, stateId, rect);
1912  if (!theme.isValid()) {
1913  QWindowsStyle::drawPrimitive(pe, option, p, widget);
1914  return;
1915  }
1916  theme.mirrorHorizontally = hMirrored;
1917  theme.mirrorVertically = vMirrored;
1918  theme.noBorder = noBorder;
1919  theme.noContent = noContent;
1920  theme.rotate = rotate;
1921  d->drawBackground(theme);
1922 }
1923 
1928  const QWidget *widget) const
1929 {
1930  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
1932  QWindowsStyle::drawControl(element, option, p, widget);
1933  return;
1934  }
1935 
1936  QRect rect(option->rect);
1937  State flags = option->state;
1938 
1939  int rotate = 0;
1940  bool hMirrored = false;
1941  bool vMirrored = false;
1942 
1943  QString name;
1944  int partId = 0;
1945  int stateId = 0;
1946  switch (element) {
1947  case CE_SizeGrip:
1948  {
1949  name = QLatin1String("STATUS");
1950  partId = SP_GRIPPER;
1951  SIZE sz;
1952  XPThemeData theme(0, p, name, partId, 0);
1953  pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz);
1954  --sz.cy;
1955  if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
1956  switch (sg->corner) {
1957  case Qt::BottomRightCorner:
1958  rect = QRect(rect.right() - sz.cx, rect.bottom() - sz.cy, sz.cx, sz.cy);
1959  break;
1960  case Qt::BottomLeftCorner:
1961  rect = QRect(rect.left() + 1, rect.bottom() - sz.cy, sz.cx, sz.cy);
1962  hMirrored = true;
1963  break;
1964  case Qt::TopRightCorner:
1965  rect = QRect(rect.right() - sz.cx, rect.top() + 1, sz.cx, sz.cy);
1966  vMirrored = true;
1967  break;
1968  case Qt::TopLeftCorner:
1969  rect = QRect(rect.left() + 1, rect.top() + 1, sz.cx, sz.cy);
1970  hMirrored = vMirrored = true;
1971  }
1972  }
1973  }
1974  break;
1975 
1976  case CE_HeaderSection:
1977  name = QLatin1String("HEADER");
1978  partId = HP_HEADERITEM;
1979  if (flags & State_Sunken)
1980  stateId = HIS_PRESSED;
1981  else if (flags & State_MouseOver)
1982  stateId = HIS_HOT;
1983  else
1984  stateId = HIS_NORMAL;
1985  break;
1986 
1987  case CE_Splitter:
1988  p->eraseRect(option->rect);
1989  return;
1990 
1991  case CE_PushButtonBevel:
1992  if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
1993  {
1994  name = QLatin1String("BUTTON");
1995  partId = BP_PUSHBUTTON;
1996  bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
1997  || ((btn->features & QStyleOptionButton::CommandLinkButton)
1998  && !(flags & State_MouseOver)
1999  && !(btn->features & QStyleOptionButton::DefaultButton));
2000  if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
2001  stateId = PBS_DISABLED;
2002  else if (justFlat)
2003  ;
2004  else if (flags & (State_Sunken | State_On))
2005  stateId = PBS_PRESSED;
2006  else if (flags & State_MouseOver)
2007  stateId = PBS_HOT;
2008  else if (btn->features & QStyleOptionButton::DefaultButton)
2009  stateId = PBS_DEFAULTED;
2010  else
2011  stateId = PBS_NORMAL;
2012 
2013  if (!justFlat) {
2014  XPThemeData theme(widget, p, name, partId, stateId, rect);
2015  d->drawBackground(theme);
2016  }
2017 
2018  if (btn->features & QStyleOptionButton::HasMenu) {
2019  int mbiw = 0, mbih = 0;
2020  XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN);
2021  if (theme.isValid()) {
2022  SIZE size;
2023  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
2024  mbiw = size.cx;
2025  mbih = size.cy;
2026  }
2027 
2028  QRect ir = btn->rect;
2029  QStyleOptionButton newBtn = *btn;
2030  newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
2031  proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
2032  }
2033  return;
2034  }
2035  break;
2036  case CE_TabBarTab:
2037  if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
2038  {
2039  stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
2040  }
2041  break;
2042 
2043  case CE_TabBarTabShape:
2044  if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
2045  {
2046  name = QLatin1String("TAB");
2047  bool isDisabled = !(tab->state & State_Enabled);
2048  bool hasFocus = tab->state & State_HasFocus;
2049  bool isHot = tab->state & State_MouseOver;
2050  bool selected = tab->state & State_Selected;
2051  bool lastTab = tab->position == QStyleOptionTab::End;
2052  bool firstTab = tab->position == QStyleOptionTab::Beginning;
2053  bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
2054  bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignLeft;
2055  bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignCenter;
2056  int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
2057  int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option, widget);
2058 
2059  if (isDisabled)
2060  stateId = TIS_DISABLED;
2061  else if (selected)
2062  stateId = TIS_SELECTED;
2063  else if (hasFocus)
2064  stateId = TIS_FOCUSED;
2065  else if (isHot)
2066  stateId = TIS_HOT;
2067  else
2068  stateId = TIS_NORMAL;
2069 
2070  // Selecting proper part depending on position
2071  if (firstTab || onlyOne) {
2072  if (leftAligned) {
2073  partId = TABP_TABITEMLEFTEDGE;
2074  } else if (centerAligned) {
2075  partId = TABP_TABITEM;
2076  } else { // rightAligned
2077  partId = TABP_TABITEMRIGHTEDGE;
2078  }
2079  } else {
2080  partId = TABP_TABITEM;
2081  }
2082 
2083  if (tab->direction == Qt::RightToLeft
2084  && (tab->shape == QTabBar::RoundedNorth
2085  || tab->shape == QTabBar::RoundedSouth)) {
2086  bool temp = firstTab;
2087  firstTab = lastTab;
2088  lastTab = temp;
2089  }
2090  bool begin = firstTab || onlyOne;
2091  bool end = lastTab || onlyOne;
2092  switch (tab->shape) {
2093  case QTabBar::RoundedNorth:
2094  if (selected)
2095  rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
2096  else
2097  rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
2098  break;
2099  case QTabBar::RoundedSouth:
2100  //vMirrored = true;
2101  rotate = 180; // Not 100% correct, but works
2102  if (selected)
2103  rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
2104  else
2105  rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
2106  break;
2107  case QTabBar::RoundedEast:
2108  rotate = 90;
2109  if (selected) {
2110  rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
2111  }else{
2112  rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
2113  }
2114  break;
2115  case QTabBar::RoundedWest:
2116  hMirrored = true;
2117  rotate = 90;
2118  if (selected) {
2119  rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
2120  }else{
2121  rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
2122  }
2123  break;
2124  default:
2125  name = QLatin1String(""); // Do our own painting for triangular
2126  break;
2127  }
2128 
2129  if (!selected) {
2130  switch (tab->shape) {
2131  case QTabBar::RoundedNorth:
2132  rect.adjust(0,0, 0,-1);
2133  break;
2134  case QTabBar::RoundedSouth:
2135  rect.adjust(0,1, 0,0);
2136  break;
2137  case QTabBar::RoundedEast:
2138  rect.adjust( 1,0, 0,0);
2139  break;
2140  case QTabBar::RoundedWest:
2141  rect.adjust(0,0, -1,0);
2142  break;
2143  default:
2144  break;
2145  }
2146  }
2147  }
2148  break;
2149 
2150  case CE_ProgressBarGroove:
2151  {
2153  if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
2154  orient = pb2->orientation;
2155  partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
2156  name = QLatin1String("PROGRESS");
2157  stateId = 1;
2158  }
2159  break;
2160 
2161  case CE_MenuEmptyArea:
2162  case CE_MenuItem:
2163  if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
2164  {
2165  int tab = menuitem->tabWidth;
2166  bool dis = !(menuitem->state & State_Enabled);
2167  bool act = menuitem->state & State_Selected;
2168  bool checkable = menuitem->menuHasCheckableItems;
2169  bool checked = checkable ? menuitem->checked : false;
2170 
2171  // windows always has a check column, regardless whether we have an icon or not
2172  int checkcol = qMax(menuitem->maxIconWidth, 12);
2173 
2174  int x, y, w, h;
2175  rect.getRect(&x, &y, &w, &h);
2176 
2177  QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
2178  p->fillRect(rect, fill);
2179 
2180  if (element == CE_MenuEmptyArea)
2181  break;
2182 
2183  // draw separator -------------------------------------------------
2184  if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
2185  int yoff = y-1 + h / 2;
2186  p->setPen(menuitem->palette.dark().color());
2187  p->drawLine(x, yoff, x+w, yoff);
2188  ++yoff;
2189  p->setPen(menuitem->palette.light().color());
2190  p->drawLine(x, yoff, x+w, yoff);
2191  return;
2192  }
2193 
2194  int xpos = x;
2195 
2196  // draw icon ------------------------------------------------------
2197  if (!menuitem->icon.isNull()) {
2198  QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
2199  if (act && !dis)
2200  mode = QIcon::Active;
2201  QPixmap pixmap = checked ?
2202  menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On) :
2203  menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
2204  int pixw = pixmap.width();
2205  int pixh = pixmap.height();
2206  QRect iconRect(0, 0, pixw, pixh);
2207  iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
2208  QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
2209  p->setPen(menuitem->palette.text().color());
2210  p->setBrush(Qt::NoBrush);
2211  if (checked)
2212  p->drawRect(vIconRect.adjusted(-1, -1, 0, 0));
2213  p->drawPixmap(vIconRect.topLeft(), pixmap);
2214 
2215  // draw checkmark -------------------------------------------------
2216  } else if (checked) {
2217  QStyleOptionMenuItem newMi = *menuitem;
2218  newMi.state = State_None;
2219  if (!dis)
2220  newMi.state |= State_Enabled;
2221  if (act)
2222  newMi.state |= State_On;
2223 
2224  QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame,
2225  menuitem->rect.y() + windowsItemFrame,
2226  checkcol - 2 * windowsItemFrame,
2227  menuitem->rect.height() - 2*windowsItemFrame);
2228  newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
2229  proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
2230  }
2231 
2232  QColor textColor = dis ? menuitem->palette.text().color() :
2233  act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
2234  p->setPen(textColor);
2235 
2236  // draw text ------------------------------------------------------
2237  int xm = windowsItemFrame + checkcol + windowsItemHMargin;
2238  xpos = menuitem->rect.x() + xm;
2239  QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
2240  QRect vTextRect = visualRect(option->direction, option->rect, textRect);
2241  QString s = menuitem->text;
2242  if (!s.isEmpty()) {
2243  p->save();
2244  int t = s.indexOf(QLatin1Char('\t'));
2246  if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
2247  text_flags |= Qt::TextHideMnemonic;
2248  // draw tab text ----------------
2249  if (t >= 0) {
2250  QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
2251  if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
2252  p->setPen(menuitem->palette.light().color());
2253  p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
2254  p->setPen(textColor);
2255  }
2256  p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
2257  s = s.left(t);
2258  }
2259  QFont font = menuitem->font;
2260  if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
2261  font.setBold(true);
2262  p->setFont(font);
2263  if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
2264  p->setPen(menuitem->palette.light().color());
2265  p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
2266  p->setPen(textColor);
2267  }
2268  p->drawText(vTextRect, text_flags, s);
2269  p->restore();
2270  }
2271 
2272  // draw sub menu arrow --------------------------------------------
2273  if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
2274  int dim = (h - 2) / 2;
2275  PrimitiveElement arrow;
2277  xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
2278  QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
2279  QStyleOptionMenuItem newMI = *menuitem;
2280  newMI.rect = vSubMenuRect;
2281  newMI.state = dis ? State_None : State_Enabled;
2282  if (act)
2284  proxy()->drawPrimitive(arrow, &newMI, p, widget);
2285  }
2286  }
2287  return;
2288 
2289  case CE_MenuBarItem:
2290  if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
2291  {
2292  if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
2293  break;
2294 
2295  bool act = mbi->state & State_Selected;
2296  bool dis = !(mbi->state & State_Enabled);
2297 
2298  QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
2299  QPalette::ColorRole textRole = dis ? QPalette::Text:
2301  QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
2302 
2304  if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
2305  alignment |= Qt::TextHideMnemonic;
2306 
2307  p->fillRect(rect, fill);
2308  if (!pix.isNull())
2309  drawItemPixmap(p, mbi->rect, alignment, pix);
2310  else
2311  drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
2312  }
2313  return;
2314 #ifndef QT_NO_DOCKWIDGET
2315  case CE_DockWidgetTitle:
2316  if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option))
2317  {
2318  int buttonMargin = 4;
2319  int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
2320  int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
2321  bool isFloating = widget && widget->isWindow();
2322  bool isActive = dwOpt->state & State_Active;
2323 
2324  const QStyleOptionDockWidgetV2 *v2
2326  bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
2327 
2328  if (verticalTitleBar) {
2329  QSize s = rect.size();
2330  s.transpose();
2331  rect.setSize(s);
2332 
2333  p->translate(rect.left() - 1, rect.top() + rect.width());
2334  p->rotate(-90);
2335  p->translate(-rect.left() + 1, -rect.top());
2336  }
2337  QRect r = rect.adjusted(0, 2, -1, -3);
2338  QRect titleRect = r;
2339 
2340  if (dwOpt->closable) {
2341  QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
2342  titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
2343  }
2344 
2345  if (dwOpt->floatable) {
2346  QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
2347  titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
2348  }
2349 
2350  if (isFloating) {
2351  titleRect.adjust(0, -fw, 0, 0);
2352  if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
2353  titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
2354  } else {
2355  titleRect.adjust(mw, 0, 0, 0);
2356  if (!dwOpt->floatable && !dwOpt->closable)
2357  titleRect.adjust(0, 0, -mw, 0);
2358  }
2359 
2360  if (!verticalTitleBar)
2361  titleRect = visualRect(dwOpt->direction, r, titleRect);
2362 
2363  if (!isFloating) {
2364  QPen oldPen = p->pen();
2365  QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
2366  p->setPen(dwOpt->palette.color(QPalette::Dark));
2367  p->drawRect(r);
2368 
2369  if (!titleText.isEmpty()) {
2370  drawItemText(p, titleRect,
2372  dwOpt->state & State_Enabled, titleText,
2374  }
2375 
2376  p->setPen(oldPen);
2377  } else {
2378  name = QLatin1String("WINDOW");
2379  if (isActive)
2380  stateId = CS_ACTIVE;
2381  else
2382  stateId = CS_INACTIVE;
2383 
2384  int titleHeight = rect.height() - 2;
2385  rect = rect.adjusted(-fw, -fw, fw, 0);
2386 
2387  XPThemeData theme(widget, p, name, 0, stateId);
2388  if (!theme.isValid())
2389  break;
2390 
2391  // Draw small type title bar
2392  theme.rect = rect;
2393  theme.partId = WP_SMALLCAPTION;
2394  d->drawBackground(theme);
2395 
2396  // Figure out maximal button space on title bar
2397 
2398  QIcon ico = widget->windowIcon();
2399  bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
2400  if (hasIcon) {
2401  QPixmap pxIco = ico.pixmap(titleHeight);
2402  if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
2403  p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
2404  else
2405  p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
2406  }
2407  if (!dwOpt->title.isEmpty()) {
2408  QPen oldPen = p->pen();
2409  QFont oldFont = p->font();
2410  QFont titleFont = oldFont;
2411  titleFont.setBold(true);
2412  p->setFont(titleFont);
2413  QString titleText
2414  = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
2415 
2416  int result = TST_NONE;
2417  pGetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
2418  if (result != TST_NONE) {
2419  COLORREF textShadowRef;
2420  pGetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
2421  QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
2422  p->setPen(textShadow);
2423  drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
2424  Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
2425  dwOpt->state & State_Enabled, titleText);
2426  }
2427 
2428  COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
2429  QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
2430  p->setPen(textColor);
2431  drawItemText(p, titleRect,
2432  Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
2433  dwOpt->state & State_Enabled, titleText);
2434  p->setFont(oldFont);
2435  p->setPen(oldPen);
2436  }
2437 
2438  }
2439 
2440  return;
2441  }
2442  break;
2443 #endif // QT_NO_DOCKWIDGET
2444 #ifndef QT_NO_RUBBERBAND
2445  case CE_RubberBand:
2446  if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
2448  p->save();
2449  p->setPen(highlight.darker(120));
2450  QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
2451  qMin(highlight.green()/2 + 110, 255),
2452  qMin(highlight.blue()/2 + 110, 255),
2453  (widget && widget->isTopLevel())? 255 : 127);
2454  p->setBrush(dimHighlight);
2455  p->drawRect(option->rect.adjusted(0, 0, -1, -1));
2456  p->restore();
2457  return;
2458  }
2459 #endif // QT_NO_RUBBERBAND
2460  case CE_HeaderEmptyArea:
2461  if (option->state & State_Horizontal)
2462  {
2463  name = QLatin1String("HEADER");
2464  stateId = HIS_NORMAL;
2465  }
2466  else {
2467  QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p, widget);
2468  return;
2469  }
2470  break;
2471  default:
2472  break;
2473  }
2474 
2475  XPThemeData theme(widget, p, name, partId, stateId, rect);
2476  if (!theme.isValid()) {
2477  QWindowsStyle::drawControl(element, option, p, widget);
2478  return;
2479  }
2480 
2481  theme.rotate = rotate;
2482  theme.mirrorHorizontally = hMirrored;
2483  theme.mirrorVertically = vMirrored;
2484  d->drawBackground(theme);
2485 }
2486 
2487 
2492  QPainter *p, const QWidget *widget) const
2493 {
2494  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
2495 
2497  QWindowsStyle::drawComplexControl(cc, option, p, widget);
2498  return;
2499  }
2500 
2501  State flags = option->state;
2502  SubControls sub = option->subControls;
2503  QRect r = option->rect;
2504 
2505  int partId = 0;
2506  int stateId = 0;
2507  if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
2508  flags |= State_MouseOver;
2509 
2510  switch (cc) {
2511 #ifndef QT_NO_SPINBOX
2512  case CC_SpinBox:
2513  if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
2514  {
2515  XPThemeData theme(widget, p, QLatin1String("SPIN"));
2516 
2517  if (sb->frame && (sub & SC_SpinBoxFrame)) {
2518  partId = EP_EDITTEXT;
2519  if (!(flags & State_Enabled))
2520  stateId = ETS_DISABLED;
2521  else if (flags & State_HasFocus)
2522  stateId = ETS_FOCUSED;
2523  else
2524  stateId = ETS_NORMAL;
2525 
2526  XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
2527  ftheme.noContent = true;
2528  d->drawBackground(ftheme);
2529  }
2530  if (sub & SC_SpinBoxUp) {
2531  theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
2532  partId = SPNP_UP;
2533  if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
2534  stateId = UPS_DISABLED;
2535  else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
2536  stateId = UPS_PRESSED;
2537  else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
2538  stateId = UPS_HOT;
2539  else
2540  stateId = UPS_NORMAL;
2541  theme.partId = partId;
2542  theme.stateId = stateId;
2543  d->drawBackground(theme);
2544  }
2545  if (sub & SC_SpinBoxDown) {
2546  theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
2547  partId = SPNP_DOWN;
2548  if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
2549  stateId = DNS_DISABLED;
2550  else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
2551  stateId = DNS_PRESSED;
2552  else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
2553  stateId = DNS_HOT;
2554  else
2555  stateId = DNS_NORMAL;
2556  theme.partId = partId;
2557  theme.stateId = stateId;
2558  d->drawBackground(theme);
2559  }
2560  }
2561  break;
2562 #endif // QT_NO_SPINBOX
2563 #ifndef QT_NO_COMBOBOX
2564  case CC_ComboBox:
2565  if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
2566  {
2567  if (sub & SC_ComboBoxEditField) {
2568  if (cmb->frame) {
2569  partId = EP_EDITTEXT;
2570  if (!(flags & State_Enabled))
2571  stateId = ETS_DISABLED;
2572  else if (flags & State_HasFocus)
2573  stateId = ETS_FOCUSED;
2574  else
2575  stateId = ETS_NORMAL;
2576  XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
2577  d->drawBackground(theme);
2578  } else {
2579  QBrush editBrush = cmb->palette.brush(QPalette::Base);
2580  p->fillRect(option->rect, editBrush);
2581  }
2582  if (!cmb->editable) {
2583  QRect re = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
2584  if (option->state & State_HasFocus) {
2585  p->fillRect(re, option->palette.highlight());
2586  p->setPen(option->palette.highlightedText().color());
2587  p->setBackground(option->palette.highlight());
2588  } else {
2589  p->fillRect(re, option->palette.base());
2590  p->setPen(option->palette.text().color());
2591  p->setBackground(option->palette.base());
2592  }
2593  }
2594  }
2595 
2596  if (sub & SC_ComboBoxArrow) {
2597  XPThemeData theme(widget, p, QLatin1String("COMBOBOX"));
2598  theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
2599  partId = CP_DROPDOWNBUTTON;
2600  if (!(flags & State_Enabled))
2601  stateId = CBXS_DISABLED;
2602  else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_Sunken))
2603  stateId = CBXS_PRESSED;
2604  else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_MouseOver))
2605  stateId = CBXS_HOT;
2606  else
2607  stateId = CBXS_NORMAL;
2608  theme.partId = partId;
2609  theme.stateId = stateId;
2610  d->drawBackground(theme);
2611  }
2612  }
2613  break;
2614 #endif // QT_NO_COMBOBOX
2615  case CC_ScrollBar:
2616  if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
2617  {
2618  XPThemeData theme(widget, p, QLatin1String("SCROLLBAR"));
2619  bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
2620  if (maxedOut)
2621  flags &= ~State_Enabled;
2622 
2623  bool isHorz = flags & State_Horizontal;
2624  bool isRTL = option->direction == Qt::RightToLeft;
2625  if (sub & SC_ScrollBarAddLine) {
2626  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
2627  partId = SBP_ARROWBTN;
2628  if (!(flags & State_Enabled))
2629  stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
2630  else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
2631  stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
2632  else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
2633  stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
2634  else
2635  stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
2636  theme.partId = partId;
2637  theme.stateId = stateId;
2638  d->drawBackground(theme);
2639  }
2640  if (sub & SC_ScrollBarSubLine) {
2641  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
2642  partId = SBP_ARROWBTN;
2643  if (!(flags & State_Enabled))
2644  stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
2645  else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
2646  stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
2647  else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
2648  stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
2649  else
2650  stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
2651  theme.partId = partId;
2652  theme.stateId = stateId;
2653  d->drawBackground(theme);
2654  }
2655  if (maxedOut) {
2656  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
2657  theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
2658  theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
2659  partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
2660  stateId = SCRBS_DISABLED;
2661  theme.partId = partId;
2662  theme.stateId = stateId;
2663  d->drawBackground(theme);
2664  } else {
2665  if (sub & SC_ScrollBarSubPage) {
2666  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
2667  partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
2668  if (!(flags & State_Enabled))
2669  stateId = SCRBS_DISABLED;
2670  else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
2671  stateId = SCRBS_PRESSED;
2672  else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
2673  stateId = SCRBS_HOT;
2674  else
2675  stateId = SCRBS_NORMAL;
2676  theme.partId = partId;
2677  theme.stateId = stateId;
2678  d->drawBackground(theme);
2679  }
2680  if (sub & SC_ScrollBarAddPage) {
2681  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
2682  partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
2683  if (!(flags & State_Enabled))
2684  stateId = SCRBS_DISABLED;
2685  else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
2686  stateId = SCRBS_PRESSED;
2687  else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
2688  stateId = SCRBS_HOT;
2689  else
2690  stateId = SCRBS_NORMAL;
2691  theme.partId = partId;
2692  theme.stateId = stateId;
2693  d->drawBackground(theme);
2694  }
2695  if (sub & SC_ScrollBarSlider) {
2696  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
2697  if (!(flags & State_Enabled))
2698  stateId = SCRBS_DISABLED;
2699  else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
2700  stateId = SCRBS_PRESSED;
2701  else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
2702  stateId = SCRBS_HOT;
2703  else
2704  stateId = SCRBS_NORMAL;
2705 
2706  // Draw handle
2707  theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
2708  theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
2709  theme.stateId = stateId;
2710  d->drawBackground(theme);
2711 
2712  // Calculate rect of gripper
2713  const int swidth = theme.rect.width();
2714  const int sheight = theme.rect.height();
2715 
2716  MARGINS contentsMargin;
2717  RECT rect = theme.toRECT(theme.rect);
2718  pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
2719 
2720  SIZE size;
2721  theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
2722  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
2723  int gw = size.cx, gh = size.cy;
2724 
2725 
2726  QRect gripperBounds;
2727  if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
2728  gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
2729  gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
2730  gripperBounds.setWidth(gw);
2731  gripperBounds.setHeight(gh);
2732  } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
2733  gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
2734  gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
2735  gripperBounds.setWidth(gw);
2736  gripperBounds.setHeight(gh);
2737  }
2738 
2739  // Draw gripper if there is enough space
2740  if (!gripperBounds.isEmpty()) {
2741  p->save();
2742  theme.rect = gripperBounds;
2743  p->setClipRegion(d->region(theme));// Only change inside the region of the gripper
2744  d->drawBackground(theme); // Transparent gripper ontop of background
2745  p->restore();
2746  }
2747  }
2748  }
2749  }
2750  break;
2751 
2752 #ifndef QT_NO_SLIDER
2753  case CC_Slider:
2754  if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option))
2755  {
2756  XPThemeData theme(widget, p, QLatin1String("TRACKBAR"));
2757  QRect slrect = slider->rect;
2758  QRegion tickreg = slrect;
2759  if (sub & SC_SliderGroove) {
2760  theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
2761  if (slider->orientation == Qt::Horizontal) {
2762  partId = TKP_TRACK;
2763  stateId = TRS_NORMAL;
2764  theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
2765  } else {
2766  partId = TKP_TRACKVERT;
2767  stateId = TRVS_NORMAL;
2768  theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
2769  }
2770  theme.partId = partId;
2771  theme.stateId = stateId;
2772  d->drawBackground(theme);
2773  tickreg -= theme.rect;
2774  }
2775  if (sub & SC_SliderTickmarks) {
2776  int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
2777  int ticks = slider->tickPosition;
2778  int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
2779  int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
2780  int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
2781  int interval = slider->tickInterval;
2782  if (interval <= 0) {
2783  interval = slider->singleStep;
2784  if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
2785  available)
2786  - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2787  0, available) < 3)
2788  interval = slider->pageStep;
2789  }
2790  if (!interval)
2791  interval = 1;
2792  int fudge = len / 2;
2793  int pos;
2794  int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0;
2795  p->setPen(d->sliderTickColor);
2797  int v = slider->minimum;
2798  while (v <= slider->maximum + 1) {
2799  if (v == slider->maximum + 1 && interval == 1)
2800  break;
2801  const int v_ = qMin(v, slider->maximum);
2802  int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
2803  pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2804  v_, available) + fudge;
2805  if (slider->orientation == Qt::Horizontal) {
2806  if (ticks & QSlider::TicksAbove)
2807  lines.append(QLine(pos, tickOffset - 1 - bothOffset,
2808  pos, tickOffset - 1 - bothOffset - tickLength));
2809 
2810  if (ticks & QSlider::TicksBelow)
2811  lines.append(QLine(pos, tickOffset + thickness + bothOffset,
2812  pos, tickOffset + thickness + bothOffset + tickLength));
2813  } else {
2814  if (ticks & QSlider::TicksAbove)
2815  lines.append(QLine(tickOffset - 1 - bothOffset, pos,
2816  tickOffset - 1 - bothOffset - tickLength, pos));
2817 
2818  if (ticks & QSlider::TicksBelow)
2819  lines.append(QLine(tickOffset + thickness + bothOffset, pos,
2820  tickOffset + thickness + bothOffset + tickLength, pos));
2821  }
2822  // in the case where maximum is max int
2823  int nextInterval = v + interval;
2824  if (nextInterval < v)
2825  break;
2826  v = nextInterval;
2827  }
2828  if (lines.size() > 0) {
2829  p->save();
2830  p->translate(slrect.topLeft());
2831  p->drawLines(lines.constData(), lines.size());
2832  p->restore();
2833  }
2834  }
2835  if (sub & SC_SliderHandle) {
2836  theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
2837  if (slider->orientation == Qt::Horizontal) {
2838  if (slider->tickPosition == QSlider::TicksAbove)
2839  partId = TKP_THUMBTOP;
2840  else if (slider->tickPosition == QSlider::TicksBelow)
2841  partId = TKP_THUMBBOTTOM;
2842  else
2843  partId = TKP_THUMB;
2844 
2845  if (!(slider->state & State_Enabled))
2846  stateId = TUS_DISABLED;
2847  else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
2848  stateId = TUS_PRESSED;
2849  else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
2850  stateId = TUS_HOT;
2851  else if (flags & State_HasFocus)
2852  stateId = TUS_FOCUSED;
2853  else
2854  stateId = TUS_NORMAL;
2855  } else {
2856  if (slider->tickPosition == QSlider::TicksLeft)
2857  partId = TKP_THUMBLEFT;
2858  else if (slider->tickPosition == QSlider::TicksRight)
2859  partId = TKP_THUMBRIGHT;
2860  else
2861  partId = TKP_THUMBVERT;
2862 
2863  if (!(slider->state & State_Enabled))
2864  stateId = TUVS_DISABLED;
2865  else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
2866  stateId = TUVS_PRESSED;
2867  else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
2868  stateId = TUVS_HOT;
2869  else if (flags & State_HasFocus)
2870  stateId = TUVS_FOCUSED;
2871  else
2872  stateId = TUVS_NORMAL;
2873  }
2874  theme.partId = partId;
2875  theme.stateId = stateId;
2876  d->drawBackground(theme);
2877  }
2878  if (slider->state & State_HasFocus) {
2879  QStyleOptionFocusRect fropt;
2880  fropt.QStyleOption::operator=(*slider);
2881  fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
2882  proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
2883  }
2884  }
2885  break;
2886 #endif
2887 #ifndef QT_NO_TOOLBUTTON
2888  case CC_ToolButton:
2889  if (const QStyleOptionToolButton *toolbutton
2890  = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
2891  QRect button, menuarea;
2892  button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
2893  menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
2894 
2895  State bflags = toolbutton->state & ~State_Sunken;
2896  State mflags = bflags;
2897  bool autoRaise = flags & State_AutoRaise;
2898  if (autoRaise) {
2899  if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
2900  bflags &= ~State_Raised;
2901  }
2902  }
2903 
2904  if (toolbutton->state & State_Sunken) {
2905  if (toolbutton->activeSubControls & SC_ToolButton) {
2906  bflags |= State_Sunken;
2907  mflags |= State_MouseOver | State_Sunken;
2908  } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
2909  mflags |= State_Sunken;
2910  bflags |= State_MouseOver;
2911  }
2912  }
2913 
2914  QStyleOption tool(0);
2915  tool.palette = toolbutton->palette;
2916  if (toolbutton->subControls & SC_ToolButton) {
2917  if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
2918  if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
2919  XPThemeData theme(widget, p, QLatin1String("TOOLBAR"));
2920  theme.partId = TP_SPLITBUTTON;
2921  theme.rect = button;
2922  if (!(bflags & State_Enabled))
2923  stateId = TS_DISABLED;
2924  else if (bflags & State_Sunken)
2925  stateId = TS_PRESSED;
2926  else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
2927  stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
2928  else if (bflags & State_On)
2929  stateId = TS_CHECKED;
2930  else
2931  stateId = TS_NORMAL;
2932  if (option->direction == Qt::RightToLeft)
2933  theme.mirrorHorizontally = true;
2934  theme.stateId = stateId;
2935  d->drawBackground(theme);
2936  } else {
2937  tool.rect = option->rect;
2938  tool.state = bflags;
2939  if (autoRaise) // for tool bars
2940  proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
2941  else
2942  proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
2943  }
2944  }
2945  }
2946 
2947  if (toolbutton->state & State_HasFocus) {
2949  fr.QStyleOption::operator=(*toolbutton);
2950  fr.rect.adjust(3, 3, -3, -3);
2951  if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
2953  toolbutton, widget), 0);
2954  proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
2955  }
2956  QStyleOptionToolButton label = *toolbutton;
2957  label.state = bflags;
2958  int fw = 2;
2959  if (!autoRaise)
2960  label.state &= ~State_Sunken;
2961  label.rect = button.adjusted(fw, fw, -fw, -fw);
2962  proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
2963 
2964  if (toolbutton->subControls & SC_ToolButtonMenu) {
2965  tool.rect = menuarea;
2966  tool.state = mflags;
2967  if (autoRaise) {
2968  proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
2969  } else {
2970  tool.state = mflags;
2971  menuarea.adjust(-2, 0, 0, 0);
2972  // Draw menu button
2973  if ((bflags & State_Sunken) != (mflags & State_Sunken)){
2974  p->save();
2975  p->setClipRect(menuarea);
2976  tool.rect = option->rect;
2977  proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0);
2978  p->restore();
2979  }
2980  // Draw arrow
2981  p->save();
2982  p->setPen(option->palette.dark().color());
2983  p->drawLine(menuarea.left(), menuarea.top() + 3,
2984  menuarea.left(), menuarea.bottom() - 3);
2985  p->setPen(option->palette.light().color());
2986  p->drawLine(menuarea.left() - 1, menuarea.top() + 3,
2987  menuarea.left() - 1, menuarea.bottom() - 3);
2988 
2989  tool.rect = menuarea.adjusted(2, 3, -2, -1);
2990  proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
2991  p->restore();
2992  }
2993  } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
2994  int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
2995  QRect ir = toolbutton->rect;
2996  QStyleOptionToolButton newBtn = *toolbutton;
2997  newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
2998  proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
2999  }
3000  }
3001  break;
3002 #endif // QT_NO_TOOLBUTTON
3003 
3004  case CC_TitleBar:
3005  {
3006  if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
3007  {
3008  bool isActive = tb->titleBarState & QStyle::State_Active;
3009  XPThemeData theme(widget, p, QLatin1String("WINDOW"));
3010  if (sub & SC_TitleBarLabel) {
3011 
3012 #ifdef QT3_SUPPORT
3013  if (widget && widget->inherits("Q3DockWindowTitleBar")) {
3014  partId = WP_SMALLCAPTION;
3015  } else
3016 #endif
3017  partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
3018  theme.rect = option->rect;
3019  if (widget && !widget->isEnabled())
3020  stateId = CS_DISABLED;
3021  else if (isActive)
3022  stateId = CS_ACTIVE;
3023  else
3024  stateId = CS_INACTIVE;
3025 
3026  theme.partId = partId;
3027  theme.stateId = stateId;
3028  d->drawBackground(theme);
3029 
3030  QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
3031 
3032  int result = TST_NONE;
3033  pGetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
3034  if (result != TST_NONE) {
3035  COLORREF textShadowRef;
3036  pGetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
3037  QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
3038  p->setPen(textShadow);
3039  p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(),
3041  }
3042  COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
3043  QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
3044  p->setPen(textColor);
3045  p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(),
3047  }
3048  if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3049  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu, widget);
3050  partId = WP_SYSBUTTON;
3051  if ((widget && !widget->isEnabled()) || !isActive)
3052  stateId = SBS_DISABLED;
3053  else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
3054  stateId = SBS_PUSHED;
3055  else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
3056  stateId = SBS_HOT;
3057  else
3058  stateId = SBS_NORMAL;
3059  if (!tb->icon.isNull()) {
3060  tb->icon.paint(p, theme.rect);
3061  } else {
3062  theme.partId = partId;
3063  theme.stateId = stateId;
3064  SIZE sz;
3065  pGetThemePartSize(theme.handle(), qt_win_display_dc(), theme.partId, theme.stateId, 0, TS_TRUE, &sz);
3066  if (sz.cx == 0 || sz.cy == 0) {
3067  int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
3068  QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb, widget).pixmap(iconSize, iconSize);
3069  p->save();
3070  drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
3071  p->restore();
3072  } else {
3073  d->drawBackground(theme);
3074  }
3075  }
3076  }
3077 
3078  if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
3079  && !(tb->titleBarState & Qt::WindowMinimized)) {
3080  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget);
3081  partId = WP_MINBUTTON;
3082  if (widget && !widget->isEnabled())
3083  stateId = MINBS_DISABLED;
3084  else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken))
3085  stateId = MINBS_PUSHED;
3086  else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver))
3087  stateId = MINBS_HOT;
3088  else if (!isActive)
3089  stateId = MINBS_INACTIVE;
3090  else
3091  stateId = MINBS_NORMAL;
3092  theme.partId = partId;
3093  theme.stateId = stateId;
3094  d->drawBackground(theme);
3095  }
3096  if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
3097  && !(tb->titleBarState & Qt::WindowMaximized)) {
3098  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget);
3099  partId = WP_MAXBUTTON;
3100  if (widget && !widget->isEnabled())
3101  stateId = MAXBS_DISABLED;
3102  else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken))
3103  stateId = MAXBS_PUSHED;
3104  else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver))
3105  stateId = MAXBS_HOT;
3106  else if (!isActive)
3107  stateId = MAXBS_INACTIVE;
3108  else
3109  stateId = MAXBS_NORMAL;
3110  theme.partId = partId;
3111  theme.stateId = stateId;
3112  d->drawBackground(theme);
3113  }
3115  && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
3116  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget);
3117  partId = WP_HELPBUTTON;
3118  if (widget && !widget->isEnabled())
3119  stateId = MINBS_DISABLED;
3120  else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken))
3121  stateId = MINBS_PUSHED;
3122  else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver))
3123  stateId = MINBS_HOT;
3124  else if (!isActive)
3125  stateId = MINBS_INACTIVE;
3126  else
3127  stateId = MINBS_NORMAL;
3128  theme.partId = partId;
3129  theme.stateId = stateId;
3130  d->drawBackground(theme);
3131  }
3132  bool drawNormalButton = (sub & SC_TitleBarNormalButton)
3133  && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3134  && (tb->titleBarState & Qt::WindowMinimized))
3135  || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3136  && (tb->titleBarState & Qt::WindowMaximized)));
3137  if (drawNormalButton) {
3138  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget);
3139  partId = WP_RESTOREBUTTON;
3140  if (widget && !widget->isEnabled())
3141  stateId = RBS_DISABLED;
3142  else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken))
3143  stateId = RBS_PUSHED;
3144  else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver))
3145  stateId = RBS_HOT;
3146  else if (!isActive)
3147  stateId = RBS_INACTIVE;
3148  else
3149  stateId = RBS_NORMAL;
3150  theme.partId = partId;
3151  theme.stateId = stateId;
3152  d->drawBackground(theme);
3153  }
3154  if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
3155  && !(tb->titleBarState & Qt::WindowMinimized)) {
3156  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget);
3157  partId = WP_MINBUTTON;
3158  if (widget && !widget->isEnabled())
3159  stateId = MINBS_DISABLED;
3160  else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken))
3161  stateId = MINBS_PUSHED;
3162  else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver))
3163  stateId = MINBS_HOT;
3164  else if (!isActive)
3165  stateId = MINBS_INACTIVE;
3166  else
3167  stateId = MINBS_NORMAL;
3168  theme.partId = partId;
3169  theme.stateId = stateId;
3170  d->drawBackground(theme);
3171  }
3172  if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
3173  && tb->titleBarState & Qt::WindowMinimized) {
3174  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget);
3175  partId = WP_RESTOREBUTTON;
3176  if (widget && !widget->isEnabled())
3177  stateId = RBS_DISABLED;
3178  else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken))
3179  stateId = RBS_PUSHED;
3180  else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver))
3181  stateId = RBS_HOT;
3182  else if (!isActive)
3183  stateId = RBS_INACTIVE;
3184  else
3185  stateId = RBS_NORMAL;
3186  theme.partId = partId;
3187  theme.stateId = stateId;
3188  d->drawBackground(theme);
3189  }
3190  if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3191  theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget);
3192  //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
3193  partId = WP_CLOSEBUTTON;
3194  if (widget && !widget->isEnabled())
3195  stateId = CBS_DISABLED;
3196  else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken))
3197  stateId = CBS_PUSHED;
3198  else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver))
3199  stateId = CBS_HOT;
3200  else if (!isActive)
3201  stateId = CBS_INACTIVE;
3202  else
3203  stateId = CBS_NORMAL;
3204  theme.partId = partId;
3205  theme.stateId = stateId;
3206  d->drawBackground(theme);
3207  }
3208  }
3209  }
3210  break;
3211 
3212 #ifndef QT_NO_WORKSPACE
3213  case CC_MdiControls:
3214  {
3215  QRect buttonRect;
3216  XPThemeData theme(widget, p, QLatin1String("WINDOW"), WP_MDICLOSEBUTTON, CBS_NORMAL);
3217 
3218  if (option->subControls & SC_MdiCloseButton) {
3219  buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
3220  if (theme.isValid()) {
3221  theme.partId = WP_MDICLOSEBUTTON;
3222  theme.rect = buttonRect;
3223  if (!(flags & State_Enabled))
3224  theme.stateId = CBS_INACTIVE;
3225  else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton))
3226  theme.stateId = CBS_PUSHED;
3227  else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton))
3228  theme.stateId = CBS_HOT;
3229  else
3230  theme.stateId = CBS_NORMAL;
3231  d->drawBackground(theme);
3232  }
3233  }
3234  if (option->subControls & SC_MdiNormalButton) {
3235  buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget);
3236  if (theme.isValid()) {
3237  theme.partId = WP_MDIRESTOREBUTTON;
3238  theme.rect = buttonRect;
3239  if (!(flags & State_Enabled))
3240  theme.stateId = CBS_INACTIVE;
3241  else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton))
3242  theme.stateId = CBS_PUSHED;
3243  else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton))
3244  theme.stateId = CBS_HOT;
3245  else
3246  theme.stateId = CBS_NORMAL;
3247  d->drawBackground(theme);
3248  }
3249  }
3250  if (option->subControls & QStyle::SC_MdiMinButton) {
3251  buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget);
3252  if (theme.isValid()) {
3253  theme.partId = WP_MDIMINBUTTON;
3254  theme.rect = buttonRect;
3255  if (!(flags & State_Enabled))
3256  theme.stateId = CBS_INACTIVE;
3257  else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton))
3258  theme.stateId = CBS_PUSHED;
3259  else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton))
3260  theme.stateId = CBS_HOT;
3261  else
3262  theme.stateId = CBS_NORMAL;
3263  d->drawBackground(theme);
3264  }
3265  }
3266  }
3267  break;
3268 #endif //QT_NO_WORKSPACE
3269 #ifndef QT_NO_DIAL
3270  case CC_Dial:
3271  if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
3272  QStyleHelper::drawDial(dial, p);
3273  break;
3274 #endif // QT_NO_DIAL
3275  default:
3276  QWindowsStyle::drawComplexControl(cc, option, p, widget);
3277  break;
3278  }
3279 }
3280 
3283 {
3285  return QWindowsStyle::pixelMetric(pm, option, widget);
3286 
3287  int res = 0;
3288  switch (pm) {
3289  case PM_MenuBarPanelWidth:
3290  res = 0;
3291  break;
3292 
3293  case PM_DefaultFrameWidth:
3294  if (qobject_cast<const QListView*>(widget))
3295  res = 2;
3296  else
3297  res = 1;
3298  break;
3299  case PM_MenuPanelWidth:
3300  case PM_SpinBoxFrameWidth:
3301  res = 1;
3302  break;
3303 
3304  case PM_TabBarTabOverlap:
3305  case PM_MenuHMargin:
3306  case PM_MenuVMargin:
3307  res = 2;
3308  break;
3309 
3310  case PM_TabBarBaseOverlap:
3311  if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
3312  switch (tab->shape) {
3313  case QTabBar::RoundedNorth:
3315  res = 1;
3316  break;
3317  case QTabBar::RoundedSouth:
3319  res = 2;
3320  break;
3321  case QTabBar::RoundedEast:
3323  res = 3;
3324  break;
3325  case QTabBar::RoundedWest:
3327  res = 1;
3328  break;
3329  }
3330  }
3331  break;
3332 
3333  case PM_SplitterWidth:
3334  res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width());
3335  break;
3336 
3337  case PM_IndicatorWidth:
3338  case PM_IndicatorHeight:
3339  {
3340  XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
3341  if (theme.isValid()) {
3342  SIZE size;
3343  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
3344  res = (pm == PM_IndicatorWidth) ? size.cx : size.cy;
3345  }
3346  }
3347  break;
3348 
3351  {
3352  XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
3353  if (theme.isValid()) {
3354  SIZE size;
3355  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
3356  res = (pm == PM_ExclusiveIndicatorWidth) ? size.cx : size.cy;
3357  }
3358  }
3359  break;
3360 
3362  {
3364  if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
3365  orient = pb2->orientation;
3366  XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
3367  if (theme.isValid()) {
3368  SIZE size;
3369  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
3370  res = (orient == Qt::Horizontal) ? size.cx : size.cy;
3371  }
3372  }
3373  break;
3374 
3375  case PM_SliderThickness:
3376  {
3377  XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB);
3378  if (theme.isValid()) {
3379  SIZE size;
3380  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
3381  res = size.cy;
3382  }
3383  }
3384  break;
3385 
3386  case PM_TitleBarHeight:
3387  {
3388 #ifdef QT3_SUPPORT
3389  if (widget && widget->inherits("Q3DockWindowTitleBar")) {
3390  res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
3391  } else
3392 #endif
3393  if (widget && (widget->windowType() == Qt::Tool))
3394  res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
3395  else
3396  res = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
3397  }
3398  break;
3399 
3401  {
3402  XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE);
3403  if (theme.isValid()) {
3404  SIZE size;
3405  pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size);
3406  res = size.cx-1;
3407  }
3408  }
3409  break;
3410 
3412  res = 160;
3413  break;
3414 
3415 #ifndef QT_NO_TOOLBAR
3417  res = int(QStyleHelper::dpiScaled(8.));
3418  break;
3419 
3420 #endif // QT_NO_TOOLBAR
3422  {
3423  XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE);
3424  if (theme.isValid()) {
3425  SIZE size;
3426  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
3427  res = size.cx;
3428  }
3429  }
3430  break;
3432  res = int(QStyleHelper::dpiScaled(4.));
3433  break;
3435  res = int(QStyleHelper::dpiScaled(4.));
3436  break;
3437 
3440  if (qstyleoption_cast<const QStyleOptionToolButton *>(option))
3441  res = 1;
3442  else
3443  res = 0;
3444  break;
3445 
3447  res = 0;
3448  break;
3449 
3450  default:
3451  res = QWindowsStyle::pixelMetric(pm, option, widget);
3452  }
3453 
3454  return res;
3455 }
3456 
3457 /*
3458  This function is used by subControlRect to check if a button
3459  should be drawn for the given subControl given a set of window flags.
3460 */
3461 static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
3462 
3463  bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3464  bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3465  const uint flags = tb->titleBarFlags;
3466  bool retVal = false;
3467  switch (sc) {
3469  if (flags & Qt::WindowContextHelpButtonHint)
3470  retVal = true;
3471  break;
3473  if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
3474  retVal = true;
3475  break;
3477  if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
3478  retVal = true;
3479  else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
3480  retVal = true;
3481  break;
3483  if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
3484  retVal = true;
3485  break;
3487  if (!isMinimized && flags & Qt::WindowShadeButtonHint)
3488  retVal = true;
3489  break;
3491  if (isMinimized && flags & Qt::WindowShadeButtonHint)
3492  retVal = true;
3493  break;
3495  if (flags & Qt::WindowSystemMenuHint)
3496  retVal = true;
3497  break;
3499  if (flags & Qt::WindowSystemMenuHint)
3500  retVal = true;
3501  break;
3502  default :
3503  retVal = true;
3504  }
3505  return retVal;
3506 }
3507 
3512  SubControl subControl, const QWidget *widget) const
3513 {
3515  return QWindowsStyle::subControlRect(cc, option, subControl, widget);
3516 
3517  QRect rect;
3518 
3519  switch (cc) {
3520  case CC_TitleBar:
3521  if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
3522  if (!buttonVisible(subControl, tb))
3523  return rect;
3524  const bool isToolTitle = false;
3525  const int height = tb->rect.height();
3526  const int width = tb->rect.width();
3527  int buttonHeight = GetSystemMetrics(SM_CYSIZE) - 4;
3528  int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
3529  const int delta = buttonWidth + 2;
3530  int controlTop = option->rect.bottom() - buttonHeight - 2;
3531  const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
3532  const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
3533  const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
3534  const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
3535  const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
3536  const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
3537  bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3538  bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3539  int offset = 0;
3540 
3541  switch (subControl) {
3542  case SC_TitleBarLabel:
3543  rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
3544  if (isToolTitle) {
3545  if (sysmenuHint) {
3546  rect.adjust(0, 0, -buttonWidth - 3, 0);
3547  }
3548  if (minimizeHint || maximizeHint)
3549  rect.adjust(0, 0, -buttonWidth - 2, 0);
3550  } else {
3551  if (sysmenuHint) {
3552  const int leftOffset = height - 8;
3553  rect.adjust(leftOffset, 0, 0, 0);
3554  }
3555  if (minimizeHint)
3556  rect.adjust(0, 0, -buttonWidth - 2, 0);
3557  if (maximizeHint)
3558  rect.adjust(0, 0, -buttonWidth - 2, 0);
3559  if (contextHint)
3560  rect.adjust(0, 0, -buttonWidth - 2, 0);
3561  if (shadeHint)
3562  rect.adjust(0, 0, -buttonWidth - 2, 0);
3563  }
3564  break;
3565 
3567  if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3568  offset += delta;
3569  //fall through
3570  case SC_TitleBarMinButton:
3571  if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3572  offset += delta;
3573  else if (subControl == SC_TitleBarMinButton)
3574  break;
3575  //fall through
3577  if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3578  offset += delta;
3579  else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3580  offset += delta;
3581  else if (subControl == SC_TitleBarNormalButton)
3582  break;
3583  //fall through
3584  case SC_TitleBarMaxButton:
3585  if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3586  offset += delta;
3587  else if (subControl == SC_TitleBarMaxButton)
3588  break;
3589  //fall through
3591  if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3592  offset += delta;
3593  else if (subControl == SC_TitleBarShadeButton)
3594  break;
3595  //fall through
3597  if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3598  offset += delta;
3599  else if (subControl == SC_TitleBarUnshadeButton)
3600  break;
3601  //fall through
3603  if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3604  offset += delta;
3605  else if (subControl == SC_TitleBarCloseButton)
3606  break;
3607 
3608  rect.setRect(width - offset - controlTop + 1, controlTop,
3609  buttonWidth, buttonHeight);
3610  break;
3611 
3612  case SC_TitleBarSysMenu:
3613  {
3614  const int controlTop = 6;
3615  const int controlHeight = height - controlTop - 3;
3616  const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
3617  QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
3618  if (tb->icon.isNull())
3619  iconSize = QSize(controlHeight, controlHeight);
3620  int hPad = (controlHeight - iconSize.height())/2;
3621  int vPad = (controlHeight - iconSize.width())/2;
3622  rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
3623  }
3624  break;
3625  default:
3626  break;
3627  }
3628  }
3629  break;
3630 
3631  case CC_ComboBox:
3632  if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
3633  int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
3634  int xpos = x;
3635  xpos += wi - 1 - 16;
3636 
3637  switch (subControl) {
3638  case SC_ComboBoxFrame:
3639  rect = cmb->rect;
3640  break;
3641 
3642  case SC_ComboBoxArrow:
3643  rect = QRect(xpos, y+1, 16, he-2);
3644  break;
3645 
3646  case SC_ComboBoxEditField:
3647  rect = QRect(x+2, y+2, wi-3-16, he-4);
3648  break;
3649 
3651  rect = cmb->rect;
3652  break;
3653 
3654  default:
3655  break;
3656  }
3657  }
3658  break;
3659 #ifndef QT_NO_WORKSPACE
3660  case CC_MdiControls:
3661  {
3662  int numSubControls = 0;
3663  if (option->subControls & SC_MdiCloseButton)
3664  ++numSubControls;
3665  if (option->subControls & SC_MdiMinButton)
3666  ++numSubControls;
3667  if (option->subControls & SC_MdiNormalButton)
3668  ++numSubControls;
3669  if (numSubControls == 0)
3670  break;
3671 
3672  int buttonWidth = option->rect.width()/ numSubControls;
3673  int offset = 0;
3674  switch (subControl) {
3675  case SC_MdiCloseButton:
3676  // Only one sub control, no offset needed.
3677  if (numSubControls == 1)
3678  break;
3679  offset += buttonWidth;
3680  //FALL THROUGH
3681  case SC_MdiNormalButton:
3682  // No offset needed if
3683  // 1) There's only one sub control
3684  // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
3685  if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
3686  break;
3687  if (option->subControls & SC_MdiNormalButton)
3688  offset += buttonWidth;
3689  break;
3690  default:
3691  break;
3692  }
3693  rect = QRect(offset, 0, buttonWidth, option->rect.height());
3694  break;
3695  }
3696 #endif // QT_NO_WORKSPACE
3697 
3698  default:
3699  rect = visualRect(option->direction, option->rect,
3700  QWindowsStyle::subControlRect(cc, option, subControl, widget));
3701  break;
3702  }
3703  return visualRect(option->direction, option->rect, rect);
3704 }
3705 
3710  const QSize &contentsSize, const QWidget *widget) const
3711 {
3713  return QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
3714 
3715  QSize sz(contentsSize);
3716  switch (ct) {
3717  case CT_LineEdit:
3718  case CT_ComboBox:
3719  {
3720  XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
3721  HTHEME theme = buttontheme.handle();
3722  MARGINS borderSize;
3723  if (theme) {
3724  int result = pGetThemeMargins(theme,
3725  NULL,
3726  BP_PUSHBUTTON,
3727  PBS_NORMAL,
3729  NULL,
3730  &borderSize);
3731  if (result == S_OK) {
3732  sz += QSize(borderSize.cxLeftWidth + borderSize.cxRightWidth - 2,
3733  borderSize.cyBottomHeight + borderSize.cyTopHeight - 2);
3734  }
3735  const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
3736  sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
3737  + textMargins, 23), 0); //arrow button
3738  }
3739  }
3740  break;
3741  case CT_SpinBox:
3742  {
3743  //Spinbox adds frame twice
3744  sz = QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
3745  int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
3746  sz -= QSize(2*border, 2*border);
3747  }
3748  break;
3749  case CT_TabWidget:
3750  sz += QSize(6, 6);
3751  break;
3752  case CT_Menu:
3753  sz += QSize(1, 0);
3754  break;
3755 #ifndef QT_NO_MENUBAR
3756  case CT_MenuBarItem:
3757  if (!sz.isEmpty())
3758  sz += QSize(windowsItemHMargin * 5 + 1, 6);
3759  break;
3760 #endif
3761  case CT_MenuItem:
3762  if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
3763  {
3764  if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) {
3765  sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
3766  sz.setHeight(sz.height() - 2);
3767  return sz;
3768  }
3769  }
3770  sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
3771  break;
3772 
3773  case CT_MdiControls:
3774  if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
3775  int width = 0;
3776  if (styleOpt->subControls & SC_MdiMinButton)
3777  width += 17 + 1;
3778  if (styleOpt->subControls & SC_MdiNormalButton)
3779  width += 17 + 1;
3780  if (styleOpt->subControls & SC_MdiCloseButton)
3781  width += 17 + 1;
3782  sz = QSize(width, 19);
3783  } else {
3784  sz = QSize(54, 19);
3785  }
3786  break;
3787 
3788  default:
3789  sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
3790  break;
3791  }
3792 
3793  return sz;
3794 }
3795 
3796 
3799  QStyleHintReturn *returnData) const
3800 {
3801  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
3803  return QWindowsStyle::styleHint(hint, option, widget, returnData);
3804 
3805  int res = 0;
3806  switch (hint) {
3807 
3808  case SH_EtchDisabledText:
3809  res = (qobject_cast<const QLabel*>(widget) != 0);
3810  break;
3811 
3813  res = 0;
3814  break;
3815 
3816  case SH_TitleBar_AutoRaise:
3817  case SH_TitleBar_NoBorder:
3818  res = 1;
3819  break;
3820 
3822  if (!widget || (widget && widget->isEnabled()))
3823  res = d->groupBoxTextColor;
3824  else
3825  res = d->groupBoxTextColorDisabled;
3826  break;
3827 
3829  res = 0xC0C0C0;
3830  break;
3831 
3832  case SH_WindowFrame_Mask:
3833  {
3834  res = 1;
3836  const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
3837  if (mask && titlebar) {
3838  // Note certain themes will not return the whole window frame but only the titlebar part when
3839  // queried This function needs to return the entire window mask, hence we will only fetch the mask for the
3840  // titlebar itself and add the remaining part of the window rect at the bottom.
3841  int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget);
3842  QRect titleBarRect = option->rect;
3843  titleBarRect.setHeight(tbHeight);
3844  XPThemeData themeData;
3845  if (titlebar->titleBarState & Qt::WindowMinimized) {
3846  themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect);
3847  } else
3848  themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect);
3849  mask->region = d->region(themeData) +
3850  QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight);
3851  }
3852  }
3853  break;
3854 #ifndef QT_NO_RUBBERBAND
3855  case SH_RubberBand_Mask:
3856  if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
3857  res = 0;
3858  break;
3859  }
3860 #endif // QT_NO_RUBBERBAND
3861 
3863  res = 1;
3864  break;
3865 
3866  default:
3867  res =QWindowsStyle::styleHint(hint, option, widget, returnData);
3868  }
3869 
3870  return res;
3871 }
3872 
3875 {
3878  else
3880 }
3881 
3886  const QWidget *widget) const
3887 {
3889  return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
3890 
3891  switch(standardPixmap) {
3892  case SP_TitleBarMaxButton:
3894  if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
3895  {
3896  if (widget && widget->isWindow()) {
3897  XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3898  if (theme.isValid()) {
3899  SIZE sz;
3900  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz);
3901  return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(QSize(sz.cx, sz.cy));
3902  }
3903  }
3904  }
3905  break;
3906  default:
3907  break;
3908  }
3909  return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
3910 }
3911 
3916  const QStyleOption *option,
3917  const QWidget *widget) const
3918 {
3920  return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
3921  }
3922 
3923  QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
3924  switch(standardIcon) {
3925  case SP_TitleBarMaxButton:
3926  if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
3927  {
3928  if (d->dockFloat.isNull()) {
3929  XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3930  XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL);
3931  if (theme.isValid()) {
3932  SIZE size;
3933  pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
3934  QPixmap pm = QPixmap(size.cx, size.cy);
3935  pm.fill(Qt::transparent);
3936  QPainter p(&pm);
3937  theme.painter = &p;
3938  theme.rect = QRect(0, 0, size.cx, size.cy);
3939  d->drawBackground(theme);
3940  d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
3941  pm.fill(Qt::transparent);
3942  theme.stateId = MAXBS_PUSHED;
3943  d->drawBackground(theme);
3944  d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
3945  pm.fill(Qt::transparent);
3946  theme.stateId = MAXBS_HOT;
3947  d->drawBackground(theme);
3948  d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
3949  pm.fill(Qt::transparent);
3950  theme.stateId = MAXBS_INACTIVE;
3951  d->drawBackground(theme);
3952  d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
3953  }
3954  }
3955  if (widget && widget->isWindow())
3956  return d->dockFloat;
3957 
3958  }
3959  break;
3961  if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
3962  {
3963  if (d->dockClose.isNull()) {
3964  XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3965  if (theme.isValid()) {
3966  SIZE size;
3967  pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
3968  QPixmap pm = QPixmap(size.cx, size.cy);
3969  pm.fill(Qt::transparent);
3970  QPainter p(&pm);
3971  theme.painter = &p;
3972  theme.partId = WP_CLOSEBUTTON; // ####
3973  theme.rect = QRect(0, 0, size.cx, size.cy);
3974  d->drawBackground(theme);
3975  d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
3976  pm.fill(Qt::transparent);
3977  theme.stateId = CBS_PUSHED;
3978  d->drawBackground(theme);
3979  d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
3980  pm.fill(Qt::transparent);
3981  theme.stateId = CBS_HOT;
3982  d->drawBackground(theme);
3983  d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
3984  pm.fill(Qt::transparent);
3985  theme.stateId = CBS_INACTIVE;
3986  d->drawBackground(theme);
3987  d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
3988  }
3989  }
3990  if (widget && widget->isWindow())
3991  return d->dockClose;
3992  }
3993  break;
3995  if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
3996  {
3997  if (d->dockFloat.isNull()) {
3998  XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3999  XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL);
4000  if (theme.isValid()) {
4001  SIZE size;
4002  pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
4003  QPixmap pm = QPixmap(size.cx, size.cy);
4004  pm.fill(Qt::transparent);
4005  QPainter p(&pm);
4006  theme.painter = &p;
4007  theme.rect = QRect(0, 0, size.cx, size.cy);
4008  d->drawBackground(theme);
4009  d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
4010  pm.fill(Qt::transparent);
4011  theme.stateId = RBS_PUSHED;
4012  d->drawBackground(theme);
4013  d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
4014  pm.fill(Qt::transparent);
4015  theme.stateId = RBS_HOT;
4016  d->drawBackground(theme);
4017  d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
4018  pm.fill(Qt::transparent);
4019  theme.stateId = RBS_INACTIVE;
4020  d->drawBackground(theme);
4021  d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
4022  }
4023  }
4024  if (widget && widget->isWindow())
4025  return d->dockFloat;
4026 
4027  }
4028  break;
4029  default:
4030  break;
4031  }
4032 
4033  return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
4034 }
4035 
4045 {
4046 }
4047 
4048 
4049 // Debugging code ---------------------------------------------------------------------[ START ]---
4050 // The code for this point on is not compiled by default, but only used as assisting
4051 // debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file.
4052 
4053 #ifdef DEBUG_XP_STYLE
4054 // The schema file expects these to be defined by the user.
4055 #define TMT_ENUMDEF 8
4056 #define TMT_ENUMVAL TEXT('A')
4057 #define TMT_ENUM TEXT('B')
4058 #define SCHEMA_STRINGS // For 2nd pass on schema file
4060 #include <tmschema.h>
4062 
4063 // A property's value, type and name combo
4064 struct PropPair {
4065  int propValue;
4066  int propType;
4067  LPCWSTR propName;
4068 };
4069 
4070 // Operator for sorting of PropPairs
4071 bool operator<(PropPair a, PropPair b) {
4072  return wcscmp(a.propName, b.propName) < 0;
4073 }
4074 
4075 // Our list of all possible properties
4076 static QList<PropPair> all_props;
4077 
4078 
4093 void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
4094 {
4095  if (w && h) {
4096  static int pCount = 0;
4097  DWORD *bufPix = (DWORD*)bufferPixels;
4098 
4099  char *bufferDump = new char[bufferH * bufferW * 16];
4100  char *bufferPos = bufferDump;
4101 
4102  memset(bufferDump, 0, sizeof(bufferDump));
4103  bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
4104  bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
4105  bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
4106  for (int iy = 0; iy < h; ++iy) {
4107  bufferPos += sprintf(bufferPos, "\n ");
4108  bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4));
4109  for (int ix = 0; ix < w; ++ix) {
4110  bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix);
4111  ++bufPix;
4112  }
4113  }
4114  bufferPos += sprintf(bufferPos, "\n};\n\n");
4115  printf(bufferDump);
4116 
4117  delete[] bufferDump;
4118  ++pCount;
4119  }
4120 }
4121 
4128 static void showProperty(XPThemeData &themeData, const PropPair &prop)
4129 {
4130  PROPERTYORIGIN origin = PO_NOTFOUND;
4131  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
4132  const char *originStr;
4133  switch(origin) {
4134  case PO_STATE:
4135  originStr = "State ";
4136  break;
4137  case PO_PART:
4138  originStr = "Part ";
4139  break;
4140  case PO_CLASS:
4141  originStr = "Class ";
4142  break;
4143  case PO_GLOBAL:
4144  originStr = "Globl ";
4145  break;
4146  case PO_NOTFOUND:
4147  default:
4148  originStr = "Unkwn ";
4149  break;
4150  }
4151 
4152  switch(prop.propType) {
4153  case TMT_STRING:
4154  {
4155  wchar_t buffer[512];
4156  pGetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
4157  printf(" (%sString) %-20S: %S\n", originStr, prop.propName, buffer);
4158  }
4159  break;
4160  case TMT_ENUM:
4161  {
4162  int result = -1;
4163  pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4164  printf(" (%sEnum) %-20S: %d\n", originStr, prop.propName, result);
4165  }
4166  break;
4167  case TMT_INT:
4168  {
4169  int result = -1;
4170  pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4171  printf(" (%sint) %-20S: %d\n", originStr, prop.propName, result);
4172  }
4173  break;
4174  case TMT_BOOL:
4175  {
4176  BOOL result = false;
4177  pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4178  printf(" (%sbool) %-20S: %d\n", originStr, prop.propName, result);
4179  }
4180  break;
4181  case TMT_COLOR:
4182  {
4183  COLORREF result = 0;
4184  pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4185  printf(" (%scolor) %-20S: 0x%08X\n", originStr, prop.propName, result);
4186  }
4187  break;
4188  case TMT_MARGINS:
4189  {
4190  MARGINS result;
4191  memset(&result, 0, sizeof(result));
4192  pGetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result);
4193  printf(" (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr,
4194  prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight);
4195  }
4196  break;
4197  case TMT_FILENAME:
4198  {
4199  wchar_t buffer[512];
4200  pGetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
4201  printf(" (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer);
4202  }
4203  break;
4204  case TMT_SIZE:
4205  {
4206  SIZE result1;
4207  SIZE result2;
4208  SIZE result3;
4209  memset(&result1, 0, sizeof(result1));
4210  memset(&result2, 0, sizeof(result2));
4211  memset(&result3, 0, sizeof(result3));
4212  pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN, &result1);
4213  pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2);
4214  pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3);
4215  printf(" (%ssize) %-20S: Min (%d, %d), True(%d, %d), Draw(%d, %d)\n", originStr, prop.propName,
4216  result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy);
4217  }
4218  break;
4219  case TMT_POSITION:
4220  {
4221  POINT result;
4222  memset(&result, 0, sizeof(result));
4223  pGetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4224  printf(" (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y);
4225  }
4226  break;
4227  case TMT_RECT:
4228  {
4229  RECT result;
4230  memset(&result, 0, sizeof(result));
4231  pGetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4232  printf(" (%sRect) %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom);
4233  }
4234  break;
4235  case TMT_FONT:
4236  {
4237  LOGFONT result;
4238  memset(&result, 0, sizeof(result));
4239  pGetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result);
4240  printf(" (%sFont) %-20S: %S height(%d) width(%d) weight(%d)\n", originStr, prop.propName,
4241  result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight);
4242  }
4243  break;
4244  case TMT_INTLIST:
4245  {
4246  INTLIST result;
4247  memset(&result, 0, sizeof(result));
4248  pGetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
4249  printf(" (%sInt list)%-20S: { ", originStr, prop.propName);
4250  for (int i = 0; i < result.iValueCount; ++i)
4251  printf("%d ", result.iValues[i]);
4252  printf("}\n");
4253  }
4254  break;
4255  default:
4256  printf(" %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType);
4257  }
4258 }
4259 
4269 void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData)
4270 {
4271  if (!all_props.count()) {
4272  const TMSCHEMAINFO *infoTable = GetSchemaInfo();
4273  for (int i = 0; i < infoTable->iPropCount; ++i) {
4274  int propType = infoTable->pPropTable[i].bPrimVal;
4275  int propValue = infoTable->pPropTable[i].sEnumVal;
4276  LPCWSTR propName = infoTable->pPropTable[i].pszName;
4277 
4278  switch(propType) {
4279  case TMT_ENUMDEF:
4280  case TMT_ENUMVAL:
4281  continue;
4282  default:
4283  if (propType != propValue) {
4284  PropPair prop;
4285  prop.propValue = propValue;
4286  prop.propName = propName;
4287  prop.propType = propType;
4288  all_props.append(prop);
4289  }
4290  }
4291  }
4292  qSort(all_props);
4293 
4294  {// List all properties
4295  printf("part properties count = %d:\n", all_props.count());
4296  printf(" Enum Property Name Description\n");
4297  printf("-----------------------------------------------------------\n");
4298  wchar_t themeName[256];
4299  pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0);
4300  for (int j = 0; j < all_props.count(); ++j) {
4301  PropPair prop = all_props.at(j);
4302  wchar_t buf[500];
4303  pGetThemeDocumentationProperty(themeName, prop.propName, buf, 500);
4304  printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf);
4305  }
4306  }
4307 
4308  {// Show Global values
4309  printf("Global Properties:\n");
4310  for (int j = 0; j < all_props.count(); ++j) {
4311  PropPair prop = all_props.at(j);
4312  PROPERTYORIGIN origin = PO_NOTFOUND;
4313  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
4314  if (origin == PO_GLOBAL) {
4315  showProperty(themeData, prop);
4316  }
4317  }
4318  }
4319  }
4320 
4321  for (int j = 0; j < all_props.count(); ++j) {
4322  PropPair prop = all_props.at(j);
4323  PROPERTYORIGIN origin = PO_NOTFOUND;
4324  pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
4325  if (origin != PO_NOTFOUND)
4326  {
4327  showProperty(themeData, prop);
4328  }
4329  }
4330 }
4331 #endif
4332 // Debugging code -----------------------------------------------------------------------[ END ]---
4333 
4334 
4336 
4337 #endif //QT_NO_WINDOWSXP
QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget=0) const
Reimplemented Function
HRESULT(WINAPI * PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint)
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or 0 if the painter is not acti...
Definition: qpainter.cpp:1530
static PtrGetThemeEnumValue pGetThemeEnumValue
HBITMAP buffer(int w=0, int h=0)
Returns a native buffer (DIB section) of at least the size of ( x , y ).
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget=0) const
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
void polish(QApplication *)
Reimplemented Function
const QWidget * widget
void unpolish(QApplication *)
Reimplemented Function
const T * constData() const
QImage toImage() const
Converts the pixmap to a QImage.
Definition: qpixmap.cpp:542
HRESULT(WINAPI * PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect)
const QBrush & highlight() const
Returns the highlight brush of the current color group.
Definition: qpalette.h:140
QPainter * painter
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
The QApplication class manages the GUI application&#39;s control flow and main settings.
Definition: qapplication.h:99
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition: qpixmap.cpp:2197
HRESULT(WINAPI * PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor)
Format
The following image formats are available in Qt.
Definition: qimage.h:91
QRect subElementRect(SubElement r, const QStyleOption *option, const QWidget *widget=0) const
Reimplemented Function
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
Definition: qimage.cpp:1410
QRect adjusted(int x1, int y1, int x2, int y2) const
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition: qrect.h:431
void setHeight(int h)
Sets the height of the rectangle to the given height.
Definition: qrect.h:445
const QBrush & base() const
Returns the base brush of the current color group.
Definition: qpalette.h:130
SubControl
This enum describes the available sub controls.
Definition: qstyle.h:402
StyleHint
This enum describes the available style hints.
Definition: qstyle.h:640
void drawBackgroundThruNativeBuffer(XPThemeData &themeData)
This function uses a secondary Native doublebuffer for painting parts.
static PtrGetThemeRect pGetThemeRect
HTHEME(WINAPI * PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList)
The QStyleHintReturn class provides style hints that return more than basic data types.
Definition: qstyleoption.h:907
void addPixmap(const QPixmap &pixmap, Mode mode=Normal, State state=Off)
Adds pixmap to the icon, as a specialization for mode and state.
Definition: qicon.cpp:814
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
static bool resolveSymbols()
Returns true if all the necessary theme engine symbols were resolved.
#define TMT_BORDERONLY
qreal opacity() const
Returns the opacity of the painter.
Definition: qpainter.cpp:2115
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QStyleOptionDockWidget class is used to describe the parameters for drawing a dock widget...
Definition: qstyleoption.h:504
const QColor & color() const
Returns the brush color.
Definition: qbrush.h:183
~QWindowsXPStyle()
Destroys the style.
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
QPointer< QWidget > widget
QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
#define TMT_TEXTCOLOR
ColorRole
The ColorRole enum defines the different symbolic color roles used in current GUIs.
Definition: qpalette.h:93
The QLine class provides a two-dimensional vector using integer precision.
Definition: qline.h:57
const QBrush & dark() const
Returns the dark brush of the current color group.
Definition: qpalette.h:127
bool isActiveWindow
whether this widget&#39;s window is the active window
Definition: qwidget.h:186
HRESULT(WINAPI * PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin)
#define RBS_INACTIVE
The QMatrix class specifies 2D transformations of a coordinate system.
Definition: qmatrix.h:61
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
#define it(className, varName)
The QStyleOptionMenuItem class is used to describe the parameter necessary for drawing a menu item...
Definition: qstyleoption.h:435
The QStyleOptionHeader class is used to describe the parameters for drawing a header.
Definition: qstyleoption.h:251
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
static PtrIsAppThemed pIsAppThemed
virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget=0) const =0
Returns the rectangle containing the specified subControl of the given complex control (with the styl...
#define BT_NONE
static QSize globalStrut()
HRESULT(WINAPI * PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList)
void rotate(qreal a)
Rotates the coordinate system the given angle clockwise.
Definition: qpainter.cpp:3287
static QPixmap * tabbody
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const =0
Returns the value of the given pixel metric.
#define TMT_TEXTSHADOWCOLOR
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
ComplexControl
This enum describes the available complex controls.
Definition: qstyle.h:386
qreal dx() const
Returns the horizontal translation factor.
Definition: qmatrix.h:77
bool remove(const T &value)
Definition: qset.h:89
QRect united(const QRect &other) const
Returns the bounding rectangle of this rectangle and the given rectangle.
Definition: qrect.h:491
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation...
Definition: qpainter.cpp:2801
#define DTBG_OMITCONTENT
Q_GUI_EXPORT HDC qt_win_display_dc()
#define GT_NONE
static const int windowsArrowHMargin
static PtrGetThemeInt pGetThemeInt
The QStyleOptionTitleBar class is used to describe the parameters for drawing a title bar...
Definition: qstyleoption.h:816
void restore()
Restores the current painter state (pops a saved state off the stack).
Definition: qpainter.cpp:1620
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
HRESULT(WINAPI * PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins)
PixelMetric
This enum describes the various available pixel metrics.
Definition: qstyle.h:474
HRESULT(WINAPI * PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions)
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
static QBasicAtomicInt ref
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
QRect translated(int dx, int dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:328
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb)
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool fixAlphaChannel(const QRect &rect)
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.
virtual void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole=QPalette::NoRole) const
Draws the given text in the specified rectangle using the provided painter and palette.
Definition: qstyle.cpp:532
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
#define DTBG_MIRRORDC
void moveTo(int x, int t)
Moves the rectangle, leaving the top-left corner at the given position (x, y).
Definition: qrect.h:334
void drawBackground(XPThemeData &themeData)
Main theme drawing function.
QStyle::SubControls activeSubControls
This variable holds a bitwise OR of the sub-controls that are active for the complex control...
Definition: qstyleoption.h:694
void drawLine(const QLineF &line)
Draws a line defined by line.
Definition: qpainter.h:573
static PtrGetThemeColor pGetThemeColor
ushort red
Returns the red color component of this color.
Definition: qcolor.h:243
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
static const WinVersion WindowsVersion
the version of the Windows operating system on which the application is run (Windows only) ...
Definition: qglobal.h:1613
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
#define BT_IMAGEFILE
T * qobject_cast(QObject *object)
Definition: qobject.h:375
const QMatrix & deviceMatrix() const
Returns the matrix that transforms from logical coordinates to device coordinates of the platform dep...
Definition: qpainter.cpp:3110
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget=0) const
Reimplemented Function
HRESULT(WINAPI * PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal)
TransformationType type() const
Returns the transformation type of this matrix.
#define Q_BASIC_ATOMIC_INITIALIZER(a)
Definition: qbasicatomic.h:218
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
#define Q_D(Class)
Definition: qglobal.h:2482
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition: qpalette.h:107
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:64
#define TMT_GLYPHTYPE
The QStyleOptionSizeGrip class is used to describe the parameter for drawing a size grip...
Definition: qstyleoption.h:853
bool operator<(int priority, const QPair< QRunnable *, int > &p)
Definition: qthreadpool.cpp:50
virtual int devType() const
Definition: qpaintdevice.h:167
#define TMT_CAPTIONMARGINS
static const int windowsItemVMargin
void append(const T &t)
void drawPoint(const QPointF &pt)
Draws a single point at the given position using the current pen&#39;s color.
Definition: qpainter.h:676
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QTabBar::Shape shape
the tab shape used to draw the tab; by default QTabBar::RoundedNorth
Definition: qstyleoption.h:316
#define SIZE(large, small, mini)
QIcon windowIcon
the widget&#39;s icon
Definition: qwidget.h:199
static int sliderPositionFromValue(int min, int max, int val, int space, bool upsideDown=false)
Converts the given logicalValue to a pixel position.
Definition: qstyle.cpp:2176
static PtrGetCurrentThemeName pGetCurrentThemeName
The QStyleOptionToolButton class is used to describe the parameters for drawing a tool button...
Definition: qstyleoption.h:768
HRESULT(WINAPI * PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal)
void save()
Saves the current painter state (pushes the state onto a stack).
Definition: qpainter.cpp:1590
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags=0) const
If the string text is wider than width, returns an elided version of the string (i.
StandardPixmap
This enum describes the available standard pixmaps.
Definition: qstyle.h:755
static QPixmap * find(const QString &key)
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
void drawBackgroundDirectly(XPThemeData &themeData)
This function draws the theme parts directly to the paintengines HDC.
#define TMT_BORDERCOLOR
Q_CORE_EXPORT void qDebug(const char *,...)
QColor darker(int f=200) const
Returns a darker (or lighter) color, but does not change this object.
Definition: qcolor.h:301
virtual HDC getDC() const
Empty default implementation.
The QStyleOptionProgressBarV2 class is used to describe the parameters necessary for drawing a progre...
Definition: qstyleoption.h:417
int width() const
Returns the width.
Definition: qsize.h:126
static QIcon windowIcon()
QRegion clipRegion() const
Returns the currently set clip region.
Definition: qpainter.cpp:2562
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position...
Definition: qpainter.cpp:6231
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option=0, const QWidget *widget=0) const
Returns an icon for the given standardIcon.
Definition: qstyle.cpp:2327
bool hasAnyData(const QRect &rect)
Returns true if the native doublebuffer contains a pixel which has a non-0xFF alpha value...
HRESULT(WINAPI * PtrGetThemeDocumentationProperty)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, OUT LPWSTR pszValueBuff, int cchMaxValChars)
const QPen & pen() const
Returns the painter&#39;s current pen.
Definition: qpainter.cpp:4152
#define TMT_BGTYPE
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
HRESULT(WINAPI * PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal)
QFontMetrics fontMetrics() const
Returns the font metrics for the painter if the painter is active.
Definition: qpainter.cpp:2077
void setBrush(ColorRole cr, const QBrush &brush)
Sets the brush for the given color role to the specified brush for all groups in the palette...
Definition: qpalette.h:206
void drawDial(const QStyleOptionSlider *option, QPainter *painter)
void setBold(bool)
If enable is true sets the font&#39;s weight to QFont::Bold ; otherwise sets the weight to QFont::Normal...
Definition: qfont.h:352
QMatrix & rotate(qreal a)
Rotates the coordinate system the given degrees counterclockwise.
Definition: qmatrix.cpp:990
const QBrush & light() const
Returns the light brush of the current color group.
Definition: qpalette.h:126
void cleanup(bool force=false)
void drawControl(ControlElement element, const QStyleOption *option, QPainter *p, const QWidget *wwidget=0) const
Reimplemented Function
void drawLines(const QLineF *lines, int lineCount)
Draws the first lineCount lines in the array lines using the current pen.
Definition: qpainter.cpp:4873
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
virtual QPalette standardPalette() const
Returns the style&#39;s standard palette.
Definition: qstyle.cpp:2283
HRESULT(WINAPI * PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)
bool hasClipping() const
Returns true if clipping has been set; otherwise returns false.
Definition: qpainter.cpp:2499
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:67
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
ContentsType
This enum describes the available contents types.
Definition: qstyle.h:602
The QStyleOptionSpinBox class is used to describe the parameters necessary for drawing a spin box...
Definition: qstyleoption.h:729
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
const QFont & font() const
Returns the currently set font used for drawing text.
Definition: qpainter.cpp:4312
void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, const QWidget *widget=0) const
Reimplemented Function
const char * name
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
bool hasAlphaChannel(const QRect &rect)
Returns true if the native doublebuffer contains pixels with varying alpha value. ...
bool isActive() const
Returns true if begin() has been called and end() has not yet been called; otherwise returns false...
Definition: qpainter.cpp:1545
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition: qicon.h:63
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
HRESULT(WINAPI * PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars)
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition: qicon.cpp:769
void adjust(int x1, int y1, int x2, int y2)
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition: qrect.h:434
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
The QStyleOptionFocusRect class is used to describe the parameters for drawing a focus rectangle with...
Definition: qstyleoption.h:103
int styleHint(StyleHint hint, const QStyleOption *option=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const
Reimplemented Function
void setSize(const QSize &s)
Sets the size of the rectangle to the given size.
Definition: qrect.h:448
void unpolish(QApplication *)
Reimplemented Function
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
void transpose()
Swaps the width and height values.
Definition: qsize.cpp:196
The QStyleOptionFrame class is used to describe the parameters for drawing a frame.
Definition: qstyleoption.h:118
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
const QTransform & deviceTransform() const
Returns the matrix that transforms from logical coordinates to device coordinates of the platform dep...
Definition: qpainter.cpp:9579
int pixelMetric(PixelMetric pm, const QStyleOption *option=0, const QWidget *widget=0) const
Reimplemented Function
QPaintEngine * paintEngine() const
Returns the paint engine that the painter is currently operating on if the painter is active; otherwi...
Definition: qpainter.cpp:1991
The QStyleOptionTabWidgetFrame class is used to describe the parameters for drawing the frame around ...
Definition: qstyleoption.h:175
QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget=0) const
Reimplemented Function
HRESULT(WINAPI * PtrGetThemeBackgroundRegion)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pRect, OUT HRGN *pRegion)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
The QStyleOptionTabBarBase class is used to describe the base of a tab bar, i.e.
Definition: qstyleoption.h:218
static QPalette * sys_pal
static PtrGetThemePartSize pGetThemePartSize
static bool isItemViewDelegateLineEdit(const QWidget *widget)
The QAbstractSpinBox class provides a spinbox and a line edit to display values.
The State element defines configurations of objects and properties.
bool isTransparent(XPThemeData &themeData)
Returns true if the part contains any transparency at all.
#define MAXBS_INACTIVE
virtual void releaseDC(HDC hdc) const
Empty default implementation.
QImage transformed(const QMatrix &matrix, Qt::TransformationMode mode=Qt::FastTransformation) const
Returns a copy of the image that is transformed using the given transformation matrix and transformat...
Definition: qimage.cpp:4698
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
static PtrGetThemeString pGetThemeString
HRESULT(WINAPI * PtrCloseThemeData)(HTHEME hTheme)
static PtrGetThemeIntList pGetThemeIntList
QImage mirrored(bool horizontally=false, bool vertically=true) const
Returns a mirror of the image, mirrored in the horizontal and/or the vertical direction depending on ...
Definition: qimage.cpp:4922
static QWidgetSet * allWidgets
Definition: qwidget_p.h:715
static const int windowsRightBorder
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition: qobject.h:275
FrameFeatures features
a bitwise OR of the features that describe this frame.
Definition: qstyleoption.h:143
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
const QPixmap * tabBody(QWidget *widget)
Returns the pointer to a tab widgets body pixmap, scaled to the height of the screen.
static PtrGetThemePosition pGetThemePosition
bool isEnabled() const
Definition: qwidget.h:948
static PtrOpenThemeData pOpenThemeData
const QBrush & brush(ColorGroup cg, ColorRole cr) const
Returns the brush in the specified color group, used for the given color role.
Definition: qpalette.cpp:874
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
static PtrGetThemeMargins pGetThemeMargins
void moveCenter(const QPoint &p)
Moves the rectangle, leaving the center point at the given position.
Definition: qrect.cpp:840
#define GT_IMAGEGLYPH
int styleHint(StyleHint hint, const QStyleOption *opt=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const
Reimplemented Function
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
Q_CORE_EXPORT QTextStream & center(QTextStream &s)
bool(WINAPI * PtrIsAppThemed)()
The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel.
static QDesktopWidget * desktop()
Returns the desktop widget (also called the root window).
void setTransparency(QWidget *widget, XPThemeData &themeData)
Sets the parts region on a window.
qreal dpiScaled(qreal value)
QPoint topRight() const
Returns the position of the rectangle&#39;s top-right corner.
Definition: qrect.h:294
RECT toRECT(const QRect &qr)
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
QPalette palette
the palette that should be used when painting the control
Definition: qstyleoption.h:92
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
const QBrush & shadow() const
Returns the shadow brush of the current color group.
Definition: qpalette.h:139
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
Draws the given pixmap in the specified rectangle, according to the specified alignment, using the provided painter.
Definition: qstyle.cpp:570
The QStyleHintReturnMask class provides style hints that return a QRegion.
Definition: qstyleoption.h:923
static PtrIsThemeActive pIsThemeActive
long HRESULT
#define DTBG_OMITBORDER
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction...
Definition: qstyle.cpp:2087
void * resolve(const char *symbol)
const QRect screenGeometry(int screen=-1) const
ushort blue
Returns the blue color component of this color.
Definition: qcolor.h:245
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p, const QWidget *widget=0) const
Reimplemented Function
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
Definition: qpainter.cpp:2917
static bool closingDown()
Returns true if the application objects are being destroyed; otherwise returns false.
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
AlphaChannelType
PrimitiveElement
This enum describes the various primitive elements.
Definition: qstyle.h:145
HRESULT(WINAPI * PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz)
static PtrGetThemeDocumentationProperty pGetThemeDocumentationProperty
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
QRegion region(XPThemeData &themeData)
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
void setClipping(bool enable)
Enables clipping if enable is true, or disables clipping if enable is false.
Definition: qpainter.cpp:2517
#define BT_BORDERFILL
qint64 cacheKey() const
Returns a number that identifies the contents of this QIcon object.
Definition: qicon.cpp:679
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
const QBrush & highlightedText() const
Returns the highlighted text brush of the current color group.
Definition: qpalette.h:141
HRESULT(WINAPI * PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars)
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
int pixelMetric(PixelMetric pm, const QStyleOption *option=0, const QWidget *widget=0) const
Reimplemented Function
HRESULT(WINAPI * PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal)
#define QT_NO_SPINBOX
T qstyleoption_cast(const QStyleOption *opt)
Definition: qstyleoption.h:885
QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *widget=0) const
Reimplemented Function
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition: qicon.cpp:730
static PtrIsThemeBackgroundPartiallyTransparent pIsThemeBackgroundPartiallyTransparent
static PtrGetThemeFilename pGetThemeFilename
static PtrGetThemeMetric pGetThemeMetric
void eraseRect(const QRectF &)
Erases the area inside the given rectangle.
Definition: qpainter.cpp:7332
#define TMT_TEXTSHADOWTYPE
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
void setRect(int x, int y, int w, int h)
Sets the coordinates of the rectangle&#39;s top-left corner to ({x}, {y}), and its size to the given widt...
Definition: qrect.h:400
Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)
Definition: qrgb.h:69
static const QStyle::SubControl SubControls[]
qreal dy() const
Returns the vertical translation factor.
Definition: qmatrix.h:78
static HWND winId(const QWidget *widget)
This function will always return a valid window handle, and might create a limbo widget to do so...
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
BOOL(WINAPI * PtrIsThemeBackgroundPartiallyTransparent)(HTHEME hTheme, int iPartId, int iStateId)
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition: qpalette.h:201
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
void setBrush(const QBrush &brush)
Sets the painter&#39;s brush to the given brush.
Definition: qpainter.cpp:4171
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given element with the provided painter with the style options specified by option...
QWindowsXPStyle()
Constructs a QWindowsStyle.
The QStyleOptionComboBox class is used to describe the parameter for drawing a combobox.
Definition: qstyleoption.h:796
void setWidth(int w)
Sets the width of the rectangle to the given width.
Definition: qrect.h:442
void setPen(const QColor &color)
Sets the painter&#39;s pen to have style Qt::SolidLine, width 0 and the specified color.
Definition: qpainter.cpp:4047
HRESULT(WINAPI * PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont)
bool isTopLevel() const
Use isWindow() instead.
Definition: qwidget.h:942
int height() const
Returns the height.
Definition: qsize.h:129
Qt::LayoutDirection direction
the text layout direction that should be used when drawing text in the control
Definition: qstyleoption.h:89
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
static bool useXP(bool update=false)
The QLabel widget provides a text or image display.
Definition: qlabel.h:55
static PtrCloseThemeData pCloseThemeData
void getRect(int *x, int *y, int *w, int *h) const
Extracts the position of the rectangle&#39;s top-left corner to *x and *y, and its dimensions to *width a...
Definition: qrect.h:392
static QWidget * limboWidget
The QStyleOptionFrameV2 class is used to describe the parameters necessary for drawing a frame in Qt ...
Definition: qstyleoption.h:134
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
static PtrGetThemeFont pGetThemeFont
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition: qpainter.h:650
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags=Qt::AutoColor)
Definition: qpainter.cpp:5936
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
const QStyle * proxy() const
Definition: qstyle.cpp:2546
static const int windowsItemHMargin
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
The QStyleOptionTab class is used to describe the parameters for drawing a tab bar.
Definition: qstyleoption.h:304
static QMap< QString, HTHEME > * handleMap
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition: qicon.cpp:693
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device...
Definition: qpainter.cpp:5619
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
HRESULT(WINAPI * PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars)
void init(bool force=false)
static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx
ControlElement
This enum represents a control element.
Definition: qstyle.h:217
The QStyleOptionSlider class is used to describe the parameters needed for drawing a slider...
Definition: qstyleoption.h:701
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
void setFont(const QFont &f)
Sets the painter&#39;s font to the given font.
Definition: qpainter.cpp:4288
static PtrGetThemeBackgroundRegion pGetThemeBackgroundRegion
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition: qwidget.h:937
QRegion translated(int dx, int dy) const
Returns a copy of the region that is translated dx along the x axis and dy along the y axis...
Definition: qregion.cpp:743
QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
#define TMT_BORDERSIZE
The QTabWidget class provides a stack of tabbed widgets.
Definition: qtabwidget.h:60
Qt::WindowFlags titleBarFlags
the widget flags for the title bar
Definition: qstyleoption.h:825
static PtrGetThemeBool pGetThemeBool
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
The QStyleOptionComplex class is used to hold parameters that are common to all complex controls...
Definition: qstyleoption.h:687
#define TMT_TRANSPARENTCOLOR
#define CBS_INACTIVE
QRegion region
the region for style hints that return a QRegion
Definition: qstyleoption.h:930
The QWindowsStyle class provides a Microsoft Windows-like look and feel.
Definition: qwindowsstyle.h:57
void polish(QApplication *)
Reimplemented Function
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
#define TMT_SIZINGMARGINS
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition: qpixmap.cpp:615
QPixmap copy(int x, int y, int width, int height) const
Returns a deep copy of the subset of the pixmap that is specified by the rectangle QRect( x...
Definition: qpixmap.h:302
AlphaChannelType alphaType
static const KeyPair *const end
int titleBarState
the state of the title bar
Definition: qstyleoption.h:824
Orientation
Definition: qnamespace.h:174
QPalette standardPalette() const
Reimplemented Function
#define qPrintable(string)
Definition: qglobal.h:1750
#define QT_NO_COMBOBOX
static const int windowsItemFrame
QRegion qt_region_from_HRGN(HRGN rgn)
Definition: qregion_win.cpp:80
The QStyleOptionButton class is used to describe the parameters for drawing buttons.
Definition: qstyleoption.h:279
QRegion systemClip() const
Returns the system clip.
ushort green
Returns the green color component of this color.
Definition: qcolor.h:244
void setWindowOpacity(qreal level)
Definition: qwidget.cpp:11497
bool(WINAPI * PtrIsThemeActive)()
QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget=0) const
static PtrGetThemePropertyOrigin pGetThemePropertyOrigin
bool swapAlphaChannel(const QRect &rect, bool allPixels=false)
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.
static PtrDrawThemeBackground pDrawThemeBackground
#define TMT_FILLCOLOR
The QStyleOptionTabWidgetFrameV2 class is used to describe the parameters for drawing the frame aroun...
Definition: qstyleoption.h:196
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QRect rect
the area that should be used for various calculations and painting
Definition: qstyleoption.h:90
#define TST_NONE
QStyle::SubControls subControls
This variable holds a bitwise OR of the sub-controls to be drawn for the complex control.
Definition: qstyleoption.h:693
#define MINBS_INACTIVE
void setBackground(const QBrush &bg)
Sets the background brush of the painter to the given brush.
Definition: qpainter.cpp:4258
QTabBar::Shape shape
the tab shape used to draw the tabs
Definition: qstyleoption.h:183
Handle handle() const
Returns a platform-specific region handle.
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *w=0) const
Reimplemented Function
const QBrush & text() const
Returns the text foreground brush of the current color group.
Definition: qpalette.h:129
int size() const
#define DTBG_CLIPRECT
SubElement
This enum represents a sub-area of a widget.
Definition: qstyle.h:289
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static int area(const QSize &s)
Definition: qicon.cpp:155
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
Definition: qpainter.cpp:3311
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:60
#define TMT_CONTENTMARGINS