summaryrefslogtreecommitdiffstats
path: root/src/widgets/styles
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/styles')
-rw-r--r--src/widgets/styles/images/cdr-128.pngbin0 -> 16418 bytes
-rw-r--r--src/widgets/styles/images/cdr-16.pngbin0 -> 845 bytes
-rw-r--r--src/widgets/styles/images/cdr-32.pngbin0 -> 2016 bytes
-rw-r--r--src/widgets/styles/images/closedock-16.pngbin0 -> 516 bytes
-rw-r--r--src/widgets/styles/images/closedock-down-16.pngbin0 -> 578 bytes
-rw-r--r--src/widgets/styles/images/computer-16.pngbin0 -> 782 bytes
-rw-r--r--src/widgets/styles/images/computer-32.pngbin0 -> 1807 bytes
-rw-r--r--src/widgets/styles/images/defaults60theme.blobbin0 -> 74127 bytes
-rw-r--r--src/widgets/styles/images/desktop-16.pngbin0 -> 773 bytes
-rw-r--r--src/widgets/styles/images/desktop-32.pngbin0 -> 1103 bytes
-rw-r--r--src/widgets/styles/images/dirclosed-128.pngbin0 -> 1386 bytes
-rw-r--r--src/widgets/styles/images/dirclosed-16.pngbin0 -> 231 bytes
-rw-r--r--src/widgets/styles/images/dirclosed-32.pngbin0 -> 474 bytes
-rw-r--r--src/widgets/styles/images/dirlink-128.pngbin0 -> 5155 bytes
-rw-r--r--src/widgets/styles/images/dirlink-16.pngbin0 -> 416 bytes
-rw-r--r--src/widgets/styles/images/dirlink-32.pngbin0 -> 1046 bytes
-rw-r--r--src/widgets/styles/images/diropen-128.pngbin0 -> 2075 bytes
-rw-r--r--src/widgets/styles/images/diropen-16.pngbin0 -> 248 bytes
-rw-r--r--src/widgets/styles/images/diropen-32.pngbin0 -> 633 bytes
-rw-r--r--src/widgets/styles/images/dockdock-16.pngbin0 -> 438 bytes
-rw-r--r--src/widgets/styles/images/dockdock-down-16.pngbin0 -> 406 bytes
-rw-r--r--src/widgets/styles/images/down-128.pngbin0 -> 9550 bytes
-rw-r--r--src/widgets/styles/images/down-16.pngbin0 -> 817 bytes
-rw-r--r--src/widgets/styles/images/down-32.pngbin0 -> 1820 bytes
-rw-r--r--src/widgets/styles/images/dvd-128.pngbin0 -> 14941 bytes
-rw-r--r--src/widgets/styles/images/dvd-16.pngbin0 -> 892 bytes
-rw-r--r--src/widgets/styles/images/dvd-32.pngbin0 -> 2205 bytes
-rw-r--r--src/widgets/styles/images/file-128.pngbin0 -> 3997 bytes
-rw-r--r--src/widgets/styles/images/file-16.pngbin0 -> 423 bytes
-rw-r--r--src/widgets/styles/images/file-32.pngbin0 -> 713 bytes
-rw-r--r--src/widgets/styles/images/filecontents-128.pngbin0 -> 8109 bytes
-rw-r--r--src/widgets/styles/images/filecontents-16.pngbin0 -> 766 bytes
-rw-r--r--src/widgets/styles/images/filecontents-32.pngbin0 -> 1712 bytes
-rw-r--r--src/widgets/styles/images/fileinfo-128.pngbin0 -> 12002 bytes
-rw-r--r--src/widgets/styles/images/fileinfo-16.pngbin0 -> 849 bytes
-rw-r--r--src/widgets/styles/images/fileinfo-32.pngbin0 -> 2010 bytes
-rw-r--r--src/widgets/styles/images/filelink-128.pngbin0 -> 5601 bytes
-rw-r--r--src/widgets/styles/images/filelink-16.pngbin0 -> 566 bytes
-rw-r--r--src/widgets/styles/images/filelink-32.pngbin0 -> 1192 bytes
-rw-r--r--src/widgets/styles/images/floppy-128.pngbin0 -> 5074 bytes
-rw-r--r--src/widgets/styles/images/floppy-16.pngbin0 -> 602 bytes
-rw-r--r--src/widgets/styles/images/floppy-32.pngbin0 -> 1019 bytes
-rw-r--r--src/widgets/styles/images/fontbitmap-16.pngbin0 -> 537 bytes
-rw-r--r--src/widgets/styles/images/fonttruetype-16.pngbin0 -> 442 bytes
-rw-r--r--src/widgets/styles/images/harddrive-128.pngbin0 -> 11250 bytes
-rw-r--r--src/widgets/styles/images/harddrive-16.pngbin0 -> 802 bytes
-rw-r--r--src/widgets/styles/images/harddrive-32.pngbin0 -> 1751 bytes
-rw-r--r--src/widgets/styles/images/left-128.pngbin0 -> 9432 bytes
-rw-r--r--src/widgets/styles/images/left-16.pngbin0 -> 826 bytes
-rw-r--r--src/widgets/styles/images/left-32.pngbin0 -> 1799 bytes
-rw-r--r--src/widgets/styles/images/media-pause-16.pngbin0 -> 229 bytes
-rw-r--r--src/widgets/styles/images/media-pause-32.pngbin0 -> 185 bytes
-rw-r--r--src/widgets/styles/images/media-play-16.pngbin0 -> 262 bytes
-rw-r--r--src/widgets/styles/images/media-play-32.pngbin0 -> 413 bytes
-rw-r--r--src/widgets/styles/images/media-seek-backward-16.pngbin0 -> 384 bytes
-rw-r--r--src/widgets/styles/images/media-seek-backward-32.pngbin0 -> 548 bytes
-rw-r--r--src/widgets/styles/images/media-seek-forward-16.pngbin0 -> 370 bytes
-rw-r--r--src/widgets/styles/images/media-seek-forward-32.pngbin0 -> 524 bytes
-rw-r--r--src/widgets/styles/images/media-skip-backward-16.pngbin0 -> 396 bytes
-rw-r--r--src/widgets/styles/images/media-skip-backward-32.pngbin0 -> 570 bytes
-rw-r--r--src/widgets/styles/images/media-skip-forward-16.pngbin0 -> 384 bytes
-rw-r--r--src/widgets/styles/images/media-skip-forward-32.pngbin0 -> 549 bytes
-rw-r--r--src/widgets/styles/images/media-stop-16.pngbin0 -> 166 bytes
-rw-r--r--src/widgets/styles/images/media-stop-32.pngbin0 -> 176 bytes
-rw-r--r--src/widgets/styles/images/media-volume-16.pngbin0 -> 799 bytes
-rw-r--r--src/widgets/styles/images/media-volume-muted-16.pngbin0 -> 668 bytes
-rw-r--r--src/widgets/styles/images/networkdrive-128.pngbin0 -> 18075 bytes
-rw-r--r--src/widgets/styles/images/networkdrive-16.pngbin0 -> 885 bytes
-rw-r--r--src/widgets/styles/images/networkdrive-32.pngbin0 -> 2245 bytes
-rw-r--r--src/widgets/styles/images/newdirectory-128.pngbin0 -> 7503 bytes
-rw-r--r--src/widgets/styles/images/newdirectory-16.pngbin0 -> 870 bytes
-rw-r--r--src/widgets/styles/images/newdirectory-32.pngbin0 -> 1590 bytes
-rw-r--r--src/widgets/styles/images/parentdir-128.pngbin0 -> 8093 bytes
-rw-r--r--src/widgets/styles/images/parentdir-16.pngbin0 -> 938 bytes
-rw-r--r--src/widgets/styles/images/parentdir-32.pngbin0 -> 1603 bytes
-rw-r--r--src/widgets/styles/images/refresh-24.pngbin0 -> 1654 bytes
-rw-r--r--src/widgets/styles/images/refresh-32.pngbin0 -> 2431 bytes
-rw-r--r--src/widgets/styles/images/right-128.pngbin0 -> 9367 bytes
-rw-r--r--src/widgets/styles/images/right-16.pngbin0 -> 811 bytes
-rw-r--r--src/widgets/styles/images/right-32.pngbin0 -> 1804 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-apply-128.pngbin0 -> 5395 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-apply-16.pngbin0 -> 611 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-apply-32.pngbin0 -> 1279 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-cancel-128.pngbin0 -> 7039 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-cancel-16.pngbin0 -> 689 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-cancel-32.pngbin0 -> 1573 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-clear-128.pngbin0 -> 3094 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-clear-16.pngbin0 -> 456 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-clear-32.pngbin0 -> 866 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-close-128.pngbin0 -> 4512 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-close-16.pngbin0 -> 366 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-close-32.pngbin0 -> 780 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-closetab-16.pngbin0 -> 406 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-closetab-down-16.pngbin0 -> 481 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-closetab-hover-16.pngbin0 -> 570 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-delete-128.pngbin0 -> 5414 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-delete-16.pngbin0 -> 722 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-delete-32.pngbin0 -> 1541 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-help-128.pngbin0 -> 10765 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-help-16.pngbin0 -> 840 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-help-32.pngbin0 -> 2066 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-no-128.pngbin0 -> 6520 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-no-16.pngbin0 -> 701 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-no-32.pngbin0 -> 1445 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-ok-128.pngbin0 -> 4232 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-ok-16.pngbin0 -> 584 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-ok-32.pngbin0 -> 1246 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-open-128.pngbin0 -> 5415 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-open-16.pngbin0 -> 629 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-open-32.pngbin0 -> 1154 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-save-128.pngbin0 -> 4398 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-save-16.pngbin0 -> 583 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-save-32.pngbin0 -> 1092 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-yes-128.pngbin0 -> 6554 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-yes-16.pngbin0 -> 687 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-yes-32.pngbin0 -> 1504 bytes
-rw-r--r--src/widgets/styles/images/stop-24.pngbin0 -> 1267 bytes
-rw-r--r--src/widgets/styles/images/stop-32.pngbin0 -> 1878 bytes
-rw-r--r--src/widgets/styles/images/trash-128.pngbin0 -> 3296 bytes
-rw-r--r--src/widgets/styles/images/trash-16.pngbin0 -> 419 bytes
-rw-r--r--src/widgets/styles/images/trash-32.pngbin0 -> 883 bytes
-rw-r--r--src/widgets/styles/images/up-128.pngbin0 -> 9363 bytes
-rw-r--r--src/widgets/styles/images/up-16.pngbin0 -> 814 bytes
-rw-r--r--src/widgets/styles/images/up-32.pngbin0 -> 1798 bytes
-rw-r--r--src/widgets/styles/images/viewdetailed-128.pngbin0 -> 4743 bytes
-rw-r--r--src/widgets/styles/images/viewdetailed-16.pngbin0 -> 499 bytes
-rw-r--r--src/widgets/styles/images/viewdetailed-32.pngbin0 -> 1092 bytes
-rw-r--r--src/widgets/styles/images/viewlist-128.pngbin0 -> 4069 bytes
-rw-r--r--src/widgets/styles/images/viewlist-16.pngbin0 -> 490 bytes
-rw-r--r--src/widgets/styles/images/viewlist-32.pngbin0 -> 1006 bytes
-rw-r--r--src/widgets/styles/qcdestyle.cpp305
-rw-r--r--src/widgets/styles/qcdestyle.h82
-rw-r--r--src/widgets/styles/qcleanlooksstyle.cpp4450
-rw-r--r--src/widgets/styles/qcleanlooksstyle.h114
-rw-r--r--src/widgets/styles/qcleanlooksstyle_p.h80
-rw-r--r--src/widgets/styles/qcommonstyle.cpp6083
-rw-r--r--src/widgets/styles/qcommonstyle.h109
-rw-r--r--src/widgets/styles/qcommonstyle_p.h113
-rw-r--r--src/widgets/styles/qcommonstylepixmaps_p.h186
-rw-r--r--src/widgets/styles/qdrawutil.cpp1053
-rw-r--r--src/widgets/styles/qdrawutil.h175
-rw-r--r--src/widgets/styles/qgtkpainter.cpp716
-rw-r--r--src/widgets/styles/qgtkpainter_p.h129
-rw-r--r--src/widgets/styles/qgtkstyle.cpp3560
-rw-r--r--src/widgets/styles/qgtkstyle.h128
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp1146
-rw-r--r--src/widgets/styles/qgtkstyle_p.h531
-rw-r--r--src/widgets/styles/qmacstyle.qdoc247
-rw-r--r--src/widgets/styles/qmacstyle_mac.h148
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm6042
-rw-r--r--src/widgets/styles/qmacstyle_mac_p.h241
-rw-r--r--src/widgets/styles/qmacstylepixmaps_mac_p.h72
-rw-r--r--src/widgets/styles/qmotifstyle.cpp2721
-rw-r--r--src/widgets/styles/qmotifstyle.h128
-rw-r--r--src/widgets/styles/qmotifstyle_p.h82
-rw-r--r--src/widgets/styles/qplastiquestyle.cpp6000
-rw-r--r--src/widgets/styles/qplastiquestyle.h119
-rw-r--r--src/widgets/styles/qproxystyle.cpp420
-rw-r--r--src/widgets/styles/qproxystyle.h114
-rw-r--r--src/widgets/styles/qproxystyle_p.h79
-rw-r--r--src/widgets/styles/qs60style.cpp3618
-rw-r--r--src/widgets/styles/qs60style.h118
-rw-r--r--src/widgets/styles/qs60style_p.h638
-rw-r--r--src/widgets/styles/qs60style_s60.cpp1591
-rw-r--r--src/widgets/styles/qs60style_simulated.cpp457
-rw-r--r--src/widgets/styles/qs60style_stub.cpp131
-rw-r--r--src/widgets/styles/qstyle.cpp2459
-rw-r--r--src/widgets/styles/qstyle.h889
-rw-r--r--src/widgets/styles/qstyle.qrc135
-rw-r--r--src/widgets/styles/qstyle_p.h108
-rw-r--r--src/widgets/styles/qstyle_s60.qrc137
-rw-r--r--src/widgets/styles/qstyle_s60_simulated.qrc6
-rw-r--r--src/widgets/styles/qstyle_wince.qrc97
-rw-r--r--src/widgets/styles/qstylefactory.cpp271
-rw-r--r--src/widgets/styles/qstylefactory.h66
-rw-r--r--src/widgets/styles/qstylehelper.cpp378
-rw-r--r--src/widgets/styles/qstylehelper_p.h89
-rw-r--r--src/widgets/styles/qstyleoption.cpp5508
-rw-r--r--src/widgets/styles/qstyleoption.h970
-rw-r--r--src/widgets/styles/qstylepainter.cpp176
-rw-r--r--src/widgets/styles/qstylepainter.h112
-rw-r--r--src/widgets/styles/qstyleplugin.cpp115
-rw-r--r--src/widgets/styles/qstyleplugin.h81
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp5900
-rw-r--r--src/widgets/styles/qstylesheetstyle_default.cpp512
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h204
-rw-r--r--src/widgets/styles/qwindowscestyle.cpp2429
-rw-r--r--src/widgets/styles/qwindowscestyle.h103
-rw-r--r--src/widgets/styles/qwindowscestyle_p.h118
-rw-r--r--src/widgets/styles/qwindowsmobilestyle.cpp7283
-rw-r--r--src/widgets/styles/qwindowsmobilestyle.h116
-rw-r--r--src/widgets/styles/qwindowsmobilestyle_p.h136
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp3390
-rw-r--r--src/widgets/styles/qwindowsstyle.h111
-rw-r--r--src/widgets/styles/qwindowsstyle_p.h106
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp2669
-rw-r--r--src/widgets/styles/qwindowsvistastyle.h108
-rw-r--r--src/widgets/styles/qwindowsvistastyle_p.h220
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp4277
-rw-r--r--src/widgets/styles/qwindowsxpstyle.h107
-rw-r--r--src/widgets/styles/qwindowsxpstyle_p.h356
-rw-r--r--src/widgets/styles/styles.pri194
202 files changed, 81862 insertions, 0 deletions
diff --git a/src/widgets/styles/images/cdr-128.png b/src/widgets/styles/images/cdr-128.png
new file mode 100644
index 0000000000..c5daa15fc8
--- /dev/null
+++ b/src/widgets/styles/images/cdr-128.png
Binary files differ
diff --git a/src/widgets/styles/images/cdr-16.png b/src/widgets/styles/images/cdr-16.png
new file mode 100644
index 0000000000..82d7533bd1
--- /dev/null
+++ b/src/widgets/styles/images/cdr-16.png
Binary files differ
diff --git a/src/widgets/styles/images/cdr-32.png b/src/widgets/styles/images/cdr-32.png
new file mode 100644
index 0000000000..dcfb085da5
--- /dev/null
+++ b/src/widgets/styles/images/cdr-32.png
Binary files differ
diff --git a/src/widgets/styles/images/closedock-16.png b/src/widgets/styles/images/closedock-16.png
new file mode 100644
index 0000000000..ab9d669eee
--- /dev/null
+++ b/src/widgets/styles/images/closedock-16.png
Binary files differ
diff --git a/src/widgets/styles/images/closedock-down-16.png b/src/widgets/styles/images/closedock-down-16.png
new file mode 100644
index 0000000000..c1791dd2cc
--- /dev/null
+++ b/src/widgets/styles/images/closedock-down-16.png
Binary files differ
diff --git a/src/widgets/styles/images/computer-16.png b/src/widgets/styles/images/computer-16.png
new file mode 100644
index 0000000000..43fb0bb581
--- /dev/null
+++ b/src/widgets/styles/images/computer-16.png
Binary files differ
diff --git a/src/widgets/styles/images/computer-32.png b/src/widgets/styles/images/computer-32.png
new file mode 100644
index 0000000000..6d750ce89b
--- /dev/null
+++ b/src/widgets/styles/images/computer-32.png
Binary files differ
diff --git a/src/widgets/styles/images/defaults60theme.blob b/src/widgets/styles/images/defaults60theme.blob
new file mode 100644
index 0000000000..f3a59528d6
--- /dev/null
+++ b/src/widgets/styles/images/defaults60theme.blob
Binary files differ
diff --git a/src/widgets/styles/images/desktop-16.png b/src/widgets/styles/images/desktop-16.png
new file mode 100644
index 0000000000..d612dfb0fc
--- /dev/null
+++ b/src/widgets/styles/images/desktop-16.png
Binary files differ
diff --git a/src/widgets/styles/images/desktop-32.png b/src/widgets/styles/images/desktop-32.png
new file mode 100644
index 0000000000..ad85b48d3a
--- /dev/null
+++ b/src/widgets/styles/images/desktop-32.png
Binary files differ
diff --git a/src/widgets/styles/images/dirclosed-128.png b/src/widgets/styles/images/dirclosed-128.png
new file mode 100644
index 0000000000..e4fa843162
--- /dev/null
+++ b/src/widgets/styles/images/dirclosed-128.png
Binary files differ
diff --git a/src/widgets/styles/images/dirclosed-16.png b/src/widgets/styles/images/dirclosed-16.png
new file mode 100644
index 0000000000..333fe8eaac
--- /dev/null
+++ b/src/widgets/styles/images/dirclosed-16.png
Binary files differ
diff --git a/src/widgets/styles/images/dirclosed-32.png b/src/widgets/styles/images/dirclosed-32.png
new file mode 100644
index 0000000000..3add907ed5
--- /dev/null
+++ b/src/widgets/styles/images/dirclosed-32.png
Binary files differ
diff --git a/src/widgets/styles/images/dirlink-128.png b/src/widgets/styles/images/dirlink-128.png
new file mode 100644
index 0000000000..ec299f8e52
--- /dev/null
+++ b/src/widgets/styles/images/dirlink-128.png
Binary files differ
diff --git a/src/widgets/styles/images/dirlink-16.png b/src/widgets/styles/images/dirlink-16.png
new file mode 100644
index 0000000000..9f16cd3520
--- /dev/null
+++ b/src/widgets/styles/images/dirlink-16.png
Binary files differ
diff --git a/src/widgets/styles/images/dirlink-32.png b/src/widgets/styles/images/dirlink-32.png
new file mode 100644
index 0000000000..776536d131
--- /dev/null
+++ b/src/widgets/styles/images/dirlink-32.png
Binary files differ
diff --git a/src/widgets/styles/images/diropen-128.png b/src/widgets/styles/images/diropen-128.png
new file mode 100644
index 0000000000..b91c4af72a
--- /dev/null
+++ b/src/widgets/styles/images/diropen-128.png
Binary files differ
diff --git a/src/widgets/styles/images/diropen-16.png b/src/widgets/styles/images/diropen-16.png
new file mode 100644
index 0000000000..95f0771d06
--- /dev/null
+++ b/src/widgets/styles/images/diropen-16.png
Binary files differ
diff --git a/src/widgets/styles/images/diropen-32.png b/src/widgets/styles/images/diropen-32.png
new file mode 100644
index 0000000000..af5f7e7e81
--- /dev/null
+++ b/src/widgets/styles/images/diropen-32.png
Binary files differ
diff --git a/src/widgets/styles/images/dockdock-16.png b/src/widgets/styles/images/dockdock-16.png
new file mode 100644
index 0000000000..4ac9483176
--- /dev/null
+++ b/src/widgets/styles/images/dockdock-16.png
Binary files differ
diff --git a/src/widgets/styles/images/dockdock-down-16.png b/src/widgets/styles/images/dockdock-down-16.png
new file mode 100644
index 0000000000..2e85a679be
--- /dev/null
+++ b/src/widgets/styles/images/dockdock-down-16.png
Binary files differ
diff --git a/src/widgets/styles/images/down-128.png b/src/widgets/styles/images/down-128.png
new file mode 100644
index 0000000000..09dfe43a93
--- /dev/null
+++ b/src/widgets/styles/images/down-128.png
Binary files differ
diff --git a/src/widgets/styles/images/down-16.png b/src/widgets/styles/images/down-16.png
new file mode 100644
index 0000000000..c60a174e25
--- /dev/null
+++ b/src/widgets/styles/images/down-16.png
Binary files differ
diff --git a/src/widgets/styles/images/down-32.png b/src/widgets/styles/images/down-32.png
new file mode 100644
index 0000000000..46eadb8e12
--- /dev/null
+++ b/src/widgets/styles/images/down-32.png
Binary files differ
diff --git a/src/widgets/styles/images/dvd-128.png b/src/widgets/styles/images/dvd-128.png
new file mode 100644
index 0000000000..9ed9dc1e55
--- /dev/null
+++ b/src/widgets/styles/images/dvd-128.png
Binary files differ
diff --git a/src/widgets/styles/images/dvd-16.png b/src/widgets/styles/images/dvd-16.png
new file mode 100644
index 0000000000..623386d4ca
--- /dev/null
+++ b/src/widgets/styles/images/dvd-16.png
Binary files differ
diff --git a/src/widgets/styles/images/dvd-32.png b/src/widgets/styles/images/dvd-32.png
new file mode 100644
index 0000000000..089b72accb
--- /dev/null
+++ b/src/widgets/styles/images/dvd-32.png
Binary files differ
diff --git a/src/widgets/styles/images/file-128.png b/src/widgets/styles/images/file-128.png
new file mode 100644
index 0000000000..46e6ceb49a
--- /dev/null
+++ b/src/widgets/styles/images/file-128.png
Binary files differ
diff --git a/src/widgets/styles/images/file-16.png b/src/widgets/styles/images/file-16.png
new file mode 100644
index 0000000000..664b56356b
--- /dev/null
+++ b/src/widgets/styles/images/file-16.png
Binary files differ
diff --git a/src/widgets/styles/images/file-32.png b/src/widgets/styles/images/file-32.png
new file mode 100644
index 0000000000..83e5c3d311
--- /dev/null
+++ b/src/widgets/styles/images/file-32.png
Binary files differ
diff --git a/src/widgets/styles/images/filecontents-128.png b/src/widgets/styles/images/filecontents-128.png
new file mode 100644
index 0000000000..50e0a838e2
--- /dev/null
+++ b/src/widgets/styles/images/filecontents-128.png
Binary files differ
diff --git a/src/widgets/styles/images/filecontents-16.png b/src/widgets/styles/images/filecontents-16.png
new file mode 100644
index 0000000000..b9399ccf2e
--- /dev/null
+++ b/src/widgets/styles/images/filecontents-16.png
Binary files differ
diff --git a/src/widgets/styles/images/filecontents-32.png b/src/widgets/styles/images/filecontents-32.png
new file mode 100644
index 0000000000..3761f70690
--- /dev/null
+++ b/src/widgets/styles/images/filecontents-32.png
Binary files differ
diff --git a/src/widgets/styles/images/fileinfo-128.png b/src/widgets/styles/images/fileinfo-128.png
new file mode 100644
index 0000000000..8c5b331876
--- /dev/null
+++ b/src/widgets/styles/images/fileinfo-128.png
Binary files differ
diff --git a/src/widgets/styles/images/fileinfo-16.png b/src/widgets/styles/images/fileinfo-16.png
new file mode 100644
index 0000000000..729be4d5f2
--- /dev/null
+++ b/src/widgets/styles/images/fileinfo-16.png
Binary files differ
diff --git a/src/widgets/styles/images/fileinfo-32.png b/src/widgets/styles/images/fileinfo-32.png
new file mode 100644
index 0000000000..ca795aa49b
--- /dev/null
+++ b/src/widgets/styles/images/fileinfo-32.png
Binary files differ
diff --git a/src/widgets/styles/images/filelink-128.png b/src/widgets/styles/images/filelink-128.png
new file mode 100644
index 0000000000..be86a82901
--- /dev/null
+++ b/src/widgets/styles/images/filelink-128.png
Binary files differ
diff --git a/src/widgets/styles/images/filelink-16.png b/src/widgets/styles/images/filelink-16.png
new file mode 100644
index 0000000000..6643f2c428
--- /dev/null
+++ b/src/widgets/styles/images/filelink-16.png
Binary files differ
diff --git a/src/widgets/styles/images/filelink-32.png b/src/widgets/styles/images/filelink-32.png
new file mode 100644
index 0000000000..1e46fdc13c
--- /dev/null
+++ b/src/widgets/styles/images/filelink-32.png
Binary files differ
diff --git a/src/widgets/styles/images/floppy-128.png b/src/widgets/styles/images/floppy-128.png
new file mode 100644
index 0000000000..fa7a3e1334
--- /dev/null
+++ b/src/widgets/styles/images/floppy-128.png
Binary files differ
diff --git a/src/widgets/styles/images/floppy-16.png b/src/widgets/styles/images/floppy-16.png
new file mode 100644
index 0000000000..91c59c567d
--- /dev/null
+++ b/src/widgets/styles/images/floppy-16.png
Binary files differ
diff --git a/src/widgets/styles/images/floppy-32.png b/src/widgets/styles/images/floppy-32.png
new file mode 100644
index 0000000000..e63b3213bf
--- /dev/null
+++ b/src/widgets/styles/images/floppy-32.png
Binary files differ
diff --git a/src/widgets/styles/images/fontbitmap-16.png b/src/widgets/styles/images/fontbitmap-16.png
new file mode 100644
index 0000000000..03efc9cbab
--- /dev/null
+++ b/src/widgets/styles/images/fontbitmap-16.png
Binary files differ
diff --git a/src/widgets/styles/images/fonttruetype-16.png b/src/widgets/styles/images/fonttruetype-16.png
new file mode 100644
index 0000000000..25205021e9
--- /dev/null
+++ b/src/widgets/styles/images/fonttruetype-16.png
Binary files differ
diff --git a/src/widgets/styles/images/harddrive-128.png b/src/widgets/styles/images/harddrive-128.png
new file mode 100644
index 0000000000..0b73d9de1e
--- /dev/null
+++ b/src/widgets/styles/images/harddrive-128.png
Binary files differ
diff --git a/src/widgets/styles/images/harddrive-16.png b/src/widgets/styles/images/harddrive-16.png
new file mode 100644
index 0000000000..45d592baa3
--- /dev/null
+++ b/src/widgets/styles/images/harddrive-16.png
Binary files differ
diff --git a/src/widgets/styles/images/harddrive-32.png b/src/widgets/styles/images/harddrive-32.png
new file mode 100644
index 0000000000..7041452b68
--- /dev/null
+++ b/src/widgets/styles/images/harddrive-32.png
Binary files differ
diff --git a/src/widgets/styles/images/left-128.png b/src/widgets/styles/images/left-128.png
new file mode 100644
index 0000000000..a26a5195f8
--- /dev/null
+++ b/src/widgets/styles/images/left-128.png
Binary files differ
diff --git a/src/widgets/styles/images/left-16.png b/src/widgets/styles/images/left-16.png
new file mode 100644
index 0000000000..110dd90f2d
--- /dev/null
+++ b/src/widgets/styles/images/left-16.png
Binary files differ
diff --git a/src/widgets/styles/images/left-32.png b/src/widgets/styles/images/left-32.png
new file mode 100644
index 0000000000..ec4107b372
--- /dev/null
+++ b/src/widgets/styles/images/left-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-pause-16.png b/src/widgets/styles/images/media-pause-16.png
new file mode 100644
index 0000000000..6cb1fd7f63
--- /dev/null
+++ b/src/widgets/styles/images/media-pause-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-pause-32.png b/src/widgets/styles/images/media-pause-32.png
new file mode 100644
index 0000000000..3f172a04d6
--- /dev/null
+++ b/src/widgets/styles/images/media-pause-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-play-16.png b/src/widgets/styles/images/media-play-16.png
new file mode 100644
index 0000000000..d7ee3ccbe3
--- /dev/null
+++ b/src/widgets/styles/images/media-play-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-play-32.png b/src/widgets/styles/images/media-play-32.png
new file mode 100644
index 0000000000..af8d2f7ba5
--- /dev/null
+++ b/src/widgets/styles/images/media-play-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-seek-backward-16.png b/src/widgets/styles/images/media-seek-backward-16.png
new file mode 100644
index 0000000000..b8a8ea42d1
--- /dev/null
+++ b/src/widgets/styles/images/media-seek-backward-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-seek-backward-32.png b/src/widgets/styles/images/media-seek-backward-32.png
new file mode 100644
index 0000000000..a21d1372fe
--- /dev/null
+++ b/src/widgets/styles/images/media-seek-backward-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-seek-forward-16.png b/src/widgets/styles/images/media-seek-forward-16.png
new file mode 100644
index 0000000000..3c900dcb62
--- /dev/null
+++ b/src/widgets/styles/images/media-seek-forward-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-seek-forward-32.png b/src/widgets/styles/images/media-seek-forward-32.png
new file mode 100644
index 0000000000..4f8d370fa1
--- /dev/null
+++ b/src/widgets/styles/images/media-seek-forward-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-skip-backward-16.png b/src/widgets/styles/images/media-skip-backward-16.png
new file mode 100644
index 0000000000..f5b3f4f56d
--- /dev/null
+++ b/src/widgets/styles/images/media-skip-backward-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-skip-backward-32.png b/src/widgets/styles/images/media-skip-backward-32.png
new file mode 100644
index 0000000000..1d338035ef
--- /dev/null
+++ b/src/widgets/styles/images/media-skip-backward-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-skip-forward-16.png b/src/widgets/styles/images/media-skip-forward-16.png
new file mode 100644
index 0000000000..27e205b02f
--- /dev/null
+++ b/src/widgets/styles/images/media-skip-forward-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-skip-forward-32.png b/src/widgets/styles/images/media-skip-forward-32.png
new file mode 100644
index 0000000000..a583fa1b11
--- /dev/null
+++ b/src/widgets/styles/images/media-skip-forward-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-stop-16.png b/src/widgets/styles/images/media-stop-16.png
new file mode 100644
index 0000000000..9ce035d696
--- /dev/null
+++ b/src/widgets/styles/images/media-stop-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-stop-32.png b/src/widgets/styles/images/media-stop-32.png
new file mode 100644
index 0000000000..aae24ba925
--- /dev/null
+++ b/src/widgets/styles/images/media-stop-32.png
Binary files differ
diff --git a/src/widgets/styles/images/media-volume-16.png b/src/widgets/styles/images/media-volume-16.png
new file mode 100644
index 0000000000..ad258340f2
--- /dev/null
+++ b/src/widgets/styles/images/media-volume-16.png
Binary files differ
diff --git a/src/widgets/styles/images/media-volume-muted-16.png b/src/widgets/styles/images/media-volume-muted-16.png
new file mode 100644
index 0000000000..06bded21e7
--- /dev/null
+++ b/src/widgets/styles/images/media-volume-muted-16.png
Binary files differ
diff --git a/src/widgets/styles/images/networkdrive-128.png b/src/widgets/styles/images/networkdrive-128.png
new file mode 100644
index 0000000000..fd4a59c6bd
--- /dev/null
+++ b/src/widgets/styles/images/networkdrive-128.png
Binary files differ
diff --git a/src/widgets/styles/images/networkdrive-16.png b/src/widgets/styles/images/networkdrive-16.png
new file mode 100644
index 0000000000..1bc62f766a
--- /dev/null
+++ b/src/widgets/styles/images/networkdrive-16.png
Binary files differ
diff --git a/src/widgets/styles/images/networkdrive-32.png b/src/widgets/styles/images/networkdrive-32.png
new file mode 100644
index 0000000000..6a389dcae4
--- /dev/null
+++ b/src/widgets/styles/images/networkdrive-32.png
Binary files differ
diff --git a/src/widgets/styles/images/newdirectory-128.png b/src/widgets/styles/images/newdirectory-128.png
new file mode 100644
index 0000000000..fdbee27688
--- /dev/null
+++ b/src/widgets/styles/images/newdirectory-128.png
Binary files differ
diff --git a/src/widgets/styles/images/newdirectory-16.png b/src/widgets/styles/images/newdirectory-16.png
new file mode 100644
index 0000000000..6c9f80318b
--- /dev/null
+++ b/src/widgets/styles/images/newdirectory-16.png
Binary files differ
diff --git a/src/widgets/styles/images/newdirectory-32.png b/src/widgets/styles/images/newdirectory-32.png
new file mode 100644
index 0000000000..4fd0329216
--- /dev/null
+++ b/src/widgets/styles/images/newdirectory-32.png
Binary files differ
diff --git a/src/widgets/styles/images/parentdir-128.png b/src/widgets/styles/images/parentdir-128.png
new file mode 100644
index 0000000000..84d14ab079
--- /dev/null
+++ b/src/widgets/styles/images/parentdir-128.png
Binary files differ
diff --git a/src/widgets/styles/images/parentdir-16.png b/src/widgets/styles/images/parentdir-16.png
new file mode 100644
index 0000000000..665f8280f2
--- /dev/null
+++ b/src/widgets/styles/images/parentdir-16.png
Binary files differ
diff --git a/src/widgets/styles/images/parentdir-32.png b/src/widgets/styles/images/parentdir-32.png
new file mode 100644
index 0000000000..44f3c4876d
--- /dev/null
+++ b/src/widgets/styles/images/parentdir-32.png
Binary files differ
diff --git a/src/widgets/styles/images/refresh-24.png b/src/widgets/styles/images/refresh-24.png
new file mode 100644
index 0000000000..4c9b72c489
--- /dev/null
+++ b/src/widgets/styles/images/refresh-24.png
Binary files differ
diff --git a/src/widgets/styles/images/refresh-32.png b/src/widgets/styles/images/refresh-32.png
new file mode 100644
index 0000000000..eecde4b8f9
--- /dev/null
+++ b/src/widgets/styles/images/refresh-32.png
Binary files differ
diff --git a/src/widgets/styles/images/right-128.png b/src/widgets/styles/images/right-128.png
new file mode 100644
index 0000000000..14b1cfd8eb
--- /dev/null
+++ b/src/widgets/styles/images/right-128.png
Binary files differ
diff --git a/src/widgets/styles/images/right-16.png b/src/widgets/styles/images/right-16.png
new file mode 100644
index 0000000000..81ca628ff6
--- /dev/null
+++ b/src/widgets/styles/images/right-16.png
Binary files differ
diff --git a/src/widgets/styles/images/right-32.png b/src/widgets/styles/images/right-32.png
new file mode 100644
index 0000000000..0f6ba8608b
--- /dev/null
+++ b/src/widgets/styles/images/right-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-apply-128.png b/src/widgets/styles/images/standardbutton-apply-128.png
new file mode 100644
index 0000000000..85f07a57ef
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-apply-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-apply-16.png b/src/widgets/styles/images/standardbutton-apply-16.png
new file mode 100644
index 0000000000..8f11ce6504
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-apply-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-apply-32.png b/src/widgets/styles/images/standardbutton-apply-32.png
new file mode 100644
index 0000000000..e8f7853a1e
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-apply-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-cancel-128.png b/src/widgets/styles/images/standardbutton-cancel-128.png
new file mode 100644
index 0000000000..16d857030f
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-cancel-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-cancel-16.png b/src/widgets/styles/images/standardbutton-cancel-16.png
new file mode 100644
index 0000000000..7bd25bd7c7
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-cancel-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-cancel-32.png b/src/widgets/styles/images/standardbutton-cancel-32.png
new file mode 100644
index 0000000000..64a78727a1
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-cancel-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-clear-128.png b/src/widgets/styles/images/standardbutton-clear-128.png
new file mode 100644
index 0000000000..107aea2234
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-clear-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-clear-16.png b/src/widgets/styles/images/standardbutton-clear-16.png
new file mode 100644
index 0000000000..5359134c72
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-clear-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-clear-32.png b/src/widgets/styles/images/standardbutton-clear-32.png
new file mode 100644
index 0000000000..8b85d6b7b3
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-clear-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-close-128.png b/src/widgets/styles/images/standardbutton-close-128.png
new file mode 100644
index 0000000000..571aeae2bd
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-close-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-close-16.png b/src/widgets/styles/images/standardbutton-close-16.png
new file mode 100644
index 0000000000..e9e481987a
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-close-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-close-32.png b/src/widgets/styles/images/standardbutton-close-32.png
new file mode 100644
index 0000000000..47e5733062
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-close-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-closetab-16.png b/src/widgets/styles/images/standardbutton-closetab-16.png
new file mode 100644
index 0000000000..540694eae3
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-closetab-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-closetab-down-16.png b/src/widgets/styles/images/standardbutton-closetab-down-16.png
new file mode 100644
index 0000000000..ccec241652
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-closetab-down-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-closetab-hover-16.png b/src/widgets/styles/images/standardbutton-closetab-hover-16.png
new file mode 100644
index 0000000000..b22a0ffaf0
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-closetab-hover-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-delete-128.png b/src/widgets/styles/images/standardbutton-delete-128.png
new file mode 100644
index 0000000000..11947ba681
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-delete-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-delete-16.png b/src/widgets/styles/images/standardbutton-delete-16.png
new file mode 100644
index 0000000000..63fe93fe98
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-delete-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-delete-32.png b/src/widgets/styles/images/standardbutton-delete-32.png
new file mode 100644
index 0000000000..336d965d1c
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-delete-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-help-128.png b/src/widgets/styles/images/standardbutton-help-128.png
new file mode 100644
index 0000000000..aa38e6fdfb
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-help-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-help-16.png b/src/widgets/styles/images/standardbutton-help-16.png
new file mode 100644
index 0000000000..e8299418da
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-help-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-help-32.png b/src/widgets/styles/images/standardbutton-help-32.png
new file mode 100644
index 0000000000..310056a632
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-help-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-no-128.png b/src/widgets/styles/images/standardbutton-no-128.png
new file mode 100644
index 0000000000..491c048ebd
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-no-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-no-16.png b/src/widgets/styles/images/standardbutton-no-16.png
new file mode 100644
index 0000000000..812d3f57dd
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-no-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-no-32.png b/src/widgets/styles/images/standardbutton-no-32.png
new file mode 100644
index 0000000000..9548d59196
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-no-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-ok-128.png b/src/widgets/styles/images/standardbutton-ok-128.png
new file mode 100644
index 0000000000..63cc5279ae
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-ok-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-ok-16.png b/src/widgets/styles/images/standardbutton-ok-16.png
new file mode 100644
index 0000000000..fb4b4dbf96
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-ok-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-ok-32.png b/src/widgets/styles/images/standardbutton-ok-32.png
new file mode 100644
index 0000000000..2dadd7a690
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-ok-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-open-128.png b/src/widgets/styles/images/standardbutton-open-128.png
new file mode 100644
index 0000000000..8a052e829d
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-open-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-open-16.png b/src/widgets/styles/images/standardbutton-open-16.png
new file mode 100644
index 0000000000..08cdc2b91f
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-open-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-open-32.png b/src/widgets/styles/images/standardbutton-open-32.png
new file mode 100644
index 0000000000..db33c79852
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-open-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-save-128.png b/src/widgets/styles/images/standardbutton-save-128.png
new file mode 100644
index 0000000000..fc6fd7ce1d
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-save-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-save-16.png b/src/widgets/styles/images/standardbutton-save-16.png
new file mode 100644
index 0000000000..dd4e228280
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-save-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-save-32.png b/src/widgets/styles/images/standardbutton-save-32.png
new file mode 100644
index 0000000000..177678c963
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-save-32.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-yes-128.png b/src/widgets/styles/images/standardbutton-yes-128.png
new file mode 100644
index 0000000000..79c8296016
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-yes-128.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-yes-16.png b/src/widgets/styles/images/standardbutton-yes-16.png
new file mode 100644
index 0000000000..cc16dbbec3
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-yes-16.png
Binary files differ
diff --git a/src/widgets/styles/images/standardbutton-yes-32.png b/src/widgets/styles/images/standardbutton-yes-32.png
new file mode 100644
index 0000000000..e3340c6453
--- /dev/null
+++ b/src/widgets/styles/images/standardbutton-yes-32.png
Binary files differ
diff --git a/src/widgets/styles/images/stop-24.png b/src/widgets/styles/images/stop-24.png
new file mode 100644
index 0000000000..99856e9640
--- /dev/null
+++ b/src/widgets/styles/images/stop-24.png
Binary files differ
diff --git a/src/widgets/styles/images/stop-32.png b/src/widgets/styles/images/stop-32.png
new file mode 100644
index 0000000000..4f4952bb2a
--- /dev/null
+++ b/src/widgets/styles/images/stop-32.png
Binary files differ
diff --git a/src/widgets/styles/images/trash-128.png b/src/widgets/styles/images/trash-128.png
new file mode 100644
index 0000000000..334fe5b6f3
--- /dev/null
+++ b/src/widgets/styles/images/trash-128.png
Binary files differ
diff --git a/src/widgets/styles/images/trash-16.png b/src/widgets/styles/images/trash-16.png
new file mode 100644
index 0000000000..c471791ee8
--- /dev/null
+++ b/src/widgets/styles/images/trash-16.png
Binary files differ
diff --git a/src/widgets/styles/images/trash-32.png b/src/widgets/styles/images/trash-32.png
new file mode 100644
index 0000000000..68625cf698
--- /dev/null
+++ b/src/widgets/styles/images/trash-32.png
Binary files differ
diff --git a/src/widgets/styles/images/up-128.png b/src/widgets/styles/images/up-128.png
new file mode 100644
index 0000000000..c10df10677
--- /dev/null
+++ b/src/widgets/styles/images/up-128.png
Binary files differ
diff --git a/src/widgets/styles/images/up-16.png b/src/widgets/styles/images/up-16.png
new file mode 100644
index 0000000000..33e939db8f
--- /dev/null
+++ b/src/widgets/styles/images/up-16.png
Binary files differ
diff --git a/src/widgets/styles/images/up-32.png b/src/widgets/styles/images/up-32.png
new file mode 100644
index 0000000000..d7157c9476
--- /dev/null
+++ b/src/widgets/styles/images/up-32.png
Binary files differ
diff --git a/src/widgets/styles/images/viewdetailed-128.png b/src/widgets/styles/images/viewdetailed-128.png
new file mode 100644
index 0000000000..363937a857
--- /dev/null
+++ b/src/widgets/styles/images/viewdetailed-128.png
Binary files differ
diff --git a/src/widgets/styles/images/viewdetailed-16.png b/src/widgets/styles/images/viewdetailed-16.png
new file mode 100644
index 0000000000..44a14b923a
--- /dev/null
+++ b/src/widgets/styles/images/viewdetailed-16.png
Binary files differ
diff --git a/src/widgets/styles/images/viewdetailed-32.png b/src/widgets/styles/images/viewdetailed-32.png
new file mode 100644
index 0000000000..fac1a3e683
--- /dev/null
+++ b/src/widgets/styles/images/viewdetailed-32.png
Binary files differ
diff --git a/src/widgets/styles/images/viewlist-128.png b/src/widgets/styles/images/viewlist-128.png
new file mode 100644
index 0000000000..cc301059c1
--- /dev/null
+++ b/src/widgets/styles/images/viewlist-128.png
Binary files differ
diff --git a/src/widgets/styles/images/viewlist-16.png b/src/widgets/styles/images/viewlist-16.png
new file mode 100644
index 0000000000..9132877ff6
--- /dev/null
+++ b/src/widgets/styles/images/viewlist-16.png
Binary files differ
diff --git a/src/widgets/styles/images/viewlist-32.png b/src/widgets/styles/images/viewlist-32.png
new file mode 100644
index 0000000000..fae3c24536
--- /dev/null
+++ b/src/widgets/styles/images/viewlist-32.png
Binary files differ
diff --git a/src/widgets/styles/qcdestyle.cpp b/src/widgets/styles/qcdestyle.cpp
new file mode 100644
index 0000000000..bb97b8a8a1
--- /dev/null
+++ b/src/widgets/styles/qcdestyle.cpp
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcdestyle.h"
+
+#if !defined(QT_NO_STYLE_CDE) || defined(QT_PLUGIN)
+
+#include "qmenu.h"
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include "qpixmap.h"
+#include "qpalette.h"
+#include "qwidget.h"
+#include "qpushbutton.h"
+#include "qscrollbar.h"
+#include "qtabbar.h"
+#include "qtabwidget.h"
+#include "qlistview.h"
+#include "qsplitter.h"
+#include "qslider.h"
+#include "qcombobox.h"
+#include "qlineedit.h"
+#include "qprogressbar.h"
+#include "qimage.h"
+#include "qfocusframe.h"
+#include "qpainterpath.h"
+#include "qdebug.h"
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCDEStyle
+ \brief The QCDEStyle class provides a CDE look and feel.
+
+ \ingroup appearance
+
+ This style provides a slightly improved Motif look similar to some
+ versions of the Common Desktop Environment (CDE). The main
+ differences are thinner frames and more modern radio buttons and
+ checkboxes. Together with a dark background and a bright
+ text/foreground color, the style looks quite attractive (at least
+ for Motif fans).
+
+ Note that most of the functions provided by QCDEStyle are
+ reimplementations of QStyle functions; see QStyle for their
+ documentation. QCDEStyle provides overloads for drawControl() and
+ drawPrimitive() which are documented here.
+
+ \img qcdestyle.png
+ \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QCDEStyle.
+
+ If \a useHighlightCols is false (the default), then the style will
+ polish the application's color palette to emulate the Motif way of
+ highlighting, which is a simple inversion between the base and the
+ text color.
+*/
+QCDEStyle::QCDEStyle(bool useHighlightCols)
+ : QMotifStyle(useHighlightCols)
+{
+}
+
+/*!
+ Destroys the style.
+*/
+QCDEStyle::~QCDEStyle()
+{
+}
+
+
+/*!\reimp
+*/
+int QCDEStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
+ const QWidget *widget) const
+/*
+int QCDEStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
+ const QWidget *widget) const
+ */
+{
+ int ret = 0;
+
+ switch(metric) {
+ case PM_MenuBarPanelWidth:
+ case PM_DefaultFrameWidth:
+ case PM_FocusFrameVMargin:
+ case PM_FocusFrameHMargin:
+ case PM_MenuPanelWidth:
+ case PM_SpinBoxFrameWidth:
+ case PM_MenuBarVMargin:
+ case PM_MenuBarHMargin:
+ case PM_DockWidgetFrameWidth:
+ ret = 1;
+ break;
+ case PM_ScrollBarExtent:
+ ret = 13;
+ break;
+ default:
+ ret = QMotifStyle::pixelMetric(metric, option, widget);
+ break;
+ }
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+void QCDEStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+
+ switch(element) {
+ case CE_MenuBarItem: {
+ if (opt->state & State_Selected) // active item
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 1,
+ &opt->palette.brush(QPalette::Button));
+ else // other item
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ QCommonStyle::drawControl(element, opt, p, widget);
+ break; }
+ case CE_RubberBand: {
+ p->save();
+ p->setClipping(false);
+ QPainterPath path;
+ path.addRect(opt->rect);
+ path.addRect(opt->rect.adjusted(2, 2, -2, -2));
+ p->fillPath(path, opt->palette.color(QPalette::Active, QPalette::Text));
+ p->restore();
+ break; }
+ default:
+ QMotifStyle::drawControl(element, opt, p, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QCDEStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch(pe) {
+ case PE_IndicatorCheckBox: {
+ bool down = opt->state & State_Sunken;
+ bool on = opt->state & State_On;
+ bool showUp = !(down ^ on);
+ QBrush fill = (showUp || (opt->state & State_NoChange)) ? opt->palette.brush(QPalette::Button) : opt->palette.brush(QPalette::Mid);
+ qDrawShadePanel(p, opt->rect, opt->palette, !showUp, pixelMetric(PM_DefaultFrameWidth), &opt->palette.brush(QPalette::Button));
+
+ if (on || (opt->state & State_NoChange)) {
+ QRect r = opt->rect;
+ QPolygon a(7 * 2);
+ int i, xx, yy;
+ xx = r.x() + 3;
+ yy = r.y() + 5;
+ if (opt->rect.width() <= 9) {
+ // When called from CE_MenuItem in QMotifStyle
+ xx -= 2;
+ yy -= 2;
+ }
+
+ for (i = 0; i < 3; i++) {
+ a.setPoint(2 * i, xx, yy);
+ a.setPoint(2 * i + 1, xx, yy + 2);
+ xx++; yy++;
+ }
+ yy -= 2;
+ for (i = 3; i < 7; i++) {
+ a.setPoint(2 * i, xx, yy);
+ a.setPoint(2 * i + 1, xx, yy + 2);
+ xx++; yy--;
+ }
+ if (opt->state & State_NoChange)
+ p->setPen(opt->palette.dark().color());
+ else
+ p->setPen(opt->palette.foreground().color());
+ p->drawPolyline(a);
+ }
+ if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ } break;
+ case PE_IndicatorRadioButton:
+ {
+ QRect r = opt->rect;
+#define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
+ static const int pts1[] = { // up left lines
+ 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
+ static const int pts4[] = { // bottom right lines
+ 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
+ 11,4, 10,3, 10,2 };
+ static const int pts5[] = { // inner fill
+ 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
+ bool down = opt->state & State_Sunken;
+ bool on = opt->state & State_On;
+ QPolygon a(INTARRLEN(pts1), pts1);
+
+ //center when rect is larger than indicator size
+ int xOffset = 0;
+ int yOffset = 0;
+ int indicatorWidth = pixelMetric(PM_ExclusiveIndicatorWidth);
+ int indicatorHeight = pixelMetric(PM_ExclusiveIndicatorWidth);
+ if (r.width() > indicatorWidth)
+ xOffset += (r.width() - indicatorWidth)/2;
+ if (r.height() > indicatorHeight)
+ yOffset += (r.height() - indicatorHeight)/2;
+ p->translate(xOffset, yOffset);
+
+ a.translate(r.x(), r.y());
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ p->setPen((down || on) ? opt->palette.dark().color() : opt->palette.light().color());
+ p->drawPolyline(a);
+ a.setPoints(INTARRLEN(pts4), pts4);
+ a.translate(r.x(), r.y());
+ p->setPen((down || on) ? opt->palette.light().color() : opt->palette.dark().color());
+ p->drawPolyline(a);
+ a.setPoints(INTARRLEN(pts5), pts5);
+ a.translate(r.x(), r.y());
+ QColor fillColor = on ? opt->palette.dark().color() : opt->palette.background().color();
+ p->setPen(fillColor);
+ p->setBrush(on ? opt->palette.brush(QPalette::Dark) :
+ opt->palette.brush(QPalette::Window));
+ p->drawPolygon(a);
+ if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+
+ p->translate(-xOffset, -yOffset);
+
+ } break;
+ default:
+ QMotifStyle::drawPrimitive(pe, opt, p, widget);
+ }
+}
+
+/*!\reimp*/
+QPalette QCDEStyle::standardPalette() const
+{
+ QColor background(0xb6, 0xb6, 0xcf);
+ QColor light = background.lighter();
+ QColor mid = background.darker(150);
+ QColor dark = background.darker();
+ QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, background);
+ return palette;
+}
+
+/*!
+ \internal
+*/
+QIcon QCDEStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ return QMotifStyle::standardIconImplementation(standardIcon, opt, widget);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/styles/qcdestyle.h b/src/widgets/styles/qcdestyle.h
new file mode 100644
index 0000000000..17ec47f938
--- /dev/null
+++ b/src/widgets/styles/qcdestyle.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QCDESTYLE_H
+#define QCDESTYLE_H
+
+#include <QtWidgets/qmotifstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_CDE)
+
+class Q_GUI_EXPORT QCDEStyle : public QMotifStyle
+{
+ Q_OBJECT
+public:
+ explicit QCDEStyle(bool useHighlightCols = false);
+ virtual ~QCDEStyle();
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+};
+
+#endif // QT_NO_STYLE_CDE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCDESTYLE_H
diff --git a/src/widgets/styles/qcleanlooksstyle.cpp b/src/widgets/styles/qcleanlooksstyle.cpp
new file mode 100644
index 0000000000..6da0e9177e
--- /dev/null
+++ b/src/widgets/styles/qcleanlooksstyle.cpp
@@ -0,0 +1,4450 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcleanlooksstyle.h"
+#include "qcleanlooksstyle_p.h"
+
+#if !defined(QT_NO_STYLE_CLEANLOOKS) || defined(QT_PLUGIN)
+
+#include "qwindowsstyle_p.h"
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qpainter.h>
+#include <qdir.h>
+#include <qhash.h>
+#include <qstyleoption.h>
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qfont.h>
+#include <qgroupbox.h>
+#include <qprocess.h>
+#include <qpixmapcache.h>
+#include <qdialogbuttonbox.h>
+#include <qscrollbar.h>
+#include <qspinbox.h>
+#include <qslider.h>
+#include <qsplitter.h>
+#include <qprogressbar.h>
+#include <qtoolbar.h>
+#include <qwizard.h>
+#include <qlibrary.h>
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QStyleHelper;
+
+enum Direction {
+ TopDown,
+ FromLeft,
+ BottomUp,
+ FromRight
+};
+
+// from windows style
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 8; // menu item ver text margin
+static const int windowsRightBorder = 15; // right border on windows
+
+/* XPM */
+static const char * const dock_widget_close_xpm[] = {
+ "11 13 7 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #8F8B88",
+ "@ c #6C6A67",
+ "# c #ABA6A3",
+ "$ c #B5B0AC",
+ "% c #A4A09D",
+ " ",
+ " +@@@@@@@+ ",
+ "+# #+",
+ "@ $@ @$ @",
+ "@ @@@ @@@ @",
+ "@ @@@@@ @",
+ "@ @@@ @",
+ "@ @@@@@ @",
+ "@ @@@ @@@ @",
+ "@ $@ @$ @",
+ "+% #+",
+ " +@@@@@@@+ ",
+ " "};
+
+static const char * const qt_cleanlooks_arrow_down_xpm[] = {
+ "11 7 2 1",
+ " c None",
+ "x c #000000",
+ " ",
+ " x x ",
+ " xxx xxx ",
+ " xxxxxxx ",
+ " xxxxx ",
+ " xxx ",
+ " x "};
+
+static const char * const qt_cleanlooks_arrow_up_xpm[] = {
+ "11 7 2 1",
+ " c None",
+ "x c #000000",
+ " x ",
+ " xxx ",
+ " xxxxx ",
+ " xxxxxxx ",
+ " xxx xxx ",
+ " x x ",
+ " "};
+
+static const char * const dock_widget_restore_xpm[] = {
+ "11 13 7 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #8F8B88",
+ "@ c #6C6A67",
+ "# c #ABA6A3",
+ "$ c #B5B0AC",
+ "% c #A4A09D",
+ " ",
+ " +@@@@@@@+ ",
+ "+# #+",
+ "@ #@@@# @",
+ "@ @ @ @",
+ "@ #@@@# @ @",
+ "@ @ @ @ @",
+ "@ @ @@@ @",
+ "@ @ @ @",
+ "@ #@@@# @",
+ "+% #+",
+ " +@@@@@@@+ ",
+ " "};
+
+static const char * const workspace_minimize[] = {
+ "11 13 7 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #8F8B88",
+ "@ c #6C6A67",
+ "# c #ABA6A3",
+ "$ c #B5B0AC",
+ "% c #A4A09D",
+ " ",
+ " +@@@@@@@+ ",
+ "+# #+",
+ "@ @",
+ "@ @",
+ "@ @",
+ "@ @@@@@@@ @",
+ "@ @@@@@@@ @",
+ "@ @",
+ "@ @",
+ "+% #+",
+ " +@@@@@@@+ ",
+ " "};
+
+
+static const char * const qt_titlebar_context_help[] = {
+ "10 10 3 1",
+ " c None",
+ "# c #000000",
+ "+ c #444444",
+ " +####+ ",
+ " ### ### ",
+ " ## ## ",
+ " +##+ ",
+ " +## ",
+ " ## ",
+ " ## ",
+ " ",
+ " ## ",
+ " ## "};
+
+static const char * const qt_cleanlooks_radiobutton[] = {
+ "13 13 9 1",
+ " c None",
+ ". c #ABA094",
+ "+ c #B7ADA0",
+ "@ c #C4BBB2",
+ "# c #DDD4CD",
+ "$ c #E7E1E0",
+ "% c #F4EFED",
+ "& c #FFFAF9",
+ "* c #FCFEFB",
+ " #@...@# ",
+ " @+@#$$#+@ ",
+ " @+$%%***&@@ ",
+ "#+$%**&&**&+#",
+ "@@$&&******#@",
+ ".#**********.",
+ ".$&******&*&.",
+ ".$*&******&*.",
+ "+#********&#@",
+ "#+*********+#",
+ " @@*******@@ ",
+ " @+#%*%#+@ ",
+ " #@...+# "};
+
+static const char * const qt_cleanlooks_radiobutton_checked[] = {
+ "13 13 20 1",
+ " c None",
+ ". c #A8ABAE",
+ "+ c #596066",
+ "@ c #283138",
+ "# c #A9ACAF",
+ "$ c #A6A9AB",
+ "% c #6B7378",
+ "& c #8C9296",
+ "* c #A2A6AA",
+ "= c #61696F",
+ "- c #596065",
+ "; c #93989C",
+ "> c #777E83",
+ ", c #60686E",
+ "' c #252D33",
+ ") c #535B62",
+ "! c #21292E",
+ "~ c #242B31",
+ "{ c #1F262B",
+ "] c #41484E",
+ " ",
+ " ",
+ " ",
+ " .+@+# ",
+ " $%&*&=# ",
+ " -&;>,'+ ",
+ " @*>,)!@ ",
+ " +&,)~{+ ",
+ " #='!{]# ",
+ " #+@+# ",
+ " ",
+ " ",
+ " "};
+
+
+static const char * const qt_scrollbar_button_arrow_left[] = {
+ "4 7 2 1",
+ " c None",
+ "* c #BFBFBF",
+ " *",
+ " **",
+ " ***",
+ "****",
+ " ***",
+ " **",
+ " *"};
+
+static const char * const qt_scrollbar_button_arrow_right[] = {
+ "4 7 2 1",
+ " c None",
+ "* c #BFBFBF",
+ "* ",
+ "** ",
+ "*** ",
+ "****",
+ "*** ",
+ "** ",
+ "* "};
+
+static const char * const qt_scrollbar_button_arrow_up[] = {
+ "7 4 2 1",
+ " c None",
+ "* c #BFBFBF",
+ " * ",
+ " *** ",
+ " ***** ",
+ "*******"};
+
+static const char * const qt_scrollbar_button_arrow_down[] = {
+ "7 4 2 1",
+ " c None",
+ "* c #BFBFBF",
+ "*******",
+ " ***** ",
+ " *** ",
+ " * "};
+
+static const char * const qt_spinbox_button_arrow_down[] = {
+ "7 4 2 1",
+ " c None",
+ "* c #BFBFBF",
+ "*******",
+ " ***** ",
+ " *** ",
+ " * "};
+
+static const char * const qt_spinbox_button_arrow_up[] = {
+ "7 4 2 1",
+ " c None",
+ "* c #BFBFBF",
+ " * ",
+ " *** ",
+ " ***** ",
+ "*******"};
+
+static const char * const qt_scrollbar_button_left[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ " .++++++++++++++",
+ ".+#############+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ ".+<<<<<<<<<<<<<+",
+ " .++++++++++++++"};
+
+static const char * const qt_scrollbar_button_right[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ "++++++++++++++. ",
+ "+#############+.",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+<<<<<<<<<<<<<+.",
+ "++++++++++++++. "};
+
+static const char * const qt_scrollbar_button_up[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ " .++++++++++++. ",
+ ".+############+.",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+<<<<<<<<<<<<<<+",
+ "++++++++++++++++"};
+
+static const char * const qt_scrollbar_button_down[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ "++++++++++++++++",
+ "+##############+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ ".+<<<<<<<<<<<<+.",
+ " .++++++++++++. "};
+
+static const char * const qt_cleanlooks_menuitem_checkbox_checked[] = {
+ "8 7 6 1",
+ " g None",
+ ". g #959595",
+ "+ g #676767",
+ "@ g #454545",
+ "# g #1D1D1D",
+ "0 g #101010",
+ " ..",
+ " .+ ",
+ " .+ ",
+ "0 .@ ",
+ "@#++. ",
+ " @# ",
+ " . "};
+
+static const char * const qt_cleanlooks_checkbox_checked[] = {
+ "13 13 3 1",
+ " c None",
+ ". c #272D33",
+ "% c #666666",
+
+ " ",
+ " % ",
+ " %. ",
+ " %.% ",
+ " %.. ",
+ " %.% %.. ",
+ " %..%..% ",
+ " %...% ",
+ " %..% ",
+ " %.% ",
+ " % ",
+ " ",
+ " "};
+
+static void qt_cleanlooks_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart,
+ const QColor &gradientStop, Direction direction = TopDown, QBrush bgBrush = QBrush())
+{
+ int x = rect.center().x();
+ int y = rect.center().y();
+ QLinearGradient *gradient;
+ switch(direction) {
+ case FromLeft:
+ gradient = new QLinearGradient(rect.left(), y, rect.right(), y);
+ break;
+ case FromRight:
+ gradient = new QLinearGradient(rect.right(), y, rect.left(), y);
+ break;
+ case BottomUp:
+ gradient = new QLinearGradient(x, rect.bottom(), x, rect.top());
+ break;
+ case TopDown:
+ default:
+ gradient = new QLinearGradient(x, rect.top(), x, rect.bottom());
+ break;
+ }
+ if (bgBrush.gradient())
+ gradient->setStops(bgBrush.gradient()->stops());
+ else {
+ gradient->setColorAt(0, gradientStart);
+ gradient->setColorAt(1, gradientStop);
+ }
+ painter->fillRect(rect, *gradient);
+ delete gradient;
+}
+
+static void qt_cleanlooks_draw_buttongradient(QPainter *painter, const QRect &rect, const QColor &gradientStart,
+ const QColor &gradientMid, const QColor &gradientStop, Direction direction = TopDown,
+ QBrush bgBrush = QBrush())
+{
+ int x = rect.center().x();
+ int y = rect.center().y();
+ QLinearGradient *gradient;
+ bool horizontal = false;
+ switch(direction) {
+ case FromLeft:
+ horizontal = true;
+ gradient = new QLinearGradient(rect.left(), y, rect.right(), y);
+ break;
+ case FromRight:
+ horizontal = true;
+ gradient = new QLinearGradient(rect.right(), y, rect.left(), y);
+ break;
+ case BottomUp:
+ gradient = new QLinearGradient(x, rect.bottom(), x, rect.top());
+ break;
+ case TopDown:
+ default:
+ gradient = new QLinearGradient(x, rect.top(), x, rect.bottom());
+ break;
+ }
+ if (bgBrush.gradient())
+ gradient->setStops(bgBrush.gradient()->stops());
+ else {
+ int size = horizontal ? rect.width() : rect.height() ;
+ if (size > 4) {
+ float edge = 4.0/(float)size;
+ gradient->setColorAt(0, gradientStart);
+ gradient->setColorAt(edge, gradientMid.lighter(104));
+ gradient->setColorAt(1.0 - edge, gradientMid.darker(100));
+ gradient->setColorAt(1.0, gradientStop);
+ }
+ }
+ painter->fillRect(rect, *gradient);
+ delete gradient;
+}
+
+static void qt_cleanlooks_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
+{
+ QColor dark;
+ dark.setHsv(option->palette.button().color().hue(),
+ qMin(255, (int)(option->palette.button().color().saturation()*1.9)),
+ qMin(255, (int)(option->palette.button().color().value()*0.7)));
+
+ QColor highlight = option->palette.highlight().color();
+
+ bool active = (option->titleBarState & QStyle::State_Active);
+ QColor titleBarHighlight(255, 255, 255, 60);
+
+ if (sunken)
+ painter->fillRect(tmp.adjusted(1, 1, -1, -1), option->palette.highlight().color().darker(120));
+ else if (hover)
+ painter->fillRect(tmp.adjusted(1, 1, -1, -1), QColor(255, 255, 255, 20));
+
+ QColor mdiButtonGradientStartColor;
+ QColor mdiButtonGradientStopColor;
+
+ mdiButtonGradientStartColor = QColor(0, 0, 0, 40);
+ mdiButtonGradientStopColor = QColor(255, 255, 255, 60);
+
+ if (sunken)
+ titleBarHighlight = highlight.darker(130);
+
+ QLinearGradient gradient(tmp.center().x(), tmp.top(), tmp.center().x(), tmp.bottom());
+ gradient.setColorAt(0, mdiButtonGradientStartColor);
+ gradient.setColorAt(1, mdiButtonGradientStopColor);
+ QColor mdiButtonBorderColor(active ? option->palette.highlight().color().darker(180): dark.darker(110));
+
+ painter->setPen(QPen(mdiButtonBorderColor, 1));
+ const QLine lines[4] = {
+ QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()),
+ QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()),
+ QLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2),
+ QLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2)
+ };
+ painter->drawLines(lines, 4);
+ const QPoint points[4] = {
+ QPoint(tmp.left() + 1, tmp.top() + 1),
+ QPoint(tmp.right() - 1, tmp.top() + 1),
+ QPoint(tmp.left() + 1, tmp.bottom() - 1),
+ QPoint(tmp.right() - 1, tmp.bottom() - 1)
+ };
+ painter->drawPoints(points, 4);
+
+ painter->setPen(titleBarHighlight);
+ painter->drawLine(tmp.left() + 2, tmp.top() + 1, tmp.right() - 2, tmp.top() + 1);
+ painter->drawLine(tmp.left() + 1, tmp.top() + 2, tmp.left() + 1, tmp.bottom() - 2);
+
+ painter->setPen(QPen(gradient, 1));
+ painter->drawLine(tmp.right() + 1, tmp.top() + 2, tmp.right() + 1, tmp.bottom() - 2);
+ painter->drawPoint(tmp.right() , tmp.top() + 1);
+
+ painter->drawLine(tmp.left() + 2, tmp.bottom() + 1, tmp.right() - 2, tmp.bottom() + 1);
+ painter->drawPoint(tmp.left() + 1, tmp.bottom());
+ painter->drawPoint(tmp.right() - 1, tmp.bottom());
+ painter->drawPoint(tmp.right() , tmp.bottom() - 1);
+}
+
+/*!
+ \class QCleanlooksStyle
+ \brief The QCleanlooksStyle class provides a widget style similar to the
+ Clearlooks style available in GNOME.
+ \since 4.2
+
+ The Cleanlooks style provides a look and feel for widgets
+ that closely resembles the Clearlooks style, introduced by Richard
+ Stellingwerff and Daniel Borgmann.
+
+ \sa {Cleanlooks Style Widget Gallery}, QWindowsXPStyle, QMacStyle, QWindowsStyle,
+ QCDEStyle, QMotifStyle, QPlastiqueStyle
+*/
+
+/*!
+ Constructs a QCleanlooksStyle object.
+*/
+QCleanlooksStyle::QCleanlooksStyle() : QWindowsStyle(*new QCleanlooksStylePrivate)
+{
+ setObjectName(QLatin1String("CleanLooks"));
+}
+
+/*!
+ \internal
+
+ Constructs a QCleanlooksStyle object.
+*/
+QCleanlooksStyle::QCleanlooksStyle(QCleanlooksStylePrivate &dd) : QWindowsStyle(dd)
+{
+}
+
+/*!
+ Destroys the QCleanlooksStyle object.
+*/
+QCleanlooksStyle::~QCleanlooksStyle()
+{
+}
+
+/*!
+ \fn void QCleanlooksStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+
+ Draws the given \a text in the specified \a rectangle using the
+ provided \a painter and \a palette.
+
+ Text is drawn using the painter's pen. If an explicit \a textRole
+ is specified, then the text is drawn using the \a palette's color
+ for the specified role. The \a enabled value indicates whether or
+ not the item is enabled; when reimplementing, this value should
+ influence how the item is drawn.
+
+ The text is aligned and wrapped according to the specified \a
+ alignment.
+
+ \sa Qt::Alignment
+*/
+void QCleanlooksStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ if (text.isEmpty())
+ return;
+
+ QPen savedPen = painter->pen();
+ if (textRole != QPalette::NoRole) {
+ painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
+ }
+ if (!enabled) {
+ QPen pen = painter->pen();
+ painter->setPen(pen);
+ }
+ painter->drawText(rect, alignment, text);
+ painter->setPen(savedPen);
+}
+
+static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
+{
+ const int maxFactor = 100;
+ QColor tmp = colorA;
+ tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
+ tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
+ tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
+ return tmp;
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem,
+ const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ Q_ASSERT(option);
+ QRect rect = option->rect;
+ int state = option->state;
+ QColor button = option->palette.button().color();
+ QColor buttonShadow = option->palette.button().color().darker(110);
+ QColor buttonShadowAlpha = buttonShadow;
+ buttonShadowAlpha.setAlpha(128);
+ QColor darkOutline;
+ QColor dark;
+ darkOutline.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*3.0)),
+ qMin(255, (int)(button.value()*0.6)));
+ dark.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
+ QColor tabFrameColor = mergedColors(option->palette.background().color(),
+ dark.lighter(135), 60);
+
+ switch(elem) {
+#ifndef QT_NO_TABBAR
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+ painter->save();
+ painter->setPen(QPen(darkOutline.lighter(110), 0));
+ switch (tbb->shape) {
+ case QTabBar::RoundedNorth: {
+ QRegion region(tbb->rect);
+ region -= tbb->selectedTabRect;
+ painter->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
+ painter->setClipRegion(region);
+ painter->setPen(option->palette.light().color());
+ painter->drawLine(tbb->rect.topLeft() + QPoint(0, 1),
+ tbb->rect.topRight() + QPoint(0, 1));
+ }
+ break;
+ case QTabBar::RoundedWest:
+ painter->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
+ break;
+ case QTabBar::RoundedSouth:
+ painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
+ tbb->rect.right(), tbb->rect.bottom());
+ break;
+ case QTabBar::RoundedEast:
+ painter->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
+ break;
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ case QTabBar::TriangularSouth:
+ painter->restore();
+ QWindowsStyle::drawPrimitive(elem, option, painter, widget);
+ return;
+ }
+ painter->restore();
+ }
+ return;
+#endif // QT_NO_TABBAR
+ case PE_IndicatorViewItemCheck:
+ {
+ QStyleOptionButton button;
+ button.QStyleOption::operator=(*option);
+ button.state &= ~State_MouseOver;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
+ }
+ return;
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ QRect r = header->rect;
+ QImage arrow;
+ if (header->sortIndicator & QStyleOptionHeader::SortUp)
+ arrow = QImage(qt_cleanlooks_arrow_up_xpm);
+ else if (header->sortIndicator & QStyleOptionHeader::SortDown)
+ arrow = QImage(qt_cleanlooks_arrow_down_xpm);
+ if (!arrow.isNull()) {
+ r.setSize(arrow.size());
+ r.moveCenter(header->rect.center());
+ arrow.setColor(1, header->palette.foreground().color().rgba());
+ painter->drawImage(r, arrow);
+ }
+ }
+ break;
+ case PE_IndicatorButtonDropDown:
+ proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
+ break;
+ case PE_IndicatorToolBarSeparator:
+ {
+ QRect rect = option->rect;
+ const int margin = 6;
+ if (option->state & State_Horizontal) {
+ const int offset = rect.width()/2;
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ painter->drawLine(rect.bottomLeft().x() + offset,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset,
+ rect.topLeft().y() + margin);
+ painter->setPen(QPen(option->palette.background().color().lighter(110)));
+ painter->drawLine(rect.bottomLeft().x() + offset + 1,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset + 1,
+ rect.topLeft().y() + margin);
+ } else { //Draw vertical separator
+ const int offset = rect.height()/2;
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset);
+ painter->setPen(QPen(option->palette.background().color().lighter(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset + 1,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset + 1);
+ }
+ }
+ break;
+ case PE_Frame:
+ painter->save();
+ painter->setPen(dark.lighter(108));
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ painter->restore();
+ break;
+ case PE_FrameMenu:
+ painter->save();
+ {
+ painter->setPen(QPen(darkOutline, 1));
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ QColor frameLight = option->palette.background().color().lighter(160);
+ QColor frameShadow = option->palette.background().color().darker(110);
+
+ //paint beveleffect
+ QRect frame = option->rect.adjusted(1, 1, -1, -1);
+ painter->setPen(frameLight);
+ painter->drawLine(frame.topLeft(), frame.bottomLeft());
+ painter->drawLine(frame.topLeft(), frame.topRight());
+
+ painter->setPen(frameShadow);
+ painter->drawLine(frame.topRight(), frame.bottomRight());
+ painter->drawLine(frame.bottomLeft(), frame.bottomRight());
+ }
+ painter->restore();
+ break;
+ case PE_FrameDockWidget:
+
+ painter->save();
+ {
+ QColor softshadow = option->palette.background().color().darker(120);
+
+ QRect rect= option->rect;
+ painter->setPen(softshadow);
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ painter->setPen(QPen(option->palette.light(), 0));
+ painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1));
+ painter->setPen(QPen(option->palette.background().color().darker(120), 0));
+ painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1));
+ painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1));
+
+ }
+ painter->restore();
+ break;
+ case PE_PanelButtonTool:
+ painter->save();
+ if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) {
+ QPen oldPen = painter->pen();
+
+ if (widget && widget->inherits("QDockWidgetTitleButton")) {
+ if (option->state & State_MouseOver)
+ proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
+ } else {
+ proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
+ }
+ }
+ painter->restore();
+ break;
+ case PE_IndicatorDockWidgetResizeHandle:
+ {
+ QStyleOption dockWidgetHandle = *option;
+ bool horizontal = option->state & State_Horizontal;
+ if (horizontal)
+ dockWidgetHandle.state &= ~State_Horizontal;
+ else
+ dockWidgetHandle.state |= State_Horizontal;
+ proxy()->drawControl(CE_Splitter, &dockWidgetHandle, painter, widget);
+ }
+ break;
+ case PE_FrameWindow:
+ painter->save();
+ {
+ QRect rect= option->rect;
+ painter->setPen(QPen(dark.darker(150), 0));
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ painter->setPen(QPen(option->palette.light(), 0));
+ painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
+ QPoint(rect.left() + 1, rect.bottom() - 1));
+ painter->setPen(QPen(option->palette.background().color().darker(120), 0));
+ painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
+ QPoint(rect.right() - 2, rect.bottom() - 1));
+ painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
+ QPoint(rect.right() - 1, rect.bottom() - 1));
+ }
+ painter->restore();
+ break;
+#ifndef QT_NO_LINEEDIT
+ case PE_FrameLineEdit:
+ // fall through
+#endif // QT_NO_LINEEDIT
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3ToolBar")) {
+ proxy()->drawPrimitive(PE_Q3Separator, option, painter, widget);
+ break;
+ }
+#endif
+ {
+ QPen oldPen = painter->pen();
+ if (option->state & State_Enabled) {
+ painter->setPen(QPen(option->palette.background(), 0));
+ painter->drawRect(rect.adjusted(0, 0, 0, 0));
+ painter->drawRect(rect.adjusted(1, 1, -1, -1));
+ } else {
+ painter->fillRect(rect, option->palette.background());
+ }
+ QRect r = rect.adjusted(0, 1, 0, -1);
+ painter->setPen(buttonShadowAlpha);
+ painter->drawLine(QPoint(r.left() + 2, r.top() - 1), QPoint(r.right() - 2, r.top() - 1));
+ const QPoint points[8] = {
+ QPoint(r.right() - 1, r.top()),
+ QPoint(r.right(), r.top() + 1),
+ QPoint(r.right() - 1, r.bottom()),
+ QPoint(r.right(), r.bottom() - 1),
+ QPoint(r.left() + 1, r.top() ),
+ QPoint(r.left(), r.top() + 1),
+ QPoint(r.left() + 1, r.bottom() ),
+ QPoint(r.left(), r.bottom() - 1)
+ };
+ painter->drawPoints(points, 8);
+ painter->setPen(QPen(option->palette.background().color(), 1));
+ painter->drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
+
+ if (option->state & State_HasFocus) {
+ QColor darkoutline = option->palette.highlight().color().darker(150);
+ QColor innerline = mergedColors(option->palette.highlight().color(), Qt::white);
+ painter->setPen(QPen(innerline, 0));
+ painter->drawRect(rect.adjusted(1, 2, -2, -3));
+ painter->setPen(QPen(darkoutline, 0));
+ }
+ else {
+ QColor highlight = Qt::white;
+ highlight.setAlpha(130);
+ painter->setPen(option->palette.base().color().darker(120));
+ painter->drawLine(QPoint(r.left() + 1, r.top() + 1),
+ QPoint(r.right() - 1, r.top() + 1));
+ painter->drawLine(QPoint(r.left() + 1, r.top() + 1),
+ QPoint(r.left() + 1, r.bottom() - 1));
+ painter->setPen(option->palette.base().color());
+ painter->drawLine(QPoint(r.right() - 1, r.top() + 1),
+ QPoint(r.right() - 1, r.bottom() - 1));
+ painter->setPen(highlight);
+ painter->drawLine(QPoint(r.left() + 1, r.bottom() + 1),
+ QPoint(r.right() - 1, r.bottom() + 1));
+ painter->drawPoint(QPoint(r.left(), r.bottom()));
+ painter->drawPoint(QPoint(r.right(), r.bottom() ));
+ painter->setPen(QPen(darkOutline.lighter(115), 1));
+ }
+ painter->drawLine(QPoint(r.left(), r.top() + 2), QPoint(r.left(), r.bottom() - 2));
+ painter->drawLine(QPoint(r.right(), r.top() + 2), QPoint(r.right(), r.bottom() - 2));
+ painter->drawLine(QPoint(r.left() + 2, r.bottom()), QPoint(r.right() - 2, r.bottom()));
+ const QPoint points2[4] = {
+ QPoint(r.right() - 1, r.bottom() - 1),
+ QPoint(r.right() - 1, r.top() + 1),
+ QPoint(r.left() + 1, r.bottom() - 1),
+ QPoint(r.left() + 1, r.top() + 1)
+ };
+ painter->drawPoints(points2, 4);
+ painter->drawLine(QPoint(r.left() + 2, r.top()), QPoint(r.right() - 2, r.top()));
+ painter->setPen(oldPen);
+ }
+ break;
+ case PE_IndicatorCheckBox:
+ painter->save();
+ if (const QStyleOptionButton *checkbox = qstyleoption_cast<const QStyleOptionButton*>(option)) {
+ QRect checkRect;
+ checkRect.setX(rect.left() );
+ checkRect.setY(rect.top() );
+ checkRect.setWidth(rect.width() - 1);
+ checkRect.setHeight(rect.height() - 1);
+ if (state & State_Sunken)
+ painter->setBrush(dark.lighter(130));
+ else
+ painter->setBrush(option->palette.base());
+ painter->setPen(QPen(dark.lighter(110), 0));
+ painter->drawRect(checkRect);
+ if (checkbox->state & (State_On | State_Sunken | State_NoChange)) {
+ QImage image(qt_cleanlooks_checkbox_checked);
+ QColor fillColor = option->palette.text().color();
+ image.setColor(1, fillColor.rgba());
+ fillColor.setAlpha(100);
+ image.setColor(2, fillColor.rgba());
+ painter->drawImage(rect, image);
+ if (checkbox->state & State_NoChange) {
+ QColor bgc = option->palette.background().color();
+ bgc.setAlpha(127);
+ painter->fillRect(checkRect.adjusted(1, 1, -1, -1), bgc);
+ }
+ }
+ }
+ painter->restore();
+ break;
+ case PE_IndicatorRadioButton:
+ painter->save();
+ {
+ painter->setRenderHint(QPainter::SmoothPixmapTransform);
+ QRect checkRect = rect.adjusted(0, 0, 0, 0);
+ if (state & (State_On )) {
+ painter->drawImage(rect, QImage(qt_cleanlooks_radiobutton));
+ painter->drawImage(checkRect, QImage(qt_cleanlooks_radiobutton_checked));
+ }
+ else if (state & State_Sunken) {
+ painter->drawImage(rect, QImage(qt_cleanlooks_radiobutton));
+ QColor bgc = buttonShadow;
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->setBrush(bgc);
+ painter->setPen(Qt::NoPen);
+ painter->drawEllipse(rect.adjusted(1, 1, -1, -1)); }
+ else {
+ painter->drawImage(rect, QImage(qt_cleanlooks_radiobutton));
+ }
+ }
+ painter->restore();
+ break;
+ case PE_IndicatorToolBarHandle:
+ painter->save();
+ if (option->state & State_Horizontal) {
+ for (int i = rect.height()/5; i <= 4*(rect.height()/5) ; ++i) {
+ int y = rect.topLeft().y() + i + 1;
+ int x1 = rect.topLeft().x() + 3;
+ int x2 = rect.topRight().x() - 2;
+
+ if (i % 2 == 0)
+ painter->setPen(QPen(option->palette.light(), 0));
+ else
+ painter->setPen(QPen(dark.lighter(110), 0));
+ painter->drawLine(x1, y, x2, y);
+ }
+ }
+ else { //vertical toolbar
+ for (int i = rect.width()/5; i <= 4*(rect.width()/5) ; ++i) {
+ int x = rect.topLeft().x() + i + 1;
+ int y1 = rect.topLeft().y() + 3;
+ int y2 = rect.topLeft().y() + 5;
+
+ if (i % 2 == 0)
+ painter->setPen(QPen(option->palette.light(), 0));
+ else
+ painter->setPen(QPen(dark.lighter(110), 0));
+ painter->drawLine(x, y1, x, y2);
+ }
+ }
+ painter->restore();
+ break;
+ case PE_FrameDefaultButton:
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *focusFrame = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) {
+ if (!(focusFrame->state & State_KeyboardFocusChange))
+ return;
+ QRect rect = focusFrame->rect;
+ painter->save();
+ painter->setBackgroundMode(Qt::TransparentMode);
+ painter->setBrush(QBrush(dark.darker(120), Qt::Dense4Pattern));
+ painter->setBrushOrigin(rect.topLeft());
+ painter->setPen(Qt::NoPen);
+ const QRect rects[4] = {
+ QRect(rect.left(), rect.top(), rect.width(), 1), // Top
+ QRect(rect.left(), rect.bottom(), rect.width(), 1), // Bottom
+ QRect(rect.left(), rect.top(), 1, rect.height()), // Left
+ QRect(rect.right(), rect.top(), 1, rect.height()) // Right
+ };
+ painter->drawRects(rects, 4);
+ painter->restore();
+ }
+ break;
+ case PE_PanelButtonCommand:
+ {
+ bool isDefault = false;
+ bool isFlat = false;
+ bool isDown = (option->state & State_Sunken) || (option->state & State_On);
+ QPen oldPen = painter->pen();
+ QBrush oldBrush = painter->brush();
+ QRect r;
+
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) {
+ isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state & State_Enabled);
+ isFlat = (button->features & QStyleOptionButton::Flat);
+ }
+
+ if (isFlat && !isDown) {
+ if (isDefault) {
+ r = option->rect.adjusted(0, 1, 0, -1);
+ painter->setPen(QPen(Qt::black, 0));
+ const QLine lines[4] = {
+ QLine(QPoint(r.left() + 2, r.top()),
+ QPoint(r.right() - 2, r.top())),
+ QLine(QPoint(r.left(), r.top() + 2),
+ QPoint(r.left(), r.bottom() - 2)),
+ QLine(QPoint(r.right(), r.top() + 2),
+ QPoint(r.right(), r.bottom() - 2)),
+ QLine(QPoint(r.left() + 2, r.bottom()),
+ QPoint(r.right() - 2, r.bottom()))
+ };
+ painter->drawLines(lines, 4);
+ const QPoint points[4] = {
+ QPoint(r.right() - 1, r.bottom() - 1),
+ QPoint(r.right() - 1, r.top() + 1),
+ QPoint(r.left() + 1, r.bottom() - 1),
+ QPoint(r.left() + 1, r.top() + 1)
+ };
+ painter->drawPoints(points, 4);
+ painter->setPen(oldPen);
+ }
+ return;
+ }
+
+ BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("pushbutton-%1").arg(isDefault))
+ r = rect.adjusted(0, 1, 0, -1);
+
+ bool isEnabled = (option->state & State_Enabled);
+
+ QColor highlightedGradientStartColor = option->palette.button().color().lighter(107);
+ QColor highlightedGradientMidColor = option->palette.button().color().lighter(105);
+ QColor highlightedGradientStopColor = buttonShadow.lighter(107);
+ QColor gradientStartColor = option->palette.button().color().lighter(108);
+
+ QColor buttonColor = option->palette.button().color();
+ QColor gradientMidColor = option->palette.button().color();
+ QColor gradientStopColor;
+ gradientStopColor.setHsv(buttonColor.hue(),
+ qMin(255, (int)(buttonColor.saturation()*1.9)),
+ qMin(255, (int)(buttonColor.value()*0.96)));
+
+ QRect gradRect = rect.adjusted(1, 2, -1, -2);
+ // gradient fill
+ QRect innerBorder = r.adjusted(1, 1, -1, 0);
+
+ if (isDown) {
+ QBrush fillColor = gradientStopColor.darker(110);
+ if (option->palette.button().gradient())
+ fillColor = option->palette.button();
+ p->fillRect(gradRect, fillColor);
+ p->setPen(gradientStopColor.darker(125));
+ p->drawLine(innerBorder.topLeft(), innerBorder.topRight());
+ p->drawLine(innerBorder.topLeft(), innerBorder.bottomLeft());
+ } else {
+ if (isEnabled && option->state & State_MouseOver ) {
+ qt_cleanlooks_draw_buttongradient(p, gradRect,
+ highlightedGradientStartColor,
+ highlightedGradientMidColor,
+ highlightedGradientStopColor, TopDown, option->palette.button());
+ } else {
+ qt_cleanlooks_draw_buttongradient(p, gradRect,
+ gradientStartColor,
+ gradientMidColor,
+ gradientStopColor, TopDown, option->palette.button());
+ }
+ }
+
+ bool hasFocus = option->state & State_HasFocus;
+
+ if (!isEnabled)
+ p->setPen(QPen(dark.lighter(115)));
+ else if (isDefault)
+ p->setPen(QPen(Qt::black, 1));
+ else
+ p->setPen(QPen(darkOutline, 1));
+
+ p->drawLine(QPoint(r.left(), r.top() + 2),
+ QPoint(r.left(), r.bottom() - 2));
+ p->drawLine(QPoint(r.right(), r.top() + 2),
+ QPoint(r.right(), r.bottom() - 2));
+ p->drawLine(QPoint(r.left() + 2, r.bottom()),
+ QPoint(r.right() - 2, r.bottom()));
+ const QPoint points[4] = {
+ QPoint(r.right() - 1, r.bottom() - 1),
+ QPoint(r.right() - 1, r.top() + 1),
+ QPoint(r.left() + 1, r.bottom() - 1),
+ QPoint(r.left() + 1, r.top() + 1)
+ };
+ p->drawPoints(points, 4);
+
+ if (!isDefault && !hasFocus && isEnabled)
+ p->setPen(QPen(darkOutline.darker(110), 0));
+
+ p->drawLine(QPoint(r.left() + 2, r.top()),
+ QPoint(r.right() - 2, r.top()));
+
+ QColor highlight = Qt::white;
+ highlight.setAlpha(110);
+ p->setPen(highlight);
+ p->drawLine(QPoint(r.left() + 1, r.top() + 2),
+ QPoint(r.left() + 1, r.bottom() - 2));
+ p->drawLine(QPoint(r.left() + 3, r.bottom() + 1),
+ QPoint(r.right() - 3, r.bottom() + 1));
+
+ QColor topShadow = darkOutline;
+ topShadow.setAlpha(60);
+
+ p->setPen(topShadow);
+ const QPoint points2[8] = {
+ QPoint(r.right(), r.top() + 1),
+ QPoint(r.right() - 1, r.top() ),
+ QPoint(r.right(), r.bottom() - 1),
+ QPoint(r.right() - 1, r.bottom() ),
+ QPoint(r.left() + 1, r.bottom()),
+ QPoint(r.left(), r.bottom() - 1),
+ QPoint(r.left() + 1, r.top()),
+ QPoint(r.left(), r.top() + 1)
+ };
+ p->drawPoints(points2, 8);
+
+ topShadow.setAlpha(30);
+ p->setPen(topShadow);
+
+ p->drawLine(QPoint(r.right() - 1, r.top() + 2),
+ QPoint(r.right() - 1, r.bottom() - 2));
+ p->drawLine(QPoint(r.left() + 2, r.top() - 1),
+ QPoint(r.right() - 2, r.top() - 1));
+
+ if (isDefault) {
+ r.adjust(-1, -1, 1, 1);
+ p->setPen(buttonShadowAlpha.darker(120));
+ const QLine lines[4] = {
+ QLine(r.topLeft() + QPoint(3, 0), r.topRight() - QPoint(3, 0)),
+ QLine(r.bottomLeft() + QPoint(3, 0), r.bottomRight() - QPoint(3, 0)),
+ QLine(r.topLeft() + QPoint(0, 3), r.bottomLeft() - QPoint(0, 3)),
+ QLine(r.topRight() + QPoint(0, 3), r.bottomRight() - QPoint(0, 3))
+ };
+ p->drawLines(lines, 4);
+ const QPoint points3[8] = {
+ r.topRight() + QPoint(-2, 1),
+ r.topRight() + QPoint(-1, 2),
+ r.bottomRight() + QPoint(-1, -2),
+ r.bottomRight() + QPoint(-2, -1),
+ r.topLeft() + QPoint(1, 2),
+ r.topLeft() + QPoint(2, 1),
+ r.bottomLeft() + QPoint(1, -2),
+ r.bottomLeft() + QPoint(2, -1)
+ };
+ p->drawPoints(points3, 8);
+ }
+ painter->setPen(oldPen);
+ painter->setBrush(oldBrush);
+ END_STYLE_PIXMAPCACHE
+ }
+ break;
+#ifndef QT_NO_TABBAR
+ case PE_FrameTabWidget:
+ painter->save();
+ {
+ painter->fillRect(option->rect, tabFrameColor);
+ }
+#ifndef QT_NO_TABWIDGET
+ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
+ QColor borderColor = darkOutline.lighter(110);
+ QColor alphaCornerColor = mergedColors(borderColor, option->palette.background().color());
+
+ int borderThickness = proxy()->pixelMetric(PM_TabBarBaseOverlap, twf, widget);
+ bool reverse = (twf->direction == Qt::RightToLeft);
+ QRect tabBarRect;
+
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ if (reverse) {
+ tabBarRect = QRect(twf->rect.right() - twf->leftCornerWidgetSize.width()
+ - twf->tabBarSize.width() + 1,
+ twf->rect.top(),
+ twf->tabBarSize.width(), borderThickness);
+ } else {
+ tabBarRect = QRect(twf->rect.left() + twf->leftCornerWidgetSize.width(),
+ twf->rect.top(),
+ twf->tabBarSize.width(), borderThickness);
+ }
+ break ;
+ case QTabBar::RoundedWest:
+ tabBarRect = QRect(twf->rect.left(),
+ twf->rect.top() + twf->leftCornerWidgetSize.height(),
+ borderThickness,
+ twf->tabBarSize.height());
+ tabBarRect = tabBarRect; //adjust
+ break ;
+ case QTabBar::RoundedEast:
+ tabBarRect = QRect(twf->rect.right() - borderThickness + 1,
+ twf->rect.top() + twf->leftCornerWidgetSize.height(),
+ 0,
+ twf->tabBarSize.height());
+ break ;
+ case QTabBar::RoundedSouth:
+ if (reverse) {
+ tabBarRect = QRect(twf->rect.right() - twf->leftCornerWidgetSize.width() - twf->tabBarSize.width() + 1,
+ twf->rect.bottom() + 1,
+ twf->tabBarSize.width(),
+ borderThickness);
+ } else {
+ tabBarRect = QRect(twf->rect.left() + twf->leftCornerWidgetSize.width(),
+ twf->rect.bottom() + 1,
+ twf->tabBarSize.width(),
+ borderThickness);
+ }
+ break;
+ default:
+ break;
+ }
+
+ QRegion region(twf->rect);
+ region -= tabBarRect;
+ painter->setClipRegion(region);
+
+ // Outer border
+ QLine leftLine = QLine(twf->rect.topLeft() + QPoint(0, 2), twf->rect.bottomLeft() - QPoint(0, 2));
+ QLine rightLine = QLine(twf->rect.topRight(), twf->rect.bottomRight() - QPoint(0, 2));
+ QLine bottomLine = QLine(twf->rect.bottomLeft() + QPoint(2, 0), twf->rect.bottomRight() - QPoint(2, 0));
+ QLine topLine = QLine(twf->rect.topLeft(), twf->rect.topRight());
+
+ painter->setPen(borderColor);
+ painter->drawLine(topLine);
+
+ // Inner border
+ QLine innerLeftLine = QLine(leftLine.p1() + QPoint(1, 0), leftLine.p2() + QPoint(1, 0));
+ QLine innerRightLine = QLine(rightLine.p1() - QPoint(1, -1), rightLine.p2() - QPoint(1, 0));
+ QLine innerBottomLine = QLine(bottomLine.p1() - QPoint(0, 1), bottomLine.p2() - QPoint(0, 1));
+ QLine innerTopLine = QLine(topLine.p1() + QPoint(0, 1), topLine.p2() + QPoint(-1, 1));
+
+ // Rounded Corner
+ QPoint leftBottomOuterCorner = QPoint(innerLeftLine.p2() + QPoint(0, 1));
+ QPoint leftBottomInnerCorner1 = QPoint(leftLine.p2() + QPoint(0, 1));
+ QPoint leftBottomInnerCorner2 = QPoint(bottomLine.p1() - QPoint(1, 0));
+ QPoint rightBottomOuterCorner = QPoint(innerRightLine.p2() + QPoint(0, 1));
+ QPoint rightBottomInnerCorner1 = QPoint(rightLine.p2() + QPoint(0, 1));
+ QPoint rightBottomInnerCorner2 = QPoint(bottomLine.p2() + QPoint(1, 0));
+ QPoint leftTopOuterCorner = QPoint(innerLeftLine.p1() - QPoint(0, 1));
+ QPoint leftTopInnerCorner1 = QPoint(leftLine.p1() - QPoint(0, 1));
+ QPoint leftTopInnerCorner2 = QPoint(topLine.p1() - QPoint(1, 0));
+
+ painter->setPen(borderColor);
+ painter->drawLine(leftLine);
+ painter->drawLine(rightLine);
+ painter->drawLine(bottomLine);
+ painter->drawPoint(leftBottomOuterCorner);
+ painter->drawPoint(rightBottomOuterCorner);
+ painter->drawPoint(leftTopOuterCorner);
+
+ painter->setPen(option->palette.light().color());
+ painter->drawLine(innerLeftLine);
+ painter->drawLine(innerTopLine);
+
+ painter->setPen(buttonShadowAlpha);
+ painter->drawLine(innerRightLine);
+ painter->drawLine(innerBottomLine);
+
+ painter->setPen(alphaCornerColor);
+ const QPoint points[6] = {
+ leftBottomInnerCorner1,
+ leftBottomInnerCorner2,
+ rightBottomInnerCorner1,
+ rightBottomInnerCorner2,
+ leftTopInnerCorner1,
+ leftTopInnerCorner2
+ };
+ painter->drawPoints(points, 6);
+ }
+#endif // QT_NO_TABWIDGET
+ painter->restore();
+ break ;
+
+ case PE_FrameStatusBarItem:
+ break;
+ case PE_IndicatorTabClose:
+ {
+ Q_D(const QCleanlooksStyle);
+ if (d->tabBarcloseButtonIcon.isNull())
+ d->tabBarcloseButtonIcon = standardIcon(SP_DialogCloseButton, option, widget);
+ if ((option->state & State_Enabled) && (option->state & State_MouseOver))
+ proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
+ QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(QSize(16, 16), QIcon::Normal, QIcon::On);
+ proxy()->drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap);
+ }
+ break;
+
+#endif // QT_NO_TABBAR
+ default:
+ QWindowsStyle::drawPrimitive(elem, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
+ const QWidget *widget) const
+{
+ QColor button = option->palette.button().color();
+ QColor dark;
+ dark.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
+ QColor darkOutline;
+ darkOutline.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*2.0)),
+ qMin(255, (int)(button.value()*0.6)));
+ QRect rect = option->rect;
+ QColor shadow = mergedColors(option->palette.background().color().darker(120),
+ dark.lighter(130), 60);
+ QColor tabFrameColor = mergedColors(option->palette.background().color(),
+ dark.lighter(135), 60);
+
+ QColor highlight = option->palette.highlight().color();
+
+ switch(element) {
+ case CE_RadioButton: //fall through
+ case CE_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool hover = (btn->state & State_MouseOver && btn->state & State_Enabled);
+ if (hover)
+ painter->fillRect(rect, btn->palette.background().color().lighter(104));
+ QStyleOptionButton copy = *btn;
+ copy.rect.adjust(2, 0, -2, 0);
+ QWindowsStyle::drawControl(element, &copy, painter, widget);
+ }
+ break;
+ case CE_Splitter:
+ painter->save();
+ {
+ // hover appearance
+ QBrush fillColor = option->palette.background().color();
+ if (option->state & State_MouseOver && option->state & State_Enabled)
+ fillColor = fillColor.color().lighter(106);
+
+ painter->fillRect(option->rect, fillColor);
+
+ QColor grooveColor = mergedColors(dark.lighter(110), option->palette.button().color(),40);
+ QColor gripShadow = grooveColor.darker(110);
+ QPalette palette = option->palette;
+ bool vertical = !(option->state & State_Horizontal);
+ QRect scrollBarSlider = option->rect;
+ int gripMargin = 4;
+ //draw grips
+ if (vertical) {
+ for( int i = -20; i< 20 ; i += 2) {
+ painter->setPen(QPen(gripShadow, 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.center().x() + i ,
+ scrollBarSlider.top() + gripMargin),
+ QPoint(scrollBarSlider.center().x() + i,
+ scrollBarSlider.bottom() - gripMargin));
+ painter->setPen(QPen(palette.light(), 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.center().x() + i + 1,
+ scrollBarSlider.top() + gripMargin ),
+ QPoint(scrollBarSlider.center().x() + i + 1,
+ scrollBarSlider.bottom() - gripMargin));
+ }
+ } else {
+ for (int i = -20; i < 20 ; i += 2) {
+ painter->setPen(QPen(gripShadow, 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.left() + gripMargin ,
+ scrollBarSlider.center().y()+ i),
+ QPoint(scrollBarSlider.right() - gripMargin,
+ scrollBarSlider.center().y()+ i));
+ painter->setPen(QPen(palette.light(), 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.left() + gripMargin,
+ scrollBarSlider.center().y() + 1 + i),
+ QPoint(scrollBarSlider.right() - gripMargin,
+ scrollBarSlider.center().y() + 1 + i));
+
+ }
+ }
+ }
+ painter->restore();
+ break;
+#ifndef QT_NO_SIZEGRIP
+ case CE_SizeGrip:
+ painter->save();
+ {
+ int x, y, w, h;
+ option->rect.getRect(&x, &y, &w, &h);
+ int sw = qMin(h, w);
+ if (h > w)
+ painter->translate(0, h - w);
+ else
+ painter->translate(w - h, 0);
+
+ int sx = x;
+ int sy = y;
+ int s = 4;
+ if (option->direction == Qt::RightToLeft) {
+ sx = x + sw;
+ for (int i = 0; i < 4; ++i) {
+ painter->setPen(QPen(option->palette.light().color(), 1));
+ painter->drawLine(x, sy - 1 , sx + 1, sw);
+ painter->setPen(QPen(dark.lighter(120), 1));
+ painter->drawLine(x, sy, sx, sw);
+ sx -= s;
+ sy += s;
+ }
+ } else {
+ for (int i = 0; i < 4; ++i) {
+ painter->setPen(QPen(option->palette.light().color(), 1));
+ painter->drawLine(sx - 1, sw, sw, sy - 1);
+ painter->setPen(QPen(dark.lighter(120), 1));
+ painter->drawLine(sx, sw, sw, sy);
+ sx += s;
+ sy += s;
+ }
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_SIZEGRIP
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ painter->save();
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ QRect rect = option->rect;
+
+ bool paintLeftBorder = true;
+ bool paintRightBorder = true;
+ bool paintBottomBorder = true;
+
+ switch (toolbar->toolBarArea) {
+ case Qt::BottomToolBarArea:
+ switch(toolbar->positionOfLine) {
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintBottomBorder = false;
+ default:
+ break;
+ }
+ case Qt::TopToolBarArea:
+ switch (toolbar->positionWithinLine) {
+ case QStyleOptionToolBar::Beginning:
+ paintLeftBorder = false;
+ break;
+ case QStyleOptionToolBar::End:
+ paintRightBorder = false;
+ break;
+ case QStyleOptionToolBar::OnlyOne:
+ paintRightBorder = false;
+ paintLeftBorder = false;
+ default:
+ break;
+ }
+ if (toolbar->direction == Qt::RightToLeft) { //reverse layout changes the order of Beginning/end
+ bool tmp = paintLeftBorder;
+ paintRightBorder=paintLeftBorder;
+ paintLeftBorder=tmp;
+ }
+ break;
+ case Qt::RightToolBarArea:
+ switch (toolbar->positionOfLine) {
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintRightBorder = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ case Qt::LeftToolBarArea:
+ switch (toolbar->positionOfLine) {
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintLeftBorder = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ QColor light = option->palette.background().color().lighter(110);
+
+ //draw top border
+ painter->setPen(QPen(light));
+ painter->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.topRight().x(),
+ rect.topRight().y());
+
+ if (paintLeftBorder) {
+ painter->setPen(QPen(light));
+ painter->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.bottomLeft().x(),
+ rect.bottomLeft().y());
+ }
+
+ if (paintRightBorder) {
+ painter->setPen(QPen(shadow));
+ painter->drawLine(rect.topRight().x(),
+ rect.topRight().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ }
+
+ if (paintBottomBorder) {
+ painter->setPen(QPen(shadow));
+ painter->drawLine(rect.bottomLeft().x(),
+ rect.bottomLeft().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+ painter->save();
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect rect = dwOpt->rect;
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget);
+ QRect r = rect.adjusted(0, 0, -1, 0);
+ if (verticalTitleBar)
+ r.adjust(0, 0, 0, -1);
+ painter->setPen(option->palette.light().color());
+ painter->drawRect(r.adjusted(1, 1, 1, 1));
+ painter->setPen(shadow);
+ painter->drawRect(r);
+
+ if (verticalTitleBar) {
+ QRect r = rect;
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+
+ painter->translate(r.left(), r.top() + r.width());
+ painter->rotate(-90);
+ painter->translate(-r.left(), -r.top());
+
+ rect = r;
+ }
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText
+ = painter->fontMetrics().elidedText(dwOpt->title,
+ Qt::ElideRight, titleRect.width());
+ proxy()->drawItemText(painter,
+ titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_DOCKWIDGET
+ case CE_HeaderSection:
+ painter->save();
+ // Draws the header in tables.
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ QPixmap cache;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("headersection"), option, option->rect.size());
+ pixmapName += QString::number(- int(header->position));
+ pixmapName += QString::number(- int(header->orientation));
+ QRect r = option->rect;
+ QColor gradientStopColor;
+ QColor gradientStartColor = option->palette.button().color();
+ gradientStopColor.setHsv(gradientStartColor.hue(),
+ qMin(255, (int)(gradientStartColor.saturation()*2)),
+ qMin(255, (int)(gradientStartColor.value()*0.96)));
+ QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
+ if (option->palette.background().gradient()) {
+ gradient.setStops(option->palette.background().gradient()->stops());
+ } else {
+ gradient.setColorAt(0, gradientStartColor);
+ gradient.setColorAt(0.8, gradientStartColor);
+ gradient.setColorAt(1, gradientStopColor);
+ }
+ painter->fillRect(r, gradient);
+
+ if (!QPixmapCache::find(pixmapName, cache)) {
+ cache = QPixmap(r.size());
+ cache.fill(Qt::transparent);
+ QRect pixmapRect(0, 0, r.width(), r.height());
+ QPainter cachePainter(&cache);
+ if (header->orientation == Qt::Vertical) {
+ cachePainter.setPen(QPen(dark));
+ cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
+ if (header->position != QStyleOptionHeader::End) {
+ cachePainter.setPen(QPen(shadow));
+ cachePainter.drawLine(pixmapRect.bottomLeft() + QPoint(3, -1), pixmapRect.bottomRight() + QPoint(-3, -1)); cachePainter.setPen(QPen(option->palette.light().color()));
+ cachePainter.drawLine(pixmapRect.bottomLeft() + QPoint(3, 0), pixmapRect.bottomRight() + QPoint(-3, 0)); }
+ } else {
+ cachePainter.setPen(QPen(dark));
+ cachePainter.drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
+ cachePainter.setPen(QPen(shadow));
+ cachePainter.drawLine(pixmapRect.topRight() + QPoint(-1, 3), pixmapRect.bottomRight() + QPoint(-1, -3)); cachePainter.setPen(QPen(option->palette.light().color()));
+ cachePainter.drawLine(pixmapRect.topRight() + QPoint(0, 3), pixmapRect.bottomRight() + QPoint(0, -3)); }
+ cachePainter.end();
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ painter->drawPixmap(r.topLeft(), cache);
+ }
+ painter->restore();
+ break;
+ case CE_ProgressBarGroove:
+ painter->save();
+ {
+ painter->fillRect(rect, option->palette.base());
+ QColor borderColor = dark.lighter(110);
+ painter->setPen(QPen(borderColor, 0));
+ const QLine lines[4] = {
+ QLine(QPoint(rect.left() + 1, rect.top()), QPoint(rect.right() - 1, rect.top())),
+ QLine(QPoint(rect.left() + 1, rect.bottom()), QPoint(rect.right() - 1, rect.bottom())),
+ QLine(QPoint(rect.left(), rect.top() + 1), QPoint(rect.left(), rect.bottom() - 1)),
+ QLine(QPoint(rect.right(), rect.top() + 1), QPoint(rect.right(), rect.bottom() - 1))
+ };
+ painter->drawLines(lines, 4);
+ QColor alphaCorner = mergedColors(borderColor, option->palette.background().color());
+ QColor innerShadow = mergedColors(borderColor, option->palette.base().color());
+
+ //corner smoothing
+ painter->setPen(alphaCorner);
+ const QPoint points[4] = {
+ rect.topRight(),
+ rect.topLeft(),
+ rect.bottomRight(),
+ rect.bottomLeft()
+ };
+ painter->drawPoints(points, 4);
+
+ //inner shadow
+ painter->setPen(innerShadow);
+ painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
+ QPoint(rect.right() - 1, rect.top() + 1));
+ painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
+ QPoint(rect.left() + 1, rect.bottom() + 1));
+
+ }
+ painter->restore();
+ break;
+ case CE_ProgressBarContents:
+ painter->save();
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ QRect rect = bar->rect;
+ bool vertical = false;
+ bool inverted = false;
+ bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
+
+ // Get extra style options if version 2
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ }
+
+ // If the orientation is vertical, we use a transform to rotate
+ // the progress bar 90 degrees clockwise. This way we can use the
+ // same rendering code for both orientations.
+ if (vertical) {
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ QTransform m = QTransform::fromTranslate(rect.height()-1, -1.0);
+ m.rotate(90.0);
+ painter->setTransform(m, true);
+ }
+
+ int maxWidth = rect.width() - 4;
+ int minWidth = 4;
+ qreal progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar
+ int progressBarWidth = (progress - bar->minimum) * qreal(maxWidth) / qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
+ int width = indeterminate ? maxWidth : qMax(minWidth, progressBarWidth);
+
+ bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
+ if (inverted)
+ reverse = !reverse;
+
+ QRect progressBar;
+ if (!indeterminate) {
+ if (!reverse) {
+ progressBar.setRect(rect.left() + 1, rect.top() + 1, width + 1, rect.height() - 3);
+ } else {
+ progressBar.setRect(rect.right() - 1 - width, rect.top() + 1, width + 1, rect.height() - 3);
+ }
+ } else {
+ Q_D(const QCleanlooksStyle);
+ int slideWidth = ((rect.width() - 4) * 2) / 3;
+ int step = ((d->animateStep * slideWidth) / d->animationFps) % slideWidth;
+ if ((((d->animateStep * slideWidth) / d->animationFps) % (2 * slideWidth)) >= slideWidth)
+ step = slideWidth - step;
+ progressBar.setRect(rect.left() + 1 + step, rect.top() + 1,
+ slideWidth / 2, rect.height() - 3);
+ }
+ QColor highlight = option->palette.color(QPalette::Normal, QPalette::Highlight);
+ painter->setPen(QPen(highlight.darker(140), 0));
+
+ QColor highlightedGradientStartColor = highlight.lighter(100);
+ QColor highlightedGradientStopColor = highlight.lighter(130);
+
+ QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(),
+ rect.bottomLeft().y()*2));
+
+ gradient.setColorAt(0, highlightedGradientStartColor);
+ gradient.setColorAt(1, highlightedGradientStopColor);
+
+ painter->setBrush(gradient);
+ painter->drawRect(progressBar);
+
+ painter->setPen(QPen(highlight.lighter(120), 0));
+ painter->drawLine(QPoint(progressBar.left() + 1, progressBar.top() + 1),
+ QPoint(progressBar.right(), progressBar.top() + 1));
+ painter->drawLine(QPoint(progressBar.left() + 1, progressBar.top() + 1),
+ QPoint(progressBar.left() + 1, progressBar.bottom() - 1));
+
+ painter->setPen(QPen(highlightedGradientStartColor, 7.0));//QPen(option->palette.highlight(), 3));
+
+ painter->save();
+ painter->setClipRect(progressBar.adjusted(2, 2, -1, -1));
+ for (int x = progressBar.left() - 32; x < rect.right() ; x+=18) {
+ painter->drawLine(x, progressBar.bottom() + 1, x + 23, progressBar.top() - 2);
+ }
+ painter->restore();
+
+ }
+ painter->restore();
+ break;
+ case CE_MenuBarItem:
+ painter->save();
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ QStyleOptionMenuItem item = *mbi;
+ item.rect = mbi->rect.adjusted(0, 3, 0, -1);
+ QColor highlightOutline = highlight.darker(125);
+ QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()*2));
+
+ if (option->palette.button().gradient()) {
+ gradient.setStops(option->palette.button().gradient()->stops());
+ } else {
+ gradient.setColorAt(0, option->palette.button().color());
+ gradient.setColorAt(1, option->palette.button().color().darker(110));
+ }
+ painter->fillRect(rect, gradient);
+
+ QCommonStyle::drawControl(element, &item, painter, widget);
+
+ bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
+ bool dis = !(mbi->state & State_Enabled);
+
+ QRect r = option->rect;
+ if (act) {
+ qt_cleanlooks_draw_gradient(painter, r.adjusted(1, 1, -1, -1),
+ highlight,
+ highlightOutline, TopDown,
+ option->palette.highlight());
+
+ painter->setPen(QPen(highlightOutline, 0));
+ const QLine lines[4] = {
+ QLine(QPoint(r.left(), r.top() + 1), QPoint(r.left(), r.bottom())),
+ QLine(QPoint(r.right(), r.top() + 1), QPoint(r.right(), r.bottom())),
+ QLine(QPoint(r.left() + 1, r.bottom()), QPoint(r.right() - 1, r.bottom())),
+ QLine(QPoint(r.left() + 1, r.top()), QPoint(r.right() - 1, r.top()))
+ };
+ painter->drawLines(lines, 4);
+
+ //draw text
+ QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+ proxy()->drawItemText(painter, item.rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+
+ }
+ painter->restore();
+ break;
+ case CE_MenuItem:
+ painter->save();
+ // Draws one item in a popup menu.
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ QColor highlightOutline = highlight.darker(125);
+ QColor menuBackground = option->palette.background().color().lighter(104);
+ QColor borderColor = option->palette.background().color().darker(160);
+ QColor alphaCornerColor;
+
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
+ }
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ painter->fillRect(menuItem->rect, menuBackground);
+ int w = 0;
+ if (!menuItem->text.isEmpty()) {
+ painter->setFont(menuItem->font);
+ proxy()->drawItemText(painter, menuItem->rect.adjusted(5, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
+ menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
+ QPalette::Text);
+ w = menuItem->fontMetrics.width(menuItem->text) + 5;
+ }
+ painter->setPen(shadow.lighter(106));
+ bool reverse = menuItem->direction == Qt::RightToLeft;
+ painter->drawLine(menuItem->rect.left() + 5 + (reverse ? 0 : w), menuItem->rect.center().y(),
+ menuItem->rect.right() - 5 - (reverse ? w : 0), menuItem->rect.center().y());
+ painter->restore();
+ break;
+ }
+ bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
+ if (selected) {
+ QRect r = option->rect.adjusted(1, 0, -2, -1);
+ qt_cleanlooks_draw_gradient(painter, r, highlight,
+ highlightOutline, TopDown,
+ highlight);
+ r = r.adjusted(-1, 0, 1, 0);
+ painter->setPen(QPen(highlightOutline, 0));
+ const QLine lines[4] = {
+ QLine(QPoint(r.left(), r.top() + 1), QPoint(r.left(), r.bottom() - 1)),
+ QLine(QPoint(r.right(), r.top() + 1), QPoint(r.right(), r.bottom() - 1)),
+ QLine(QPoint(r.left() + 1, r.bottom()), QPoint(r.right() - 1, r.bottom())),
+ QLine(QPoint(r.left() + 1, r.top()), QPoint(r.right() - 1, r.top()))
+ };
+ painter->drawLines(lines, 4);
+ } else {
+ painter->fillRect(option->rect, menuBackground);
+ }
+
+ bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
+ bool checked = menuItem->checked;
+ bool sunken = menuItem->state & State_Sunken;
+ bool enabled = menuItem->state & State_Enabled;
+
+ bool ignoreCheckMark = false;
+ int checkcol = qMax(menuItem->maxIconWidth, 20);
+
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox*>(widget))
+ ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
+#endif
+
+ if (!ignoreCheckMark) {
+ // Check
+ QRect checkRect(option->rect.left() + 7, option->rect.center().y() - 6, 13, 13);
+ checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
+ if (checkable) {
+ if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
+ // Radio button
+ if (checked || sunken) {
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->setPen(Qt::NoPen);
+
+ QPalette::ColorRole textRole = !enabled ? QPalette::Text:
+ selected ? QPalette::HighlightedText : QPalette::ButtonText;
+ painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole));
+ painter->drawEllipse(checkRect.adjusted(4, 4, -4, -4));
+ }
+ } else {
+ // Check box
+ if (menuItem->icon.isNull()) {
+ if (checked || sunken) {
+ QImage image(qt_cleanlooks_menuitem_checkbox_checked);
+ if (enabled && (menuItem->state & State_Selected)) {
+ image.setColor(1, 0x55ffffff);
+ image.setColor(2, 0xAAffffff);
+ image.setColor(3, 0xBBffffff);
+ image.setColor(4, 0xFFffffff);
+ image.setColor(5, 0x33ffffff);
+ } else {
+ image.setColor(1, 0x55000000);
+ image.setColor(2, 0xAA000000);
+ image.setColor(3, 0xBB000000);
+ image.setColor(4, 0xFF000000);
+ image.setColor(5, 0x33000000);
+ }
+ painter->drawImage(QPoint(checkRect.center().x() - image.width() / 2,
+ checkRect.center().y() - image.height() / 2), image);
+ }
+ }
+ }
+ }
+ } else { //ignore checkmark
+ if (menuItem->icon.isNull())
+ checkcol = 0;
+ else
+ checkcol = menuItem->maxIconWidth;
+ }
+
+ // Text and icon, ripped from windows style
+ bool dis = !(menuItem->state & State_Enabled);
+ bool act = menuItem->state & State_Selected;
+ const QStyleOption *opt = option;
+ const QStyleOptionMenuItem *menuitem = menuItem;
+
+ QPainter *p = painter;
+ QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
+ QRect(menuitem->rect.x(), menuitem->rect.y(),
+ checkcol, menuitem->rect.height()));
+ if (!menuItem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+
+ int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
+ QSize iconSize(smallIconSize, smallIconSize);
+#ifndef QT_NO_COMBOBOX
+ if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
+ iconSize = combo->iconSize();
+#endif // QT_NO_COMBOBOX
+ if (checked)
+ pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
+ else
+ pixmap = menuItem->icon.pixmap(iconSize, mode);
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(menuItem->palette.text().color());
+ if (checkable && checked) {
+ QStyleOption opt = *option;
+ if (act) {
+ QColor activeColor = mergedColors(option->palette.background().color(),
+ option->palette.highlight().color());
+ opt.palette.setBrush(QPalette::Button, activeColor);
+ }
+ opt.state |= State_Sunken;
+ opt.rect = vCheckRect;
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
+ }
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ }
+ if (selected) {
+ painter->setPen(menuItem->palette.highlightedText().color());
+ } else {
+ painter->setPen(menuItem->palette.text().color());
+ }
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ p->setPen(discol);
+ }
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, s.mid(t + 1));
+ p->setPen(discol);
+ }
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ // font may not have any "hard" flags set. We override
+ // the point size so that when it is resolved against the device, this font will win.
+ // This is mainly to handle cases where someone sets the font on the window
+ // and then the combo inherits it and passes it onward. At that point the resolve mask
+ // is very, very weak. This makes it stonger.
+ font.setPointSizeF(QFontInfo(menuItem->font).pointSizeF());
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+
+ p->setFont(font);
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, s.left(t));
+ p->setPen(discol);
+ }
+ p->drawText(vTextRect, text_flags, s.left(t));
+ p->restore();
+ }
+
+ // Arrow
+ if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (menuItem->rect.height() - 4) / 2;
+ PrimitiveElement arrow;
+ arrow = QApplication::isRightToLeft() ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ int xpos = menuItem->rect.left() + menuItem->rect.width() - 3 - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
+ QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuItem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = !enabled ? State_None : State_Enabled;
+ if (selected)
+ newMI.palette.setColor(QPalette::ButtonText,
+ newMI.palette.highlightedText().color());
+ proxy()->drawPrimitive(arrow, &newMI, painter, widget);
+ }
+ }
+ painter->restore();
+ break;
+ case CE_MenuHMargin:
+ case CE_MenuVMargin:
+ break;
+ case CE_MenuEmptyArea:
+ break;
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ QRect ir = button->rect;
+ uint tf = Qt::AlignVCenter;
+ if (styleHint(SH_UnderlineShortcut, button, widget))
+ tf |= Qt::TextShowMnemonic;
+ else
+ tf |= Qt::TextHideMnemonic;
+
+ if (!button->icon.isNull()) {
+ //Center both icon and text
+ QPoint point;
+
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+ QIcon::State state = QIcon::Off;
+ if (button->state & State_On)
+ state = QIcon::On;
+
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int w = pixmap.width();
+ int h = pixmap.height();
+
+ if (!button->text.isEmpty())
+ w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 2;
+
+ point = QPoint(ir.x() + ir.width() / 2 - w / 2,
+ ir.y() + ir.height() / 2 - h / 2);
+
+ if (button->direction == Qt::RightToLeft)
+ point.rx() += pixmap.width();
+
+ painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap);
+
+ if (button->direction == Qt::RightToLeft)
+ ir.translate(-point.x() - 2, 0);
+ else
+ ir.translate(point.x() + pixmap.width(), 0);
+
+ // left-align text if there is
+ if (!button->text.isEmpty())
+ tf |= Qt::AlignLeft;
+
+ } else {
+ tf |= Qt::AlignHCenter;
+ }
+
+ if (button->features & QStyleOptionButton::HasMenu)
+ ir = ir.adjusted(0, 0, -proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
+ proxy()->drawItemText(painter, ir, tf, button->palette, (button->state & State_Enabled),
+ button->text, QPalette::ButtonText);
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+ QColor shadow = mergedColors(option->palette.background().color().darker(120),
+ dark.lighter(140), 60);
+
+ QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()*2));
+ gradient.setColorAt(0, option->palette.button().color());
+ gradient.setColorAt(1, option->palette.button().color().darker(110));
+ painter->fillRect(rect, gradient);
+
+#ifndef QT_NO_MAINWINDOW
+ if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
+ QPen oldPen = painter->pen();
+ painter->setPen(QPen(shadow));
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ }
+#endif // QT_NO_MAINWINDOW
+ }
+ painter->restore();
+ break;
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ painter->save();
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+
+ bool rtlHorTabs = (tab->direction == Qt::RightToLeft
+ && (tab->shape == QTabBar::RoundedNorth
+ || tab->shape == QTabBar::RoundedSouth));
+ bool selected = tab->state & State_Selected;
+ bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning));
+ bool onlyTab = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool leftCornerWidget = (tab->cornerWidgets & QStyleOptionTab::LeftCornerWidget);
+
+ bool atBeginning = ((tab->position == (tab->direction == Qt::LeftToRight ?
+ QStyleOptionTab::Beginning : QStyleOptionTab::End)) || onlyTab);
+
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool previousSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
+ bool nextSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition
+ == QStyleOptionTab::PreviousIsSelected));
+ int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget);
+ bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignRight);
+
+ bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignLeft);
+
+ QColor light = tab->palette.light().color();
+
+ QColor background = tab->palette.background().color();
+ int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
+ if (selected)
+ borderThinkness /= 2;
+ QRect r2(option->rect);
+ int x1 = r2.left();
+ int x2 = r2.right();
+ int y1 = r2.top();
+ int y2 = r2.bottom();
+
+ QTransform rotMatrix;
+ bool flip = false;
+ painter->setPen(shadow);
+ QColor activeHighlight = option->palette.color(QPalette::Normal, QPalette::Highlight);
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ break;
+ case QTabBar::RoundedSouth:
+ rotMatrix.rotate(180);
+ rotMatrix.translate(0, -rect.height() + 1);
+ rotMatrix.scale(-1, 1);
+ painter->setTransform(rotMatrix, true);
+ break;
+ case QTabBar::RoundedWest:
+ rotMatrix.rotate(180 + 90);
+ rotMatrix.scale(-1, 1);
+ flip = true;
+ painter->setTransform(rotMatrix, true);
+ break;
+ case QTabBar::RoundedEast:
+ rotMatrix.rotate(90);
+ rotMatrix.translate(0, - rect.width() + 1);
+ flip = true;
+ painter->setTransform(rotMatrix, true);
+ break;
+ default:
+ painter->restore();
+ QWindowsStyle::drawControl(element, tab, painter, widget);
+ return;
+ }
+
+ if (flip) {
+ QRect tmp = rect;
+ rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width());
+ int temp = x1;
+ x1 = y1;
+ y1 = temp;
+ temp = x2;
+ x2 = y2;
+ y2 = temp;
+ }
+
+ QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
+ if (option->palette.button().gradient()) {
+ if (selected)
+ gradient.setStops(option->palette.background().gradient()->stops());
+ else
+ gradient.setStops(option->palette.background().gradient()->stops());
+ }
+ else if (selected) {
+ gradient.setColorAt(0, option->palette.background().color().lighter(104));
+ gradient.setColorAt(1, tabFrameColor);
+ painter->fillRect(rect.adjusted(0, 2, 0, -1), gradient);
+ } else {
+ y1 += 2;
+ gradient.setColorAt(0, option->palette.background().color());
+ gradient.setColorAt(1, dark.lighter(120));
+ painter->fillRect(rect.adjusted(0, 2, 0, -2), gradient);
+ }
+
+ // Delete border
+ if (selected) {
+ painter->setPen(QPen(activeHighlight, 0));
+ painter->drawLine(x1 + 1, y1 + 1, x2 - 1, y1 + 1);
+ painter->drawLine(x1 , y1 + 2, x2 , y1 + 2);
+ } else {
+ painter->setPen(dark);
+ painter->drawLine(x1, y2 - 1, x2 + 2, y2 - 1 );
+ if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedWest) {
+ painter->setPen(light);
+ painter->drawLine(x1, y2 , x2, y2 );
+ }
+ }
+ // Left
+ if (atBeginning || selected ) {
+ painter->setPen(light);
+ painter->drawLine(x1 + 1, y1 + 2 + 1, x1 + 1, y2 - ((onlyOne || atBeginning) && selected && leftAligned ? 0 : borderThinkness) - (atBeginning && leftCornerWidget ? 1 : 0));
+ painter->drawPoint(x1 + 1, y1 + 1);
+ painter->setPen(dark);
+ painter->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || atBeginning) && leftAligned ? 0 : borderThinkness) - (atBeginning && leftCornerWidget ? 1 : 0));
+ }
+ // Top
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ painter->setPen(light);
+
+ if (!selected)painter->drawLine(beg - 2, y1 + 1, end, y1 + 1);
+
+ if (selected)
+ painter->setPen(QPen(activeHighlight.darker(150), 0));
+ else
+ painter->setPen(darkOutline);
+ painter->drawLine(beg, y1 , end, y1);
+
+ if (atBeginning|| selected) {
+ painter->drawPoint(beg - 1, y1 + 1);
+ } else if (!atBeginning) {
+ painter->drawPoint(beg - 1, y1);
+ painter->drawPoint(beg - 2, y1);
+ if (!lastTab) {
+ painter->setPen(dark.lighter(130));
+ painter->drawPoint(end + 1, y1);
+ painter->drawPoint(end + 2 , y1);
+ painter->drawPoint(end + 2, y1 + 1);
+ }
+ }
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ painter->setPen(darkOutline);
+ painter->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ if (selected)
+ painter->setPen(QPen(activeHighlight.darker(150), 0));
+ else
+ painter->setPen(darkOutline);
+ painter->drawPoint(x2 - 1, y1 + 1);
+
+ if (selected) {
+ painter->setPen(background.darker(110));
+ painter->drawLine(x2 - 1, y1 + 3, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ }
+ }
+ }
+ painter->restore();
+ break;
+
+#endif // QT_NO_TABBAR
+ default:
+ QWindowsStyle::drawControl(element,option,painter,widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+QPalette QCleanlooksStyle::standardPalette () const
+{
+ QPalette palette = QWindowsStyle::standardPalette();
+ palette.setBrush(QPalette::Active, QPalette::Highlight, QColor(98, 140, 178));
+ palette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(145, 141, 126));
+ palette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 141, 126));
+
+ QColor backGround(239, 235, 231);
+
+ QColor light = backGround.lighter(150);
+ QColor base = Qt::white;
+ QColor dark = QColor(170, 156, 143).darker(110);
+ dark = backGround.darker(150);
+ QColor darkDisabled = QColor(209, 200, 191).darker(110);
+
+ //### Find the correct disabled text color
+ palette.setBrush(QPalette::Disabled, QPalette::Text, QColor(190, 190, 190));
+
+ palette.setBrush(QPalette::Window, backGround);
+ palette.setBrush(QPalette::Mid, backGround.darker(130));
+ palette.setBrush(QPalette::Light, light);
+
+ palette.setBrush(QPalette::Active, QPalette::Base, base);
+ palette.setBrush(QPalette::Inactive, QPalette::Base, base);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, backGround);
+
+ palette.setBrush(QPalette::Midlight, palette.mid().color().lighter(110));
+
+ palette.setBrush(QPalette::All, QPalette::Dark, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
+
+ QColor button = backGround;
+
+ palette.setBrush(QPalette::Button, button);
+
+ QColor shadow = dark.darker(135);
+ palette.setBrush(QPalette::Shadow, shadow);
+ palette.setBrush(QPalette::Disabled, QPalette::Shadow, shadow.lighter(150));
+ palette.setBrush(QPalette::HighlightedText, QColor(QRgb(0xffffffff)));
+ return palette;
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QColor button = option->palette.button().color();
+ QColor dark;
+ QColor grooveColor;
+ QColor darkOutline;
+ dark.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
+ grooveColor.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*2.6)),
+ qMin(255, (int)(button.value()*0.9)));
+ darkOutline.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*3.0)),
+ qMin(255, (int)(button.value()*0.6)));
+
+ QColor alphaCornerColor;
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), darkOutline);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), darkOutline);
+ }
+ QColor gripShadow = grooveColor.darker(110);
+ QColor buttonShadow = option->palette.button().color().darker(110);
+
+ QColor gradientStartColor = option->palette.button().color().lighter(108);
+ QColor gradientStopColor = mergedColors(option->palette.button().color().darker(108), dark.lighter(150), 70);
+
+ QPalette palette = option->palette;
+
+ switch (control) {
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QPixmap cache;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("spinbox"), spinBox, spinBox->rect.size());
+ if (!QPixmapCache::find(pixmapName, cache)) {
+ cache = QPixmap(spinBox->rect.size());
+ cache.fill(Qt::transparent);
+ QRect pixmapRect(0, 0, spinBox->rect.width(), spinBox->rect.height());
+ QPainter cachePainter(&cache);
+
+ bool isEnabled = (spinBox->state & State_Enabled);
+ //bool focus = isEnabled && (spinBox->state & State_HasFocus);
+ bool hover = isEnabled && (spinBox->state & State_MouseOver);
+ bool sunken = (spinBox->state & State_Sunken);
+ bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
+ bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
+
+ QRect rect = pixmapRect;
+ QStyleOptionSpinBox spinBoxCopy = *spinBox;
+ spinBoxCopy.rect = pixmapRect;
+ QRect upRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxUp, widget);
+ QRect downRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxDown, widget);
+
+ int fw = spinBoxCopy.frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, &spinBoxCopy, widget) : 0;
+ cachePainter.fillRect(rect.adjusted(1, qMax(fw - 1, 0), -1, -fw),
+ option->palette.base());
+
+ QRect r = rect.adjusted(0, 1, 0, -1);
+ if (spinBox->frame) {
+
+ QColor topShadow = darkOutline;
+ topShadow.setAlpha(60);
+ cachePainter.setPen(topShadow);
+
+ // antialias corners
+ const QPoint points[8] = {
+ QPoint(r.right(), r.top() + 1),
+ QPoint(r.right() - 1, r.top() ),
+ QPoint(r.right(), r.bottom() - 1),
+ QPoint(r.right() - 1, r.bottom() ),
+ QPoint(r.left() + 1, r.bottom()),
+ QPoint(r.left(), r.bottom() - 1),
+ QPoint(r.left() + 1, r.top()),
+ QPoint(r.left(), r.top() + 1)
+ };
+ cachePainter.drawPoints(points, 8);
+
+ // draw frame
+ topShadow.setAlpha(30);
+ cachePainter.setPen(topShadow);
+ cachePainter.drawLine(QPoint(r.left() + 2, r.top() - 1), QPoint(r.right() - 2, r.top() - 1));
+
+ cachePainter.setPen(QPen(option->palette.background().color(), 1));
+ cachePainter.drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
+ QColor highlight = Qt::white;
+ highlight.setAlpha(130);
+ cachePainter.setPen(option->palette.base().color().darker(120));
+ cachePainter.drawLine(QPoint(r.left() + 1, r.top() + 1),
+ QPoint(r.right() - 1, r.top() + 1));
+ cachePainter.drawLine(QPoint(r.left() + 1, r.top() + 1),
+ QPoint(r.left() + 1, r.bottom() - 1));
+ cachePainter.setPen(option->palette.base().color());
+ cachePainter.drawLine(QPoint(r.right() - 1, r.top() + 1),
+ QPoint(r.right() - 1, r.bottom() - 1));
+ cachePainter.drawLine(QPoint(r.left() + 1, r.bottom() - 1),
+ QPoint(r.right() - 1, r.bottom() - 1));
+ cachePainter.setPen(highlight);
+ cachePainter.drawLine(QPoint(r.left() + 3, r.bottom() + 1),
+ QPoint(r.right() - 3, r.bottom() + 1));
+
+ cachePainter.setPen(QPen(darkOutline, 1));
+
+ // top and bottom lines
+ const QLine lines[4] = {
+ QLine(QPoint(r.left() + 2, r.bottom()), QPoint(r.right()- 2, r.bottom())),
+ QLine(QPoint(r.left() + 2, r.top()), QPoint(r.right() - 2, r.top())),
+ QLine(QPoint(r.right(), r.top() + 2), QPoint(r.right(), r.bottom() - 2)),
+ QLine(QPoint(r.left(), r.top() + 2), QPoint(r.left(), r.bottom() - 2))
+ };
+ cachePainter.drawLines(lines, 4);
+ }
+
+ // gradients
+ qt_cleanlooks_draw_gradient(&cachePainter, upRect,
+ gradientStartColor.darker(106),
+ gradientStopColor, TopDown, option->palette.button());
+ qt_cleanlooks_draw_gradient(&cachePainter, downRect.adjusted(0, 0, 0, 1),
+ gradientStartColor.darker(106),
+ gradientStopColor, TopDown, option->palette.button());
+ if (isEnabled) {
+ if(upIsActive) {
+ if (sunken) {
+ cachePainter.fillRect(upRect.adjusted(1, 0, 0, 0), gradientStopColor.darker(110));
+ } else if (hover) {
+ qt_cleanlooks_draw_gradient(&cachePainter, upRect.adjusted(1, 0, 0, 0),
+ gradientStartColor.lighter(110),
+ gradientStopColor.lighter(110), TopDown, option->palette.button());
+ }
+ }
+ if(downIsActive) {
+ if (sunken) {
+ cachePainter.fillRect(downRect.adjusted(1, 0, 0, 1), gradientStopColor.darker(110));
+
+ } else if (hover) {
+ qt_cleanlooks_draw_gradient(&cachePainter, downRect.adjusted(1, 0, 0, 1),
+ gradientStartColor.lighter(110),
+ gradientStopColor.lighter(110), TopDown, option->palette.button());
+ }
+ }
+ }
+
+ if (spinBox->frame) {
+ // rounded corners
+ const QPoint points[4] = {
+ QPoint(r.left() + 1, r.bottom() - 1),
+ QPoint(r.left() + 1, r.top() + 1),
+ QPoint(r.right() - 1, r.bottom() - 1),
+ QPoint(r.right() - 1, r.top() + 1)
+ };
+ cachePainter.drawPoints(points, 4);
+
+ if (option->state & State_HasFocus) {
+ QColor darkoutline = option->palette.highlight().color().darker(150);
+ QColor innerline = mergedColors(option->palette.highlight().color(), Qt::white);
+ cachePainter.setPen(QPen(innerline, 0));
+ if (spinBox->direction == Qt::LeftToRight) {
+ cachePainter.drawRect(rect.adjusted(1, 2, -3 -downRect.width(), -3));
+ cachePainter.setPen(QPen(darkoutline, 0));
+ const QLine lines[4] = {
+ QLine(QPoint(r.left() + 2, r.bottom()), QPoint(r.right()- downRect.width() - 1, r.bottom())),
+ QLine(QPoint(r.left() + 2, r.top()), QPoint(r.right() - downRect.width() - 1, r.top())),
+ QLine(QPoint(r.right() - downRect.width() - 1, r.top() + 1), QPoint(r.right()- downRect.width() - 1, r.bottom() - 1)),
+ QLine(QPoint(r.left(), r.top() + 2), QPoint(r.left(), r.bottom() - 2))
+ };
+ cachePainter.drawLines(lines, 4);
+ cachePainter.drawPoint(QPoint(r.left() + 1, r.bottom() - 1));
+ cachePainter.drawPoint(QPoint(r.left() + 1, r.top() + 1));
+ cachePainter.drawLine(QPoint(r.left(), r.top() + 2), QPoint(r.left(), r.bottom() - 2));
+ } else {
+ cachePainter.drawRect(rect.adjusted(downRect.width() + 2, 2, -2, -3));
+ cachePainter.setPen(QPen(darkoutline, 0));
+ cachePainter.drawLine(QPoint(r.left() + downRect.width(), r.bottom()), QPoint(r.right()- 2 - 1, r.bottom()));
+ cachePainter.drawLine(QPoint(r.left() + downRect.width(), r.top()), QPoint(r.right() - 2 - 1, r.top()));
+
+ cachePainter.drawLine(QPoint(r.right(), r.top() + 2), QPoint(r.right(), r.bottom() - 2));
+ cachePainter.drawPoint(QPoint(r.right() - 1, r.bottom() - 1));
+ cachePainter.drawPoint(QPoint(r.right() - 1, r.top() + 1));
+ cachePainter.drawLine(QPoint(r.left() + downRect.width() + 1, r.top()),
+ QPoint(r.left() + downRect.width() + 1, r.bottom()));
+ }
+ }
+ }
+
+ // outline the up/down buttons
+ cachePainter.setPen(darkOutline);
+ QColor light = option->palette.light().color().lighter();
+
+ if (spinBox->direction == Qt::RightToLeft) {
+ cachePainter.drawLine(upRect.right(), upRect.top() - 1, upRect.right(), downRect.bottom() + 1);
+ cachePainter.setPen(light);
+ cachePainter.drawLine(upRect.right() - 1, upRect.top() + 3, upRect.right() - 1, downRect.bottom() );
+ } else {
+ cachePainter.drawLine(upRect.left(), upRect.top() - 1, upRect.left(), downRect.bottom() + 1);
+ cachePainter.setPen(light);
+ cachePainter.drawLine(upRect.left() + 1, upRect.top() , upRect.left() + 1, downRect.bottom() );
+ }
+ if (upIsActive && sunken) {
+ cachePainter.setPen(gradientStopColor.darker(130));
+ cachePainter.drawLine(upRect.left() + 1, upRect.top(), upRect.left() + 1, upRect.bottom());
+ cachePainter.drawLine(upRect.left(), upRect.top() - 1, upRect.right(), upRect.top() - 1);
+ } else {
+ cachePainter.setPen(light);
+ cachePainter.drawLine(upRect.topLeft() + QPoint(1, -1), upRect.topRight() + QPoint(-1, -1));
+ cachePainter.setPen(darkOutline);
+ cachePainter.drawLine(upRect.bottomLeft(), upRect.bottomRight());
+ }
+ if (downIsActive && sunken) {
+ cachePainter.setPen(gradientStopColor.darker(130));
+ cachePainter.drawLine(downRect.left() + 1, downRect.top(), downRect.left() + 1, downRect.bottom() + 1);
+ cachePainter.drawLine(downRect.left(), downRect.top(), downRect.right(), downRect.top());
+ cachePainter.setPen(gradientStopColor.darker(110));
+ cachePainter.drawLine(downRect.left(), downRect.bottom() + 1, downRect.right(), downRect.bottom() + 1);
+ } else {
+ cachePainter.setPen(light);
+ cachePainter.drawLine(downRect.topLeft() + QPoint(2,0), downRect.topRight());
+ }
+
+ if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
+ int centerX = upRect.center().x();
+ int centerY = upRect.center().y();
+ cachePainter.setPen(spinBox->palette.foreground().color());
+
+ // plus/minus
+ if (spinBox->activeSubControls == SC_SpinBoxUp && sunken) {
+ cachePainter.drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
+ cachePainter.drawLine(1 + centerX, 1 + centerY - 2, 1 + centerX, 1 + centerY + 2);
+ } else {
+ cachePainter.drawLine(centerX - 2, centerY, centerX + 2, centerY);
+ cachePainter.drawLine(centerX, centerY - 2, centerX, centerY + 2);
+ }
+
+ centerX = downRect.center().x();
+ centerY = downRect.center().y();
+ if (spinBox->activeSubControls == SC_SpinBoxDown && sunken) {
+ cachePainter.drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
+ } else {
+ cachePainter.drawLine(centerX - 2, centerY, centerX + 2, centerY);
+ }
+ } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows){
+ // arrows
+ QImage upArrow(qt_spinbox_button_arrow_up);
+ upArrow.setColor(1, spinBox->palette.foreground().color().rgba());
+
+ cachePainter.drawImage(upRect.center().x() - upArrow.width() / 2,
+ upRect.center().y() - upArrow.height() / 2,
+ upArrow);
+
+ QImage downArrow(qt_spinbox_button_arrow_down);
+ downArrow.setColor(1, spinBox->palette.foreground().color().rgba());
+
+ cachePainter.drawImage(downRect.center().x() - downArrow.width() / 2,
+ downRect.center().y() - downArrow.height() / 2 + 1,
+ downArrow);
+ }
+
+ QColor disabledColor = option->palette.background().color();
+ disabledColor.setAlpha(150);
+ if (!(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled))
+ cachePainter.fillRect(upRect.adjusted(1, 0, 0, 0), disabledColor);
+ if (!(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ cachePainter.fillRect(downRect.adjusted(1, 0, 0, 0), disabledColor);
+ }
+ cachePainter.end();
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ painter->drawPixmap(spinBox->rect.topLeft(), cache);
+ }
+ break;
+#endif // QT_NO_SPINBOX
+ case CC_TitleBar:
+ painter->save();
+ if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ const int buttonMargin = 5;
+ bool active = (titleBar->titleBarState & State_Active);
+ QRect fullRect = titleBar->rect;
+ QPalette palette = option->palette;
+ QColor highlight = option->palette.highlight().color();
+
+ QColor titleBarFrameBorder(active ? highlight.darker(180): dark.darker(110));
+ QColor titleBarHighlight(active ? highlight.lighter(120): palette.background().color().lighter(120));
+ QColor textColor(active ? 0xffffff : 0xff000000);
+ QColor textAlphaColor(active ? 0xffffff : 0xff000000 );
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ QStyleOptionDockWidgetV2 dockwidget;
+ dockwidget.QStyleOption::operator=(*option);
+ proxy()->drawControl(CE_DockWidgetTitle, &dockwidget, painter, widget);
+ } else
+#endif // QT3_SUPPORT
+ {
+ // Fill title bar gradient
+ QColor titlebarColor = QColor(active ? highlight: palette.background().color());
+ QLinearGradient gradient(option->rect.center().x(), option->rect.top(),
+ option->rect.center().x(), option->rect.bottom());
+
+ gradient.setColorAt(0, titlebarColor.lighter(114));
+ gradient.setColorAt(0.5, titlebarColor.lighter(102));
+ gradient.setColorAt(0.51, titlebarColor.darker(104));
+ gradient.setColorAt(1, titlebarColor);
+ painter->fillRect(option->rect.adjusted(1, 1, -1, 0), gradient);
+
+ // Frame and rounded corners
+ painter->setPen(titleBarFrameBorder);
+
+ // top outline
+ painter->drawLine(fullRect.left() + 5, fullRect.top(), fullRect.right() - 5, fullRect.top());
+ painter->drawLine(fullRect.left(), fullRect.top() + 4, fullRect.left(), fullRect.bottom());
+ const QPoint points[5] = {
+ QPoint(fullRect.left() + 4, fullRect.top() + 1),
+ QPoint(fullRect.left() + 3, fullRect.top() + 1),
+ QPoint(fullRect.left() + 2, fullRect.top() + 2),
+ QPoint(fullRect.left() + 1, fullRect.top() + 3),
+ QPoint(fullRect.left() + 1, fullRect.top() + 4)
+ };
+ painter->drawPoints(points, 5);
+
+ painter->drawLine(fullRect.right(), fullRect.top() + 4, fullRect.right(), fullRect.bottom());
+ const QPoint points2[5] = {
+ QPoint(fullRect.right() - 3, fullRect.top() + 1),
+ QPoint(fullRect.right() - 4, fullRect.top() + 1),
+ QPoint(fullRect.right() - 2, fullRect.top() + 2),
+ QPoint(fullRect.right() - 1, fullRect.top() + 3),
+ QPoint(fullRect.right() - 1, fullRect.top() + 4)
+ };
+ painter->drawPoints(points2, 5);
+
+ // draw bottomline
+ painter->drawLine(fullRect.right(), fullRect.bottom(), fullRect.left(), fullRect.bottom());
+
+ // top highlight
+ painter->setPen(titleBarHighlight);
+ painter->drawLine(fullRect.left() + 6, fullRect.top() + 1, fullRect.right() - 6, fullRect.top() + 1);
+ }
+ // draw title
+ QRect textRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget);
+ QFont font = painter->font();
+ font.setBold(true);
+ painter->setFont(font);
+ painter->setPen(active? (titleBar->palette.text().color().lighter(120)) :
+ titleBar->palette.text().color() );
+ // Note workspace also does elliding but it does not use the correct font
+ QString title = QFontMetrics(font).elidedText(titleBar->text, Qt::ElideRight, textRect.width() - 14);
+ painter->drawText(textRect.adjusted(1, 1, 1, 1), title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
+ painter->setPen(Qt::white);
+ if (active)
+ painter->drawText(textRect, title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
+ // min button
+ if ((titleBar->subControls & SC_TitleBarMinButton) && (titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
+ !(titleBar->titleBarState& Qt::WindowMinimized)) {
+ QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMinButton, widget);
+ if (minButtonRect.isValid()) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_Sunken);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, minButtonRect, hover, sunken);
+ QRect minButtonIconRect = minButtonRect.adjusted(buttonMargin ,buttonMargin , -buttonMargin, -buttonMargin);
+ painter->setPen(textColor);
+ painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 3,
+ minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 3);
+ painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 4,
+ minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 4);
+ painter->setPen(textAlphaColor);
+ painter->drawLine(minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 3,
+ minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 4);
+ painter->drawLine(minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 3,
+ minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 4);
+ }
+ }
+ // max button
+ if ((titleBar->subControls & SC_TitleBarMaxButton) && (titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
+ !(titleBar->titleBarState & Qt::WindowMaximized)) {
+ QRect maxButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMaxButton, widget);
+ if (maxButtonRect.isValid()) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_Sunken);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, maxButtonRect, hover, sunken);
+
+ QRect maxButtonIconRect = maxButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
+
+ painter->setPen(textColor);
+ painter->drawRect(maxButtonIconRect.adjusted(0, 0, -1, -1));
+ painter->drawLine(maxButtonIconRect.left() + 1, maxButtonIconRect.top() + 1,
+ maxButtonIconRect.right() - 1, maxButtonIconRect.top() + 1);
+ painter->setPen(textAlphaColor);
+ const QPoint points[4] = {
+ maxButtonIconRect.topLeft(),
+ maxButtonIconRect.topRight(),
+ maxButtonIconRect.bottomLeft(),
+ maxButtonIconRect.bottomRight()
+ };
+ painter->drawPoints(points, 4);
+ }
+ }
+
+ // close button
+ if ((titleBar->subControls & SC_TitleBarCloseButton) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
+ QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarCloseButton, widget);
+ if (closeButtonRect.isValid()) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_Sunken);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, closeButtonRect, hover, sunken);
+ QRect closeIconRect = closeButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
+ painter->setPen(textAlphaColor);
+ const QLine lines[4] = {
+ QLine(closeIconRect.left() + 1, closeIconRect.top(),
+ closeIconRect.right(), closeIconRect.bottom() - 1),
+ QLine(closeIconRect.left(), closeIconRect.top() + 1,
+ closeIconRect.right() - 1, closeIconRect.bottom()),
+ QLine(closeIconRect.right() - 1, closeIconRect.top(),
+ closeIconRect.left(), closeIconRect.bottom() - 1),
+ QLine(closeIconRect.right(), closeIconRect.top() + 1,
+ closeIconRect.left() + 1, closeIconRect.bottom())
+ };
+ painter->drawLines(lines, 4);
+ const QPoint points[4] = {
+ closeIconRect.topLeft(),
+ closeIconRect.topRight(),
+ closeIconRect.bottomLeft(),
+ closeIconRect.bottomRight()
+ };
+ painter->drawPoints(points, 4);
+
+ painter->setPen(textColor);
+ painter->drawLine(closeIconRect.left() + 1, closeIconRect.top() + 1,
+ closeIconRect.right() - 1, closeIconRect.bottom() - 1);
+ painter->drawLine(closeIconRect.left() + 1, closeIconRect.bottom() - 1,
+ closeIconRect.right() - 1, closeIconRect.top() + 1);
+ }
+ }
+
+ // normalize button
+ if ((titleBar->subControls & SC_TitleBarNormalButton) &&
+ (((titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
+ (titleBar->titleBarState & Qt::WindowMinimized)) ||
+ ((titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
+ (titleBar->titleBarState & Qt::WindowMaximized)))) {
+ QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarNormalButton, widget);
+ if (normalButtonRect.isValid()) {
+
+ bool hover = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_Sunken);
+ QRect normalButtonIconRect = normalButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, normalButtonRect, hover, sunken);
+
+ QRect frontWindowRect = normalButtonIconRect.adjusted(0, 3, -3, 0);
+ painter->setPen(textColor);
+ painter->drawRect(frontWindowRect.adjusted(0, 0, -1, -1));
+ painter->drawLine(frontWindowRect.left() + 1, frontWindowRect.top() + 1,
+ frontWindowRect.right() - 1, frontWindowRect.top() + 1);
+ painter->setPen(textAlphaColor);
+ const QPoint points[4] = {
+ frontWindowRect.topLeft(),
+ frontWindowRect.topRight(),
+ frontWindowRect.bottomLeft(),
+ frontWindowRect.bottomRight()
+ };
+ painter->drawPoints(points, 4);
+
+ QRect backWindowRect = normalButtonIconRect.adjusted(3, 0, 0, -3);
+ QRegion clipRegion = backWindowRect;
+ clipRegion -= frontWindowRect;
+ painter->save();
+ painter->setClipRegion(clipRegion);
+ painter->setPen(textColor);
+ painter->drawRect(backWindowRect.adjusted(0, 0, -1, -1));
+ painter->drawLine(backWindowRect.left() + 1, backWindowRect.top() + 1,
+ backWindowRect.right() - 1, backWindowRect.top() + 1);
+ painter->setPen(textAlphaColor);
+ const QPoint points2[4] = {
+ backWindowRect.topLeft(),
+ backWindowRect.topRight(),
+ backWindowRect.bottomLeft(),
+ backWindowRect.bottomRight()
+ };
+ painter->drawPoints(points2, 4);
+ painter->restore();
+ }
+ }
+
+ // context help button
+ if (titleBar->subControls & SC_TitleBarContextHelpButton
+ && (titleBar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
+ QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarContextHelpButton, widget);
+ if (contextHelpButtonRect.isValid()) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken);
+
+ QColor blend;
+ QImage image(qt_titlebar_context_help);
+ QColor alpha = textColor;
+ alpha.setAlpha(128);
+ image.setColor(1, textColor.rgba());
+ image.setColor(2, alpha.rgba());
+ painter->setRenderHint(QPainter::SmoothPixmapTransform);
+ painter->drawImage(contextHelpButtonRect.adjusted(4, 4, -4, -4), image);
+ }
+ }
+
+ // shade button
+ if (titleBar->subControls & SC_TitleBarShadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
+ QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarShadeButton, widget);
+ if (shadeButtonRect.isValid()) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
+ QImage image(qt_scrollbar_button_arrow_up);
+ image.setColor(1, textColor.rgba());
+ painter->drawImage(shadeButtonRect.adjusted(5, 7, -5, -7), image);
+ }
+ }
+
+ // unshade button
+ if (titleBar->subControls & SC_TitleBarUnshadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
+ QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarUnshadeButton, widget);
+ if (unshadeButtonRect.isValid()) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
+ qt_cleanlooks_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
+ QImage image(qt_scrollbar_button_arrow_down);
+ image.setColor(1, textColor.rgba());
+ painter->drawImage(unshadeButtonRect.adjusted(5, 7, -5, -7), image);
+ }
+ }
+
+ if ((titleBar->subControls & SC_TitleBarSysMenu) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
+ QRect iconRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget);
+ if (iconRect.isValid()) {
+ if (!titleBar->icon.isNull()) {
+ titleBar->icon.paint(painter, iconRect);
+ } else {
+ QStyleOption tool(0);
+ tool.palette = titleBar->palette;
+ QPixmap pm = standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16);
+ tool.rect = iconRect;
+ painter->save();
+ proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
+ painter->restore();
+ }
+ }
+ }
+ }
+ painter->restore();
+ break;
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ painter->save();
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ bool isEnabled = scrollBar->state & State_Enabled;
+ bool reverse = scrollBar->direction == Qt::RightToLeft;
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+ bool sunken = scrollBar->state & State_Sunken;
+
+ painter->fillRect(option->rect, option->palette.background());
+
+ QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
+ QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
+ QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
+ QRect grooveRect = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
+
+ // paint groove
+ if (scrollBar->subControls & SC_ScrollBarGroove) {
+ painter->setBrush(grooveColor);
+ painter->setPen(Qt::NoPen);
+ if (horizontal) {
+ painter->drawRect(grooveRect);
+ painter->setPen(darkOutline);
+ painter->drawLine(grooveRect.topLeft(), grooveRect.topRight());
+ painter->drawLine(grooveRect.bottomLeft(), grooveRect.bottomRight());
+ } else {
+ painter->drawRect(grooveRect);
+ painter->setPen(darkOutline);
+ painter->drawLine(grooveRect.topLeft(), grooveRect.bottomLeft());
+ painter->drawLine(grooveRect.topRight(), grooveRect.bottomRight());
+ }
+ }
+ //paint slider
+ if (scrollBar->subControls & SC_ScrollBarSlider) {
+ QRect pixmapRect = scrollBarSlider;
+ if (horizontal)
+ pixmapRect.adjust(-1, 0, 0, -1);
+ else
+ pixmapRect.adjust(0, -1, -1, 0);
+
+ if (isEnabled) {
+ QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
+ pixmapRect.center().x(), pixmapRect.bottom());
+ if (!horizontal)
+ gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(),
+ pixmapRect.right(), pixmapRect.center().y());
+
+ if (option->palette.button().gradient()) {
+ gradient.setStops(option->palette.button().gradient()->stops());
+ } else {
+ if (sunken || (option->state & State_MouseOver &&
+ (scrollBar->activeSubControls & SC_ScrollBarSlider))) {
+ gradient.setColorAt(0, gradientStartColor.lighter(110));
+ gradient.setColorAt(1, gradientStopColor.lighter(110));
+ } else {
+ gradient.setColorAt(0, gradientStartColor);
+ gradient.setColorAt(1, gradientStopColor);
+ }
+ }
+ painter->setPen(QPen(darkOutline, 0));
+ painter->setBrush(gradient);
+ painter->drawRect(pixmapRect);
+
+
+ //calculate offsets used by highlight and shadow
+ int yoffset, xoffset;
+ if (option->state & State_Horizontal) {
+ xoffset = 0;
+ yoffset = 1;
+ } else {
+ xoffset = 1;
+ yoffset = 0;
+ }
+ //draw slider highlights
+ painter->setPen(QPen(gradientStopColor, 0));
+ painter->drawLine(scrollBarSlider.left() + xoffset,
+ scrollBarSlider.bottom() - yoffset,
+ scrollBarSlider.right() - xoffset,
+ scrollBarSlider.bottom() - yoffset);
+ painter->drawLine(scrollBarSlider.right() - xoffset,
+ scrollBarSlider.top() + yoffset,
+ scrollBarSlider.right() - xoffset,
+ scrollBarSlider.bottom() - yoffset);
+
+ //draw slider shadow
+ painter->setPen(QPen(gradientStartColor, 0));
+ painter->drawLine(scrollBarSlider.left() + xoffset,
+ scrollBarSlider.top() + yoffset,
+ scrollBarSlider.right() - xoffset,
+ scrollBarSlider.top() + yoffset);
+ painter->drawLine(scrollBarSlider.left() + xoffset,
+ scrollBarSlider.top() + yoffset,
+ scrollBarSlider.left() + xoffset,
+ scrollBarSlider.bottom() - yoffset);
+ } else {
+ QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
+ pixmapRect.center().x(), pixmapRect.bottom());
+ if (!horizontal) {
+ gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(),
+ pixmapRect.right(), pixmapRect.center().y());
+ }
+ if (sunken) {
+ gradient.setColorAt(0, gradientStartColor.lighter(110));
+ gradient.setColorAt(1, gradientStopColor.lighter(110));
+ } else {
+ gradient.setColorAt(0, gradientStartColor);
+ gradient.setColorAt(1, gradientStopColor);
+ }
+ painter->setPen(darkOutline);
+ painter->setBrush(gradient);
+ painter->drawRect(pixmapRect);
+ }
+ int gripMargin = 4;
+ //draw grips
+ if (horizontal) {
+ for (int i = -3; i< 6 ; i += 3) {
+ painter->setPen(QPen(gripShadow, 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.center().x() + i ,
+ scrollBarSlider.top() + gripMargin),
+ QPoint(scrollBarSlider.center().x() + i,
+ scrollBarSlider.bottom() - gripMargin));
+ painter->setPen(QPen(palette.light(), 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.center().x() + i + 1,
+ scrollBarSlider.top() + gripMargin ),
+ QPoint(scrollBarSlider.center().x() + i + 1,
+ scrollBarSlider.bottom() - gripMargin));
+ }
+ } else {
+ for (int i = -3; i < 6 ; i += 3) {
+ painter->setPen(QPen(gripShadow, 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.left() + gripMargin ,
+ scrollBarSlider.center().y()+ i),
+ QPoint(scrollBarSlider.right() - gripMargin,
+ scrollBarSlider.center().y()+ i));
+ painter->setPen(QPen(palette.light(), 1));
+ painter->drawLine(
+ QPoint(scrollBarSlider.left() + gripMargin,
+ scrollBarSlider.center().y() + 1 + i),
+ QPoint(scrollBarSlider.right() - gripMargin,
+ scrollBarSlider.center().y() + 1 + i));
+ }
+ }
+ }
+
+ // The SubLine (up/left) buttons
+ if (scrollBar->subControls & SC_ScrollBarSubLine) {
+ //int scrollBarExtent = proxy()->pixelMetric(PM_ScrollBarExtent, option, widget);
+ QRect pixmapRect = scrollBarSubLine;
+ if (isEnabled ) {
+ QRect fillRect = pixmapRect.adjusted(1, 1, -1, -1);
+ // Gradients
+ if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken) {
+ qt_cleanlooks_draw_gradient(painter,
+ QRect(fillRect),
+ gradientStopColor.darker(120),
+ gradientStopColor.darker(120),
+ horizontal ? TopDown : FromLeft, option->palette.button());
+ } else {
+ qt_cleanlooks_draw_gradient(painter,
+ QRect(fillRect),
+ gradientStartColor.lighter(105),
+ gradientStopColor,
+ horizontal ? TopDown : FromLeft, option->palette.button());
+ }
+ }
+ // Details
+ QImage subButton;
+ if (horizontal) {
+ subButton = QImage(reverse ? qt_scrollbar_button_right : qt_scrollbar_button_left);
+ } else {
+ subButton = QImage(qt_scrollbar_button_up);
+ }
+ subButton.setColor(1, alphaCornerColor.rgba());
+ subButton.setColor(2, darkOutline.rgba());
+ if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken) {
+ subButton.setColor(3, gradientStopColor.darker(140).rgba());
+ subButton.setColor(4, gradientStopColor.darker(120).rgba());
+ } else {
+ subButton.setColor(3, gradientStartColor.lighter(105).rgba());
+ subButton.setColor(4, gradientStopColor.rgba());
+ }
+ subButton.setColor(5, scrollBar->palette.text().color().rgba());
+ painter->drawImage(pixmapRect, subButton);
+
+ // Arrows
+ PrimitiveElement arrow;
+ if (option->state & State_Horizontal)
+ arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft: PE_IndicatorArrowRight;
+ else
+ arrow = PE_IndicatorArrowUp;
+ QStyleOption arrowOpt = *option;
+ arrowOpt.rect = scrollBarSubLine.adjusted(3, 3, -2, -2);
+ proxy()->drawPrimitive(arrow, &arrowOpt, painter, widget);
+
+
+ // The AddLine (down/right) button
+ if (scrollBar->subControls & SC_ScrollBarAddLine) {
+ QString addLinePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_addline"), option, QSize(16, 16));
+ QRect pixmapRect = scrollBarAddLine;
+ if (isEnabled) {
+ QRect fillRect = pixmapRect.adjusted(1, 1, -1, -1);
+ // Gradients
+ if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken) {
+ qt_cleanlooks_draw_gradient(painter,
+ fillRect,
+ gradientStopColor.darker(120),
+ gradientStopColor.darker(120),
+ horizontal ? TopDown: FromLeft, option->palette.button());
+ } else {
+ qt_cleanlooks_draw_gradient(painter,
+ fillRect,
+ gradientStartColor.lighter(105),
+ gradientStopColor,
+ horizontal ? TopDown : FromLeft, option->palette.button());
+ }
+ }
+ // Details
+ QImage addButton;
+ if (horizontal) {
+ addButton = QImage(reverse ? qt_scrollbar_button_left : qt_scrollbar_button_right);
+ } else {
+ addButton = QImage(qt_scrollbar_button_down);
+ }
+ addButton.setColor(1, alphaCornerColor.rgba());
+ addButton.setColor(2, darkOutline.rgba());
+ if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken) {
+ addButton.setColor(3, gradientStopColor.darker(140).rgba());
+ addButton.setColor(4, gradientStopColor.darker(120).rgba());
+ } else {
+ addButton.setColor(3, gradientStartColor.lighter(105).rgba());
+ addButton.setColor(4, gradientStopColor.rgba());
+ }
+ addButton.setColor(5, scrollBar->palette.text().color().rgba());
+ painter->drawImage(pixmapRect, addButton);
+
+ PrimitiveElement arrow;
+ if (option->state & State_Horizontal)
+ arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
+ else
+ arrow = PE_IndicatorArrowDown;
+
+ QStyleOption arrowOpt = *option;
+ arrowOpt.rect = scrollBarAddLine.adjusted(3, 3, -2, -2);
+ proxy()->drawPrimitive(arrow, &arrowOpt, painter, widget);
+ }
+ }
+ }
+ painter->restore();
+ break;;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ painter->save();
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
+ bool isEnabled = (comboBox->state & State_Enabled);
+ bool focus = isEnabled && (comboBox->state & State_HasFocus);
+ QPixmap cache;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("combobox"), option, comboBox->rect.size());
+ if (sunken)
+ pixmapName += QLatin1String("-sunken");
+ if (comboBox->editable)
+ pixmapName += QLatin1String("-editable");
+ if (isEnabled)
+ pixmapName += QLatin1String("-enabled");
+
+ if (!QPixmapCache::find(pixmapName, cache)) {
+ cache = QPixmap(comboBox->rect.size());
+ cache.fill(Qt::transparent);
+ QPainter cachePainter(&cache);
+ QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height());
+ QStyleOptionComboBox comboBoxCopy = *comboBox;
+ comboBoxCopy.rect = pixmapRect;
+
+ QRect rect = pixmapRect;
+ QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
+ SC_ComboBoxArrow, widget);
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
+ SC_ComboBoxEditField, widget);
+ // Draw a push button
+ if (comboBox->editable) {
+ QStyleOptionFrame buttonOption;
+ buttonOption.QStyleOption::operator=(*comboBox);
+ buttonOption.rect = rect;
+ buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver);
+
+ if (sunken) {
+ buttonOption.state |= State_Sunken;
+ buttonOption.state &= ~State_MouseOver;
+ }
+
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
+
+ //remove shadow from left side of edit field when pressed:
+ if (comboBox->direction != Qt::RightToLeft)
+ cachePainter.fillRect(editRect.left() - 1, editRect.top() + 1, editRect.left(),
+ editRect.bottom() - 3, option->palette.base());
+
+ cachePainter.setPen(dark.lighter(110));
+ if (!sunken) {
+ int borderSize = 2;
+ if (comboBox->direction == Qt::RightToLeft) {
+ cachePainter.drawLine(QPoint(downArrowRect.right() - 1, downArrowRect.top() + borderSize ),
+ QPoint(downArrowRect.right() - 1, downArrowRect.bottom() - borderSize));
+ cachePainter.setPen(option->palette.light().color());
+ cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.right(), downArrowRect.bottom() - borderSize));
+ } else {
+ cachePainter.drawLine(QPoint(downArrowRect.left() , downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.left() , downArrowRect.bottom() - borderSize));
+ cachePainter.setPen(option->palette.light().color());
+ cachePainter.drawLine(QPoint(downArrowRect.left() + 1, downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.left() + 1, downArrowRect.bottom() - borderSize));
+ }
+ } else {
+ if (comboBox->direction == Qt::RightToLeft) {
+ cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + 2),
+ QPoint(downArrowRect.right(), downArrowRect.bottom() - 2));
+
+ } else {
+ cachePainter.drawLine(QPoint(downArrowRect.left(), downArrowRect.top() + 2),
+ QPoint(downArrowRect.left(), downArrowRect.bottom() - 2));
+ }
+ }
+ } else {
+ QStyleOptionButton buttonOption;
+ buttonOption.QStyleOption::operator=(*comboBox);
+ buttonOption.rect = rect;
+ buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver);
+ if (sunken) {
+ buttonOption.state |= State_Sunken;
+ buttonOption.state &= ~State_MouseOver;
+ }
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
+
+ cachePainter.setPen(buttonShadow.darker(102));
+ int borderSize = 4;
+
+ if (!sunken) {
+ if (comboBox->direction == Qt::RightToLeft) {
+ cachePainter.drawLine(QPoint(downArrowRect.right() + 1, downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.right() + 1, downArrowRect.bottom() - borderSize));
+ cachePainter.setPen(option->palette.light().color());
+ cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.right(), downArrowRect.bottom() - borderSize));
+ } else {
+ cachePainter.drawLine(QPoint(downArrowRect.left() - 1, downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.left() - 1, downArrowRect.bottom() - borderSize));
+ cachePainter.setPen(option->palette.light().color());
+ cachePainter.drawLine(QPoint(downArrowRect.left() , downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.left() , downArrowRect.bottom() - borderSize));
+ }
+ } else {
+ cachePainter.setPen(dark.lighter(110));
+ if (comboBox->direction == Qt::RightToLeft) {
+ cachePainter.drawLine(QPoint(downArrowRect.right() + 1, downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.right() + 1, downArrowRect.bottom() - borderSize));
+
+ } else {
+ cachePainter.drawLine(QPoint(downArrowRect.left() - 1, downArrowRect.top() + borderSize),
+ QPoint(downArrowRect.left() - 1, downArrowRect.bottom() - borderSize));
+ }
+ }
+ }
+
+
+ if (comboBox->subControls & SC_ComboBoxArrow) {
+ if (comboBox->editable) {
+ // Draw the down arrow
+ QImage downArrow(qt_cleanlooks_arrow_down_xpm);
+ downArrow.setColor(1, comboBox->palette.foreground().color().rgba());
+ cachePainter.drawImage(downArrowRect.center().x() - downArrow.width() / 2,
+ downArrowRect.center().y() - downArrow.height() / 2 + 1, downArrow);
+ } else {
+ // Draw the up/down arrow
+ QImage upArrow(qt_scrollbar_button_arrow_up);
+ upArrow.setColor(1, comboBox->palette.foreground().color().rgba());
+ QImage downArrow(qt_scrollbar_button_arrow_down);
+ downArrow.setColor(1, comboBox->palette.foreground().color().rgba());
+ cachePainter.drawImage(downArrowRect.center().x() - downArrow.width() / 2,
+ downArrowRect.center().y() - upArrow.height() - 1 , upArrow);
+ cachePainter.drawImage(downArrowRect.center().x() - downArrow.width() / 2,
+ downArrowRect.center().y() + 2, downArrow);
+ }
+ }
+ // Draw the focus rect
+ if (focus && !comboBox->editable
+ && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget))) {
+ QStyleOptionFocusRect focus;
+ focus.rect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy, SC_ComboBoxEditField, widget)
+ .adjusted(0, 2, option->direction == Qt::RightToLeft ? 1 : -1, -2);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, &cachePainter, widget);
+ }
+ cachePainter.end();
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ painter->drawPixmap(comboBox->rect.topLeft(), cache);
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ painter->save();
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ QRect textRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
+ QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxCheckBox, widget);
+ bool flat = groupBox->features & QStyleOptionFrameV2::Flat;
+
+ if(!flat) {
+ if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*groupBox);
+ frame.features = groupBox->features;
+ frame.lineWidth = groupBox->lineWidth;
+ frame.midLineWidth = groupBox->midLineWidth;
+ frame.rect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
+
+ painter->save();
+ QRegion region(groupBox->rect);
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ region -= checkBoxRect.united(textRect).adjusted(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
+ if (!groupBox->text.isEmpty() || groupBox->subControls & SC_GroupBoxCheckBox)
+ painter->setClipRegion(region);
+ frame.palette.setBrush(QPalette::Dark, option->palette.mid().color().lighter(110));
+ proxy()->drawPrimitive(PE_FrameGroupBox, &frame, painter);
+ painter->restore();
+ }
+ }
+ // Draw title
+ if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ if (!groupBox->text.isEmpty()) {
+ QColor textColor = groupBox->textColor;
+ if (textColor.isValid())
+ painter->setPen(textColor);
+ int alignment = int(groupBox->textAlignment);
+ if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+ alignment |= Qt::TextHideMnemonic;
+ if (flat) {
+ QFont font = painter->font();
+ font.setBold(true);
+ painter->setFont(font);
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ textRect.adjust(checkBoxRect.right() + 4, 0, checkBoxRect.right() + 4, 0);
+ }
+ }
+ painter->drawText(textRect, Qt::TextShowMnemonic | Qt::AlignLeft| alignment, groupBox->text);
+ }
+ }
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_GROUPBOX
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
+ bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
+ QColor activeHighlight = option->palette.color(QPalette::Normal, QPalette::Highlight);
+ QPixmap cache;
+
+ QBrush oldBrush = painter->brush();
+ QPen oldPen = painter->pen();
+
+ QColor shadowAlpha(Qt::black);
+ shadowAlpha.setAlpha(10);
+ QColor highlightAlpha(Qt::white);
+ highlightAlpha.setAlpha(80);
+
+ if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
+ QString groovePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_groove"), option, groove.size());
+ QRect pixmapRect(0, 0, groove.width(), groove.height());
+
+ // draw background groove
+ if (!QPixmapCache::find(groovePixmapName, cache)) {
+ cache = QPixmap(pixmapRect.size());
+ cache.fill(Qt::transparent);
+ QPainter groovePainter(&cache);
+
+ groovePainter.setPen(shadowAlpha);
+ groovePainter.drawLine(1, 0, groove.width(), 0);
+ groovePainter.drawLine(0, 0, 0, groove.height() - 1);
+
+ groovePainter.setPen(highlightAlpha);
+ groovePainter.drawLine(1, groove.height() - 1, groove.width() - 1, groove.height() - 1);
+ groovePainter.drawLine(groove.width() - 1, 1, groove.width() - 1, groove.height() - 1);
+ QLinearGradient gradient;
+ if (horizontal) {
+ gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
+ gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
+ }
+ else {
+ gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
+ gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
+ }
+ groovePainter.setPen(QPen(darkOutline.darker(110), 0));
+ gradient.setColorAt(0, grooveColor.darker(110));//dark.lighter(120));
+ gradient.setColorAt(1, grooveColor.lighter(110));//palette.button().color().darker(115));
+ groovePainter.setBrush(gradient);
+ groovePainter.drawRect(pixmapRect.adjusted(1, 1, -2, -2));
+ groovePainter.end();
+ QPixmapCache::insert(groovePixmapName, cache);
+ }
+ painter->drawPixmap(groove.topLeft(), cache);
+
+ // draw blue groove highlight
+ QRect clipRect;
+ groovePixmapName += QLatin1String("_blue");
+ if (!QPixmapCache::find(groovePixmapName, cache)) {
+ cache = QPixmap(pixmapRect.size());
+ cache.fill(Qt::transparent);
+ QPainter groovePainter(&cache);
+ QLinearGradient gradient;
+ if (horizontal) {
+ gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
+ gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
+ }
+ else {
+ gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
+ gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
+ }
+ groovePainter.setPen(QPen(activeHighlight.darker(150), 0));
+ gradient.setColorAt(0, activeHighlight.darker(120));
+ gradient.setColorAt(1, activeHighlight.lighter(160));
+ groovePainter.setBrush(gradient);
+ groovePainter.drawRect(pixmapRect.adjusted(1, 1, -2, -2));
+ groovePainter.end();
+ QPixmapCache::insert(groovePixmapName, cache);
+ }
+ if (horizontal) {
+ if (slider->upsideDown)
+ clipRect = QRect(handle.right(), groove.top(), groove.right() - handle.right(), groove.height());
+ else
+ clipRect = QRect(groove.left(), groove.top(), handle.left(), groove.height());
+ } else {
+ if (slider->upsideDown)
+ clipRect = QRect(groove.left(), handle.bottom(), groove.width(), groove.height() - handle.bottom());
+ else
+ clipRect = QRect(groove.left(), groove.top(), groove.width(), handle.top() - groove.top());
+ }
+ painter->save();
+ painter->setClipRect(clipRect.adjusted(0, 0, 1, 1));
+ painter->drawPixmap(groove.topLeft(), cache);
+ painter->restore();
+ }
+
+ // draw handle
+ if ((option->subControls & SC_SliderHandle) ) {
+ QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_handle"), option, handle.size());
+ if (!QPixmapCache::find(handlePixmapName, cache)) {
+ cache = QPixmap(handle.size());
+ cache.fill(Qt::transparent);
+ QRect pixmapRect(0, 0, handle.width(), handle.height());
+ QPainter handlePainter(&cache);
+
+ QColor gradientStartColor = mergedColors(option->palette.button().color().lighter(155),
+ dark.lighter(155), 50);
+ QColor gradientStopColor = gradientStartColor.darker(108);
+ QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2);
+
+ QColor gradientBgStartColor = gradientStartColor;
+ QColor gradientBgStopColor = gradientStopColor;
+
+ QColor outline = option->state & State_Enabled ? dark : dark.lighter(130);
+ if (option->state & State_Enabled && option->activeSubControls & SC_SliderHandle) {
+ gradientBgStartColor = option->palette.highlight().color().lighter(180);
+ gradientBgStopColor = option->palette.highlight().color().lighter(110);
+ outline = option->palette.highlight().color().darker(130);
+ }
+
+ // gradient fill
+ QRect r = pixmapRect.adjusted(1, 1, -1, -1);
+
+ qt_cleanlooks_draw_gradient(&handlePainter, gradRect,
+ gradientBgStartColor,
+ gradientBgStopColor,
+ horizontal ? TopDown : FromLeft, option->palette.button());
+
+ handlePainter.setPen(QPen(outline.darker(110), 1));
+ handlePainter.drawLine(QPoint(r.left(), r.top() + 3), QPoint(r.left(), r.bottom() - 3));
+ handlePainter.drawLine(QPoint(r.right(), r.top() + 3), QPoint(r.right(), r.bottom() - 3));
+ handlePainter.drawLine(QPoint(r.left() + 3, r.bottom()), QPoint(r.right() - 3, r.bottom()));
+
+ handlePainter.save();
+ handlePainter.setRenderHint(QPainter::Antialiasing);
+ handlePainter.translate(0.5, 0.5);
+ const QLine lines[4] = {
+ QLine(QPoint(r.left(), r.bottom() - 2), QPoint(r.left() + 2, r.bottom())),
+ QLine(QPoint(r.left(), r.top() + 2), QPoint(r.left() + 2, r.top())),
+ QLine(QPoint(r.right(), r.bottom() - 2), QPoint(r.right() - 2, r.bottom())),
+ QLine(QPoint(r.right(), r.top() + 2), QPoint(r.right() - 2, r.top()))
+ };
+ handlePainter.drawLines(lines, 4);
+ handlePainter.restore();;
+ handlePainter.setPen(QPen(outline.darker(130), 1));
+ handlePainter.drawLine(QPoint(r.left() + 3, r.top()), QPoint(r.right() - 3, r.top()));
+ QColor cornerAlpha = outline.darker(120);
+ cornerAlpha.setAlpha(80);
+
+ handlePainter.setPen(cornerAlpha);
+ if (horizontal) {
+ handlePainter.drawLine(QPoint(r.left() + 6, r.top()), QPoint(r.left() + 6, r.bottom()));
+ handlePainter.drawLine(QPoint(r.right() - 6, r.top()), QPoint(r.right() - 6, r.bottom()));
+ } else {
+ handlePainter.drawLine(QPoint(r.left(), r.top() + 6), QPoint(r.right(), r.top() + 6));
+ handlePainter.drawLine(QPoint(r.left(), r.bottom() - 6), QPoint(r.right(), r.bottom() - 6));
+ }
+
+ //handle shadow
+ handlePainter.setPen(shadowAlpha);
+ handlePainter.drawLine(QPoint(r.left() + 2, r.bottom() + 1), QPoint(r.right() - 2, r.bottom() + 1));
+ handlePainter.drawLine(QPoint(r.right() + 1, r.bottom() - 3), QPoint(r.right() + 1, r.top() + 4));
+ handlePainter.drawLine(QPoint(r.right() - 1, r.bottom()), QPoint(r.right() + 1, r.bottom() - 2));
+
+ qt_cleanlooks_draw_gradient(&handlePainter, horizontal ?
+ gradRect.adjusted(6, 0, -6, 0) : gradRect.adjusted(0, 6, 0, -6),
+ gradientStartColor,
+ gradientStopColor.darker(106),
+ horizontal ? TopDown : FromLeft,
+ option->palette.button());
+
+ //draw grips
+ for (int i = -3; i< 6 ; i += 3) {
+ for (int j = -3; j< 6 ; j += 3) {
+ handlePainter.fillRect(r.center().x() + i, r.center().y() + j, 2, 2, highlightAlpha);
+ handlePainter.setPen(gripShadow);
+ handlePainter.drawPoint(r.center().x() + i, r.center().y() + j );
+ }
+ }
+ handlePainter.end();
+ QPixmapCache::insert(handlePixmapName, cache);
+ }
+
+ painter->drawPixmap(handle.topLeft(), cache);
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = slider->rect;
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+ if (option->subControls & SC_SliderTickmarks) {
+ painter->setPen(darkOutline);
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+ if (interval <= 0) {
+ interval = slider->singleStep;
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+ if (interval <= 0)
+ interval = 1;
+
+ int v = slider->minimum;
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, (horizontal
+ ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown) + len / 2;
+ int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
+
+ if (horizontal) {
+ if (ticksAbove) {
+ painter->drawLine(pos, slider->rect.top() + extra,
+ pos, slider->rect.top() + tickSize);
+ }
+ if (ticksBelow) {
+ painter->drawLine(pos, slider->rect.bottom() - extra,
+ pos, slider->rect.bottom() - tickSize);
+ }
+ } else {
+ if (ticksAbove) {
+ painter->drawLine(slider->rect.left() + extra, pos,
+ slider->rect.left() + tickSize, pos);
+ }
+ if (ticksBelow) {
+ painter->drawLine(slider->rect.right() - extra, pos,
+ slider->rect.right() - tickSize, pos);
+ }
+ }
+ // in the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ }
+ painter->setBrush(oldBrush);
+ painter->setPen(oldPen);
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_DIAL
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ QStyleHelper::drawDial(dial, painter);
+ break;
+#endif // QT_NO_DIAL
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+int QCleanlooksStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ int ret = -1;
+ switch (metric) {
+ case PM_ToolTipLabelFrameWidth:
+ ret = 2;
+ break;
+ case PM_ButtonDefaultIndicator:
+ ret = 0;
+ break;
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+ case PM_MessageBoxIconSize:
+ ret = 48;
+ break;
+ case PM_ListViewIconSize:
+ ret = 24;
+ break;
+ case PM_DialogButtonsSeparator:
+ case PM_SplitterWidth:
+ ret = 6;
+ break;
+ case PM_ScrollBarSliderMin:
+ ret = 26;
+ break;
+ case PM_MenuPanelWidth: //menu framewidth
+ ret = 2;
+ break;
+ case PM_TitleBarHeight:
+ ret = 24;
+ break;
+ case PM_ScrollBarExtent:
+ ret = 15;
+ break;
+ case PM_SliderThickness:
+ ret = 15;
+ break;
+ case PM_SliderLength:
+ ret = 27;
+ break;
+ case PM_DockWidgetTitleMargin:
+ ret = 1;
+ break;
+ case PM_MenuBarVMargin:
+ ret = 1;
+ break;
+ case PM_DefaultFrameWidth:
+ ret = 2;
+ break;
+ case PM_SpinBoxFrameWidth:
+ ret = 3;
+ break;
+ case PM_MenuBarItemSpacing:
+ ret = 6;
+ break;
+ case PM_MenuBarHMargin:
+ ret = 0;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = 9;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 2;
+ break;
+ case PM_ToolBarFrameWidth:
+ ret = 0;
+ break;
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+ case PM_SmallIconSize:
+ ret = 16;
+ break;
+ case PM_ButtonIconSize:
+ ret = 24;
+ break;
+ case PM_MenuVMargin:
+ case PM_MenuHMargin:
+ ret = 0;
+ break;
+ case PM_DockWidgetTitleBarButtonMargin:
+ ret = 4;
+ break;
+ case PM_MaximumDragDistance:
+ return -1;
+ case PM_TabCloseIndicatorWidth:
+ case PM_TabCloseIndicatorHeight:
+ return 20;
+ default:
+ break;
+ }
+
+ return ret != -1 ? ret : QWindowsStyle::pixelMetric(metric, option, widget);
+}
+
+/*!
+ \reimp
+*/
+QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ switch (type) {
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ if (!btn->text.isEmpty() && newSize.width() < 80)
+ newSize.setWidth(80);
+ if (!btn->icon.isNull() && btn->iconSize.height() > 16)
+ newSize -= QSize(0, 2);
+ newSize += QSize(0, 1);
+ }
+ if (const QPushButton *button = qobject_cast<const QPushButton *>(widget)) {
+ if (qobject_cast<const QDialogButtonBox *>(button->parentWidget())) {
+ if (newSize.height() < 32)
+ newSize.setHeight(32);
+ }
+ }
+ break;
+#ifndef QT_NO_GROUPBOX
+ case CT_GroupBox:
+ // Since we use a bold font we have to recalculate base width
+ if (const QGroupBox *gb = qobject_cast<const QGroupBox*>(widget)) {
+ QFont font = gb->font();
+ font.setBold(true);
+ QFontMetrics metrics(font);
+ int baseWidth = metrics.width(gb->title()) + metrics.width(QLatin1Char(' '));
+ if (gb->isCheckable()) {
+ baseWidth += proxy()->pixelMetric(QStyle::PM_IndicatorWidth, option, widget);
+ baseWidth += proxy()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, option, widget);
+ }
+ newSize.setWidth(qMax(baseWidth, newSize.width()));
+ }
+ newSize += QSize(0, 1);
+ break;
+#endif //QT_NO_GROUPBOX
+ case CT_RadioButton:
+ case CT_CheckBox:
+ newSize += QSize(0, 1);
+ break;
+ case CT_ToolButton:
+#ifndef QT_NO_TOOLBAR
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
+ newSize += QSize(4, 6);
+#endif // QT_NO_TOOLBAR
+ break;
+ case CT_SpinBox:
+ newSize += QSize(0, -2);
+ break;
+ case CT_ComboBox:
+ newSize += QSize(2, 4);
+ break;
+ case CT_LineEdit:
+ newSize += QSize(0, 4);
+ break;
+ case CT_MenuBarItem:
+ newSize += QSize(0, 2);
+ break;
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ if (!menuItem->text.isEmpty()) {
+ newSize.setHeight(menuItem->fontMetrics.height());
+ }
+ }
+#ifndef QT_NO_COMBOBOX
+ else if (!menuItem->icon.isNull()) {
+ if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget)) {
+ newSize.setHeight(qMax(combo->iconSize().height() + 2, newSize.height()));
+ }
+ }
+#endif // QT_NO_COMBOBOX
+ }
+ break;
+ case CT_SizeGrip:
+ newSize += QSize(4, 4);
+ break;
+ case CT_MdiControls:
+ if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
+ int width = 0;
+ if (styleOpt->subControls & SC_MdiMinButton)
+ width += 19 + 1;
+ if (styleOpt->subControls & SC_MdiNormalButton)
+ width += 19 + 1;
+ if (styleOpt->subControls & SC_MdiCloseButton)
+ width += 19 + 1;
+ newSize = QSize(width, 19);
+ } else {
+ newSize = QSize(60, 19);
+ }
+ break;
+ default:
+ break;
+ }
+ return newSize;
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::polish(QApplication *app)
+{
+ QWindowsStyle::polish(app);
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::polish(QWidget *widget)
+{
+ QWindowsStyle::polish(widget);
+ if (qobject_cast<QAbstractButton*>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox *>(widget)
+#endif
+#ifndef QT_NO_PROGRESSBAR
+ || qobject_cast<QProgressBar *>(widget)
+#endif
+#ifndef QT_NO_SCROLLBAR
+ || qobject_cast<QScrollBar *>(widget)
+#endif
+#ifndef QT_NO_SPLITTER
+ || qobject_cast<QSplitterHandle *>(widget)
+#endif
+ || qobject_cast<QAbstractSlider *>(widget)
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox *>(widget)
+#endif
+ || (widget->inherits("QWorkspaceChild"))
+ || (widget->inherits("QDockSeparator"))
+ || (widget->inherits("QDockWidgetSeparator"))
+ ) {
+ widget->setAttribute(Qt::WA_Hover, true);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::polish(QPalette &pal)
+{
+ QWindowsStyle::polish(pal);
+ //this is a workaround for some themes such as Human, where the contrast
+ //between text and background is too low.
+ QColor highlight = pal.highlight().color();
+ QColor highlightText = pal.highlightedText().color();
+ if (qAbs(qGray(highlight.rgb()) - qGray(highlightText.rgb())) < 150) {
+ if (qGray(highlightText.rgb()) < 128)
+ pal.setBrush(QPalette::Highlight, highlight.lighter(145));
+ }
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::unpolish(QWidget *widget)
+{
+ QWindowsStyle::unpolish(widget);
+ if (qobject_cast<QAbstractButton*>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox *>(widget)
+#endif
+#ifndef QT_NO_PROGRESSBAR
+ || qobject_cast<QProgressBar *>(widget)
+#endif
+#ifndef QT_NO_SCROLLBAR
+ || qobject_cast<QScrollBar *>(widget)
+#endif
+#ifndef QT_NO_SPLITTER
+ || qobject_cast<QSplitterHandle *>(widget)
+#endif
+ || qobject_cast<QAbstractSlider *>(widget)
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox *>(widget)
+#endif
+ || (widget->inherits("QWorkspaceChild"))
+ || (widget->inherits("QDockSeparator"))
+ || (widget->inherits("QDockWidgetSeparator"))
+ ) {
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::unpolish(QApplication *app)
+{
+ QWindowsStyle::unpolish(app);
+}
+
+/*!
+ \reimp
+*/
+QRect QCleanlooksStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+
+ switch (control) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+ switch (subControl) {
+ case SC_SliderHandle: {
+ if (slider->orientation == Qt::Horizontal) {
+ rect.setHeight(proxy()->pixelMetric(PM_SliderThickness));
+ rect.setWidth(proxy()->pixelMetric(PM_SliderLength));
+ int centerY = slider->rect.center().y() - rect.height() / 2;
+ if (slider->tickPosition & QSlider::TicksAbove)
+ centerY += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ centerY -= tickSize;
+ rect.moveTop(centerY);
+ } else {
+ rect.setWidth(proxy()->pixelMetric(PM_SliderThickness));
+ rect.setHeight(proxy()->pixelMetric(PM_SliderLength));
+ int centerX = slider->rect.center().x() - rect.width() / 2;
+ if (slider->tickPosition & QSlider::TicksAbove)
+ centerX += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ centerX -= tickSize;
+ rect.moveLeft(centerX);
+ }
+ }
+ break;
+ case SC_SliderGroove: {
+ QPoint grooveCenter = slider->rect.center();
+ if (slider->orientation == Qt::Horizontal) {
+ rect.setHeight(7);
+ if (slider->tickPosition & QSlider::TicksAbove)
+ grooveCenter.ry() += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ grooveCenter.ry() -= tickSize;
+ } else {
+ rect.setWidth(7);
+ if (slider->tickPosition & QSlider::TicksAbove)
+ grooveCenter.rx() += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ grooveCenter.rx() -= tickSize;
+ }
+ rect.moveCenter(grooveCenter);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+ case CC_ScrollBar:
+ break;
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QSize bs;
+ int center = spinbox->rect.height() / 2;
+ int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
+ int y = fw;
+ bs.setHeight(qMax(8, spinbox->rect.height()/2 - y));
+ bs.setWidth(15);
+ int x, lx, rx;
+ x = spinbox->rect.width() - y - bs.width() + 2;
+ lx = fw;
+ rx = x - fw;
+ switch (subControl) {
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = QRect(x, fw, bs.width(), center - fw);
+ break;
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+
+ rect = QRect(x, center, bs.width(), spinbox->rect.bottom() - center - fw + 1);
+ break;
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ rect = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
+ } else {
+ rect = QRect(lx, fw, rx - qMax(fw - 1, 0), spinbox->rect.height() - 2*fw);
+ }
+ break;
+ case SC_SpinBoxFrame:
+ rect = spinbox->rect;
+ default:
+ break;
+ }
+ rect = visualRect(spinbox->direction, spinbox->rect, rect);
+ }
+ break;
+#endif // Qt_NO_SPINBOX
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ int topMargin = 0;
+ int topHeight = 0;
+ int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
+ bool flat = groupBox->features & QStyleOptionFrameV2::Flat;
+ if (!groupBox->text.isEmpty()) {
+ topHeight = groupBox->fontMetrics.height();
+ if (verticalAlignment & Qt::AlignVCenter)
+ topMargin = topHeight / 2;
+ else if (verticalAlignment & Qt::AlignTop)
+ topMargin = topHeight;
+ }
+ QRect frameRect = groupBox->rect;
+ frameRect.setTop(topMargin);
+ if (subControl == SC_GroupBoxFrame) {
+ return rect;
+ }
+ else if (subControl == SC_GroupBoxContents) {
+ if( flat ) {
+ int margin = 0;
+ int leftMarginExtension = 16;
+ rect = frameRect.adjusted(leftMarginExtension + margin, margin + topHeight, -margin, -margin);
+ }
+ break;
+ }
+ if(flat) {
+ if (const QGroupBox *groupBoxWidget = qobject_cast<const QGroupBox *>(widget)) {
+ //Prepare metrics for a bold font
+ QFont font = widget->font();
+ font.setBold(true);
+ QFontMetrics fontMetrics(font);
+
+ QSize textRect = fontMetrics.boundingRect(groupBoxWidget->title()).size() + QSize(2, 2);
+ if (subControl == SC_GroupBoxCheckBox) {
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
+ int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
+ rect.setWidth(indicatorWidth);
+ rect.setHeight(indicatorHeight);
+ rect.moveTop((fontMetrics.height() - indicatorHeight) / 2 + 2);
+ } else if (subControl == SC_GroupBoxLabel) {
+ rect.setSize(textRect);
+ }
+ }
+ }
+ }
+ return rect;
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ switch (subControl) {
+ case SC_ComboBoxArrow:
+ rect = visualRect(option->direction, option->rect, rect);
+ rect.setRect(rect.right() - 18, rect.top() - 2,
+ 19, rect.height() + 4);
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ case SC_ComboBoxEditField: {
+ int frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ rect = visualRect(option->direction, option->rect, rect);
+ rect.setRect(option->rect.left() + frameWidth, option->rect.top() + frameWidth,
+ option->rect.width() - 19 - 2 * frameWidth,
+ option->rect.height() - 2 * frameWidth);
+ if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ if (!box->editable) {
+ rect.adjust(2, 0, 0, 0);
+ if (box->state & (State_Sunken | State_On))
+ rect.translate(1, 1);
+ }
+ }
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#endif //QT_NO_GROUPBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ SubControl sc = subControl;
+ QRect &ret = rect;
+ const int indent = 3;
+ const int controlTopMargin = 3;
+ const int controlBottomMargin = 3;
+ const int controlWidthMargin = 2;
+ const int controlHeight = tb->rect.height() - controlTopMargin - controlBottomMargin ;
+ const int delta = controlHeight + controlWidthMargin;
+ int offset = 0;
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+
+ switch (sc) {
+ case SC_TitleBarLabel:
+ if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
+ ret = tb->rect;
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ ret.adjust(delta, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ }
+ break;
+ case SC_TitleBarContextHelpButton:
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ offset += delta;
+ case SC_TitleBarMinButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarMinButton)
+ break;
+ case SC_TitleBarNormalButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarNormalButton)
+ break;
+ case SC_TitleBarMaxButton:
+ if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarMaxButton)
+ break;
+ case SC_TitleBarShadeButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarShadeButton)
+ break;
+ case SC_TitleBarUnshadeButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarUnshadeButton)
+ break;
+ case SC_TitleBarCloseButton:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ offset += delta;
+ else if (sc == SC_TitleBarCloseButton)
+ break;
+ ret.setRect(tb->rect.right() - indent - offset, tb->rect.top() + controlTopMargin,
+ controlHeight, controlHeight);
+ break;
+ case SC_TitleBarSysMenu:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ ret.setRect(tb->rect.left() + controlWidthMargin + indent, tb->rect.top() + controlTopMargin,
+ controlHeight, controlHeight);
+ }
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(tb->direction, tb->rect, ret);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return rect;
+}
+
+
+/*!
+ \reimp
+*/
+QRect QCleanlooksStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
+{
+ return QWindowsStyle::itemPixmapRect(r, flags, pixmap);
+}
+
+/*!
+ \reimp
+*/
+void QCleanlooksStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const
+{
+ QWindowsStyle::drawItemPixmap(painter, rect, alignment, pixmap);
+}
+
+/*!
+ \reimp
+*/
+QStyle::SubControl QCleanlooksStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const
+{
+ return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
+}
+
+/*!
+ \reimp
+*/
+QPixmap QCleanlooksStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const
+{
+ return QWindowsStyle::generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+/*!
+ \reimp
+*/
+int QCleanlooksStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = 0;
+ switch (hint) {
+ case SH_ScrollBar_MiddleClickAbsolutePosition:
+ ret = true;
+ break;
+ case SH_EtchDisabledText:
+ ret = 1;
+ break;
+ case SH_Menu_AllowActiveAndDisabled:
+ ret = false;
+ break;
+ case SH_MainWindow_SpaceBelowMenuBar:
+ ret = 0;
+ break;
+ case SH_MenuBar_MouseTracking:
+ ret = 1;
+ break;
+ case SH_TitleBar_AutoRaise:
+ ret = 1;
+ break;
+ case SH_TitleBar_NoBorder:
+ ret = 1;
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+ ret = true;
+ break;
+ case SH_Table_GridLineColor:
+ if (option) {
+ ret = option->palette.background().color().darker(120).rgb();
+ break;
+ }
+ case SH_ComboBox_Popup:
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3ComboBox"))
+ return 0;
+#endif
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ ret = !cmb->editable;
+ else
+ ret = 0;
+ break;
+ case SH_WindowFrame_Mask:
+ ret = 1;
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData)) {
+ //left rounded corner
+ mask->region = option->rect;
+ mask->region -= QRect(option->rect.left(), option->rect.top(), 5, 1);
+ mask->region -= QRect(option->rect.left(), option->rect.top() + 1, 3, 1);
+ mask->region -= QRect(option->rect.left(), option->rect.top() + 2, 2, 1);
+ mask->region -= QRect(option->rect.left(), option->rect.top() + 3, 1, 2);
+
+ //right rounded corner
+ mask->region -= QRect(option->rect.right() - 4, option->rect.top(), 5, 1);
+ mask->region -= QRect(option->rect.right() - 2, option->rect.top() + 1, 3, 1);
+ mask->region -= QRect(option->rect.right() - 1, option->rect.top() + 2, 2, 1);
+ mask->region -= QRect(option->rect.right() , option->rect.top() + 3, 1, 2);
+ }
+ break;
+ case SH_MessageBox_TextInteractionFlags:
+ ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+ ret = true;
+ break;
+ case SH_MessageBox_CenterButtons:
+ ret = false;
+ break;
+#ifndef QT_NO_WIZARD
+ case SH_WizardStyle:
+ ret = QWizard::ClassicStyle;
+ break;
+#endif
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = false;
+ break;
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 225; // default from GtkMenu
+ break;
+ default:
+ ret = QWindowsStyle::styleHint(hint, option, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+/*! \reimp */
+QRect QCleanlooksStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
+{
+ QRect r = QWindowsStyle::subElementRect(sr, opt, w);
+ switch (sr) {
+ case SE_PushButtonFocusRect:
+ r.adjust(0, 1, 0, -1);
+ break;
+ case SE_DockWidgetTitleBarText: {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+ if (verticalTitleBar) {
+ r.adjust(0, 0, 0, -4);
+ } else {
+ if (opt->direction == Qt::LeftToRight)
+ r.adjust(4, 0, 0, 0);
+ else
+ r.adjust(0, 0, -4, 0);
+ }
+
+ break;
+ }
+ case SE_ProgressBarContents:
+ r = subElementRect(SE_ProgressBarGroove, opt, w);
+ break;
+ default:
+ break;
+ }
+ return r;
+}
+
+/*!
+ \internal
+*/
+QIcon QCleanlooksStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+/*!
+ \reimp
+ */
+QPixmap QCleanlooksStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ QPixmap pixmap;
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ switch (standardPixmap) {
+ case SP_TitleBarNormalButton:
+ return QPixmap((const char **)dock_widget_restore_xpm);
+ case SP_TitleBarMinButton:
+ return QPixmap((const char **)workspace_minimize);
+ case SP_TitleBarCloseButton:
+ case SP_DockWidgetCloseButton:
+ return QPixmap((const char **)dock_widget_close_xpm);
+
+ default:
+ break;
+ }
+#endif //QT_NO_IMAGEFORMAT_XPM
+
+ return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_CLEANLOOKS || QT_PLUGIN
diff --git a/src/widgets/styles/qcleanlooksstyle.h b/src/widgets/styles/qcleanlooksstyle.h
new file mode 100644
index 0000000000..0c82497742
--- /dev/null
+++ b/src/widgets/styles/qcleanlooksstyle.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLEANLOOKSSTYLE_H
+#define QCLEANLOOKSSTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_CLEANLOOKS)
+
+class QCleanlooksStylePrivate;
+class Q_GUI_EXPORT QCleanlooksStyle : public QWindowsStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QCleanlooksStyle)
+
+public:
+ QCleanlooksStyle();
+ ~QCleanlooksStyle();
+
+ QPalette standardPalette () const;
+ void drawPrimitive(PrimitiveElement elem,
+ const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement ce, const QStyleOption *option, QPainter *painter,
+ const QWidget *widget) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+ QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ void drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const;
+ void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &pal);
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+protected:
+ QCleanlooksStyle(QCleanlooksStylePrivate &dd);
+
+};
+
+#endif // QT_NO_STYLE_CLEANLOOKS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCLEANLOOKSSTYLE_H
diff --git a/src/widgets/styles/qcleanlooksstyle_p.h b/src/widgets/styles/qcleanlooksstyle_p.h
new file mode 100644
index 0000000000..4df13c8a43
--- /dev/null
+++ b/src/widgets/styles/qcleanlooksstyle_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLEANLOOKSSTYLE_P_H
+#define QCLEANLOOKSSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsstyle.h"
+#include "qwindowsstyle_p.h"
+
+#ifndef QT_NO_STYLE_CLEANLOOKS
+
+QT_BEGIN_NAMESPACE
+
+class QCleanlooksStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QCleanlooksStyle)
+public:
+ QCleanlooksStylePrivate()
+ : QWindowsStylePrivate() {
+ animationFps = 24;
+ }
+
+ ~QCleanlooksStylePrivate() {
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_CLEANLOOKS
+
+#endif //QCLEANLOOKSSTYLE_P_H
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
new file mode 100644
index 0000000000..e5171d854a
--- /dev/null
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -0,0 +1,6083 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonstyle.h"
+#include "qcommonstyle_p.h"
+
+#include <qfile.h>
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qcache.h>
+#include <qdockwidget.h>
+#include <qdrawutil.h>
+#include <qdialogbuttonbox.h>
+#include <qformlayout.h>
+#include <qgroupbox.h>
+#include <qmath.h>
+#include <qmenu.h>
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <qpainterpath.h>
+#include <qslider.h>
+#include <qstyleoption.h>
+#include <qtabbar.h>
+#include <qtabwidget.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qrubberband.h>
+#include <private/qcommonstylepixmaps_p.h>
+#include <private/qmath_p.h>
+#include <qdebug.h>
+#include <qtextformat.h>
+#include <qwizard.h>
+#include <qtabbar.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qsettings.h>
+#include <qpixmapcache.h>
+#include <private/qguiplatformplugin_p.h>
+
+#include <limits.h>
+
+#ifndef QT_NO_ITEMVIEWS
+# include "private/qtextengine_p.h"
+#endif
+
+#ifdef Q_WS_X11
+# include <private/qt_x11_p.h>
+#elif defined(Q_WS_MAC)
+# include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCommonStyle
+ \brief The QCommonStyle class encapsulates the common Look and Feel of a GUI.
+
+ \ingroup appearance
+
+ This abstract class implements some of the widget's look and feel
+ that is common to all GUI styles provided and shipped as part of
+ Qt.
+
+ Since QCommonStyle inherits QStyle, all of its functions are fully documented
+ in the QStyle documentation.
+ \omit
+ , although the
+ extra functions that QCommonStyle provides, e.g.
+ drawComplexControl(), drawControl(), drawPrimitive(),
+ hitTestComplexControl(), subControlRect(), sizeFromContents(), and
+ subElementRect() are documented here.
+ \endomit
+
+ \sa QStyle, QMotifStyle, QWindowsStyle
+*/
+
+/*!
+ Constructs a QCommonStyle.
+*/
+QCommonStyle::QCommonStyle()
+ : QStyle(*new QCommonStylePrivate)
+{ }
+
+/*! \internal
+*/
+QCommonStyle::QCommonStyle(QCommonStylePrivate &dd)
+ : QStyle(dd)
+{ }
+
+/*!
+ Destroys the style.
+*/
+QCommonStyle::~QCommonStyle()
+{ }
+
+
+/*!
+ \reimp
+*/
+void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ Q_D(const QCommonStyle);
+ switch (pe) {
+ case PE_FrameButtonBevel:
+ case PE_FrameButtonTool:
+ qDrawShadeRect(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1, 0);
+ break;
+ case PE_PanelButtonCommand:
+ case PE_PanelButtonBevel:
+ case PE_PanelButtonTool:
+ case PE_IndicatorButtonDropDown:
+ qDrawShadePanel(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1,
+ &opt->palette.brush(QPalette::Button));
+ break;
+ case PE_IndicatorViewItemCheck:
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, opt, p, widget);
+ break;
+ case PE_IndicatorCheckBox:
+ if (opt->state & State_NoChange) {
+ p->setPen(opt->palette.foreground().color());
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ p->drawRect(opt->rect);
+ p->drawLine(opt->rect.topLeft(), opt->rect.bottomRight());
+ } else {
+ qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(),
+ opt->palette, opt->state & (State_Sunken | State_On), 1,
+ &opt->palette.brush(QPalette::Button));
+ }
+ break;
+ case PE_IndicatorRadioButton: {
+ QRect ir = opt->rect;
+ p->setPen(opt->palette.dark().color());
+ p->drawArc(opt->rect, 0, 5760);
+ if (opt->state & (State_Sunken | State_On)) {
+ ir.adjust(2, 2, -2, -2);
+ p->setBrush(opt->palette.foreground());
+ p->drawEllipse(ir);
+ }
+ break; }
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
+ QColor bg = fropt->backgroundColor;
+ QPen oldPen = p->pen();
+ if (bg.isValid()) {
+ int h, s, v;
+ bg.getHsv(&h, &s, &v);
+ if (v >= 128)
+ p->setPen(Qt::black);
+ else
+ p->setPen(Qt::white);
+ } else {
+ p->setPen(opt->palette.foreground().color());
+ }
+ QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
+ p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive
+ p->setPen(oldPen);
+ }
+ break;
+ case PE_IndicatorMenuCheckMark: {
+ const int markW = opt->rect.width() > 7 ? 7 : opt->rect.width();
+ const int markH = markW;
+ int posX = opt->rect.x() + (opt->rect.width() - markW)/2 + 1;
+ int posY = opt->rect.y() + (opt->rect.height() - markH)/2;
+
+ QVector<QLineF> a;
+ a.reserve(markH);
+
+ int i, xx, yy;
+ xx = posX;
+ yy = 3 + posY;
+ for (i = 0; i < markW/2; ++i) {
+ a << QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ ++yy;
+ }
+ yy -= 2;
+ for (; i < markH; ++i) {
+ a << QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ --yy;
+ }
+ if (!(opt->state & State_Enabled) && !(opt->state & State_On)) {
+ p->save();
+ p->translate(1, 1);
+ p->setPen(opt->palette.light().color());
+ p->drawLines(a);
+ p->restore();
+ }
+ p->setPen((opt->state & State_On) ? opt->palette.highlightedText().color() : opt->palette.text().color());
+ p->drawLines(a);
+ break; }
+ case PE_Frame:
+ case PE_FrameMenu:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (pe == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) {
+ qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
+ frame->lineWidth);
+ } else {
+ qDrawPlainRect(p, frame->rect, frame->palette.foreground().color(), frame->lineWidth);
+ }
+ }
+ break;
+#ifndef QT_NO_TOOLBAR
+ case PE_PanelMenuBar:
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
+ break;
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)){
+ qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth,
+ &frame->palette.brush(QPalette::Button));
+
+ }
+ else if (const QStyleOptionToolBar *frame = qstyleoption_cast<const QStyleOptionToolBar *>(opt)){
+ qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth,
+ &frame->palette.brush(QPalette::Button));
+ }
+
+ break;
+ case PE_PanelMenu:
+ break;
+ case PE_PanelToolBar:
+ break;
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_PROGRESSBAR
+ case PE_IndicatorProgressChunk:
+ {
+ bool vertical = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
+ vertical = (pb2->orientation == Qt::Vertical);
+ if (!vertical) {
+ p->fillRect(opt->rect.x(), opt->rect.y() + 3, opt->rect.width() -2, opt->rect.height() - 6,
+ opt->palette.brush(QPalette::Highlight));
+ } else {
+ p->fillRect(opt->rect.x() + 2, opt->rect.y(), opt->rect.width() -6, opt->rect.height() - 2,
+ opt->palette.brush(QPalette::Highlight));
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+#ifdef QT3_SUPPORT
+ case PE_Q3CheckListController:
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ p->drawPixmap(opt->rect.topLeft(), QPixmap(check_list_controller_xpm));
+#endif
+ break;
+ case PE_Q3CheckListExclusiveIndicator:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (lv->items.isEmpty())
+ return;
+ int x = lv->rect.x(),
+ y = lv->rect.y();
+#define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
+ static const int pts1[] = { // dark lines
+ 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
+ static const int pts2[] = { // black lines
+ 2,8, 1,7, 1,4, 2,3, 2,2, 3,2, 4,1, 7,1, 8,2, 9,2 };
+ static const int pts3[] = { // background lines
+ 2,9, 3,9, 4,10, 7,10, 8,9, 9,9, 9,8, 10,7, 10,4, 9,3 };
+ static const int pts4[] = { // white lines
+ 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
+ 11,4, 10,3, 10,2 };
+ // static const int pts5[] = { // inner fill
+ // 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
+ //QPolygon a;
+
+ if (lv->state & State_Enabled)
+ p->setPen(lv->palette.text().color());
+ else
+ p->setPen(QPen(lv->viewportPalette.color(QPalette::Disabled, QPalette::Text)));
+ QPolygon a(INTARRLEN(pts1), pts1);
+ a.translate(x, y);
+ //p->setPen(pal.dark());
+ p->drawPolyline(a);
+ a.setPoints(INTARRLEN(pts2), pts2);
+ a.translate(x, y);
+ p->drawPolyline(a);
+ a.setPoints(INTARRLEN(pts3), pts3);
+ a.translate(x, y);
+ // p->setPen(black);
+ p->drawPolyline(a);
+ a.setPoints(INTARRLEN(pts4), pts4);
+ a.translate(x, y);
+ // p->setPen(blue);
+ p->drawPolyline(a);
+ // a.setPoints(INTARRLEN(pts5), pts5);
+ // a.translate(x, y);
+ // QColor fillColor = isDown() ? g.background() : g.base();
+ // p->setPen(fillColor);
+ // p->setBrush(fillColor);
+ // p->drawPolygon(a);
+ if (opt->state & State_On) {
+ p->setPen(Qt::NoPen);
+ p->setBrush(opt->palette.text());
+ p->drawRect(x + 5, y + 4, 2, 4);
+ p->drawRect(x + 4, y + 5, 4, 2);
+ }
+#undef INTARRLEN
+ }
+ break;
+ case PE_Q3CheckListIndicator:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if(lv->items.isEmpty())
+ break;
+ QStyleOptionQ3ListViewItem item = lv->items.at(0);
+ int x = lv->rect.x(),
+ y = lv->rect.y(),
+ w = lv->rect.width(),
+ h = lv->rect.width(),
+ marg = lv->itemMargin;
+
+ if (lv->state & State_Enabled)
+ p->setPen(QPen(lv->palette.text().color(), 2));
+ else
+ p->setPen(QPen(lv->viewportPalette.color(QPalette::Disabled, QPalette::Text), 2));
+ if (opt->state & State_Selected && !lv->rootIsDecorated
+ && !(item.features & QStyleOptionQ3ListViewItem::ParentControl)) {
+ p->fillRect(0, 0, x + marg + w + 4, item.height,
+ lv->palette.brush(QPalette::Highlight));
+ if (item.state & State_Enabled)
+ p->setPen(QPen(lv->palette.highlightedText().color(), 2));
+ }
+
+ if (lv->state & State_NoChange)
+ p->setBrush(lv->palette.brush(QPalette::Button));
+ p->drawRect(x + marg, y + 2, w - 4, h - 4);
+ /////////////////////
+ ++x;
+ ++y;
+ if (lv->state & State_On || lv->state & State_NoChange) {
+ QLineF lines[7];
+ int i,
+ xx = x + 1 + marg,
+ yy = y + 5;
+ for (i = 0; i < 3; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ ++yy;
+ }
+ yy -= 2;
+ for (i = 3; i < 7; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ --yy;
+ }
+ p->drawLines(lines, 7);
+ }
+ }
+ break;
+#endif // QT3_SUPPORT
+ case PE_IndicatorBranch: {
+ int mid_h = opt->rect.x() + opt->rect.width() / 2;
+ int mid_v = opt->rect.y() + opt->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ static const int decoration_size = 9;
+ static QPixmap open(tree_branch_open_xpm);
+ static QPixmap closed(tree_branch_closed_xpm);
+ if (opt->state & State_Children) {
+ int delta = decoration_size / 2;
+ bef_h -= delta;
+ bef_v -= delta;
+ aft_h += delta;
+ aft_v += delta;
+ p->drawPixmap(bef_h, bef_v, opt->state & State_Open ? open : closed);
+ }
+#endif // QT_NO_IMAGEFORMAT_XPM
+ if (opt->state & State_Item) {
+ if (opt->direction == Qt::RightToLeft)
+ p->drawLine(opt->rect.left(), mid_v, bef_h, mid_v);
+ else
+ p->drawLine(aft_h, mid_v, opt->rect.right(), mid_v);
+ }
+ if (opt->state & State_Sibling)
+ p->drawLine(mid_h, aft_v, mid_h, opt->rect.bottom());
+ if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
+ p->drawLine(mid_h, opt->rect.y(), mid_h, bef_v);
+ break; }
+#ifdef QT3_SUPPORT
+ case PE_Q3Separator:
+ qDrawShadeLine(p, opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.bottom(),
+ opt->palette, opt->state & State_Sunken, 1, 0);
+ break;
+#endif // QT3_SUPPORT
+ case PE_FrameStatusBarItem:
+ qDrawShadeRect(p, opt->rect, opt->palette, true, 1, 0, 0);
+ break;
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QPen oldPen = p->pen();
+ if (header->sortIndicator & QStyleOptionHeader::SortUp) {
+ QPolygon pa(3);
+ p->setPen(QPen(opt->palette.light(), 0));
+ p->drawLine(opt->rect.x() + opt->rect.width(), opt->rect.y(),
+ opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height());
+ p->setPen(QPen(opt->palette.dark(), 0));
+ pa.setPoint(0, opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height());
+ pa.setPoint(1, opt->rect.x(), opt->rect.y());
+ pa.setPoint(2, opt->rect.x() + opt->rect.width(), opt->rect.y());
+ p->drawPolyline(pa);
+ } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
+ QPolygon pa(3);
+ p->setPen(QPen(opt->palette.light(), 0));
+ pa.setPoint(0, opt->rect.x(), opt->rect.y() + opt->rect.height());
+ pa.setPoint(1, opt->rect.x() + opt->rect.width(), opt->rect.y() + opt->rect.height());
+ pa.setPoint(2, opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
+ p->drawPolyline(pa);
+ p->setPen(QPen(opt->palette.dark(), 0));
+ p->drawLine(opt->rect.x(), opt->rect.y() + opt->rect.height(),
+ opt->rect.x() + opt->rect.width() / 2, opt->rect.y());
+ }
+ p->setPen(oldPen);
+ }
+ break;
+#ifndef QT_NO_TABBAR
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) {
+ p->save();
+ switch (tbb->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ p->setPen(QPen(tbb->palette.light(), 0));
+ p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ p->setPen(QPen(tbb->palette.light(), 0));
+ p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ p->setPen(QPen(tbb->palette.shadow(), 0));
+ p->drawLine(tbb->rect.left(), tbb->rect.bottom(),
+ tbb->rect.right(), tbb->rect.bottom());
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.left(), tbb->rect.bottom() - 1,
+ tbb->rect.right() - 1, tbb->rect.bottom() - 1);
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
+ break;
+ }
+ p->restore();
+ }
+ break;
+ case PE_IndicatorTabClose: {
+ if (d->tabBarcloseButtonIcon.isNull()) {
+ d->tabBarcloseButtonIcon.addPixmap(QPixmap(
+ QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-16.png")),
+ QIcon::Normal, QIcon::Off);
+ d->tabBarcloseButtonIcon.addPixmap(QPixmap(
+ QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-down-16.png")),
+ QIcon::Normal, QIcon::On);
+ d->tabBarcloseButtonIcon.addPixmap(QPixmap(
+ QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-hover-16.png")),
+ QIcon::Active, QIcon::Off);
+ }
+
+ int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize);
+ QIcon::Mode mode = opt->state & State_Enabled ?
+ (opt->state & State_Raised ? QIcon::Active : QIcon::Normal)
+ : QIcon::Disabled;
+ if (!(opt->state & State_Raised)
+ && !(opt->state & State_Sunken)
+ && !(opt->state & QStyle::State_Selected))
+ mode = QIcon::Disabled;
+
+ QIcon::State state = opt->state & State_Sunken ? QIcon::On : QIcon::Off;
+ QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(size, mode, state);
+ proxy()->drawItemPixmap(p, opt->rect, Qt::AlignCenter, pixmap);
+ break;
+ }
+#endif // QT_NO_TABBAR
+ case PE_FrameTabWidget:
+ case PE_FrameWindow:
+ qDrawWinPanel(p, opt->rect, opt->palette, false, 0);
+ break;
+ case PE_FrameLineEdit:
+ proxy()->drawPrimitive(PE_Frame, opt, p, widget);
+ break;
+#ifndef QT_NO_GROUPBOX
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt);
+ if (frame2 && (frame2->features & QStyleOptionFrameV2::Flat)) {
+ QRect fr = frame->rect;
+ QPoint p1(fr.x(), fr.y() + 1);
+ QPoint p2(fr.x() + fr.width(), p1.y());
+ qDrawShadeLine(p, p1, p2, frame->palette, true,
+ frame->lineWidth, frame->midLineWidth);
+ } else {
+ qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(),
+ frame->rect.height(), frame->palette, true,
+ frame->lineWidth, frame->midLineWidth);
+ }
+ }
+ break;
+#endif // QT_NO_GROUPBOX
+#ifndef QT_NO_DOCKWIDGET
+ case PE_FrameDockWidget:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ int lw = frame->lineWidth;
+ if (lw <= 0)
+ lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth);
+
+ qDrawShadePanel(p, frame->rect, frame->palette, false, lw);
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarHandle:
+ p->save();
+ p->translate(opt->rect.x(), opt->rect.y());
+ if (opt->state & State_Horizontal) {
+ int x = opt->rect.width() / 3;
+ if (opt->direction == Qt::RightToLeft)
+ x -= 2;
+ if (opt->rect.height() > 4) {
+ qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
+ opt->palette, false, 1, 0);
+ qDrawShadePanel(p, x+3, 2, 3, opt->rect.height() - 4,
+ opt->palette, false, 1, 0);
+ }
+ } else {
+ if (opt->rect.width() > 4) {
+ int y = opt->rect.height() / 3;
+ qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
+ opt->palette, false, 1, 0);
+ qDrawShadePanel(p, 2, y+3, opt->rect.width() - 4, 3,
+ opt->palette, false, 1, 0);
+ }
+ }
+ p->restore();
+ break;
+ case PE_Q3DockWindowSeparator:
+ proxy()->drawPrimitive(PE_IndicatorToolBarSeparator, opt, p, widget);
+ break;
+ case PE_IndicatorToolBarSeparator:
+ {
+ QPoint p1, p2;
+ if (opt->state & State_Horizontal) {
+ p1 = QPoint(opt->rect.width()/2, 0);
+ p2 = QPoint(p1.x(), opt->rect.height());
+ } else {
+ p1 = QPoint(0, opt->rect.height()/2);
+ p2 = QPoint(opt->rect.width(), p1.y());
+ }
+ qDrawShadeLine(p, p1, p2, opt->palette, 1, 1, 0);
+ break;
+ }
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_SPINBOX
+ case PE_IndicatorSpinPlus:
+ case PE_IndicatorSpinMinus: {
+ QRect r = opt->rect;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ QRect br = r.adjusted(fw, fw, -fw, -fw);
+
+ int offset = (opt->state & State_Sunken) ? 1 : 0;
+ int step = (br.width() + 4) / 5;
+ p->fillRect(br.x() + offset, br.y() + offset +br.height() / 2 - step / 2,
+ br.width(), step,
+ opt->palette.buttonText());
+ if (pe == PE_IndicatorSpinPlus)
+ p->fillRect(br.x() + br.width() / 2 - step / 2 + offset, br.y() + offset,
+ step, br.height(),
+ opt->palette.buttonText());
+
+ break; }
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinDown: {
+ QRect r = opt->rect;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ // QRect br = r.adjusted(fw, fw, -fw, -fw);
+ int x = r.x(), y = r.y(), w = r.width(), h = r.height();
+ int sw = w-4;
+ if (sw < 3)
+ break;
+ else if (!(sw & 1))
+ sw--;
+ sw -= (sw / 7) * 2; // Empty border
+ int sh = sw/2 + 2; // Must have empty row at foot of arrow
+
+ int sx = x + w / 2 - sw / 2;
+ int sy = y + h / 2 - sh / 2;
+
+ if (pe == PE_IndicatorSpinUp && fw)
+ --sy;
+
+ QPolygon a;
+ if (pe == PE_IndicatorSpinDown)
+ a.setPoints(3, 0, 1, sw-1, 1, sh-2, sh-1);
+ else
+ a.setPoints(3, 0, sh-1, sw-1, sh-1, sh-2, 1);
+ int bsx = 0;
+ int bsy = 0;
+ if (opt->state & State_Sunken) {
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ }
+ p->save();
+ p->translate(sx + bsx, sy + bsy);
+ p->setPen(opt->palette.buttonText().color());
+ p->setBrush(opt->palette.buttonText());
+ p->drawPolygon(a);
+ p->restore();
+ break; }
+#endif // QT_NO_SPINBOX
+ case PE_PanelTipLabel: {
+ QBrush oldBrush = p->brush();
+ QPen oldPen = p->pen();
+ p->setPen(QPen(opt->palette.toolTipText(), 0));
+ p->setBrush(opt->palette.toolTipBase());
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+ break;
+ }
+#ifndef QT_NO_TABBAR
+ case PE_IndicatorTabTear:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ bool rtl = tab->direction == Qt::RightToLeft;
+ QRect rect = tab->rect;
+ QPainterPath path;
+
+ rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
+ rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
+
+ path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
+ int count = 4;
+ for(int jags = 1; jags <= count; ++jags, rtl = !rtl)
+ path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
+
+ p->setPen(QPen(tab->palette.light(), qreal(.8)));
+ p->setBrush(tab->palette.background());
+ p->setRenderHint(QPainter::Antialiasing);
+ p->drawPath(path);
+ }
+ break;
+#endif // QT_NO_TABBAR
+#ifndef QT_NO_LINEEDIT
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ p->fillRect(panel->rect.adjusted(panel->lineWidth, panel->lineWidth, -panel->lineWidth, -panel->lineWidth),
+ panel->palette.brush(QPalette::Base));
+
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
+ }
+ break;
+#endif // QT_NO_LINEEDIT
+#ifndef QT_NO_COLUMNVIEW
+ case PE_IndicatorColumnViewArrow: {
+ if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
+ bool reverse = (viewOpt->direction == Qt::RightToLeft);
+ p->save();
+ QPainterPath path;
+ int x = viewOpt->rect.x() + 1;
+ int offset = (viewOpt->rect.height() / 3);
+ int height = (viewOpt->rect.height()) - offset * 2;
+ if (height % 2 == 1)
+ --height;
+ int x2 = x + height - 1;
+ if (reverse) {
+ x = viewOpt->rect.x() + viewOpt->rect.width() - 1;
+ x2 = x - height + 1;
+ }
+ path.moveTo(x, viewOpt->rect.y() + offset);
+ path.lineTo(x, viewOpt->rect.y() + offset + height);
+ path.lineTo(x2, viewOpt->rect.y() + offset+height/2);
+ path.closeSubpath();
+ if (viewOpt->state & QStyle::State_Selected ) {
+ if (viewOpt->showDecorationSelected) {
+ QColor color = viewOpt->palette.color(QPalette::Active, QPalette::HighlightedText);
+ p->setPen(color);
+ p->setBrush(color);
+ } else {
+ QColor color = viewOpt->palette.color(QPalette::Active, QPalette::WindowText);
+ p->setPen(color);
+ p->setBrush(color);
+ }
+
+ } else {
+ QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Mid);
+ p->setPen(color);
+ p->setBrush(color);
+ }
+ p->drawPath(path);
+
+ // draw the vertical and top triangle line
+ if (!(viewOpt->state & QStyle::State_Selected)) {
+ QPainterPath lines;
+ lines.moveTo(x, viewOpt->rect.y() + offset);
+ lines.lineTo(x, viewOpt->rect.y() + offset + height);
+ lines.moveTo(x, viewOpt->rect.y() + offset);
+ lines.lineTo(x2, viewOpt->rect.y() + offset+height/2);
+ QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Dark);
+ p->setPen(color);
+ p->drawPath(lines);
+ }
+ p->restore();
+ }
+ break; }
+#endif //QT_NO_COLUMNVIEW
+ case PE_IndicatorItemViewItemDrop: {
+ QRect rect = opt->rect;
+ if (opt->rect.height() == 0)
+ p->drawLine(rect.topLeft(), rect.topRight());
+ else
+ p->drawRect(rect);
+ break; }
+#ifndef QT_NO_ITEMVIEWS
+ case PE_PanelItemViewRow:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QPalette::ColorGroup cg = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, opt, widget))
+ p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight));
+ else if (vopt->features & QStyleOptionViewItemV2::Alternate)
+ p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase));
+ }
+ break;
+ case PE_PanelItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QPalette::ColorGroup cg = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) {
+ p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight));
+ } else {
+ if (vopt->backgroundBrush.style() != Qt::NoBrush) {
+ QPointF oldBO = p->brushOrigin();
+ p->setBrushOrigin(vopt->rect.topLeft());
+ p->fillRect(vopt->rect, vopt->backgroundBrush);
+ p->setBrushOrigin(oldBO);
+ }
+
+ if (vopt->state & QStyle::State_Selected) {
+ QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, opt, widget);
+ p->fillRect(textRect, vopt->palette.brush(cg, QPalette::Highlight));
+ }
+ }
+ }
+ break;
+#endif //QT_NO_ITEMVIEWS
+ case PE_PanelScrollAreaCorner: {
+ const QBrush brush(opt->palette.brush(QPalette::Window));
+ p->fillRect(opt->rect, brush);
+ } break;
+ default:
+ break;
+ }
+}
+
+#ifndef QT_NO_TOOLBUTTON
+static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton,
+ const QRect &rect, QPainter *painter, const QWidget *widget = 0)
+{
+ QStyle::PrimitiveElement pe;
+ switch (toolbutton->arrowType) {
+ case Qt::LeftArrow:
+ pe = QStyle::PE_IndicatorArrowLeft;
+ break;
+ case Qt::RightArrow:
+ pe = QStyle::PE_IndicatorArrowRight;
+ break;
+ case Qt::UpArrow:
+ pe = QStyle::PE_IndicatorArrowUp;
+ break;
+ case Qt::DownArrow:
+ pe = QStyle::PE_IndicatorArrowDown;
+ break;
+ default:
+ return;
+ }
+ QStyleOption arrowOpt;
+ arrowOpt.rect = rect;
+ arrowOpt.palette = toolbutton->palette;
+ arrowOpt.state = toolbutton->state;
+ style->drawPrimitive(pe, &arrowOpt, painter, widget);
+}
+#endif // QT_NO_TOOLBUTTON
+
+#ifndef QT_NO_ITEMVIEWS
+
+QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, int role) const
+{
+ Q_Q(const QCommonStyle);
+
+ const QWidget *widget = option->widget;
+ switch (role) {
+ case Qt::CheckStateRole:
+ if (option->features & QStyleOptionViewItemV2::HasCheckIndicator)
+ return QSize(q->pixelMetric(QStyle::PM_IndicatorWidth, option, widget),
+ q->pixelMetric(QStyle::PM_IndicatorHeight, option, widget));
+ break;
+ case Qt::DisplayRole:
+ if (option->features & QStyleOptionViewItemV2::HasDisplay) {
+ QTextOption textOption;
+ textOption.setWrapMode(QTextOption::WordWrap);
+ QTextLayout textLayout;
+ textLayout.setTextOption(textOption);
+ textLayout.setFont(option->font);
+ textLayout.setText(option->text);
+ const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
+ const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1;
+ QRect bounds = option->rect;
+ switch (option->decorationPosition) {
+ case QStyleOptionViewItem::Left:
+ case QStyleOptionViewItem::Right:
+ bounds.setWidth(wrapText && bounds.isValid() ? bounds.width() - 2 * textMargin : QFIXED_MAX);
+ break;
+ case QStyleOptionViewItem::Top:
+ case QStyleOptionViewItem::Bottom:
+ bounds.setWidth(wrapText ? option->decorationSize.width() : QFIXED_MAX);
+ break;
+ default:
+ break;
+ }
+
+ qreal height = 0, widthUsed = 0;
+ textLayout.beginLayout();
+ while (true) {
+ QTextLine line = textLayout.createLine();
+ if (!line.isValid())
+ break;
+ line.setLineWidth(bounds.width());
+ line.setPosition(QPointF(0, height));
+ height += line.height();
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ }
+ textLayout.endLayout();
+ const QSize size(qCeil(widthUsed), qCeil(height));
+ return QSize(size.width() + 2 * textMargin, size.height());
+ }
+ break;
+ case Qt::DecorationRole:
+ if (option->features & QStyleOptionViewItemV2::HasDecoration) {
+ return option->decorationSize;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return QSize(0, 0);
+}
+
+static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
+{
+ qreal height = 0;
+ qreal widthUsed = 0;
+ textLayout.beginLayout();
+ while (true) {
+ QTextLine line = textLayout.createLine();
+ if (!line.isValid())
+ break;
+ line.setLineWidth(lineWidth);
+ line.setPosition(QPointF(0, height));
+ height += line.height();
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ }
+ textLayout.endLayout();
+ return QSizeF(widthUsed, height);
+}
+
+
+void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const
+{
+ Q_Q(const QCommonStyle);
+ const QWidget *widget = option->widget;
+ const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
+
+ QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
+ const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText;
+ QTextOption textOption;
+ textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
+ textOption.setTextDirection(option->direction);
+ textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment));
+ QTextLayout textLayout;
+ textLayout.setTextOption(textOption);
+ textLayout.setFont(option->font);
+ textLayout.setText(option->text);
+
+ viewItemTextLayout(textLayout, textRect.width());
+
+ QString elidedText;
+ qreal height = 0;
+ qreal width = 0;
+ int elidedIndex = -1;
+ const int lineCount = textLayout.lineCount();
+ for (int j = 0; j < lineCount; ++j) {
+ const QTextLine line = textLayout.lineAt(j);
+ if (j + 1 <= lineCount - 1) {
+ const QTextLine nextLine = textLayout.lineAt(j + 1);
+ if ((nextLine.y() + nextLine.height()) > textRect.height()) {
+ int start = line.textStart();
+ int length = line.textLength() + nextLine.textLength();
+ const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
+ elidedText = engine.elidedText(option->textElideMode, textRect.width());
+ height += line.height();
+ width = textRect.width();
+ elidedIndex = j;
+ break;
+ }
+ }
+ if (line.naturalTextWidth() > textRect.width()) {
+ int start = line.textStart();
+ int length = line.textLength();
+ const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
+ elidedText = engine.elidedText(option->textElideMode, textRect.width());
+ height += line.height();
+ width = textRect.width();
+ elidedIndex = j;
+ break;
+ }
+ width = qMax<qreal>(width, line.width());
+ height += line.height();
+ }
+
+ const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
+ QSize(int(width), int(height)), textRect);
+ const QPointF position = layoutRect.topLeft();
+ for (int i = 0; i < lineCount; ++i) {
+ const QTextLine line = textLayout.lineAt(i);
+ if (i == elidedIndex) {
+ qreal x = position.x() + line.x();
+ qreal y = position.y() + line.y() + line.ascent();
+ p->save();
+ p->setFont(option->font);
+ p->drawText(QPointF(x, y), elidedText);
+ p->restore();
+ break;
+ }
+ line.draw(p, position);
+ }
+}
+
+/*! \internal
+ compute the position for the different component of an item (pixmap, text, checkbox)
+
+ Set sizehint to false to layout the elements inside opt->rect. Set sizehint to true to ignore
+ opt->rect and return rectangles in infinite space
+
+ Code duplicated in QItemDelegate::doLayout
+*/
+void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt, QRect *checkRect,
+ QRect *pixmapRect, QRect *textRect, bool sizehint) const
+{
+ Q_Q(const QCommonStyle);
+ Q_ASSERT(checkRect && pixmapRect && textRect);
+ *pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole));
+ *textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole));
+ *checkRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::CheckStateRole));
+
+ const QWidget *widget = opt->widget;
+ const bool hasCheck = checkRect->isValid();
+ const bool hasPixmap = pixmapRect->isValid();
+ const bool hasText = textRect->isValid();
+ const int textMargin = hasText ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
+ const int pixmapMargin = hasPixmap ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
+ const int checkMargin = hasCheck ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0;
+ int x = opt->rect.left();
+ int y = opt->rect.top();
+ int w, h;
+
+ if (textRect->height() == 0 && (!hasPixmap || !sizehint)) {
+ //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
+ textRect->setHeight(opt->fontMetrics.height());
+ }
+
+ QSize pm(0, 0);
+ if (hasPixmap) {
+ pm = pixmapRect->size();
+ pm.rwidth() += 2 * pixmapMargin;
+ }
+ if (sizehint) {
+ h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
+ if (opt->decorationPosition == QStyleOptionViewItem::Left
+ || opt->decorationPosition == QStyleOptionViewItem::Right) {
+ w = textRect->width() + pm.width();
+ } else {
+ w = qMax(textRect->width(), pm.width());
+ }
+ } else {
+ w = opt->rect.width();
+ h = opt->rect.height();
+ }
+
+ int cw = 0;
+ QRect check;
+ if (hasCheck) {
+ cw = checkRect->width() + 2 * checkMargin;
+ if (sizehint) w += cw;
+ if (opt->direction == Qt::RightToLeft) {
+ check.setRect(x + w - cw, y, cw, h);
+ } else {
+ check.setRect(x, y, cw, h);
+ }
+ }
+
+ QRect display;
+ QRect decoration;
+ switch (opt->decorationPosition) {
+ case QStyleOptionViewItem::Top: {
+ if (hasPixmap)
+ pm.setHeight(pm.height() + pixmapMargin); // add space
+ h = sizehint ? textRect->height() : h - pm.height();
+
+ if (opt->direction == Qt::RightToLeft) {
+ decoration.setRect(x, y, w - cw, pm.height());
+ display.setRect(x, y + pm.height(), w - cw, h);
+ } else {
+ decoration.setRect(x + cw, y, w - cw, pm.height());
+ display.setRect(x + cw, y + pm.height(), w - cw, h);
+ }
+ break; }
+ case QStyleOptionViewItem::Bottom: {
+ if (hasText)
+ textRect->setHeight(textRect->height() + textMargin); // add space
+ h = sizehint ? textRect->height() + pm.height() : h;
+
+ if (opt->direction == Qt::RightToLeft) {
+ display.setRect(x, y, w - cw, textRect->height());
+ decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
+ } else {
+ display.setRect(x + cw, y, w - cw, textRect->height());
+ decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
+ }
+ break; }
+ case QStyleOptionViewItem::Left: {
+ if (opt->direction == Qt::LeftToRight) {
+ decoration.setRect(x + cw, y, pm.width(), h);
+ display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
+ } else {
+ display.setRect(x, y, w - pm.width() - cw, h);
+ decoration.setRect(display.right() + 1, y, pm.width(), h);
+ }
+ break; }
+ case QStyleOptionViewItem::Right: {
+ if (opt->direction == Qt::LeftToRight) {
+ display.setRect(x + cw, y, w - pm.width() - cw, h);
+ decoration.setRect(display.right() + 1, y, pm.width(), h);
+ } else {
+ decoration.setRect(x, y, pm.width(), h);
+ display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
+ }
+ break; }
+ default:
+ qWarning("doLayout: decoration position is invalid");
+ decoration = *pixmapRect;
+ break;
+ }
+
+ if (!sizehint) { // we only need to do the internal layout if we are going to paint
+ *checkRect = QStyle::alignedRect(opt->direction, Qt::AlignCenter,
+ checkRect->size(), check);
+ *pixmapRect = QStyle::alignedRect(opt->direction, opt->decorationAlignment,
+ pixmapRect->size(), decoration);
+ // the text takes up all available space, unless the decoration is not shown as selected
+ if (opt->showDecorationSelected)
+ *textRect = display;
+ else
+ *textRect = QStyle::alignedRect(opt->direction, opt->displayAlignment,
+ textRect->size().boundedTo(display.size()), display);
+ } else {
+ *checkRect = check;
+ *pixmapRect = decoration;
+ *textRect = display;
+ }
+}
+#endif // QT_NO_ITEMVIEWS
+
+
+#ifndef QT_NO_TABBAR
+/*! \internal
+ Compute the textRect and the pixmapRect from the opt rect
+
+ Uses the same computation than in QTabBar::tabSizeHint
+ */
+void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
+{
+ Q_ASSERT(textRect);
+ Q_ASSERT(iconRect);
+ QRect tr = opt->rect;
+ bool verticalTabs = opt->shape == QTabBar::RoundedEast
+ || opt->shape == QTabBar::RoundedWest
+ || opt->shape == QTabBar::TriangularEast
+ || opt->shape == QTabBar::TriangularWest;
+ if (verticalTabs)
+ tr.setRect(0, 0, tr.height(), tr.width()); //0, 0 as we will have a translate transform
+
+ int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget);
+ int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget);
+ int hpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
+ int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2;
+ if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
+ verticalShift = -verticalShift;
+ tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);
+ bool selected = opt->state & QStyle::State_Selected;
+ if (selected) {
+ tr.setTop(tr.top() - verticalShift);
+ tr.setRight(tr.right() - horizontalShift);
+ }
+
+ // left widget
+ if (!opt->leftButtonSize.isEmpty()) {
+ tr.setLeft(tr.left() + 4 +
+ (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width()));
+ }
+ // right widget
+ if (!opt->rightButtonSize.isEmpty()) {
+ tr.setRight(tr.right() - 4 -
+ (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width()));
+ }
+
+ // icon
+ if (!opt->icon.isNull()) {
+ QSize iconSize = opt->iconSize;
+ if (!iconSize.isValid()) {
+ int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize);
+ iconSize = QSize(iconExtent, iconExtent);
+ }
+ QSize tabIconSize = opt->icon.actualSize(iconSize,
+ (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
+ (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off );
+
+ *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
+ tabIconSize.width(), tabIconSize .height());
+ if (!verticalTabs)
+ *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);
+ tr.setLeft(tr.left() + tabIconSize.width() + 4);
+ }
+
+ if (!verticalTabs)
+ tr = proxyStyle->visualRect(opt->direction, opt->rect, tr);
+
+ *textRect = tr;
+}
+#endif //QT_NO_TABBAR
+
+
+/*!
+ \reimp
+*/
+void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
+ QPainter *p, const QWidget *widget) const
+{
+ Q_D(const QCommonStyle);
+ switch (element) {
+
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
+ if (btn->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QRect br = btn->rect;
+ int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
+ if (btn->features & QStyleOptionButton::DefaultButton)
+ proxy()->drawPrimitive(PE_FrameDefaultButton, opt, p, widget);
+ if (btn->features & QStyleOptionButton::AutoDefaultButton)
+ br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
+ if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton))
+ || btn->state & (State_Sunken | State_On)
+ || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) {
+ QStyleOptionButton tmpBtn = *btn;
+ tmpBtn.rect = br;
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, p, widget);
+ }
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
+ QRect ir = btn->rect;
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QRect(ir.right() - mbi + 2, ir.height()/2 - mbi/2 + 3, mbi - 6, mbi - 6);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ }
+ break;
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QRect textRect = button->rect;
+ uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
+ tf |= Qt::TextHideMnemonic;
+
+ if (!button->icon.isNull()) {
+ //Center both icon and text
+ QRect iconRect;
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+ QIcon::State state = QIcon::Off;
+ if (button->state & State_On)
+ state = QIcon::On;
+
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int labelWidth = pixmap.width();
+ int labelHeight = pixmap.height();
+ int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
+ int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
+ if (!button->text.isEmpty())
+ labelWidth += (textWidth + iconSpacing);
+
+ iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
+ textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+
+ iconRect = visualRect(button->direction, textRect, iconRect);
+
+ tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
+
+ if (button->direction == Qt::RightToLeft)
+ textRect.setRight(iconRect.left() - iconSpacing);
+ else
+ textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
+
+ if (button->state & (State_On | State_Sunken))
+ iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
+ p->drawPixmap(iconRect, pixmap);
+ } else {
+ tf |= Qt::AlignHCenter;
+ }
+ if (button->state & (State_On | State_Sunken))
+ textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
+
+ if (button->features & QStyleOptionButton::HasMenu) {
+ int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
+ if (button->direction == Qt::LeftToRight)
+ textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
+ else
+ textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
+ }
+ proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
+ button->text, QPalette::ButtonText);
+ }
+ break;
+ case CE_RadioButton:
+ case CE_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ bool isRadio = (element == CE_RadioButton);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, p, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+ proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
+ if (btn->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+ case CE_RadioButtonLabel:
+ case CE_CheckBoxLabel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
+
+ if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
+ alignment |= Qt::TextHideMnemonic;
+ QPixmap pix;
+ QRect textRect = btn->rect;
+ if (!btn->icon.isNull()) {
+ pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
+ proxy()->drawItemPixmap(p, btn->rect, alignment, pix);
+ if (btn->direction == Qt::RightToLeft)
+ textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
+ else
+ textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
+ }
+ if (!btn->text.isEmpty()){
+ proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
+ btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
+ }
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CE_MenuScroller: {
+ p->fillRect(opt->rect, opt->palette.background());
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.state |= State_Enabled;
+ proxy()->drawPrimitive(((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp),
+ &arrowOpt, p, widget);
+ break; }
+ case CE_MenuTearoff:
+ if (opt->state & State_Selected)
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Highlight));
+ else
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
+ p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2 - 1,
+ opt->rect.x() + opt->rect.width() - 4,
+ opt->rect.y() + opt->rect.height() / 2 - 1);
+ p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
+ p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2,
+ opt->rect.x() + opt->rect.width() - 4, opt->rect.y() + opt->rect.height() / 2);
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_MENUBAR
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+ QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
+ if (!pix.isNull())
+ proxy()->drawItemPixmap(p,mbi->rect, alignment, pix);
+ else
+ proxy()->drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled,
+ mbi->text, QPalette::ButtonText);
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ if (widget && !widget->testAttribute(Qt::WA_NoSystemBackground))
+ p->eraseRect(opt->rect);
+ break;
+#endif // QT_NO_MENUBAR
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBar:
+ if (const QStyleOptionProgressBar *pb
+ = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QStyleOptionProgressBarV2 subopt = *pb;
+ subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget);
+ proxy()->drawControl(CE_ProgressBarGroove, &subopt, p, widget);
+ subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget);
+ proxy()->drawControl(CE_ProgressBarContents, &subopt, p, widget);
+ if (pb->textVisible) {
+ subopt.rect = subElementRect(SE_ProgressBarLabel, pb, widget);
+ proxy()->drawControl(CE_ProgressBarLabel, &subopt, p, widget);
+ }
+ }
+ break;
+ case CE_ProgressBarGroove:
+ if (opt->rect.isValid())
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 1,
+ &opt->palette.brush(QPalette::Window));
+ break;
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ bool vertical = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ }
+ if (!vertical) {
+ QPalette::ColorRole textRole = QPalette::NoRole;
+ if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible
+ && ((qint64(pb->progress) - qint64(pb->minimum)) * 2 >= (qint64(pb->maximum) - qint64(pb->minimum)))) {
+ textRole = QPalette::HighlightedText;
+ //Draw text shadow, This will increase readability when the background of same color
+ QRect shadowRect(pb->rect);
+ shadowRect.translate(1,1);
+ QColor shadowColor = (pb->palette.color(textRole).value() <= 128)
+ ? QColor(255,255,255,160) : QColor(0,0,0,160);
+ QPalette shadowPalette = pb->palette;
+ shadowPalette.setColor(textRole, shadowColor);
+ proxy()->drawItemText(p, shadowRect, Qt::AlignCenter | Qt::TextSingleLine, shadowPalette,
+ pb->state & State_Enabled, pb->text, textRole);
+ }
+ proxy()->drawItemText(p, pb->rect, Qt::AlignCenter | Qt::TextSingleLine, pb->palette,
+ pb->state & State_Enabled, pb->text, textRole);
+ }
+ }
+ break;
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+
+ QRect rect = pb->rect;
+ bool vertical = false;
+ bool inverted = false;
+ qint64 minimum = qint64(pb->minimum);
+ qint64 maximum = qint64(pb->maximum);
+ qint64 progress = qint64(pb->progress);
+
+ // Get extra style options if version 2
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
+ if (pb2) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+ QMatrix m;
+
+ if (vertical) {
+ rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+
+ QPalette pal2 = pb->palette;
+ // Correct the highlight color if it is the same as the background
+ if (pal2.highlight() == pal2.background())
+ pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
+ QPalette::Highlight));
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ int w = rect.width();
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ // draw busy indicator
+ int x = (progress - minimum) % (w * 2);
+ if (x > w)
+ x = 2 * w - x;
+ x = reverse ? rect.right() - x : x + rect.x();
+ p->setPen(QPen(pal2.highlight().color(), 4));
+ p->drawLine(x, rect.y(), x, rect.height());
+ } else {
+ const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
+ if (!unit_width)
+ return;
+
+ int u;
+ if (unit_width > 1)
+ u = ((rect.width() + unit_width) / unit_width);
+ else
+ u = w / unit_width;
+ qint64 p_v = progress - minimum;
+ qint64 t_s = (maximum - minimum) ? (maximum - minimum) : qint64(1);
+
+ if (u > 0 && p_v >= INT_MAX / u && t_s >= u) {
+ // scale down to something usable.
+ p_v /= u;
+ t_s /= u;
+ }
+
+ // nu < tnu, if last chunk is only a partial chunk
+ int tnu, nu;
+ tnu = nu = p_v * u / t_s;
+
+ if (nu * unit_width > w)
+ --nu;
+
+ // Draw nu units out of a possible u of unit_width
+ // width, each a rectangle bordered by background
+ // color, all in a sunken panel with a percentage text
+ // display at the end.
+ int x = 0;
+ int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0)
+ : rect.x();
+
+ QStyleOptionProgressBarV2 pbBits = *pb;
+ pbBits.rect = rect;
+ pbBits.palette = pal2;
+ int myY = pbBits.rect.y();
+ int myHeight = pbBits.rect.height();
+ pbBits.state = State_None;
+ for (int i = 0; i < nu; ++i) {
+ pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
+ pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
+ proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
+ x += reverse ? -unit_width : unit_width;
+ }
+
+ // Draw the last partial chunk to fill up the
+ // progress bar entirely
+ if (nu < tnu) {
+ int pixels_left = w - (nu * unit_width);
+ int offset = reverse ? x0 + x + unit_width-pixels_left : x0 + x;
+ pbBits.rect.setRect(offset, myY, pixels_left, myHeight);
+ pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
+ proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ case CE_HeaderLabel:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRect rect = header->rect;
+ if (!header->icon.isNull()) {
+ QPixmap pixmap
+ = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
+ int pixw = pixmap.width();
+
+ QRect aligned = alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size(), rect);
+ QRect inter = aligned.intersected(rect);
+ p->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
+
+ if (header->direction == Qt::LeftToRight)
+ rect.setLeft(rect.left() + pixw + 2);
+ else
+ rect.setRight(rect.right() - pixw - 2);
+ }
+ if (header->state & QStyle::State_On) {
+ QFont fnt = p->font();
+ fnt.setBold(true);
+ p->setFont(fnt);
+ }
+ proxy()->drawItemText(p, rect, header->textAlignment, header->palette,
+ (header->state & State_Enabled), header->text, QPalette::ButtonText);
+ }
+ break;
+#ifndef QT_NO_TOOLBUTTON
+ case CE_ToolButtonLabel:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QRect rect = toolbutton->rect;
+ int shiftX = 0;
+ int shiftY = 0;
+ if (toolbutton->state & (State_Sunken | State_On)) {
+ shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, toolbutton, widget);
+ shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, toolbutton, widget);
+ }
+ // Arrow type always overrules and is always shown
+ bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow;
+ if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty())
+ || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) {
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
+ alignment |= Qt::TextHideMnemonic;
+ rect.translate(shiftX, shiftY);
+ p->setFont(toolbutton->font);
+ proxy()->drawItemText(p, rect, alignment, toolbutton->palette,
+ opt->state & State_Enabled, toolbutton->text,
+ QPalette::ButtonText);
+ } else {
+ QPixmap pm;
+ QSize pmSize = toolbutton->iconSize;
+ if (!toolbutton->icon.isNull()) {
+ QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off;
+ QIcon::Mode mode;
+ if (!(toolbutton->state & State_Enabled))
+ mode = QIcon::Disabled;
+ else if ((opt->state & State_MouseOver) && (opt->state & State_AutoRaise))
+ mode = QIcon::Active;
+ else
+ mode = QIcon::Normal;
+ pm = toolbutton->icon.pixmap(toolbutton->rect.size().boundedTo(toolbutton->iconSize),
+ mode, state);
+ pmSize = pm.size();
+ }
+
+ if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) {
+ p->setFont(toolbutton->font);
+ QRect pr = rect,
+ tr = rect;
+ int alignment = Qt::TextShowMnemonic;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
+ pr.setHeight(pmSize.height() + 6);
+ tr.adjust(0, pr.height() - 1, 0, -2);
+ pr.translate(shiftX, shiftY);
+ if (!hasArrow) {
+ proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm);
+ } else {
+ drawArrow(this, toolbutton, pr, p, widget);
+ }
+ alignment |= Qt::AlignCenter;
+ } else {
+ pr.setWidth(pmSize.width() + 8);
+ tr.adjust(pr.width(), 0, 0, 0);
+ pr.translate(shiftX, shiftY);
+ if (!hasArrow) {
+ proxy()->drawItemPixmap(p, QStyle::visualRect(opt->direction, rect, pr), Qt::AlignCenter, pm);
+ } else {
+ drawArrow(this, toolbutton, pr, p, widget);
+ }
+ alignment |= Qt::AlignLeft | Qt::AlignVCenter;
+ }
+ tr.translate(shiftX, shiftY);
+ proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
+ toolbutton->state & State_Enabled, toolbutton->text,
+ QPalette::ButtonText);
+ } else {
+ rect.translate(shiftX, shiftY);
+ if (hasArrow) {
+ drawArrow(this, toolbutton, rect, p, widget);
+ } else {
+ proxy()->drawItemPixmap(p, rect, Qt::AlignCenter, pm);
+ }
+ }
+ }
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+#ifndef QT_NO_TOOLBOX
+ case CE_ToolBoxTab:
+ if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
+ proxy()->drawControl(CE_ToolBoxTabShape, tb, p, widget);
+ proxy()->drawControl(CE_ToolBoxTabLabel, tb, p, widget);
+ }
+ break;
+ case CE_ToolBoxTabShape:
+ if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
+ int d = 20 + tb->rect.height() - 3;
+ QPolygon a(7);
+ if (tb->direction != Qt::RightToLeft) {
+ a.setPoint(0, -1, tb->rect.height() + 1);
+ a.setPoint(1, -1, 1);
+ a.setPoint(2, tb->rect.width() - d, 1);
+ a.setPoint(3, tb->rect.width() - 20, tb->rect.height() - 2);
+ a.setPoint(4, tb->rect.width() - 1, tb->rect.height() - 2);
+ a.setPoint(5, tb->rect.width() - 1, tb->rect.height() + 1);
+ a.setPoint(6, -1, tb->rect.height() + 1);
+ } else {
+ a.setPoint(0, tb->rect.width(), tb->rect.height() + 1);
+ a.setPoint(1, tb->rect.width(), 1);
+ a.setPoint(2, d - 1, 1);
+ a.setPoint(3, 20 - 1, tb->rect.height() - 2);
+ a.setPoint(4, 0, tb->rect.height() - 2);
+ a.setPoint(5, 0, tb->rect.height() + 1);
+ a.setPoint(6, tb->rect.width(), tb->rect.height() + 1);
+ }
+
+ p->setPen(tb->palette.mid().color().darker(150));
+ p->drawPolygon(a);
+ p->setPen(tb->palette.light().color());
+ if (tb->direction != Qt::RightToLeft) {
+ p->drawLine(0, 2, tb->rect.width() - d, 2);
+ p->drawLine(tb->rect.width() - d - 1, 2, tb->rect.width() - 21, tb->rect.height() - 1);
+ p->drawLine(tb->rect.width() - 20, tb->rect.height() - 1,
+ tb->rect.width(), tb->rect.height() - 1);
+ } else {
+ p->drawLine(tb->rect.width() - 1, 2, d - 1, 2);
+ p->drawLine(d, 2, 20, tb->rect.height() - 1);
+ p->drawLine(19, tb->rect.height() - 1,
+ -1, tb->rect.height() - 1);
+ }
+ p->setBrush(Qt::NoBrush);
+ }
+ break;
+#endif // QT_NO_TOOLBOX
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ proxy()->drawControl(CE_TabBarTabShape, tab, p, widget);
+ proxy()->drawControl(CE_TabBarTabLabel, tab, p, widget);
+ }
+ break;
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ p->save();
+
+ QRect rect(tab->rect);
+ bool selected = tab->state & State_Selected;
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ int tabOverlap = onlyOne ? 0 : proxy()->pixelMetric(PM_TabBarTabOverlap, opt, widget);
+
+ if (!selected) {
+ switch (tab->shape) {
+ case QTabBar::TriangularNorth:
+ rect.adjust(0, 0, 0, -tabOverlap);
+ if(!selected)
+ rect.adjust(1, 1, -1, 0);
+ break;
+ case QTabBar::TriangularSouth:
+ rect.adjust(0, tabOverlap, 0, 0);
+ if(!selected)
+ rect.adjust(1, 0, -1, -1);
+ break;
+ case QTabBar::TriangularEast:
+ rect.adjust(tabOverlap, 0, 0, 0);
+ if(!selected)
+ rect.adjust(0, 1, -1, -1);
+ break;
+ case QTabBar::TriangularWest:
+ rect.adjust(0, 0, -tabOverlap, 0);
+ if(!selected)
+ rect.adjust(1, 1, 0, -1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ p->setPen(QPen(tab->palette.foreground(), 0));
+ if (selected) {
+ p->setBrush(tab->palette.base());
+ } else {
+ if (widget && widget->parentWidget())
+ p->setBrush(widget->parentWidget()->palette().background());
+ else
+ p->setBrush(tab->palette.background());
+ }
+
+ int y;
+ int x;
+ QPolygon a(10);
+ switch (tab->shape) {
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularSouth: {
+ a.setPoint(0, 0, -1);
+ a.setPoint(1, 0, 0);
+ y = rect.height() - 2;
+ x = y / 3;
+ a.setPoint(2, x++, y - 1);
+ ++x;
+ a.setPoint(3, x++, y++);
+ a.setPoint(4, x, y);
+
+ int i;
+ int right = rect.width() - 1;
+ for (i = 0; i < 5; ++i)
+ a.setPoint(9 - i, right - a.point(i).x(), a.point(i).y());
+ if (tab->shape == QTabBar::TriangularNorth)
+ for (i = 0; i < 10; ++i)
+ a.setPoint(i, a.point(i).x(), rect.height() - 1 - a.point(i).y());
+
+ a.translate(rect.left(), rect.top());
+ p->setRenderHint(QPainter::Antialiasing);
+ p->translate(0, 0.5);
+
+ QPainterPath path;
+ path.addPolygon(a);
+ p->drawPath(path);
+ break; }
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest: {
+ a.setPoint(0, -1, 0);
+ a.setPoint(1, 0, 0);
+ x = rect.width() - 2;
+ y = x / 3;
+ a.setPoint(2, x - 1, y++);
+ ++y;
+ a.setPoint(3, x++, y++);
+ a.setPoint(4, x, y);
+ int i;
+ int bottom = rect.height() - 1;
+ for (i = 0; i < 5; ++i)
+ a.setPoint(9 - i, a.point(i).x(), bottom - a.point(i).y());
+ if (tab->shape == QTabBar::TriangularWest)
+ for (i = 0; i < 10; ++i)
+ a.setPoint(i, rect.width() - 1 - a.point(i).x(), a.point(i).y());
+ a.translate(rect.left(), rect.top());
+ p->setRenderHint(QPainter::Antialiasing);
+ p->translate(0.5, 0);
+ QPainterPath path;
+ path.addPolygon(a);
+ p->drawPath(path);
+ break; }
+ default:
+ break;
+ }
+ p->restore();
+ }
+ break;
+ case CE_ToolBoxTabLabel:
+ if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
+ bool enabled = tb->state & State_Enabled;
+ bool selected = tb->state & State_Selected;
+ QPixmap pm = tb->icon.pixmap(proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb, widget),
+ enabled ? QIcon::Normal : QIcon::Disabled);
+
+ QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget);
+ QRect tr, ir;
+ int ih = 0;
+ if (pm.isNull()) {
+ tr = cr;
+ tr.adjust(4, 0, -8, 0);
+ } else {
+ int iw = pm.width() + 4;
+ ih = pm.height();
+ ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
+ tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
+ }
+
+ if (selected && proxy()->styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb, widget)) {
+ QFont f(p->font());
+ f.setBold(true);
+ p->setFont(f);
+ }
+
+ QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width());
+
+ if (ih)
+ p->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm);
+
+ int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
+ if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, tb, widget))
+ alignment |= Qt::TextHideMnemonic;
+ proxy()->drawItemText(p, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText);
+
+ if (!txt.isEmpty() && opt->state & State_HasFocus) {
+ QStyleOptionFocusRect opt;
+ opt.rect = tr;
+ opt.palette = tb->palette;
+ opt.state = QStyle::State_None;
+ proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, widget);
+ }
+ }
+ break;
+ case CE_TabBarTabLabel:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ QStyleOptionTabV3 tabV2(*tab);
+ QRect tr = tabV2.rect;
+ bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
+ || tabV2.shape == QTabBar::RoundedWest
+ || tabV2.shape == QTabBar::TriangularEast
+ || tabV2.shape == QTabBar::TriangularWest;
+
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ if (verticalTabs) {
+ p->save();
+ int newX, newY, newRot;
+ if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
+ newX = tr.width() + tr.x();
+ newY = tr.y();
+ newRot = 90;
+ } else {
+ newX = tr.x();
+ newY = tr.y() + tr.height();
+ newRot = -90;
+ }
+ QTransform m = QTransform::fromTranslate(newX, newY);
+ m.rotate(newRot);
+ p->setTransform(m, true);
+ }
+ QRect iconRect;
+ d->tabLayout(&tabV2, widget, &tr, &iconRect);
+ tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect
+
+ if (!tabV2.icon.isNull()) {
+ QPixmap tabIcon = tabV2.icon.pixmap(tabV2.iconSize,
+ (tabV2.state & State_Enabled) ? QIcon::Normal
+ : QIcon::Disabled,
+ (tabV2.state & State_Selected) ? QIcon::On
+ : QIcon::Off);
+ p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
+ }
+
+ proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
+ if (verticalTabs)
+ p->restore();
+
+ if (tabV2.state & State_HasFocus) {
+ const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);
+
+ int x1, x2;
+ x1 = tabV2.rect.left();
+ x2 = tabV2.rect.right() - 1;
+
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*tab);
+ fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
+ x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
+ drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_TABBAR
+#ifndef QT_NO_SIZEGRIP
+ case CE_SizeGrip: {
+ p->save();
+ int x, y, w, h;
+ opt->rect.getRect(&x, &y, &w, &h);
+
+ int sw = qMin(h, w);
+ if (h > w)
+ p->translate(0, h - w);
+ else
+ p->translate(w - h, 0);
+
+ int sx = x;
+ int sy = y;
+ int s = sw / 3;
+
+ Qt::Corner corner;
+ if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt))
+ corner = sgOpt->corner;
+ else if (opt->direction == Qt::RightToLeft)
+ corner = Qt::BottomLeftCorner;
+ else
+ corner = Qt::BottomRightCorner;
+
+ if (corner == Qt::BottomLeftCorner) {
+ sx = x + sw;
+ for (int i = 0; i < 4; ++i) {
+ p->setPen(QPen(opt->palette.light().color(), 1));
+ p->drawLine(x, sy - 1 , sx + 1, sw);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(x, sy, sx, sw);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(x, sy + 1, sx - 1, sw);
+ sx -= s;
+ sy += s;
+ }
+ } else if (corner == Qt::BottomRightCorner) {
+ for (int i = 0; i < 4; ++i) {
+ p->setPen(QPen(opt->palette.light().color(), 1));
+ p->drawLine(sx - 1, sw, sw, sy - 1);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(sx, sw, sw, sy);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(sx + 1, sw, sw, sy + 1);
+ sx += s;
+ sy += s;
+ }
+ } else if (corner == Qt::TopRightCorner) {
+ sy = y + sw;
+ for (int i = 0; i < 4; ++i) {
+ p->setPen(QPen(opt->palette.light().color(), 1));
+ p->drawLine(sx - 1, y, sw, sy + 1);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(sx, y, sw, sy);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(sx + 1, y, sw, sy - 1);
+ sx += s;
+ sy -= s;
+ }
+ } else if (corner == Qt::TopLeftCorner) {
+ for (int i = 0; i < 4; ++i) {
+ p->setPen(QPen(opt->palette.light().color(), 1));
+ p->drawLine(x, sy - 1, sx - 1, y);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(x, sy, sx, y);
+ p->setPen(QPen(opt->palette.dark().color(), 1));
+ p->drawLine(x, sy + 1, sx + 1, y);
+ sx += s;
+ sy += s;
+ }
+ }
+ p->restore();
+ break; }
+#endif // QT_NO_SIZEGRIP
+#ifndef QT_NO_RUBBERBAND
+ case CE_RubberBand: {
+ if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ QPixmap tiledPixmap(16, 16);
+ QPainter pixmapPainter(&tiledPixmap);
+ pixmapPainter.setPen(Qt::NoPen);
+ pixmapPainter.setBrush(Qt::Dense4Pattern);
+ pixmapPainter.setBackground(QBrush(opt->palette.base()));
+ pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
+ pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
+ pixmapPainter.end();
+ // ### workaround for borked XRENDER
+ tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
+
+ p->save();
+ QRect r = opt->rect;
+ QStyleHintReturnMask mask;
+ if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
+ p->setClipRegion(mask.region);
+ p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
+ p->setPen(opt->palette.color(QPalette::Active, QPalette::WindowText));
+ p->setBrush(Qt::NoBrush);
+ p->drawRect(r.adjusted(0, 0, -1, -1));
+ if (rbOpt->shape == QRubberBand::Rectangle)
+ p->drawRect(r.adjusted(3, 3, -4, -4));
+ p->restore();
+ }
+ break; }
+#endif // QT_NO_RUBBERBAND
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
+ QRect r = dwOpt->rect.adjusted(0, 0, -1, -1);
+ if (dwOpt->movable) {
+ p->setPen(dwOpt->palette.color(QPalette::Dark));
+ p->drawRect(r);
+ }
+
+ if (!dwOpt->title.isEmpty()) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ if (verticalTitleBar) {
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ p->save();
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ const int indent = p->fontMetrics().descent();
+ proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, dwOpt->title,
+ QPalette::WindowText);
+
+ if (verticalTitleBar)
+ p->restore();
+ }
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+ case CE_Header:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRegion clipRegion = p->clipRegion();
+ p->setClipRect(opt->rect);
+ proxy()->drawControl(CE_HeaderSection, header, p, widget);
+ QStyleOptionHeader subopt = *header;
+ subopt.rect = subElementRect(SE_HeaderLabel, header, widget);
+ if (subopt.rect.isValid())
+ proxy()->drawControl(CE_HeaderLabel, &subopt, p, widget);
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ subopt.rect = subElementRect(SE_HeaderArrow, opt, widget);
+ proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, p, widget);
+ }
+ p->setClipRegion(clipRegion);
+ }
+ break;
+ case CE_FocusFrame:
+ p->fillRect(opt->rect, opt->palette.foreground());
+ break;
+ case CE_HeaderSection:
+ qDrawShadePanel(p, opt->rect, opt->palette,
+ opt->state & State_Sunken, 1,
+ &opt->palette.brush(QPalette::Button));
+ break;
+ case CE_HeaderEmptyArea:
+ p->fillRect(opt->rect, opt->palette.background());
+ break;
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
+ p->save();
+ p->setClipRect(editRect);
+ if (!cb->currentIcon.isNull()) {
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width() + 4);
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ if (cb->editable)
+ p->fillRect(iconRect, opt->palette.brush(QPalette::Base));
+ proxy()->drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-4 - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + 4, 0);
+ }
+ if (!cb->currentText.isEmpty() && !cb->editable) {
+ proxy()->drawItemText(p, editRect.adjusted(1, 0, -1, 0),
+ visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ cb->palette, cb->state & State_Enabled, cb->currentText);
+ }
+ p->restore();
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ // Compatibility with styles that use PE_PanelToolBar
+ QStyleOptionFrame frame;
+ frame.QStyleOption::operator=(*toolBar);
+ frame.lineWidth = toolBar->lineWidth;
+ frame.midLineWidth = toolBar->midLineWidth;
+ proxy()->drawPrimitive(PE_PanelToolBar, opt, p, widget);
+
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget()))
+ break;
+ qDrawShadePanel(p, toolBar->rect, toolBar->palette, false, toolBar->lineWidth,
+ &toolBar->palette.brush(QPalette::Button));
+ }
+ break;
+#endif // QT_NO_TOOLBAR
+ case CE_ColumnViewGrip: {
+ // draw background gradients
+ QLinearGradient g(0, 0, opt->rect.width(), 0);
+ g.setColorAt(0, opt->palette.color(QPalette::Active, QPalette::Mid));
+ g.setColorAt(0.5, Qt::white);
+ p->fillRect(QRect(0, 0, opt->rect.width(), opt->rect.height()), g);
+
+ // draw the two lines
+ QPen pen(p->pen());
+ pen.setWidth(opt->rect.width()/20);
+ pen.setColor(opt->palette.color(QPalette::Active, QPalette::Dark));
+ p->setPen(pen);
+
+ int line1starting = opt->rect.width()*8 / 20;
+ int line2starting = opt->rect.width()*13 / 20;
+ int top = opt->rect.height()*20/75;
+ int bottom = opt->rect.height() - 1 - top;
+ p->drawLine(line1starting, top, line1starting, bottom);
+ p->drawLine(line2starting, top, line2starting, bottom);
+ }
+ break;
+
+#ifndef QT_NO_ITEMVIEWS
+ case CE_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ p->save();
+ p->setClipRect(opt->rect);
+
+ QRect checkRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
+ QRect iconRect = subElementRect(SE_ItemViewItemDecoration, vopt, widget);
+ QRect textRect = subElementRect(SE_ItemViewItemText, vopt, widget);
+
+ // draw the background
+ proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);
+
+ // draw the check mark
+ if (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) {
+ QStyleOptionViewItemV4 option(*vopt);
+ option.rect = checkRect;
+ option.state = option.state & ~QStyle::State_HasFocus;
+
+ switch (vopt->checkState) {
+ case Qt::Unchecked:
+ option.state |= QStyle::State_Off;
+ break;
+ case Qt::PartiallyChecked:
+ option.state |= QStyle::State_NoChange;
+ break;
+ case Qt::Checked:
+ option.state |= QStyle::State_On;
+ break;
+ }
+ proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, p, widget);
+ }
+
+ // draw the icon
+ QIcon::Mode mode = QIcon::Normal;
+ if (!(vopt->state & QStyle::State_Enabled))
+ mode = QIcon::Disabled;
+ else if (vopt->state & QStyle::State_Selected)
+ mode = QIcon::Selected;
+ QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
+ vopt->icon.paint(p, iconRect, vopt->decorationAlignment, mode, state);
+
+ // draw the text
+ if (!vopt->text.isEmpty()) {
+ QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ if (vopt->state & QStyle::State_Selected) {
+ p->setPen(vopt->palette.color(cg, QPalette::HighlightedText));
+ } else {
+ p->setPen(vopt->palette.color(cg, QPalette::Text));
+ }
+ if (vopt->state & QStyle::State_Editing) {
+ p->setPen(vopt->palette.color(cg, QPalette::Text));
+ p->drawRect(textRect.adjusted(0, 0, -1, -1));
+ }
+
+ d->viewItemDrawText(p, vopt, textRect);
+ }
+
+ // draw the focus rect
+ if (vopt->state & QStyle::State_HasFocus) {
+ QStyleOptionFocusRect o;
+ o.QStyleOption::operator=(*vopt);
+ o.rect = proxy()->subElementRect(SE_ItemViewItemFocusRect, vopt, widget);
+ o.state |= QStyle::State_KeyboardFocusChange;
+ o.state |= QStyle::State_Item;
+ QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled)
+ ? QPalette::Normal : QPalette::Disabled;
+ o.backgroundColor = vopt->palette.color(cg, (vopt->state & QStyle::State_Selected)
+ ? QPalette::Highlight : QPalette::Window);
+ proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, p, widget);
+ }
+
+ p->restore();
+ }
+ break;
+
+#endif // QT_NO_ITEMVIEWS
+#ifndef QT_NO_FRAME
+ case CE_ShapedFrame:
+ if (const QStyleOptionFrameV3 *f = qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) {
+ int frameShape = f->frameShape;
+ int frameShadow = QFrame::Plain;
+ if (f->state & QStyle::State_Sunken) {
+ frameShadow = QFrame::Sunken;
+ } else if (f->state & QStyle::State_Raised) {
+ frameShadow = QFrame::Raised;
+ }
+
+ int lw = f->lineWidth;
+ int mlw = f->midLineWidth;
+ QPalette::ColorRole foregroundRole = QPalette::WindowText;
+ if (widget)
+ foregroundRole = widget->foregroundRole();
+
+ switch (frameShape) {
+ case QFrame::Box:
+ if (frameShadow == QFrame::Plain) {
+ qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
+ } else {
+ qDrawShadeRect(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
+ }
+ break;
+ case QFrame::StyledPanel:
+ //keep the compatibility with Qt 4.4 if there is a proxy style.
+ //be sure to call drawPrimitive(QStyle::PE_Frame) on the proxy style
+ if (widget) {
+ widget->style()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
+ } else {
+ proxy()->drawPrimitive(QStyle::PE_Frame, opt, p, widget);
+ }
+ break;
+ case QFrame::Panel:
+ if (frameShadow == QFrame::Plain) {
+ qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
+ } else {
+ qDrawShadePanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw);
+ }
+ break;
+ case QFrame::WinPanel:
+ if (frameShadow == QFrame::Plain) {
+ qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw);
+ } else {
+ qDrawWinPanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken);
+ }
+ break;
+ case QFrame::HLine:
+ case QFrame::VLine: {
+ QPoint p1, p2;
+ if (frameShape == QFrame::HLine) {
+ p1 = QPoint(opt->rect.x(), opt->rect.height() / 2);
+ p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y());
+ } else {
+ p1 = QPoint(opt->rect.x()+opt->rect.width() / 2, 0);
+ p2 = QPoint(p1.x(), opt->rect.height());
+ }
+ if (frameShadow == QFrame::Plain) {
+ QPen oldPen = p->pen();
+ p->setPen(QPen(opt->palette.brush(foregroundRole), lw));
+ p->drawLine(p1, p2);
+ p->setPen(oldPen);
+ } else {
+ qDrawShadeLine(p, p1, p2, f->palette, frameShadow == QFrame::Sunken, lw, mlw);
+ }
+ break;
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ Q_D(const QCommonStyle);
+ QRect r;
+ switch (sr) {
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ int dx1, dx2;
+ dx1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+ if (btn->features & QStyleOptionButton::AutoDefaultButton)
+ dx1 += proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
+ dx2 = dx1 * 2;
+ r.setRect(opt->rect.x() + dx1, opt->rect.y() + dx1, opt->rect.width() - dx2,
+ opt->rect.height() - dx2);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+ case SE_PushButtonFocusRect:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ int dbw1 = 0, dbw2 = 0;
+ if (btn->features & QStyleOptionButton::AutoDefaultButton){
+ dbw1 = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
+ dbw2 = dbw1 * 2;
+ }
+
+ int dfw1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget) + 1,
+ dfw2 = dfw1 * 2;
+
+ r.setRect(btn->rect.x() + dfw1 + dbw1, btn->rect.y() + dfw1 + dbw1,
+ btn->rect.width() - dfw2 - dbw2, btn->rect.height()- dfw2 - dbw2);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+ case SE_CheckBoxIndicator:
+ {
+ int h = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
+ r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
+ proxy()->pixelMetric(PM_IndicatorWidth, opt, widget), h);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+
+ case SE_CheckBoxContents:
+ {
+ // Deal with the logical first, then convert it back to screen coords.
+ QRect ir = visualRect(opt->direction, opt->rect,
+ subElementRect(SE_CheckBoxIndicator, opt, widget));
+ int spacing = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget);
+ r.setRect(ir.right() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
+ opt->rect.height());
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+
+ case SE_CheckBoxFocusRect:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (btn->icon.isNull() && btn->text.isEmpty()) {
+ r = subElementRect(SE_CheckBoxIndicator, opt, widget);
+ r.adjust(1, 1, -1, -1);
+ break;
+ }
+ // As above, deal with the logical first, then convert it back to screen coords.
+ QRect cr = visualRect(btn->direction, btn->rect,
+ subElementRect(SE_CheckBoxContents, btn, widget));
+
+ QRect iconRect, textRect;
+ if (!btn->text.isEmpty()) {
+ textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft
+ | Qt::AlignVCenter | Qt::TextShowMnemonic,
+ btn->state & State_Enabled, btn->text);
+ }
+ if (!btn->icon.isNull()) {
+ iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
+ | Qt::TextShowMnemonic,
+ btn->icon.pixmap(btn->iconSize, QIcon::Normal));
+ if (!textRect.isEmpty())
+ textRect.translate(iconRect.right() + 4, 0);
+ }
+ r = iconRect | textRect;
+ r.adjust(-3, -2, 3, 2);
+ r = r.intersected(btn->rect);
+ r = visualRect(btn->direction, btn->rect, r);
+ }
+ break;
+
+ case SE_RadioButtonIndicator:
+ {
+ int h = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget);
+ r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2),
+ proxy()->pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), h);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+
+ case SE_RadioButtonContents:
+ {
+ QRect ir = visualRect(opt->direction, opt->rect,
+ subElementRect(SE_RadioButtonIndicator, opt, widget));
+ int spacing = proxy()->pixelMetric(PM_RadioButtonLabelSpacing, opt, widget);
+ r.setRect(ir.left() + ir.width() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing,
+ opt->rect.height());
+ r = visualRect(opt->direction, opt->rect, r);
+ break;
+ }
+
+ case SE_RadioButtonFocusRect:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (btn->icon.isNull() && btn->text.isEmpty()) {
+ r = subElementRect(SE_RadioButtonIndicator, opt, widget);
+ r.adjust(1, 1, -1, -1);
+ break;
+ }
+ QRect cr = visualRect(btn->direction, btn->rect,
+ subElementRect(SE_RadioButtonContents, opt, widget));
+
+ QRect iconRect, textRect;
+ if (!btn->text.isEmpty()){
+ textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter
+ | Qt::TextShowMnemonic, btn->state & State_Enabled, btn->text);
+ }
+ if (!btn->icon.isNull()) {
+ iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic,
+ btn->icon.pixmap(btn->iconSize, QIcon::Normal));
+ if (!textRect.isEmpty())
+ textRect.translate(iconRect.right() + 4, 0);
+ }
+ r = iconRect | textRect;
+ r.adjust(-3, -2, 3, 2);
+ r = r.intersected(btn->rect);
+ r = visualRect(btn->direction, btn->rect, r);
+ }
+ break;
+#ifndef QT_NO_SLIDER
+ case SE_SliderFocusRect:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ if (slider->orientation == Qt::Horizontal)
+ r.setRect(0, tickOffset - 1, slider->rect.width(), thickness + 2);
+ else
+ r.setRect(tickOffset - 1, 0, thickness + 2, slider->rect.height());
+ r = r.intersected(slider->rect);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_PROGRESSBAR
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ int textw = 0;
+ bool vertical = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ }
+ if (!vertical) {
+ if (pb->textVisible)
+ textw = qMax(pb->fontMetrics.width(pb->text), pb->fontMetrics.width(QLatin1String("100%"))) + 6;
+ }
+
+ if ((pb->textAlignment & Qt::AlignCenter) == 0) {
+ if (sr != SE_ProgressBarLabel)
+ r.setCoords(pb->rect.left(), pb->rect.top(),
+ pb->rect.right() - textw, pb->rect.bottom());
+ else
+ r.setCoords(pb->rect.right() - textw, pb->rect.top(),
+ pb->rect.right(), pb->rect.bottom());
+ } else {
+ r = pb->rect;
+ }
+ r = visualRect(pb->direction, pb->rect, r);
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+#ifdef QT3_SUPPORT
+ case SE_Q3DockWindowHandleRect:
+ if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
+ if (!dw->docked || !dw->closeEnabled)
+ r.setRect(0, 0, dw->rect.width(), dw->rect.height());
+ else {
+ if (dw->state & State_Horizontal)
+ r.setRect(0, 15, dw->rect.width(), dw->rect.height() - 15);
+ else
+ r.setRect(0, 1, dw->rect.width() - 15, dw->rect.height() - 1);
+ }
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+#endif // QT3_SUPPORT
+#ifndef QT_NO_COMBOBOX
+ case SE_ComboBoxFocusRect:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ int margin = cb->frame ? 3 : 0;
+ r.setRect(opt->rect.left() + margin, opt->rect.top() + margin,
+ opt->rect.width() - 2*margin - 16, opt->rect.height() - 2*margin);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_TOOLBOX
+ case SE_ToolBoxTabContents:
+ r = opt->rect;
+ r.adjust(0, 0, -30, 0);
+ break;
+#endif // QT_NO_TOOLBOX
+ case SE_HeaderLabel: {
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
+ r.setRect(opt->rect.x() + margin, opt->rect.y() + margin,
+ opt->rect.width() - margin * 2, opt->rect.height() - margin * 2);
+
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ // Subtract width needed for arrow, if there is one
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ if (opt->state & State_Horizontal)
+ r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2));
+ else
+ r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2));
+ }
+ }
+ r = visualRect(opt->direction, opt->rect, r);
+ break; }
+ case SE_HeaderArrow: {
+ int h = opt->rect.height();
+ int w = opt->rect.width();
+ int x = opt->rect.x();
+ int y = opt->rect.y();
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
+
+ if (opt->state & State_Horizontal) {
+ int horiz_size = h / 2;
+ r.setRect(x + w - margin * 2 - horiz_size, y + 5,
+ horiz_size, h - margin * 2 - 5);
+ } else {
+ int vert_size = w / 2;
+ r.setRect(x + 5, y + h - margin * 2 - vert_size,
+ w - margin * 2 - 5, vert_size);
+ }
+ r = visualRect(opt->direction, opt->rect, r);
+ break; }
+
+ case SE_RadioButtonClickRect:
+ r = subElementRect(SE_RadioButtonFocusRect, opt, widget);
+ r |= subElementRect(SE_RadioButtonIndicator, opt, widget);
+ break;
+ case SE_CheckBoxClickRect:
+ r = subElementRect(SE_CheckBoxFocusRect, opt, widget);
+ r |= subElementRect(SE_CheckBoxIndicator, opt, widget);
+ break;
+#ifndef QT_NO_TABWIDGET
+ case SE_TabWidgetTabBar:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ r.setSize(twf->tabBarSize);
+ const uint alingMask = Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter;
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ // Constrain the size now, otherwise, center could get off the page
+ // This of course repeated for all the other directions
+ r.setWidth(qMin(r.width(), twf->rect.width()
+ - twf->leftCornerWidgetSize.width()
+ - twf->rightCornerWidgetSize.width()));
+ switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
+ default:
+ case Qt::AlignLeft:
+ r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0));
+ break;
+ case Qt::AlignHCenter:
+ r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
+ + (twf->leftCornerWidgetSize.width() / 2)
+ - (twf->rightCornerWidgetSize.width() / 2), 0));
+ break;
+ case Qt::AlignRight:
+ r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
+ - twf->rightCornerWidgetSize.width(), 0));
+ break;
+ }
+ r = visualRect(twf->direction, twf->rect, r);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r.setWidth(qMin(r.width(), twf->rect.width()
+ - twf->leftCornerWidgetSize.width()
+ - twf->rightCornerWidgetSize.width()));
+ switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
+ default:
+ case Qt::AlignLeft:
+ r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(),
+ twf->rect.height() - twf->tabBarSize.height()));
+ break;
+ case Qt::AlignHCenter:
+ r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f)
+ + (twf->leftCornerWidgetSize.width() / 2)
+ - (twf->rightCornerWidgetSize.width() / 2),
+ twf->rect.height() - twf->tabBarSize.height()));
+ break;
+ case Qt::AlignRight:
+ r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width()
+ - twf->rightCornerWidgetSize.width(),
+ twf->rect.height() - twf->tabBarSize.height()));
+ break;
+ }
+ r = visualRect(twf->direction, twf->rect, r);
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ r.setHeight(qMin(r.height(), twf->rect.height()
+ - twf->leftCornerWidgetSize.height()
+ - twf->rightCornerWidgetSize.height()));
+ switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
+ default:
+ case Qt::AlignLeft:
+ r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
+ twf->leftCornerWidgetSize.height()));
+ break;
+ case Qt::AlignHCenter:
+ r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
+ twf->rect.center().y() - r.height() / 2));
+ break;
+ case Qt::AlignRight:
+ r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
+ twf->rect.height() - twf->tabBarSize.height()
+ - twf->rightCornerWidgetSize.height()));
+ break;
+ }
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ r.setHeight(qMin(r.height(), twf->rect.height()
+ - twf->leftCornerWidgetSize.height()
+ - twf->rightCornerWidgetSize.height()));
+ switch (proxy()->styleHint(SH_TabBar_Alignment, twf, widget) & alingMask) {
+ default:
+ case Qt::AlignLeft:
+ r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height()));
+ break;
+ case Qt::AlignHCenter:
+ r.moveTopLeft(QPoint(0, twf->rect.center().y() - r.height() / 2));
+ break;
+ case Qt::AlignRight:
+ r.moveTopLeft(QPoint(0, twf->rect.height() - twf->tabBarSize.height()
+ - twf->rightCornerWidgetSize.height()));
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case SE_TabWidgetTabPane:
+ case SE_TabWidgetTabContents:
+ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QStyleOptionTab tabopt;
+ tabopt.shape = twf->shape;
+ int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &tabopt, widget);
+ if (twf->lineWidth == 0)
+ overlap = 0;
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ r = QRect(QPoint(0,qMax(twf->tabBarSize.height() - overlap, 0)),
+ QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r = QRect(QPoint(0,0), QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height())));
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ r = QRect(QPoint(0, 0), QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ r = QRect(QPoint(qMax(twf->tabBarSize.width() - overlap, 0), 0),
+ QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height()));
+ break;
+ }
+ if (sr == SE_TabWidgetTabContents && twf->lineWidth > 0)
+ r.adjust(2, 2, -2, -2);
+ }
+ break;
+ case SE_TabWidgetLeftCorner:
+ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()),
+ twf->leftCornerWidgetSize);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
+ break;
+ default:
+ break;
+ }
+ r = visualRect(twf->direction, twf->rect, r);
+ }
+ break;
+ case SE_TabWidgetRightCorner:
+ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
+ paneRect.y() - twf->rightCornerWidgetSize.height()),
+ twf->rightCornerWidgetSize);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(),
+ paneRect.height()), twf->rightCornerWidgetSize);
+ break;
+ default:
+ break;
+ }
+ r = visualRect(twf->direction, twf->rect, r);
+ }
+ break;
+ case SE_TabBarTabText:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ QStyleOptionTabV3 tabV3(*tab);
+ QRect dummyIconRect;
+ d->tabLayout(&tabV3, widget, &r, &dummyIconRect);
+ }
+ break;
+ case SE_TabBarTabLeftButton:
+ case SE_TabBarTabRightButton:
+ if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
+ bool selected = tab->state & State_Selected;
+ int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
+ int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
+ int hpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
+ hpadding = qMax(hpadding, 4); //workaround KStyle returning 0 because they workaround an old bug in Qt
+
+ bool verticalTabs = tab->shape == QTabBar::RoundedEast
+ || tab->shape == QTabBar::RoundedWest
+ || tab->shape == QTabBar::TriangularEast
+ || tab->shape == QTabBar::TriangularWest;
+
+ QRect tr = tab->rect;
+ if (tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::TriangularSouth)
+ verticalShift = -verticalShift;
+ if (verticalTabs) {
+ qSwap(horizontalShift, verticalShift);
+ horizontalShift *= -1;
+ verticalShift *= -1;
+ }
+ if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest)
+ horizontalShift = -horizontalShift;
+
+ tr.adjust(0, 0, horizontalShift, verticalShift);
+ if (selected)
+ {
+ tr.setBottom(tr.bottom() - verticalShift);
+ tr.setRight(tr.right() - horizontalShift);
+ }
+
+ QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
+ int w = size.width();
+ int h = size.height();
+ int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
+ int midWidth = ((tr.width() - w) / 2);
+
+ bool atTheTop = true;
+ switch (tab->shape) {
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ atTheTop = (sr == SE_TabBarTabLeftButton);
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ atTheTop = (sr == SE_TabBarTabRightButton);
+ break;
+ default:
+ if (sr == SE_TabBarTabLeftButton)
+ r = QRect(tab->rect.x() + hpadding, midHeight, w, h);
+ else
+ r = QRect(tab->rect.right() - w - hpadding, midHeight, w, h);
+ r = visualRect(tab->direction, tab->rect, r);
+ }
+ if (verticalTabs) {
+ if (atTheTop)
+ r = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h);
+ else
+ r = QRect(midWidth, tr.y() + hpadding, w, h);
+ }
+ }
+
+ break;
+#endif // QT_NO_TABWIDGET
+#ifndef QT_NO_TABBAR
+ case SE_TabBarTearIndicator:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r.setRect(tab->rect.left(), tab->rect.top(), 4, opt->rect.height());
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), 4);
+ break;
+ default:
+ break;
+ }
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+#endif
+ case SE_TreeViewDisclosureItem:
+ r = opt->rect;
+ break;
+ case SE_LineEditContents:
+ if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ r = f->rect.adjusted(f->lineWidth, f->lineWidth, -f->lineWidth, -f->lineWidth);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+ case SE_FrameContents:
+ if (const QStyleOptionFrameV2 *f = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt)) {
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, f, widget);
+ r = opt->rect.adjusted(fw, fw, -fw, -fw);
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
+ case SE_ShapedFrameContents:
+ if (const QStyleOptionFrameV3 *f = qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) {
+ int frameShape = f->frameShape;
+ int frameShadow = QFrame::Plain;
+ if (f->state & QStyle::State_Sunken) {
+ frameShadow = QFrame::Sunken;
+ } else if (f->state & QStyle::State_Raised) {
+ frameShadow = QFrame::Raised;
+ }
+
+ int frameWidth = 0;
+
+ switch (frameShape) {
+ case QFrame::NoFrame:
+ frameWidth = 0;
+ break;
+
+ case QFrame::Box:
+ case QFrame::HLine:
+ case QFrame::VLine:
+ switch (frameShadow) {
+ case QFrame::Plain:
+ frameWidth = f->lineWidth;
+ break;
+ case QFrame::Raised:
+ case QFrame::Sunken:
+ frameWidth = (short)(f->lineWidth*2 + f->midLineWidth);
+ break;
+ }
+ break;
+
+ case QFrame::StyledPanel:
+ //keep the compatibility with Qt 4.4 if there is a proxy style.
+ //be sure to call drawPrimitive(QStyle::SE_FrameContents) on the proxy style
+ if (widget)
+ return widget->style()->subElementRect(QStyle::SE_FrameContents, opt, widget);
+ else
+ return subElementRect(QStyle::SE_FrameContents, opt, widget);
+ break;
+
+ case QFrame::WinPanel:
+ frameWidth = 2;
+ break;
+
+ case QFrame::Panel:
+ switch (frameShadow) {
+ case QFrame::Plain:
+ case QFrame::Raised:
+ case QFrame::Sunken:
+ frameWidth = f->lineWidth;
+ break;
+ }
+ break;
+ }
+ r = f->rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth);
+ }
+ break;
+#ifndef QT_NO_DOCKWIDGET
+ case SE_DockWidgetCloseButton:
+ case SE_DockWidgetFloatButton:
+ case SE_DockWidgetTitleBarText:
+ case SE_DockWidgetIcon: {
+ int iconSize = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ int buttonMargin = proxy()->pixelMetric(PM_DockWidgetTitleBarButtonMargin, opt, widget);
+ int margin = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, opt, widget);
+ QRect rect = opt->rect;
+
+ const QStyleOptionDockWidget *dwOpt
+ = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
+ bool canClose = dwOpt == 0 ? true : dwOpt->closable;
+ bool canFloat = dwOpt == 0 ? false : dwOpt->floatable;
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ // If this is a vertical titlebar, we transpose and work as if it was
+ // horizontal, then transpose again.
+
+ if (verticalTitleBar) {
+ QSize size = rect.size();
+ size.transpose();
+ rect.setSize(size);
+ }
+
+ do {
+
+ int right = rect.right();
+ int left = rect.left();
+
+ QRect closeRect;
+ if (canClose) {
+ QSize sz = standardIcon(QStyle::SP_TitleBarCloseButton,
+ opt, widget).actualSize(QSize(iconSize, iconSize));
+ sz += QSize(buttonMargin, buttonMargin);
+ if (verticalTitleBar)
+ sz.transpose();
+ closeRect = QRect(right - sz.width(),
+ rect.center().y() - sz.height()/2,
+ sz.width(), sz.height());
+ right = closeRect.left() - 1;
+ }
+ if (sr == SE_DockWidgetCloseButton) {
+ r = closeRect;
+ break;
+ }
+
+ QRect floatRect;
+ if (canFloat) {
+ QSize sz = standardIcon(QStyle::SP_TitleBarNormalButton,
+ opt, widget).actualSize(QSize(iconSize, iconSize));
+ sz += QSize(buttonMargin, buttonMargin);
+ if (verticalTitleBar)
+ sz.transpose();
+ floatRect = QRect(right - sz.width(),
+ rect.center().y() - sz.height()/2,
+ sz.width(), sz.height());
+ right = floatRect.left() - 1;
+ }
+ if (sr == SE_DockWidgetFloatButton) {
+ r = floatRect;
+ break;
+ }
+
+ QRect iconRect;
+ if (const QDockWidget *dw = qobject_cast<const QDockWidget*>(widget)) {
+ QIcon icon;
+ if (dw->isFloating())
+ icon = dw->windowIcon();
+ if (!icon.isNull()
+ && icon.cacheKey() != QApplication::windowIcon().cacheKey()) {
+ QSize sz = icon.actualSize(QSize(r.height(), r.height()));
+ if (verticalTitleBar)
+ sz.transpose();
+ iconRect = QRect(left, rect.center().y() - sz.height()/2,
+ sz.width(), sz.height());
+ left = iconRect.right() + margin;
+ }
+ }
+ if (sr == SE_DockWidgetIcon) {
+ r = iconRect;
+ break;
+ }
+
+ QRect textRect = QRect(left, rect.top(),
+ right - left, rect.height());
+ if (sr == SE_DockWidgetTitleBarText) {
+ r = textRect;
+ break;
+ }
+
+ } while (false);
+
+ if (verticalTitleBar) {
+ r = QRect(rect.left() + r.top() - rect.top(),
+ rect.top() + rect.right() - r.right(),
+ r.height(), r.width());
+ } else {
+ r = visualRect(opt->direction, rect, r);
+ }
+ break;
+ }
+#endif
+#ifndef QT_NO_ITEMVIEWS
+ case SE_ItemViewItemCheckIndicator:
+ if (!qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ r = subElementRect(SE_CheckBoxIndicator, opt, widget);
+ break;
+ }
+ case SE_ItemViewItemDecoration:
+ case SE_ItemViewItemText:
+ case SE_ItemViewItemFocusRect:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ if (!d->isViewItemCached(*vopt)) {
+ d->viewItemLayout(vopt, &d->checkRect, &d->decorationRect, &d->displayRect, false);
+ if (d->cachedOption) {
+ delete d->cachedOption;
+ d->cachedOption = 0;
+ }
+ d->cachedOption = new QStyleOptionViewItemV4(*vopt);
+ }
+ if (sr == SE_ViewItemCheckIndicator)
+ r = d->checkRect;
+ else if (sr == SE_ItemViewItemDecoration)
+ r = d->decorationRect;
+ else if (sr == SE_ItemViewItemText || sr == SE_ItemViewItemFocusRect)
+ r = d->displayRect;
+ }
+ break;
+#endif //QT_NO_ITEMVIEWS
+#ifndef QT_NO_TOOLBAR
+ case SE_ToolBarHandle:
+ if (const QStyleOptionToolBar *tbopt = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ if (tbopt->features & QStyleOptionToolBar::Movable) {
+ ///we need to access the widget here because the style option doesn't
+ //have all the information we need (ie. the layout's margin)
+ const QToolBar *tb = qobject_cast<const QToolBar*>(widget);
+ const int margin = tb && tb->layout() ? tb->layout()->margin() : 2;
+ const int handleExtent = pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
+ if (tbopt->state & QStyle::State_Horizontal) {
+ r = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin);
+ r = QStyle::visualRect(tbopt->direction, tbopt->rect, r);
+ } else {
+ r = QRect(margin, margin, tbopt->rect.width() - 2*margin, handleExtent);
+ }
+ }
+ }
+ break;
+#endif //QT_NO_TOOLBAR
+ default:
+ break;
+ }
+ return r;
+}
+
+#ifndef QT_NO_DIAL
+
+static QPolygonF calcArrow(const QStyleOptionSlider *dial, qreal &a)
+{
+ int width = dial->rect.width();
+ int height = dial->rect.height();
+ int r = qMin(width, height) / 2;
+ int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
+
+ if (dial->maximum == dial->minimum)
+ a = Q_PI / 2;
+ else if (dial->dialWrapping)
+ a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI
+ / (dial->maximum - dial->minimum);
+ else
+ a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI
+ / (dial->maximum - dial->minimum)) / 6;
+
+ int xc = width / 2;
+ int yc = height / 2;
+
+ int len = r - QStyleHelper::calcBigLineSize(r) - 5;
+ if (len < 5)
+ len = 5;
+ int back = len / 2;
+
+ QPolygonF arrow(3);
+ arrow[0] = QPointF(0.5 + xc + len * qCos(a),
+ 0.5 + yc - len * qSin(a));
+ arrow[1] = QPointF(0.5 + xc + back * qCos(a + Q_PI * 5 / 6),
+ 0.5 + yc - back * qSin(a + Q_PI * 5 / 6));
+ arrow[2] = QPointF(0.5 + xc + back * qCos(a - Q_PI * 5 / 6),
+ 0.5 + yc - back * qSin(a - Q_PI * 5 / 6));
+ return arrow;
+}
+
+#endif // QT_NO_DIAL
+
+/*!
+ \reimp
+*/
+void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ QPainter *p, const QWidget *widget) const
+{
+ switch (cc) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ if (slider->subControls == SC_SliderTickmarks) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int ticks = slider->tickPosition;
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+ if (interval <= 0) {
+ interval = slider->singleStep;
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+ if (!interval)
+ interval = 1;
+ int fudge = len / 2;
+ int pos;
+ // Since there is no subrect for tickmarks do a translation here.
+ p->save();
+ p->translate(slider->rect.x(), slider->rect.y());
+ p->setPen(slider->palette.foreground().color());
+ int v = slider->minimum;
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, available) + fudge;
+ if (slider->orientation == Qt::Horizontal) {
+ if (ticks & QSlider::TicksAbove)
+ p->drawLine(pos, 0, pos, tickOffset - 2);
+ if (ticks & QSlider::TicksBelow)
+ p->drawLine(pos, tickOffset + thickness + 1, pos,
+ slider->rect.height()-1);
+ } else {
+ if (ticks & QSlider::TicksAbove)
+ p->drawLine(0, pos, tickOffset - 2, pos);
+ if (ticks & QSlider::TicksBelow)
+ p->drawLine(tickOffset + thickness + 1, pos,
+ slider->rect.width()-1, pos);
+ }
+ // in the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ p->restore();
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ // Make a copy here and reset it for each primitive.
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ State saveFlags = scrollbar->state;
+
+ if (scrollbar->subControls & SC_ScrollBarSubLine) {
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubLine, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarSubLine, &newScrollbar, p, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarAddLine) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddLine, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarAddLine, &newScrollbar, p, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarSubPage) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubPage, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSubPage))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarSubPage, &newScrollbar, p, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarAddPage) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddPage, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarAddPage))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarAddPage, &newScrollbar, p, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarFirst) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarFirst, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarFirst))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarFirst, &newScrollbar, p, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarLast) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarLast, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarLast))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarLast, &newScrollbar, p, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarSlider) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSlider, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ proxy()->drawControl(CE_ScrollBarSlider, &newScrollbar, p, widget);
+
+ if (scrollbar->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(newScrollbar);
+ fropt.rect.setRect(newScrollbar.rect.x() + 2, newScrollbar.rect.y() + 2,
+ newScrollbar.rect.width() - 5,
+ newScrollbar.rect.height() - 5);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ }
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifdef QT3_SUPPORT
+ case CC_Q3ListView:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (lv->subControls & SC_Q3ListView)
+ p->fillRect(lv->rect, lv->viewportPalette.brush(lv->viewportBGRole));
+ }
+ break;
+#endif // QT3_SUPPORT
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox copy = *sb;
+ PrimitiveElement pe;
+
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
+ qDrawWinPanel(p, r, sb->palette, true);
+ }
+
+ if (sb->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &copy, p, widget);
+ copy.rect.adjust(3, 0, -4, 0);
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+
+ if (sb->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = sb->state;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &copy, p, widget);
+ copy.rect.adjust(3, 0, -4, 0);
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
+
+ State bflags = toolbutton->state & ~State_Sunken;
+
+ if (bflags & State_AutoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+ State mflags = bflags;
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ mflags |= State_Sunken;
+ }
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised)) {
+ tool.rect = button;
+ tool.state = bflags;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ }
+ }
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect.adjust(3, 3, -3, -3);
+ if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
+ fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
+ toolbutton, widget), 0);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if (mflags & (State_Sunken | State_On | State_Raised))
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
+ } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() + 5 - mbi, ir.y() + ir.height() - mbi + 4, mbi - 6, mbi - 6);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRect ir;
+ if (opt->subControls & SC_TitleBarLabel) {
+ QColor left = tb->palette.highlight().color();
+ QColor right = tb->palette.base().color();
+
+ QBrush fillBrush(left);
+ if (left != right) {
+ QPoint p1(tb->rect.x(), tb->rect.top() + tb->rect.height()/2);
+ QPoint p2(tb->rect.right(), tb->rect.top() + tb->rect.height()/2);
+ QLinearGradient lg(p1, p2);
+ lg.setColorAt(0, left);
+ lg.setColorAt(1, right);
+ fillBrush = lg;
+ }
+
+ p->fillRect(opt->rect, fillBrush);
+
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
+
+ p->setPen(tb->palette.highlightedText().color());
+ p->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+
+ bool down = false;
+ QPixmap pm;
+
+ QStyleOption tool(0);
+ tool.palette = tb->palette;
+ if (tb->subControls & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarCloseButton, widget);
+ down = tb->activeSubControls & SC_TitleBarCloseButton && (opt->state & State_Sunken);
+ if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool
+#ifndef QT_NO_DOCKWIDGET
+ || qobject_cast<const QDockWidget *>(widget)
+#endif
+ )
+ pm = standardIcon(SP_DockWidgetCloseButton, &tool, widget).pixmap(10, 10);
+ else
+ pm = standardIcon(SP_TitleBarCloseButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+
+ if (tb->subControls & SC_TitleBarMaxButton
+ && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
+ && !(tb->titleBarState & Qt::WindowMaximized)) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMaxButton, widget);
+
+ down = tb->activeSubControls & SC_TitleBarMaxButton && (opt->state & State_Sunken);
+ pm = standardIcon(SP_TitleBarMaxButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+
+ if (tb->subControls & SC_TitleBarMinButton
+ && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
+ && !(tb->titleBarState & Qt::WindowMinimized)) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMinButton, widget);
+ down = tb->activeSubControls & SC_TitleBarMinButton && (opt->state & State_Sunken);
+ pm = standardIcon(SP_TitleBarMinButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+
+ bool drawNormalButton = (tb->subControls & SC_TitleBarNormalButton)
+ && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ && (tb->titleBarState & Qt::WindowMinimized))
+ || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ && (tb->titleBarState & Qt::WindowMaximized)));
+
+ if (drawNormalButton) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarNormalButton, widget);
+ down = tb->activeSubControls & SC_TitleBarNormalButton && (opt->state & State_Sunken);
+ pm = standardIcon(SP_TitleBarNormalButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+
+ if (tb->subControls & SC_TitleBarShadeButton
+ && tb->titleBarFlags & Qt::WindowShadeButtonHint
+ && !(tb->titleBarState & Qt::WindowMinimized)) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarShadeButton, widget);
+ down = (tb->activeSubControls & SC_TitleBarShadeButton && (opt->state & State_Sunken));
+ pm = standardIcon(SP_TitleBarShadeButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+
+ if (tb->subControls & SC_TitleBarUnshadeButton
+ && tb->titleBarFlags & Qt::WindowShadeButtonHint
+ && tb->titleBarState & Qt::WindowMinimized) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarUnshadeButton, widget);
+
+ down = tb->activeSubControls & SC_TitleBarUnshadeButton && (opt->state & State_Sunken);
+ pm = standardIcon(SP_TitleBarUnshadeButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+ if (tb->subControls & SC_TitleBarContextHelpButton
+ && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarContextHelpButton, widget);
+
+ down = tb->activeSubControls & SC_TitleBarContextHelpButton && (opt->state & State_Sunken);
+ pm = standardIcon(SP_TitleBarContextHelpButton, &tool, widget).pixmap(10, 10);
+ tool.rect = ir;
+ tool.state = down ? State_Sunken : State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ p->save();
+ if (down)
+ p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget));
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+ if (tb->subControls & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarSysMenu, widget);
+ if (!tb->icon.isNull()) {
+ tb->icon.paint(p, ir);
+ } else {
+ int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
+ pm = standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(iconSize, iconSize);
+ tool.rect = ir;
+ p->save();
+ proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ p->restore();
+ }
+ }
+ }
+ break;
+#ifndef QT_NO_DIAL
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ // OK, this is more a port of things over
+ p->save();
+
+ // avoid dithering
+ if (p->paintEngine()->hasFeature(QPaintEngine::Antialiasing))
+ p->setRenderHint(QPainter::Antialiasing);
+
+ int width = dial->rect.width();
+ int height = dial->rect.height();
+ qreal r = qMin(width, height) / 2;
+ qreal d_ = r / 6;
+ qreal dx = dial->rect.x() + d_ + (width - 2 * r) / 2 + 1;
+ qreal dy = dial->rect.y() + d_ + (height - 2 * r) / 2 + 1;
+ QRect br = QRect(int(dx), int(dy), int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2));
+
+ QPalette pal = opt->palette;
+ // draw notches
+ if (dial->subControls & QStyle::SC_DialTickmarks) {
+ p->setPen(pal.foreground().color());
+ p->drawLines(QStyleHelper::calcLines(dial));
+ }
+
+ if (dial->state & State_Enabled) {
+ p->setBrush(pal.brush(QPalette::ColorRole(proxy()->styleHint(SH_Dial_BackgroundRole,
+ dial, widget))));
+ p->setPen(Qt::NoPen);
+ p->drawEllipse(br);
+ p->setBrush(Qt::NoBrush);
+ }
+ p->setPen(QPen(pal.dark().color()));
+ p->drawArc(br, 60 * 16, 180 * 16);
+ p->setPen(QPen(pal.light().color()));
+ p->drawArc(br, 240 * 16, 180 * 16);
+
+ qreal a;
+ QPolygonF arrow(calcArrow(dial, a));
+
+ p->setPen(Qt::NoPen);
+ p->setBrush(pal.button());
+ p->drawPolygon(arrow);
+
+ a = QStyleHelper::angle(QPointF(width / 2, height / 2), arrow[0]);
+ p->setBrush(Qt::NoBrush);
+
+ if (a <= 0 || a > 200) {
+ p->setPen(pal.light().color());
+ p->drawLine(arrow[2], arrow[0]);
+ p->drawLine(arrow[1], arrow[2]);
+ p->setPen(pal.dark().color());
+ p->drawLine(arrow[0], arrow[1]);
+ } else if (a > 0 && a < 45) {
+ p->setPen(pal.light().color());
+ p->drawLine(arrow[2], arrow[0]);
+ p->setPen(pal.dark().color());
+ p->drawLine(arrow[1], arrow[2]);
+ p->drawLine(arrow[0], arrow[1]);
+ } else if (a >= 45 && a < 135) {
+ p->setPen(pal.dark().color());
+ p->drawLine(arrow[2], arrow[0]);
+ p->drawLine(arrow[1], arrow[2]);
+ p->setPen(pal.light().color());
+ p->drawLine(arrow[0], arrow[1]);
+ } else if (a >= 135 && a < 200) {
+ p->setPen(pal.dark().color());
+ p->drawLine(arrow[2], arrow[0]);
+ p->setPen(pal.light().color());
+ p->drawLine(arrow[0], arrow[1]);
+ p->drawLine(arrow[1], arrow[2]);
+ }
+
+ // draw focus rect around the dial
+ QStyleOptionFocusRect fropt;
+ fropt.rect = dial->rect;
+ fropt.state = dial->state;
+ fropt.palette = dial->palette;
+ if (fropt.state & QStyle::State_HasFocus) {
+ br.adjust(0, 0, 2, 2);
+ if (dial->subControls & SC_DialTickmarks) {
+ int r = qMin(width, height) / 2;
+ br.translate(-r / 6, - r / 6);
+ br.setWidth(br.width() + r / 3);
+ br.setHeight(br.height() + r / 3);
+ }
+ fropt.rect = br.adjusted(-2, -2, 2, 2);
+ proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, p, widget);
+ }
+ p->restore();
+ }
+ break;
+#endif // QT_NO_DIAL
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ // Draw frame
+ QRect textRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
+ QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
+ if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*groupBox);
+ frame.features = groupBox->features;
+ frame.lineWidth = groupBox->lineWidth;
+ frame.midLineWidth = groupBox->midLineWidth;
+ frame.rect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
+ p->save();
+ QRegion region(groupBox->rect);
+ if (!groupBox->text.isEmpty()) {
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ QRect finalRect;
+ if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
+ finalRect = checkBoxRect.united(textRect);
+ finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
+ } else {
+ finalRect = textRect;
+ }
+ region -= finalRect;
+ }
+ p->setClipRegion(region);
+ proxy()->drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
+ p->restore();
+ }
+
+ // Draw title
+ if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ QColor textColor = groupBox->textColor;
+ if (textColor.isValid())
+ p->setPen(textColor);
+ int alignment = int(groupBox->textAlignment);
+ if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, opt, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ proxy()->drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
+ groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
+ textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
+
+ if (groupBox->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*groupBox);
+ fropt.rect = textRect;
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+
+ // Draw checkbox
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_GROUPBOX
+#ifndef QT_NO_WORKSPACE
+ case CC_MdiControls:
+ {
+ QStyleOptionButton btnOpt;
+ btnOpt.QStyleOption::operator=(*opt);
+ btnOpt.state &= ~State_MouseOver;
+ int bsx = 0;
+ int bsy = 0;
+ if (opt->subControls & QStyle::SC_MdiCloseButton) {
+ if (opt->activeSubControls & QStyle::SC_MdiCloseButton && (opt->state & State_Sunken)) {
+ btnOpt.state |= State_Sunken;
+ btnOpt.state &= ~State_Raised;
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ } else {
+ btnOpt.state |= State_Raised;
+ btnOpt.state &= ~State_Sunken;
+ bsx = 0;
+ bsy = 0;
+ }
+ btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiCloseButton, widget);
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget);
+ QPixmap pm = standardIcon(SP_TitleBarCloseButton).pixmap(16, 16);
+ proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm);
+ }
+ if (opt->subControls & QStyle::SC_MdiNormalButton) {
+ if (opt->activeSubControls & QStyle::SC_MdiNormalButton && (opt->state & State_Sunken)) {
+ btnOpt.state |= State_Sunken;
+ btnOpt.state &= ~State_Raised;
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ } else {
+ btnOpt.state |= State_Raised;
+ btnOpt.state &= ~State_Sunken;
+ bsx = 0;
+ bsy = 0;
+ }
+ btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiNormalButton, widget);
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget);
+ QPixmap pm = standardIcon(SP_TitleBarNormalButton).pixmap(16, 16);
+ proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm);
+ }
+ if (opt->subControls & QStyle::SC_MdiMinButton) {
+ if (opt->activeSubControls & QStyle::SC_MdiMinButton && (opt->state & State_Sunken)) {
+ btnOpt.state |= State_Sunken;
+ btnOpt.state &= ~State_Raised;
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ } else {
+ btnOpt.state |= State_Raised;
+ btnOpt.state &= ~State_Sunken;
+ bsx = 0;
+ bsy = 0;
+ }
+ btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiMinButton, widget);
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget);
+ QPixmap pm = standardIcon(SP_TitleBarMinButton).pixmap(16, 16);
+ proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm);
+ }
+ }
+ break;
+#endif // QT_NO_WORKSPACE
+
+ default:
+ qWarning("QCommonStyle::drawComplexControl: Control %d not handled", cc);
+ }
+}
+
+/*!
+ \reimp
+*/
+QStyle::SubControl QCommonStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *widget) const
+{
+ SubControl sc = SC_None;
+ switch (cc) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QRect r = proxy()->subControlRect(cc, slider, SC_SliderHandle, widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = SC_SliderHandle;
+ } else {
+ r = proxy()->subControlRect(cc, slider, SC_SliderGroove ,widget);
+ if (r.isValid() && r.contains(pt))
+ sc = SC_SliderGroove;
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QRect r;
+ uint ctrl = SC_ScrollBarAddLine;
+ while (ctrl <= SC_ScrollBarGroove) {
+ r = proxy()->subControlRect(cc, scrollbar, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QRect r;
+ uint ctrl = SC_ToolButton;
+ while (ctrl <= SC_ToolButtonMenu) {
+ r = proxy()->subControlRect(cc, toolbutton, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+#ifdef QT3_SUPPORT
+ case CC_Q3ListView:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (pt.x() >= 0 && pt.x() < lv->treeStepSize)
+ sc = SC_Q3ListViewExpand;
+ }
+ break;
+#endif // QT3_SUPPORT
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QRect r;
+ uint ctrl = SC_SpinBoxUp;
+ while (ctrl <= SC_SpinBoxEditField) {
+ r = proxy()->subControlRect(cc, spinbox, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRect r;
+ uint ctrl = SC_TitleBarSysMenu;
+
+ while (ctrl <= SC_TitleBarLabel) {
+ r = proxy()->subControlRect(cc, tb, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ }
+ break;
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QRect r;
+ uint ctrl = SC_ComboBoxArrow; // Start here and go down.
+ while (ctrl > 0) {
+ r = proxy()->subControlRect(cc, cb, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl >>= 1;
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ QRect r;
+ uint ctrl = SC_GroupBoxCheckBox;
+ while (ctrl <= SC_GroupBoxFrame) {
+ r = proxy()->subControlRect(cc, groupBox, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ }
+ break;
+#endif // QT_NO_GROUPBOX
+ case CC_MdiControls:
+ {
+ QRect r;
+ uint ctrl = SC_MdiMinButton;
+ while (ctrl <= SC_MdiCloseButton) {
+ r = proxy()->subControlRect(CC_MdiControls, opt, QStyle::SubControl(ctrl), widget);
+ if (r.isValid() && r.contains(pt) && (opt->subControls & ctrl)) {
+ sc = QStyle::SubControl(ctrl);
+ return sc;
+ }
+ ctrl <<= 1;
+ }
+ }
+ break;
+ default:
+ qWarning("QCommonStyle::hitTestComplexControl: Case %d not handled", cc);
+ }
+ return sc;
+}
+
+/*!
+ \reimp
+*/
+QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const
+{
+ QRect ret;
+ switch (cc) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+
+ switch (sc) {
+ case SC_SliderHandle: {
+ int sliderPos = 0;
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ slider->sliderPosition,
+ (horizontal ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown);
+ if (horizontal)
+ ret.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness);
+ else
+ ret.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len);
+ break; }
+ case SC_SliderGroove:
+ if (slider->orientation == Qt::Horizontal)
+ ret.setRect(slider->rect.x(), slider->rect.y() + tickOffset,
+ slider->rect.width(), thickness);
+ else
+ ret.setRect(slider->rect.x() + tickOffset, slider->rect.y(),
+ thickness, slider->rect.height());
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(slider->direction, slider->rect, ret);
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ const QRect scrollBarRect = scrollbar->rect;
+ int sbextent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar, widget);
+ int maxlen = ((scrollbar->orientation == Qt::Horizontal) ?
+ scrollBarRect.width() : scrollBarRect.height()) - (sbextent * 2);
+ int sliderlen;
+
+ // calculate slider length
+ if (scrollbar->maximum != scrollbar->minimum) {
+ uint range = scrollbar->maximum - scrollbar->minimum;
+ sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep);
+
+ int slidermin = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollbar, widget);
+ if (sliderlen < slidermin || range > INT_MAX / 2)
+ sliderlen = slidermin;
+ if (sliderlen > maxlen)
+ sliderlen = maxlen;
+ } else {
+ sliderlen = maxlen;
+ }
+
+ int sliderstart = sbextent + sliderPositionFromValue(scrollbar->minimum,
+ scrollbar->maximum,
+ scrollbar->sliderPosition,
+ maxlen - sliderlen,
+ scrollbar->upsideDown);
+
+ switch (sc) {
+ case SC_ScrollBarSubLine: // top/left button
+ if (scrollbar->orientation == Qt::Horizontal) {
+ int buttonWidth = qMin(scrollBarRect.width() / 2, sbextent);
+ ret.setRect(0, 0, buttonWidth, scrollBarRect.height());
+ } else {
+ int buttonHeight = qMin(scrollBarRect.height() / 2, sbextent);
+ ret.setRect(0, 0, scrollBarRect.width(), buttonHeight);
+ }
+ break;
+ case SC_ScrollBarAddLine: // bottom/right button
+ if (scrollbar->orientation == Qt::Horizontal) {
+ int buttonWidth = qMin(scrollBarRect.width()/2, sbextent);
+ ret.setRect(scrollBarRect.width() - buttonWidth, 0, buttonWidth, scrollBarRect.height());
+ } else {
+ int buttonHeight = qMin(scrollBarRect.height()/2, sbextent);
+ ret.setRect(0, scrollBarRect.height() - buttonHeight, scrollBarRect.width(), buttonHeight);
+ }
+ break;
+ case SC_ScrollBarSubPage: // between top/left button and slider
+ if (scrollbar->orientation == Qt::Horizontal)
+ ret.setRect(sbextent, 0, sliderstart - sbextent, scrollBarRect.height());
+ else
+ ret.setRect(0, sbextent, scrollBarRect.width(), sliderstart - sbextent);
+ break;
+ case SC_ScrollBarAddPage: // between bottom/right button and slider
+ if (scrollbar->orientation == Qt::Horizontal)
+ ret.setRect(sliderstart + sliderlen, 0,
+ maxlen - sliderstart - sliderlen + sbextent, scrollBarRect.height());
+ else
+ ret.setRect(0, sliderstart + sliderlen, scrollBarRect.width(),
+ maxlen - sliderstart - sliderlen + sbextent);
+ break;
+ case SC_ScrollBarGroove:
+ if (scrollbar->orientation == Qt::Horizontal)
+ ret.setRect(sbextent, 0, scrollBarRect.width() - sbextent * 2,
+ scrollBarRect.height());
+ else
+ ret.setRect(0, sbextent, scrollBarRect.width(),
+ scrollBarRect.height() - sbextent * 2);
+ break;
+ case SC_ScrollBarSlider:
+ if (scrollbar->orientation == Qt::Horizontal)
+ ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height());
+ else
+ ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen);
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(scrollbar->direction, scrollBarRect, ret);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QSize bs;
+ int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
+ bs.setHeight(qMax(8, spinbox->rect.height()/2 - fw));
+ // 1.6 -approximate golden mean
+ bs.setWidth(qMax(16, qMin(bs.height() * 8 / 5, spinbox->rect.width() / 4)));
+ bs = bs.expandedTo(QApplication::globalStrut());
+ int y = fw + spinbox->rect.y();
+ int x, lx, rx;
+ x = spinbox->rect.x() + spinbox->rect.width() - fw - bs.width();
+ lx = fw;
+ rx = x - fw;
+ switch (sc) {
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ ret = QRect(x, y, bs.width(), bs.height());
+ break;
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+
+ ret = QRect(x, y + bs.height(), bs.width(), bs.height());
+ break;
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ ret = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
+ } else {
+ ret = QRect(lx, fw, rx, spinbox->rect.height() - 2*fw);
+ }
+ break;
+ case SC_SpinBoxFrame:
+ ret = spinbox->rect;
+ default:
+ break;
+ }
+ ret = visualRect(spinbox->direction, spinbox->rect, ret);
+ }
+ break;
+#endif // Qt_NO_SPINBOX
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, tb, widget);
+ ret = tb->rect;
+ switch (sc) {
+ case SC_ToolButton:
+ if ((tb->features
+ & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::MenuButtonPopup)
+ ret.adjust(0, 0, -mbi, 0);
+ break;
+ case SC_ToolButtonMenu:
+ if ((tb->features
+ & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::MenuButtonPopup)
+ ret.adjust(ret.width() - mbi, 0, 0, 0);
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(tb->direction, tb->rect, ret);
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ int x = cb->rect.x(),
+ y = cb->rect.y(),
+ wi = cb->rect.width(),
+ he = cb->rect.height();
+ int xpos = x;
+ int margin = cb->frame ? 3 : 0;
+ int bmarg = cb->frame ? 2 : 0;
+ xpos += wi - bmarg - 16;
+
+
+ switch (sc) {
+ case SC_ComboBoxFrame:
+ ret = cb->rect;
+ break;
+ case SC_ComboBoxArrow:
+ ret.setRect(xpos, y + bmarg, 16, he - 2*bmarg);
+ break;
+ case SC_ComboBoxEditField:
+ ret.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
+ break;
+ case SC_ComboBoxListBoxPopup:
+ ret = cb->rect;
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(cb->direction, cb->rect, ret);
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ const int controlMargin = 2;
+ const int controlHeight = tb->rect.height() - controlMargin *2;
+ const int delta = controlHeight + controlMargin;
+ int offset = 0;
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+
+ switch (sc) {
+ case SC_TitleBarLabel:
+ if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
+ ret = tb->rect;
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ ret.adjust(delta, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ }
+ break;
+ case SC_TitleBarContextHelpButton:
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ offset += delta;
+ case SC_TitleBarMinButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarMinButton)
+ break;
+ case SC_TitleBarNormalButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarNormalButton)
+ break;
+ case SC_TitleBarMaxButton:
+ if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarMaxButton)
+ break;
+ case SC_TitleBarShadeButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarShadeButton)
+ break;
+ case SC_TitleBarUnshadeButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarUnshadeButton)
+ break;
+ case SC_TitleBarCloseButton:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ offset += delta;
+ else if (sc == SC_TitleBarCloseButton)
+ break;
+ ret.setRect(tb->rect.right() - offset, tb->rect.top() + controlMargin,
+ controlHeight, controlHeight);
+ break;
+ case SC_TitleBarSysMenu:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ ret.setRect(tb->rect.left() + controlMargin, tb->rect.top() + controlMargin,
+ controlHeight, controlHeight);
+ }
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(tb->direction, tb->rect, ret);
+ }
+ break;
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox: {
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ switch (sc) {
+ case SC_GroupBoxFrame:
+ // FALL THROUGH
+ case SC_GroupBoxContents: {
+ int topMargin = 0;
+ int topHeight = 0;
+ int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
+ if (groupBox->text.size() || (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)) {
+ topHeight = groupBox->fontMetrics.height();
+ if (verticalAlignment & Qt::AlignVCenter)
+ topMargin = topHeight / 2;
+ else if (verticalAlignment & Qt::AlignTop)
+ topMargin = topHeight;
+ }
+
+ QRect frameRect = groupBox->rect;
+ frameRect.setTop(topMargin);
+
+ if (sc == SC_GroupBoxFrame) {
+ ret = frameRect;
+ break;
+ }
+
+ int frameWidth = 0;
+ if (!(widget && widget->inherits("Q3GroupBox"))
+ && ((groupBox->features & QStyleOptionFrameV2::Flat) == 0)) {
+ frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, groupBox, widget);
+ }
+ ret = frameRect.adjusted(frameWidth, frameWidth + topHeight - topMargin,
+ -frameWidth, -frameWidth);
+ break;
+ }
+ case SC_GroupBoxCheckBox:
+ // FALL THROUGH
+ case SC_GroupBoxLabel: {
+ QFontMetrics fontMetrics = groupBox->fontMetrics;
+ int h = fontMetrics.height();
+ int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
+ int marg = (groupBox->features & QStyleOptionFrameV2::Flat) ? 0 : 8;
+ ret = groupBox->rect.adjusted(marg, 0, -marg, 0);
+ ret.setHeight(h);
+
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
+ int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget) - 1;
+ bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
+ int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
+
+ // Adjusted rect for label + indicatorWidth + indicatorSpace
+ QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment,
+ QSize(tw + checkBoxSize, h), ret);
+
+ // Adjust totalRect if checkbox is set
+ if (hasCheckBox) {
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ int left = 0;
+ // Adjust for check box
+ if (sc == SC_GroupBoxCheckBox) {
+ int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
+ left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
+ int top = totalRect.top() + (fontMetrics.height() - indicatorHeight) / 2;
+ totalRect.setRect(left, top, indicatorWidth, indicatorHeight);
+ // Adjust for label
+ } else {
+ left = ltr ? (totalRect.left() + checkBoxSize - 2) : totalRect.left();
+ totalRect.setRect(left, totalRect.top(),
+ totalRect.width() - checkBoxSize, totalRect.height());
+ }
+ }
+ ret = totalRect;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
+ }
+#endif // QT_NO_GROUPBOX
+#ifndef QT_NO_WORKSPACE
+ case CC_MdiControls:
+ {
+ int numSubControls = 0;
+ if (opt->subControls & SC_MdiCloseButton)
+ ++numSubControls;
+ if (opt->subControls & SC_MdiMinButton)
+ ++numSubControls;
+ if (opt->subControls & SC_MdiNormalButton)
+ ++numSubControls;
+ if (numSubControls == 0)
+ break;
+
+ int buttonWidth = opt->rect.width()/ numSubControls - 1;
+ int offset = 0;
+ switch (sc) {
+ case SC_MdiCloseButton:
+ // Only one sub control, no offset needed.
+ if (numSubControls == 1)
+ break;
+ offset += buttonWidth + 2;
+ //FALL THROUGH
+ case SC_MdiNormalButton:
+ // No offset needed if
+ // 1) There's only one sub control
+ // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
+ if (numSubControls == 1 || (numSubControls == 2 && !(opt->subControls & SC_MdiMinButton)))
+ break;
+ if (opt->subControls & SC_MdiNormalButton)
+ offset += buttonWidth;
+ break;
+ default:
+ break;
+ }
+
+ // Subtract one pixel if we only have one sub control. At this point
+ // buttonWidth is the actual width + 1 pixel margin, but we don't want the
+ // margin when there are no other controllers.
+ if (numSubControls == 1)
+ --buttonWidth;
+ ret = QRect(offset, 0, buttonWidth, opt->rect.height());
+ break;
+ }
+#endif // QT_NO_WORKSPACE
+ default:
+ qWarning("QCommonStyle::subControlRect: Case %d not handled", cc);
+ }
+ return ret;
+}
+
+/*! \reimp */
+int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *widget) const
+{
+ int ret;
+
+ switch (m) {
+ case PM_FocusFrameVMargin:
+ case PM_FocusFrameHMargin:
+ ret = 2;
+ break;
+ case PM_MenuBarVMargin:
+ case PM_MenuBarHMargin:
+ ret = 0;
+ break;
+ case PM_DialogButtonsSeparator:
+ ret = int(QStyleHelper::dpiScaled(5.));
+ break;
+ case PM_DialogButtonsButtonWidth:
+ ret = int(QStyleHelper::dpiScaled(70.));
+ break;
+ case PM_DialogButtonsButtonHeight:
+ ret = int(QStyleHelper::dpiScaled(30.));
+ break;
+ case PM_CheckListControllerSize:
+ case PM_CheckListButtonSize:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+ case PM_TitleBarHeight: {
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) {
+ ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 16);
+#ifndef QT_NO_DOCKWIDGET
+ } else if (qobject_cast<const QDockWidget*>(widget)) {
+ ret = qMax(widget->fontMetrics().height(), int(QStyleHelper::dpiScaled(13)));
+#endif
+ } else {
+ ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 18);
+ }
+ } else {
+ ret = int(QStyleHelper::dpiScaled(18.));
+ }
+
+ break; }
+ case PM_ScrollBarSliderMin:
+ ret = int(QStyleHelper::dpiScaled(9.));
+ break;
+
+ case PM_ButtonMargin:
+ ret = int(QStyleHelper::dpiScaled(6.));
+ break;
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ ret = int(QStyleHelper::dpiScaled(2.));
+ break;
+
+ case PM_ButtonDefaultIndicator:
+ ret = 0;
+ break;
+
+ case PM_MenuButtonIndicator:
+ ret = int(QStyleHelper::dpiScaled(12.));
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+
+ case PM_DefaultFrameWidth:
+ ret = 2;
+ break;
+
+ case PM_ComboBoxFrameWidth:
+ case PM_SpinBoxFrameWidth:
+ case PM_MenuPanelWidth:
+ case PM_TabBarBaseOverlap:
+ case PM_TabBarBaseHeight:
+ ret = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ break;
+
+ case PM_MdiSubWindowFrameWidth:
+ ret = int(QStyleHelper::dpiScaled(4.));
+ break;
+
+ case PM_MdiSubWindowMinimizedWidth:
+ ret = int(QStyleHelper::dpiScaled(196.));
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case PM_ScrollBarExtent:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int s = sb->orientation == Qt::Horizontal ?
+ QApplication::globalStrut().height()
+ : QApplication::globalStrut().width();
+ ret = qMax(16, s);
+ } else {
+ ret = int(QStyleHelper::dpiScaled(16.));
+ }
+ break;
+#endif
+ case PM_MaximumDragDistance:
+ ret = -1;
+ break;
+
+#ifndef QT_NO_SLIDER
+ case PM_SliderThickness:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+
+ case PM_SliderTickmarkOffset:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height()
+ : sl->rect.width();
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, sl, widget);
+ int ticks = sl->tickPosition;
+
+ if (ticks == QSlider::TicksBothSides)
+ ret = (space - thickness) / 2;
+ else if (ticks == QSlider::TicksAbove)
+ ret = space - thickness;
+ else
+ ret = 0;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case PM_SliderSpaceAvailable:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ if (sl->orientation == Qt::Horizontal)
+ ret = sl->rect.width() - proxy()->pixelMetric(PM_SliderLength, sl, widget);
+ else
+ ret = sl->rect.height() - proxy()->pixelMetric(PM_SliderLength, sl, widget);
+ } else {
+ ret = 0;
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_DOCKWIDGET
+ case PM_DockWidgetSeparatorExtent:
+ ret = int(QStyleHelper::dpiScaled(6.));
+ break;
+
+ case PM_DockWidgetHandleExtent:
+ ret = int(QStyleHelper::dpiScaled(8.));
+ break;
+ case PM_DockWidgetTitleMargin:
+ ret = 0;
+ break;
+ case PM_DockWidgetFrameWidth:
+ ret = 1;
+ break;
+#endif // QT_NO_DOCKWIDGET
+
+ case PM_SpinBoxSliderHeight:
+ case PM_MenuBarPanelWidth:
+ ret = 2;
+ break;
+
+ case PM_MenuBarItemSpacing:
+ ret = 0;
+ break;
+
+#ifndef QT_NO_TOOLBAR
+ case PM_ToolBarFrameWidth:
+ ret = 1;
+ break;
+
+ case PM_ToolBarItemMargin:
+ ret = 0;
+ break;
+
+ case PM_ToolBarItemSpacing:
+ ret = int(QStyleHelper::dpiScaled(4.));
+ break;
+
+ case PM_ToolBarHandleExtent:
+ ret = int(QStyleHelper::dpiScaled(8.));
+ break;
+
+ case PM_ToolBarSeparatorExtent:
+ ret = int(QStyleHelper::dpiScaled(6.));
+ break;
+
+ case PM_ToolBarExtensionExtent:
+ ret = int(QStyleHelper::dpiScaled(12.));
+ break;
+#endif // QT_NO_TOOLBAR
+
+#ifndef QT_NO_TABBAR
+ case PM_TabBarTabOverlap:
+ ret = 3;
+ break;
+
+ case PM_TabBarTabHSpace:
+ ret = int(QStyleHelper::dpiScaled(24.));
+ break;
+
+ case PM_TabBarTabShiftHorizontal:
+ ret = 0;
+ break;
+
+ case PM_TabBarTabShiftVertical:
+ ret = 2;
+ break;
+
+ case PM_TabBarTabVSpace: {
+ const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt);
+ if (tb && (tb->shape == QTabBar::RoundedNorth || tb->shape == QTabBar::RoundedSouth
+ || tb->shape == QTabBar::RoundedWest || tb->shape == QTabBar::RoundedEast))
+ ret = 8;
+ else
+ if(tb && (tb->shape == QTabBar::TriangularWest || tb->shape == QTabBar::TriangularEast))
+ ret = 3;
+ else
+ ret = 2;
+ break; }
+#endif
+
+ case PM_ProgressBarChunkWidth:
+ ret = 9;
+ break;
+
+ case PM_IndicatorWidth:
+ ret = int(QStyleHelper::dpiScaled(13.));
+ break;
+
+ case PM_IndicatorHeight:
+ ret = int(QStyleHelper::dpiScaled(13.));
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ ret = int(QStyleHelper::dpiScaled(12.));
+ break;
+
+ case PM_ExclusiveIndicatorHeight:
+ ret = int(QStyleHelper::dpiScaled(12.));
+ break;
+
+ case PM_MenuTearoffHeight:
+ ret = int(QStyleHelper::dpiScaled(10.));
+ break;
+
+ case PM_MenuScrollerHeight:
+ ret = int(QStyleHelper::dpiScaled(10.));
+ break;
+
+ case PM_MenuDesktopFrameWidth:
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ ret = 0;
+ break;
+
+ case PM_HeaderMargin:
+ ret = int(QStyleHelper::dpiScaled(4.));
+ break;
+ case PM_HeaderMarkSize:
+ ret = int(QStyleHelper::dpiScaled(32.));
+ break;
+ case PM_HeaderGripMargin:
+ ret = int(QStyleHelper::dpiScaled(4.));
+ break;
+ case PM_TabBarScrollButtonWidth:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+ case PM_LayoutLeftMargin:
+ case PM_LayoutTopMargin:
+ case PM_LayoutRightMargin:
+ case PM_LayoutBottomMargin:
+ {
+ bool isWindow = false;
+ if (opt) {
+ isWindow = (opt->state & State_Window);
+ } else if (widget) {
+ isWindow = widget->isWindow();
+ }
+ ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin);
+ }
+ break;
+ case PM_LayoutHorizontalSpacing:
+ case PM_LayoutVerticalSpacing:
+ ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing);
+ break;
+
+ case PM_DefaultTopLevelMargin:
+ ret = int(QStyleHelper::dpiScaled(11.));
+ break;
+ case PM_DefaultChildMargin:
+ ret = int(QStyleHelper::dpiScaled(9.));
+ break;
+ case PM_DefaultLayoutSpacing:
+ ret = int(QStyleHelper::dpiScaled(6.));
+ break;
+
+ case PM_ToolBarIconSize:
+ ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolBarIconSize);
+ if (!ret)
+ ret = int(QStyleHelper::dpiScaled(24.));
+ break;
+
+ case PM_TabBarIconSize:
+ case PM_ListViewIconSize:
+ ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ break;
+
+ case PM_ButtonIconSize:
+ case PM_SmallIconSize:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+ case PM_IconViewIconSize:
+ ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
+ break;
+
+ case PM_LargeIconSize:
+ ret = int(QStyleHelper::dpiScaled(32.));
+ break;
+
+ case PM_ToolTipLabelFrameWidth:
+ ret = 1;
+ break;
+ case PM_CheckBoxLabelSpacing:
+ case PM_RadioButtonLabelSpacing:
+ ret = int(QStyleHelper::dpiScaled(6.));
+ break;
+ case PM_SizeGripSize:
+ ret = int(QStyleHelper::dpiScaled(13.));
+ break;
+ case PM_MessageBoxIconSize:
+#ifdef Q_WS_MAC
+ if (QApplication::desktopSettingsAware()) {
+ ret = 64; // No DPI scaling, it's handled elsewhere.
+ } else
+#endif
+ {
+ ret = int(QStyleHelper::dpiScaled(32.));
+ }
+ break;
+ case PM_TextCursorWidth:
+ ret = 1;
+ break;
+ case PM_TabBar_ScrollButtonOverlap:
+ ret = 1;
+ break;
+ case PM_TabCloseIndicatorWidth:
+ case PM_TabCloseIndicatorHeight:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+ case PM_ScrollView_ScrollBarSpacing:
+ ret = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ break;
+ case PM_SubMenuOverlap:
+ ret = -proxy()->pixelMetric(QStyle::PM_MenuPanelWidth, opt, widget);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *widget) const
+{
+ Q_D(const QCommonStyle);
+ QSize sz(csz);
+ switch (ct) {
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ int w = csz.width(),
+ h = csz.height(),
+ bm = proxy()->pixelMetric(PM_ButtonMargin, btn, widget),
+ fw = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget) * 2;
+ w += bm + fw;
+ h += bm + fw;
+ if (btn->features & QStyleOptionButton::AutoDefaultButton){
+ int dbw = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget) * 2;
+ w += dbw;
+ h += dbw;
+ }
+ sz = QSize(w, h);
+ }
+ break;
+ case CT_RadioButton:
+ case CT_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ bool isRadio = (ct == CT_RadioButton);
+
+ int w = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth
+ : PM_IndicatorWidth, btn, widget);
+ int h = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
+ : PM_IndicatorHeight, btn, widget);
+
+ int margins = 0;
+ // we add 4 pixels for label margins
+ if (!btn->icon.isNull() || !btn->text.isEmpty())
+ margins = 4 + proxy()->pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
+ : PM_CheckBoxLabelSpacing, opt, widget);
+ sz += QSize(w + margins, 4);
+ sz.setHeight(qMax(sz.height(), h));
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ bool checkable = mi->menuHasCheckableItems;
+ int maxpmw = mi->maxIconWidth;
+ int w = sz.width(), h = sz.height();
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ w = 10;
+ h = 2;
+ } else {
+ h = mi->fontMetrics.height() + 8;
+ if (!mi->icon.isNull()) {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
+ }
+ }
+ if (mi->text.contains(QLatin1Char('\t')))
+ w += 12;
+ if (maxpmw > 0)
+ w += maxpmw + 6;
+ if (checkable && maxpmw < 20)
+ w += 20 - maxpmw;
+ if (checkable || maxpmw > 0)
+ w += 2;
+ w += 12;
+ sz = QSize(w, h);
+ }
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_TOOLBUTTON
+ case CT_ToolButton:
+ sz = QSize(sz.width() + 6, sz.height() + 5);
+ break;
+#endif // QT_NO_TOOLBUTTON
+#ifndef QT_NO_COMBOBOX
+ case CT_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ int fw = cmb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0;
+ const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
+ // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
+ int other = qMax(23, 2*textMargins + proxy()->pixelMetric(QStyle::PM_ScrollBarExtent, opt, widget));
+ sz = QSize(sz.width() + fw + other, sz.height() + fw);
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ case CT_HeaderSection:
+ if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ bool nullIcon = hdr->icon.isNull();
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr, widget);
+ int iconSize = nullIcon ? 0 : proxy()->pixelMetric(QStyle::PM_SmallIconSize, hdr, widget);
+ QSize txt = hdr->fontMetrics.size(0, hdr->text);
+ sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
+ sz.setWidth((nullIcon ? 0 : margin) + iconSize
+ + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
+ }
+ break;
+ case CT_TabWidget:
+ sz += QSize(4, 4);
+ break;
+ case CT_LineEdit:
+ if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
+ sz += QSize(2*f->lineWidth, 2*f->lineWidth);
+ break;
+#ifndef QT_NO_GROUPBOX
+ case CT_GroupBox:
+ if (const QGroupBox *grb = static_cast<const QGroupBox *>(widget))
+ sz += QSize(!grb->isFlat() ? 16 : 0, 0);
+ break;
+#endif // QT_NO_GROUPBOX
+ case CT_MdiControls:
+ if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
+ int width = 1;
+ if (styleOpt->subControls & SC_MdiMinButton)
+ width += 16 + 1;
+ if (styleOpt->subControls & SC_MdiNormalButton)
+ width += 16 + 1;
+ if (styleOpt->subControls & SC_MdiCloseButton)
+ width += 16 + 1;
+ sz = QSize(width, 16);
+ } else {
+ sz = QSize(52, 16);
+ }
+ break;
+#ifndef QT_NO_ITEMVIEWS
+ case CT_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QRect decorationRect, displayRect, checkRect;
+ d->viewItemLayout(vopt, &checkRect, &decorationRect, &displayRect, true);
+ sz = (decorationRect|displayRect|checkRect).size();
+ }
+ break;
+#endif // QT_NO_ITEMVIEWS
+ case CT_ScrollBar:
+ case CT_MenuBar:
+ case CT_Menu:
+ case CT_MenuBarItem:
+ case CT_Q3Header:
+ case CT_Slider:
+ case CT_ProgressBar:
+ case CT_TabBarTab:
+ // just return the contentsSize for now
+ // fall through intended
+ default:
+ break;
+ }
+ return sz;
+}
+
+
+/*! \reimp */
+int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *hret) const
+{
+ int ret = 0;
+
+ switch (sh) {
+ case SH_Menu_KeyboardSearch:
+ ret = false;
+ break;
+ case SH_Slider_AbsoluteSetButtons:
+ ret = Qt::MidButton;
+ break;
+ case SH_Slider_PageSetButtons:
+ ret = Qt::LeftButton;
+ break;
+ case SH_ScrollBar_ContextMenu:
+ ret = true;
+ break;
+ case SH_DialogButtons_DefaultButton: // This value not used anywhere.
+ ret = QDialogButtonBox::AcceptRole;
+ break;
+#ifndef QT_NO_GROUPBOX
+ case SH_GroupBox_TextLabelVerticalAlignment:
+ ret = Qt::AlignVCenter;
+ break;
+
+ case SH_GroupBox_TextLabelColor:
+ ret = opt ? int(opt->palette.color(QPalette::Text).rgba()) : 0;
+ break;
+#endif // QT_NO_GROUPBOX
+
+ case SH_Q3ListViewExpand_SelectMouseType:
+ case SH_TabBar_SelectMouseType:
+ ret = QEvent::MouseButtonPress;
+ break;
+
+#ifdef QT3_SUPPORT
+ case SH_GUIStyle:
+ ret = Qt::WindowsStyle;
+ break;
+#endif
+
+ case SH_TabBar_Alignment:
+ case SH_Header_ArrowAlignment:
+ ret = Qt::AlignLeft;
+ break;
+
+ case SH_TitleBar_AutoRaise:
+ ret = false;
+ break;
+
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 256;
+ break;
+
+ case SH_ProgressDialog_TextLabelAlignment:
+ ret = Qt::AlignCenter;
+ break;
+
+ case SH_BlinkCursorWhenTextSelected:
+ ret = 1;
+ break;
+
+ case SH_Table_GridLineColor:
+ if (opt)
+ ret = opt->palette.color(QPalette::Mid).rgb();
+ else
+ ret = -1;
+ break;
+ case SH_LineEdit_PasswordCharacter: {
+ const QFontMetrics &fm = opt ? opt->fontMetrics
+ : (widget ? widget->fontMetrics() : QFontMetrics(QFont()));
+ ret = 0;
+ if (fm.inFont(QChar(0x25CF))) {
+ ret = 0x25CF;
+ } else if (fm.inFont(QChar(0x2022))) {
+ ret = 0x2022;
+ } else {
+ ret = '*';
+ }
+ break;
+ }
+
+
+ case SH_ToolBox_SelectedPageTitleBold:
+ ret = 1;
+ break;
+
+ case SH_UnderlineShortcut:
+ ret = 1;
+ break;
+
+ case SH_SpinBox_ClickAutoRepeatRate:
+ ret = 150;
+ break;
+
+ case SH_SpinBox_ClickAutoRepeatThreshold:
+ ret = 500;
+ break;
+
+ case SH_SpinBox_KeyPressAutoRepeatRate:
+ ret = 75;
+ break;
+
+ case SH_Menu_SelectionWrap:
+ ret = true;
+ break;
+
+ case SH_Menu_FillScreenWithScroll:
+ ret = true;
+ break;
+
+ case SH_ToolTipLabel_Opacity:
+ ret = 255;
+ break;
+
+ case SH_Button_FocusPolicy:
+ ret = Qt::StrongFocus;
+ break;
+
+ case SH_MenuBar_DismissOnSecondClick:
+ ret = 1;
+ break;
+
+ case SH_MessageBox_UseBorderForButtonSpacing:
+ ret = 0;
+ break;
+
+ case SH_ToolButton_PopupDelay:
+ ret = 600;
+ break;
+
+ case SH_FocusFrame_Mask:
+ ret = 1;
+ if (widget) {
+ if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
+ mask->region = widget->rect();
+ int vmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin),
+ hmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin);
+ mask->region -= QRect(widget->rect().adjusted(hmargin, vmargin, -hmargin, -vmargin));
+ }
+ }
+ break;
+#ifndef QT_NO_RUBBERBAND
+ case SH_RubberBand_Mask:
+ if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ ret = 0;
+ if (rbOpt->shape == QRubberBand::Rectangle) {
+ ret = true;
+ if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
+ mask->region = opt->rect;
+ int margin = proxy()->pixelMetric(PM_DefaultFrameWidth) * 2;
+ mask->region -= opt->rect.adjusted(margin, margin, -margin, -margin);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_RUBBERBAND
+ case SH_SpinControls_DisableOnBounds:
+ ret = 1;
+ break;
+
+ case SH_Dial_BackgroundRole:
+ ret = QPalette::Window;
+ break;
+
+ case SH_ComboBox_LayoutDirection:
+ ret = opt ? opt->direction : Qt::LeftToRight;
+ break;
+
+ case SH_ItemView_EllipsisLocation:
+ ret = Qt::AlignTrailing;
+ break;
+
+ case SH_ItemView_ShowDecorationSelected:
+ ret = false;
+ break;
+
+ case SH_ItemView_ActivateItemOnSingleClick:
+ ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ItemView_ActivateItemOnSingleClick);
+ break;
+
+ case SH_TitleBar_ModifyNotification:
+ ret = true;
+ break;
+ case SH_ScrollBar_RollBetweenButtons:
+ ret = false;
+ break;
+ case SH_TabBar_ElideMode:
+ ret = Qt::ElideNone;
+ break;
+ case SH_DialogButtonLayout:
+ ret = QDialogButtonBox::WinLayout;
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE)
+ ret = QDialogButtonBox::KdeLayout;
+ else if (X11->desktopEnvironment == DE_GNOME)
+ ret = QDialogButtonBox::GnomeLayout;
+#endif
+ break;
+ case SH_ComboBox_PopupFrameStyle:
+ ret = QFrame::StyledPanel | QFrame::Plain;
+ break;
+ case SH_MessageBox_TextInteractionFlags:
+ ret = Qt::LinksAccessibleByMouse;
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+#ifdef Q_WS_X11
+ return true;
+#endif
+ ret = 0;
+ break;
+ case SH_SpellCheckUnderlineStyle:
+ ret = QTextCharFormat::WaveUnderline;
+ break;
+ case SH_MessageBox_CenterButtons:
+ ret = true;
+ break;
+ case SH_ItemView_MovementWithoutUpdatingSelection:
+ ret = true;
+ break;
+ case SH_FocusFrame_AboveWidget:
+ ret = false;
+ break;
+#ifndef QT_NO_TABWIDGET
+ case SH_TabWidget_DefaultTabPosition:
+ ret = QTabWidget::North;
+ break;
+#endif
+ case SH_ToolBar_Movable:
+ ret = true;
+ break;
+ case SH_TextControl_FocusIndicatorTextCharFormat:
+ ret = true;
+ if (QStyleHintReturnVariant *vret = qstyleoption_cast<QStyleHintReturnVariant*>(hret)) {
+ QPen outline(opt->palette.color(QPalette::Text), 1, Qt::DotLine);
+ QTextCharFormat fmt;
+ fmt.setProperty(QTextFormat::OutlinePen, outline);
+ vret->variant = fmt;
+ }
+ break;
+#ifndef QT_NO_WIZARD
+ case SH_WizardStyle:
+ ret = QWizard::ClassicStyle;
+ break;
+#endif
+ case SH_FormLayoutWrapPolicy:
+ ret = QFormLayout::DontWrapRows;
+ break;
+ case SH_FormLayoutFieldGrowthPolicy:
+ ret = QFormLayout::AllNonFixedFieldsGrow;
+ break;
+ case SH_FormLayoutFormAlignment:
+ ret = Qt::AlignLeft | Qt::AlignTop;
+ break;
+ case SH_FormLayoutLabelAlignment:
+ ret = Qt::AlignLeft;
+ break;
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = false;
+ break;
+ case SH_ItemView_DrawDelegateFrame:
+ ret = 0;
+ break;
+#ifndef QT_NO_TABBAR
+ case SH_TabBar_CloseButtonPosition:
+ ret = QTabBar::RightSide;
+ break;
+#endif
+ case SH_DockWidget_ButtonsHaveFrame:
+ ret = true;
+ break;
+ case SH_ToolButtonStyle:
+ ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolButtonStyle);
+ break;
+ case SH_RequestSoftwareInputPanel:
+ ret = RSIP_OnMouseClickAndAlreadyFocused;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+/*! \reimp */
+QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft());
+#ifdef QT_NO_IMAGEFORMAT_PNG
+ Q_UNUSED(widget);
+ Q_UNUSED(sp);
+#else
+ QPixmap pixmap;
+
+ if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
+ switch (sp) {
+ case SP_DialogYesButton:
+ case SP_DialogOkButton:
+ pixmap = QIcon::fromTheme(QLatin1String("dialog-ok")).pixmap(16);
+ break;
+ case SP_DialogApplyButton:
+ pixmap = QIcon::fromTheme(QLatin1String("dialog-ok-apply")).pixmap(16);
+ break;
+ case SP_DialogDiscardButton:
+ pixmap = QIcon::fromTheme(QLatin1String("edit-delete")).pixmap(16);
+ break;
+ case SP_DialogCloseButton:
+ pixmap = QIcon::fromTheme(QLatin1String("dialog-close")).pixmap(16);
+ break;
+ case SP_DirHomeIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("user-home")).pixmap(16);
+ break;
+ case SP_MessageBoxInformation:
+ pixmap = QIcon::fromTheme(QLatin1String("messagebox_info")).pixmap(16);
+ break;
+ case SP_MessageBoxWarning:
+ pixmap = QIcon::fromTheme(QLatin1String("messagebox_warning")).pixmap(16);
+ break;
+ case SP_MessageBoxCritical:
+ pixmap = QIcon::fromTheme(QLatin1String("messagebox_critical")).pixmap(16);
+ break;
+ case SP_MessageBoxQuestion:
+ pixmap = QIcon::fromTheme(QLatin1String("help")).pixmap(16);
+ break;
+ case SP_DialogOpenButton:
+ case SP_DirOpenIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("folder-open")).pixmap(16);
+ break;
+ case SP_FileIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("text-x-generic"),
+ QIcon::fromTheme(QLatin1String("empty"))).pixmap(16);
+ break;
+ case SP_DirClosedIcon:
+ case SP_DirIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("folder")).pixmap(16);
+ break;
+ case SP_DriveFDIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("media-floppy"),
+ QIcon::fromTheme(QLatin1String("3floppy_unmount"))).pixmap(16);
+ break;
+ case SP_ComputerIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("computer"),
+ QIcon::fromTheme(QLatin1String("system"))).pixmap(16);
+ break;
+ case SP_DesktopIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("user-desktop"),
+ QIcon::fromTheme(QLatin1String("desktop"))).pixmap(16);
+ break;
+ case SP_TrashIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("user-trash"),
+ QIcon::fromTheme(QLatin1String("trashcan_empty"))).pixmap(16);
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("media-optical"),
+ QIcon::fromTheme(QLatin1String("cdrom_unmount"))).pixmap(16);
+ break;
+ case SP_DriveHDIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("drive-harddisk"),
+ QIcon::fromTheme(QLatin1String("hdd_unmount"))).pixmap(16);
+ break;
+ case SP_FileDialogToParent:
+ pixmap = QIcon::fromTheme(QLatin1String("go-up"),
+ QIcon::fromTheme(QLatin1String("up"))).pixmap(16);
+ break;
+ case SP_FileDialogNewFolder:
+ pixmap = QIcon::fromTheme(QLatin1String("folder_new")).pixmap(16);
+ break;
+ case SP_ArrowUp:
+ pixmap = QIcon::fromTheme(QLatin1String("go-up"),
+ QIcon::fromTheme(QLatin1String("up"))).pixmap(16);
+ break;
+ case SP_ArrowDown:
+ pixmap = QIcon::fromTheme(QLatin1String("go-down"),
+ QIcon::fromTheme(QLatin1String("down"))).pixmap(16);
+ break;
+ case SP_ArrowRight:
+ pixmap = QIcon::fromTheme(QLatin1String("go-next"),
+ QIcon::fromTheme(QLatin1String("forward"))).pixmap(16);
+ break;
+ case SP_ArrowLeft:
+ pixmap = QIcon::fromTheme(QLatin1String("go-previous"),
+ QIcon::fromTheme(QLatin1String("back"))).pixmap(16);
+ break;
+ case SP_FileDialogDetailedView:
+ pixmap = QIcon::fromTheme(QLatin1String("view_detailed")).pixmap(16);
+ break;
+ case SP_FileDialogListView:
+ pixmap = QIcon::fromTheme(QLatin1String("view_icon")).pixmap(16);
+ break;
+ case SP_BrowserReload:
+ pixmap = QIcon::fromTheme(QLatin1String("reload")).pixmap(16);
+ break;
+ case SP_BrowserStop:
+ pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(16);
+ break;
+ case SP_MediaPlay:
+ pixmap = QIcon::fromTheme(QLatin1String("media-playback-start")).pixmap(16);
+ break;
+ case SP_MediaPause:
+ pixmap = QIcon::fromTheme(QLatin1String("media-playback-pause")).pixmap(16);
+ break;
+ case SP_MediaStop:
+ pixmap = QIcon::fromTheme(QLatin1String("media-playback-stop")).pixmap(16);
+ break;
+ case SP_MediaSeekForward:
+ pixmap = QIcon::fromTheme(QLatin1String("media-seek-forward")).pixmap(16);
+ break;
+ case SP_MediaSeekBackward:
+ pixmap = QIcon::fromTheme(QLatin1String("media-seek-backward")).pixmap(16);
+ break;
+ case SP_MediaSkipForward:
+ pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
+ break;
+ case SP_MediaSkipBackward:
+ pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
+ break;
+ case SP_DialogResetButton:
+ pixmap = QIcon::fromTheme(QLatin1String("edit-clear")).pixmap(24);
+ break;
+ case SP_DialogHelpButton:
+ pixmap = QIcon::fromTheme(QLatin1String("help-contents")).pixmap(24);
+ break;
+ case SP_DialogNoButton:
+ case SP_DialogCancelButton:
+ pixmap = QIcon::fromTheme(QLatin1String("dialog-cancel"),
+ QIcon::fromTheme(QLatin1String("process-stop"))).pixmap(24);
+ break;
+ case SP_DialogSaveButton:
+ pixmap = QIcon::fromTheme(QLatin1String("document-save")).pixmap(24);
+ break;
+ case SP_FileLinkIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16);
+ if (!pixmap.isNull()) {
+ QPixmap fileIcon = QIcon::fromTheme(QLatin1String("text-x-generic")).pixmap(16);
+ if (fileIcon.isNull())
+ fileIcon = QIcon::fromTheme(QLatin1String("empty")).pixmap(16);
+ if (!fileIcon.isNull()) {
+ QPainter painter(&fileIcon);
+ painter.drawPixmap(0, 0, 16, 16, pixmap);
+ return fileIcon;
+ }
+ }
+ break;
+ case SP_DirLinkIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16);
+ if (!pixmap.isNull()) {
+ QPixmap dirIcon = QIcon::fromTheme(QLatin1String("folder")).pixmap(16);
+ if (!dirIcon.isNull()) {
+ QPainter painter(&dirIcon);
+ painter.drawPixmap(0, 0, 16, 16, pixmap);
+ return dirIcon;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!pixmap.isNull())
+ return pixmap;
+#endif //QT_NO_IMAGEFORMAT_PNG
+ switch (sp) {
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ case SP_ToolBarHorizontalExtensionButton:
+ if (rtl) {
+ QImage im(tb_extension_arrow_h_xpm);
+ im = im.convertToFormat(QImage::Format_ARGB32).mirrored(true, false);
+ return QPixmap::fromImage(im);
+ }
+ return QPixmap(tb_extension_arrow_h_xpm);
+ case SP_ToolBarVerticalExtensionButton:
+ return QPixmap(tb_extension_arrow_v_xpm);
+ case SP_FileDialogStart:
+ return QPixmap(filedialog_start_xpm);
+ case SP_FileDialogEnd:
+ return QPixmap(filedialog_end_xpm);
+#endif
+#ifndef QT_NO_IMAGEFORMAT_PNG
+ case SP_CommandLink:
+ case SP_ArrowForward:
+ if (rtl)
+ return proxy()->standardPixmap(SP_ArrowLeft, option, widget);
+ return proxy()->standardPixmap(SP_ArrowRight, option, widget);
+ case SP_ArrowBack:
+ if (rtl)
+ return proxy()->standardPixmap(SP_ArrowRight, option, widget);
+ return proxy()->standardPixmap(SP_ArrowLeft, option, widget);
+ case SP_ArrowLeft:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/left-16.png"));
+ case SP_ArrowRight:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/right-16.png"));
+ case SP_ArrowUp:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/up-16.png"));
+ case SP_ArrowDown:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/down-16.png"));
+ case SP_FileDialogToParent:
+ return proxy()->standardPixmap(SP_ArrowUp, option, widget);
+ case SP_FileDialogNewFolder:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-16.png"));
+ case SP_FileDialogDetailedView:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-16.png"));
+ case SP_FileDialogInfoView:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-16.png"));
+ case SP_FileDialogContentsView:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-16.png"));
+ case SP_FileDialogListView:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-16.png"));
+ case SP_FileDialogBack:
+ return proxy()->standardPixmap(SP_ArrowBack, option, widget);
+ case SP_DriveHDIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/harddrive-16.png"));
+ case SP_TrashIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/trash-16.png"));
+ case SP_DriveFDIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/floppy-16.png"));
+ case SP_DriveNetIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/networkdrive-16.png"));
+ case SP_DesktopIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/desktop-16.png"));
+ case SP_ComputerIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/computer-16.png"));
+ case SP_DriveCDIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-16.png"));
+ case SP_DriveDVDIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-16.png"));
+ case SP_DirHomeIcon:
+ case SP_DirOpenIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-16.png"));
+ case SP_DirIcon:
+ case SP_DirClosedIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-16.png"));
+ case SP_DirLinkIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/dirlink-16.png"));
+ case SP_FileIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png"));
+ case SP_FileLinkIcon:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-16.png"));
+ case SP_DialogOkButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-16.png"));
+ case SP_DialogCancelButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-16.png"));
+ case SP_DialogHelpButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-16.png"));
+ case SP_DialogOpenButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png"));
+ case SP_DialogSaveButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png"));
+ case SP_DialogCloseButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-16.png"));
+ case SP_DialogApplyButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-16.png"));
+ case SP_DialogResetButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-16.png"));
+ case SP_DialogDiscardButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-16.png"));
+ case SP_DialogYesButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-16.png"));
+ case SP_DialogNoButton:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-16.png"));
+ case SP_BrowserReload:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/refresh-24.png"));
+ case SP_BrowserStop:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/stop-24.png"));
+ case SP_MediaPlay:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-play-32.png"));
+ case SP_MediaPause:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-pause-32.png"));
+ case SP_MediaStop:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-stop-32.png"));
+ case SP_MediaSeekForward:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-forward-32.png"));
+ case SP_MediaSeekBackward:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-backward-32.png"));
+ case SP_MediaSkipForward:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-forward-32.png"));
+ case SP_MediaSkipBackward:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-backward-32.png"));
+ case SP_MediaVolume:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-16.png"));
+ case SP_MediaVolumeMuted:
+ return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-muted-16.png"));
+#endif // QT_NO_IMAGEFORMAT_PNG
+ default:
+ break;
+ }
+ return QPixmap();
+}
+
+/*!
+ \internal
+*/
+QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ QIcon icon;
+ const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft());
+ if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
+ switch (standardIcon) {
+ case SP_DirHomeIcon:
+ icon = QIcon::fromTheme(QLatin1String("user-home"));
+ break;
+ case SP_MessageBoxInformation:
+ icon = QIcon::fromTheme(QLatin1String("dialog-information"));
+ break;
+ case SP_MessageBoxWarning:
+ icon = QIcon::fromTheme(QLatin1String("dialog-warning"));
+ break;
+ case SP_MessageBoxCritical:
+ icon = QIcon::fromTheme(QLatin1String("dialog-error"));
+ break;
+ case SP_MessageBoxQuestion:
+ icon = QIcon::fromTheme(QLatin1String("dialog-question"));
+ break;
+ case SP_DialogOpenButton:
+ case SP_DirOpenIcon:
+ icon = QIcon::fromTheme(QLatin1String("folder-open"));
+ break;
+ case SP_DialogSaveButton:
+ icon = QIcon::fromTheme(QLatin1String("document-save"));
+ break;
+ case SP_DialogApplyButton:
+ icon = QIcon::fromTheme(QLatin1String("dialog-ok-apply"));
+ break;
+ case SP_DialogYesButton:
+ case SP_DialogOkButton:
+ icon = QIcon::fromTheme(QLatin1String("dialog-ok"));
+ break;
+ case SP_DialogDiscardButton:
+ icon = QIcon::fromTheme(QLatin1String("edit-delete"));
+ break;
+ case SP_DialogResetButton:
+ icon = QIcon::fromTheme(QLatin1String("edit-clear"));
+ break;
+ case SP_DialogHelpButton:
+ icon = QIcon::fromTheme(QLatin1String("help-contents"));
+ break;
+ case SP_FileIcon:
+ icon = QIcon::fromTheme(QLatin1String("text-x-generic"));
+ break;
+ case SP_DirClosedIcon:
+ case SP_DirIcon:
+ icon = QIcon::fromTheme(QLatin1String("folder"));
+ break;
+ case SP_DriveFDIcon:
+ icon = QIcon::fromTheme(QLatin1String("floppy_unmount"));
+ break;
+ case SP_ComputerIcon:
+ icon = QIcon::fromTheme(QLatin1String("computer"),
+ QIcon::fromTheme(QLatin1String("system")));
+ break;
+ case SP_DesktopIcon:
+ icon = QIcon::fromTheme(QLatin1String("user-desktop"));
+ break;
+ case SP_TrashIcon:
+ icon = QIcon::fromTheme(QLatin1String("user-trash"));
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ icon = QIcon::fromTheme(QLatin1String("media-optical"));
+ break;
+ case SP_DriveHDIcon:
+ icon = QIcon::fromTheme(QLatin1String("drive-harddisk"));
+ break;
+ case SP_FileDialogToParent:
+ icon = QIcon::fromTheme(QLatin1String("go-up"));
+ break;
+ case SP_FileDialogNewFolder:
+ icon = QIcon::fromTheme(QLatin1String("folder-new"));
+ break;
+ case SP_ArrowUp:
+ icon = QIcon::fromTheme(QLatin1String("go-up"));
+ break;
+ case SP_ArrowDown:
+ icon = QIcon::fromTheme(QLatin1String("go-down"));
+ break;
+ case SP_ArrowRight:
+ icon = QIcon::fromTheme(QLatin1String("go-next"));
+ break;
+ case SP_ArrowLeft:
+ icon = QIcon::fromTheme(QLatin1String("go-previous"));
+ break;
+ case SP_DialogCancelButton:
+ icon = QIcon::fromTheme(QLatin1String("dialog-cancel"),
+ QIcon::fromTheme(QLatin1String("process-stop")));
+ break;
+ case SP_DialogCloseButton:
+ icon = QIcon::fromTheme(QLatin1String("window-close"));
+ break;
+ case SP_FileDialogDetailedView:
+ icon = QIcon::fromTheme(QLatin1String("view-list-details"));
+ break;
+ case SP_FileDialogListView:
+ icon = QIcon::fromTheme(QLatin1String("view-list-icons"));
+ break;
+ case SP_BrowserReload:
+ icon = QIcon::fromTheme(QLatin1String("view-refresh"));
+ break;
+ case SP_BrowserStop:
+ icon = QIcon::fromTheme(QLatin1String("process-stop"));
+ break;
+ case SP_MediaPlay:
+ icon = QIcon::fromTheme(QLatin1String("media-playback-start"));
+ break;
+ case SP_MediaPause:
+ icon = QIcon::fromTheme(QLatin1String("media-playback-pause"));
+ break;
+ case SP_MediaStop:
+ icon = QIcon::fromTheme(QLatin1String("media-playback-stop"));
+ break;
+ case SP_MediaSeekForward:
+ icon = QIcon::fromTheme(QLatin1String("media-seek-forward"));
+ break;
+ case SP_MediaSeekBackward:
+ icon = QIcon::fromTheme(QLatin1String("media-seek-backward"));
+ break;
+ case SP_MediaSkipForward:
+ icon = QIcon::fromTheme(QLatin1String("media-skip-forward"));
+ break;
+ case SP_MediaSkipBackward:
+ icon = QIcon::fromTheme(QLatin1String("media-skip-backward"));
+ break;
+ case SP_MediaVolume:
+ icon = QIcon::fromTheme(QLatin1String("audio-volume-medium"));
+ break;
+ case SP_MediaVolumeMuted:
+ icon = QIcon::fromTheme(QLatin1String("audio-volume-muted"));
+ break;
+ case SP_ArrowForward:
+ if (rtl)
+ return standardIconImplementation(SP_ArrowLeft, option, widget);
+ return standardIconImplementation(SP_ArrowRight, option, widget);
+ case SP_ArrowBack:
+ if (rtl)
+ return standardIconImplementation(SP_ArrowRight, option, widget);
+ return standardIconImplementation(SP_ArrowLeft, option, widget);
+ case SP_FileLinkIcon:
+ {
+ QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link"));
+ if (!linkIcon.isNull()) {
+ QIcon baseIcon = standardIconImplementation(SP_FileIcon, option, widget);
+ const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off);
+ for (int i = 0 ; i < sizes.size() ; ++i) {
+ int size = sizes[i].width();
+ QPixmap basePixmap = baseIcon.pixmap(size);
+ QPixmap linkPixmap = linkIcon.pixmap(size/2);
+ QPainter painter(&basePixmap);
+ painter.drawPixmap(size/2, size/2, linkPixmap);
+ icon.addPixmap(basePixmap);
+ }
+ }
+ }
+ break;
+ case SP_DirLinkIcon:
+ {
+ QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link"));
+ if (!linkIcon.isNull()) {
+ QIcon baseIcon = standardIconImplementation(SP_DirIcon, option, widget);
+ const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off);
+ for (int i = 0 ; i < sizes.size() ; ++i) {
+ int size = sizes[i].width();
+ QPixmap basePixmap = baseIcon.pixmap(size);
+ QPixmap linkPixmap = linkIcon.pixmap(size/2);
+ QPainter painter(&basePixmap);
+ painter.drawPixmap(size/2, size/2, linkPixmap);
+ icon.addPixmap(basePixmap);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } // if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty())
+ if (!icon.isNull())
+ return icon;
+#if defined(Q_WS_MAC)
+ if (QApplication::desktopSettingsAware()) {
+ OSType iconType = 0;
+ switch (standardIcon) {
+ case QStyle::SP_MessageBoxQuestion:
+ iconType = kQuestionMarkIcon;
+ break;
+ case QStyle::SP_MessageBoxInformation:
+ iconType = kAlertNoteIcon;
+ break;
+ case QStyle::SP_MessageBoxWarning:
+ iconType = kAlertCautionIcon;
+ break;
+ case QStyle::SP_MessageBoxCritical:
+ iconType = kAlertStopIcon;
+ break;
+ case SP_DesktopIcon:
+ iconType = kDesktopIcon;
+ break;
+ case SP_TrashIcon:
+ iconType = kTrashIcon;
+ break;
+ case SP_ComputerIcon:
+ iconType = kComputerIcon;
+ break;
+ case SP_DriveFDIcon:
+ iconType = kGenericFloppyIcon;
+ break;
+ case SP_DriveHDIcon:
+ iconType = kGenericHardDiskIcon;
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ iconType = kGenericCDROMIcon;
+ break;
+ case SP_DriveNetIcon:
+ iconType = kGenericNetworkIcon;
+ break;
+ case SP_DirOpenIcon:
+ iconType = kOpenFolderIcon;
+ break;
+ case SP_DirClosedIcon:
+ case SP_DirLinkIcon:
+ iconType = kGenericFolderIcon;
+ break;
+ case SP_FileLinkIcon:
+ case SP_FileIcon:
+ iconType = kGenericDocumentIcon;
+ break;
+ case SP_DirIcon: {
+ // A rather special case
+ QIcon closeIcon = QStyle::standardIcon(SP_DirClosedIcon, option, widget);
+ QIcon openIcon = QStyle::standardIcon(SP_DirOpenIcon, option, widget);
+ closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
+ return closeIcon;
+ }
+ case SP_TitleBarNormalButton:
+ case SP_TitleBarCloseButton: {
+ QIcon titleBarIcon;
+ if (standardIcon == SP_TitleBarCloseButton) {
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-16.png"));
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ } else {
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-16.png"));
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ }
+ return titleBarIcon;
+ }
+ default:
+ break;
+ }
+ if (iconType != 0) {
+ QIcon retIcon;
+ IconRef icon;
+ IconRef overlayIcon = 0;
+ if (iconType != kGenericApplicationIcon) {
+ GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
+ } else {
+ FSRef fsRef;
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ GetProcessBundleLocation(&psn, &fsRef);
+ GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
+ if (standardIcon == SP_MessageBoxCritical) {
+ overlayIcon = icon;
+ GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
+ }
+ }
+ if (icon) {
+ qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon);
+ ReleaseIconRef(icon);
+ }
+ if (overlayIcon)
+ ReleaseIconRef(overlayIcon);
+ return retIcon;
+ }
+ } // if (QApplication::desktopSettingsAware())
+#endif // Q_WS_MAC
+
+ switch (standardIcon) {
+#ifndef QT_NO_IMAGEFORMAT_PNG
+ case SP_FileDialogNewFolder:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-128.png"), QSize(128, 128));
+ break;
+ case SP_FileDialogBack:
+ return standardIconImplementation(SP_ArrowBack, option, widget);
+ case SP_FileDialogToParent:
+ return standardIconImplementation(SP_ArrowUp, option, widget);
+ case SP_FileDialogDetailedView:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-128.png"), QSize(128, 128));
+ break;
+ case SP_FileDialogInfoView:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-128.png"), QSize(128, 128));
+ break;
+ case SP_FileDialogContentsView:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-128.png"), QSize(128, 128));
+ break;
+ case SP_FileDialogListView:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogOkButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogCancelButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogHelpButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogOpenButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogSaveButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogCloseButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogApplyButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogResetButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogDiscardButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogYesButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-128.png"), QSize(128, 128));
+ break;
+ case SP_DialogNoButton:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-128.png"), QSize(128, 128));
+ break;
+ case SP_ArrowForward:
+ if (rtl)
+ return standardIconImplementation(SP_ArrowLeft, option, widget);
+ return standardIconImplementation(SP_ArrowRight, option, widget);
+ case SP_ArrowBack:
+ if (rtl)
+ return standardIconImplementation(SP_ArrowRight, option, widget);
+ return standardIconImplementation(SP_ArrowLeft, option, widget);
+ case SP_ArrowLeft:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/left-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/left-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/left-128.png"), QSize(128, 128));
+ break;
+ case SP_ArrowRight:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/right-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/right-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/right-128.png"), QSize(128, 128));
+ break;
+ case SP_ArrowUp:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/up-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/up-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/up-128.png"), QSize(128, 128));
+ break;
+ case SP_ArrowDown:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/down-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/down-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/down-128.png"), QSize(128, 128));
+ break;
+ case SP_DirHomeIcon:
+ case SP_DirIcon:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-16.png"),
+ QSize(), QIcon::Normal, QIcon::Off);
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-16.png"),
+ QSize(), QIcon::Normal, QIcon::On);
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-32.png"),
+ QSize(32, 32), QIcon::Normal, QIcon::Off);
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-32.png"),
+ QSize(32, 32), QIcon::Normal, QIcon::On);
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-128.png"),
+ QSize(128, 128), QIcon::Normal, QIcon::Off);
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-128.png"),
+ QSize(128, 128), QIcon::Normal, QIcon::On);
+ break;
+ case SP_DriveCDIcon:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-128.png"), QSize(128, 128));
+ break;
+ case SP_DriveDVDIcon:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-128.png"), QSize(128, 128));
+ break;
+ case SP_FileIcon:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/file-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/file-128.png"), QSize(128, 128));
+ break;
+ case SP_FileLinkIcon:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-128.png"), QSize(128, 128));
+ break;
+ case SP_TrashIcon:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/trash-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/trash-32.png"), QSize(32, 32));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/trash-128.png"), QSize(128, 128));
+ break;
+ case SP_BrowserReload:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/refresh-24.png"), QSize(24, 24));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/refresh-32.png"), QSize(32, 32));
+ break;
+ case SP_BrowserStop:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/stop-24.png"), QSize(24, 24));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/stop-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaPlay:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-play-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-play-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaPause:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-pause-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-pause-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaStop:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-stop-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-stop-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaSeekForward:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-forward-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-forward-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaSeekBackward:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-backward-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-backward-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaSkipForward:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-forward-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-forward-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaSkipBackward:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-backward-16.png"), QSize(16, 16));
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-backward-32.png"), QSize(32, 32));
+ break;
+ case SP_MediaVolume:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-16.png"), QSize(16, 16));
+ break;
+ case SP_MediaVolumeMuted:
+ icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-muted-16.png"), QSize(16, 16));
+ break;
+#endif // QT_NO_IMAGEFORMAT_PNG
+ default:
+ icon.addPixmap(proxy()->standardPixmap(standardIcon, option, widget));
+ break;
+ }
+ return icon;
+}
+
+static inline uint qt_intensity(uint r, uint g, uint b)
+{
+ // 30% red, 59% green, 11% blue
+ return (77 * r + 150 * g + 28 * b) / 255;
+}
+
+/*! \reimp */
+QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const
+{
+ switch (iconMode) {
+ case QIcon::Disabled: {
+ QImage im = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+
+ // Create a colortable based on the background (black -> bg -> white)
+ QColor bg = opt->palette.color(QPalette::Disabled, QPalette::Window);
+ int red = bg.red();
+ int green = bg.green();
+ int blue = bg.blue();
+ uchar reds[256], greens[256], blues[256];
+ for (int i=0; i<128; ++i) {
+ reds[i] = uchar((red * (i<<1)) >> 8);
+ greens[i] = uchar((green * (i<<1)) >> 8);
+ blues[i] = uchar((blue * (i<<1)) >> 8);
+ }
+ for (int i=0; i<128; ++i) {
+ reds[i+128] = uchar(qMin(red + (i << 1), 255));
+ greens[i+128] = uchar(qMin(green + (i << 1), 255));
+ blues[i+128] = uchar(qMin(blue + (i << 1), 255));
+ }
+
+ int intensity = qt_intensity(red, green, blue);
+ const int factor = 191;
+
+ // High intensity colors needs dark shifting in the color table, while
+ // low intensity colors needs light shifting. This is to increase the
+ // percieved contrast.
+ if ((red - factor > green && red - factor > blue)
+ || (green - factor > red && green - factor > blue)
+ || (blue - factor > red && blue - factor > green))
+ intensity = qMin(255, intensity + 91);
+ else if (intensity <= 128)
+ intensity -= 51;
+
+ for (int y=0; y<im.height(); ++y) {
+ QRgb *scanLine = (QRgb*)im.scanLine(y);
+ for (int x=0; x<im.width(); ++x) {
+ QRgb pixel = *scanLine;
+ // Calculate color table index, taking intensity adjustment
+ // and a magic offset into account.
+ uint ci = uint(qGray(pixel)/3 + (130 - intensity / 3));
+ *scanLine = qRgba(reds[ci], greens[ci], blues[ci], qAlpha(pixel));
+ ++scanLine;
+ }
+ }
+
+ return QPixmap::fromImage(im);
+ }
+ case QIcon::Selected: {
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QColor color = opt->palette.color(QPalette::Normal, QPalette::Highlight);
+ color.setAlphaF(qreal(0.3));
+ QPainter painter(&img);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
+ painter.fillRect(0, 0, img.width(), img.height(), color);
+ painter.end();
+ return QPixmap::fromImage(img); }
+ case QIcon::Active:
+ return pixmap;
+ default:
+ break;
+ }
+ return pixmap;
+}
+
+/*!
+ \reimp
+*/
+void QCommonStyle::polish(QPalette &pal)
+{
+ QStyle::polish(pal);
+}
+
+/*!
+ \reimp
+ */
+void QCommonStyle::polish(QWidget *widget)
+{
+ QStyle::polish(widget);
+}
+
+/*!
+ \reimp
+ */
+void QCommonStyle::unpolish(QWidget *widget)
+{
+ QStyle::unpolish(widget);
+}
+
+/*!
+ \reimp
+*/
+void QCommonStyle::polish(QApplication *app)
+{
+ QStyle::polish(app);
+}
+
+/*!
+ \reimp
+ */
+void QCommonStyle::unpolish(QApplication *application)
+{
+ Q_D(const QCommonStyle);
+ d->tabBarcloseButtonIcon = QIcon();
+ QStyle::unpolish(application);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qcommonstyle.h b/src/widgets/styles/qcommonstyle.h
new file mode 100644
index 0000000000..d7afea9333
--- /dev/null
+++ b/src/widgets/styles/qcommonstyle.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMMONSTYLE_H
+#define QCOMMONSTYLE_H
+
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+QT_MODULE(Gui)
+
+class QCommonStylePrivate;
+
+class Q_GUI_EXPORT QCommonStyle: public QStyle
+{
+ Q_OBJECT
+
+public:
+ QCommonStyle();
+ ~QCommonStyle();
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric m, const QStyleOption *opt = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+
+ void polish(QPalette &);
+ void polish(QApplication *app);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *application);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ QCommonStyle(QCommonStylePrivate &dd);
+
+private:
+ Q_DECLARE_PRIVATE(QCommonStyle)
+ Q_DISABLE_COPY(QCommonStyle)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOMMONSTYLE_H
diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h
new file mode 100644
index 0000000000..554a8130f6
--- /dev/null
+++ b/src/widgets/styles/qcommonstyle_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMMONSTYLE_P_H
+#define QCOMMONSTYLE_P_H
+
+#include "qcommonstyle.h"
+#include "qstyle_p.h"
+
+#include "qstyleoption.h"
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class QStringList;
+
+// Private class
+class QCommonStylePrivate : public QStylePrivate
+{
+ Q_DECLARE_PUBLIC(QCommonStyle)
+public:
+ inline QCommonStylePrivate()
+#ifndef QT_NO_ITEMVIEWS
+ : cachedOption(0)
+#endif
+ { }
+
+#ifndef QT_NO_ITEMVIEWS
+ ~QCommonStylePrivate()
+ {
+ delete cachedOption;
+ }
+ void viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const;
+ void viewItemLayout(const QStyleOptionViewItemV4 *opt, QRect *checkRect,
+ QRect *pixmapRect, QRect *textRect, bool sizehint) const;
+ QSize viewItemSize(const QStyleOptionViewItemV4 *option, int role) const;
+
+ mutable QRect decorationRect, displayRect, checkRect;
+ mutable QStyleOptionViewItemV4 *cachedOption;
+ bool isViewItemCached(const QStyleOptionViewItemV4 &option) const {
+ return cachedOption && (option.rect == cachedOption->rect
+ && option.direction == cachedOption->direction
+ && option.state == cachedOption->state
+ && option.displayAlignment == cachedOption->displayAlignment
+ && option.decorationAlignment == cachedOption->decorationAlignment
+ && option.decorationPosition == cachedOption->decorationPosition
+ && option.decorationSize == cachedOption->decorationSize
+ && option.font == cachedOption->font
+ && option.features == cachedOption->features
+ && option.widget == cachedOption->widget
+ && option.index == cachedOption->index
+ && option.icon.isNull() == cachedOption->icon.isNull()
+ && option.text == cachedOption->text
+ && option.viewItemPosition == cachedOption->viewItemPosition);
+ }
+#endif
+ mutable QIcon tabBarcloseButtonIcon;
+#ifndef QT_NO_TABBAR
+ void tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif //QCOMMONSTYLE_P_H
diff --git a/src/widgets/styles/qcommonstylepixmaps_p.h b/src/widgets/styles/qcommonstylepixmaps_p.h
new file mode 100644
index 0000000000..93cd837fb7
--- /dev/null
+++ b/src/widgets/styles/qcommonstylepixmaps_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+static const char * const check_list_controller_xpm[] = {
+"16 16 4 1",
+" c None",
+". c #000000000000",
+"X c #FFFFFFFF0000",
+"o c #C71BC30BC71B",
+" ",
+" ",
+" .......... ",
+" .XXXXXXXX. ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" ..........oo ",
+" oooooooooo ",
+" oooooooooo ",
+" ",
+" "};
+
+static const char * const tree_branch_open_xpm[] = {
+"9 9 2 1",
+" c None",
+"# c #000000",
+"#########",
+"# #",
+"# ##### #",
+"# ### #",
+"# ### #",
+"# # #",
+"# # #",
+"# #",
+"#########"};
+
+static const char * const tree_branch_closed_xpm[] = {
+"9 9 2 1",
+" c None",
+"# c #000000",
+"#########",
+"# #",
+"# # #",
+"# ### #",
+"# ##### #",
+"# ### #",
+"# # #",
+"# #",
+"#########"};
+
+static const char * const tb_extension_arrow_v_xpm[] = {
+ "5 8 3 1",
+ " c None",
+ ". c #000000",
+ "+ c none",
+ ".+++.",
+ "..+..",
+ "+...+",
+ "++.++",
+ ".+++.",
+ "..+..",
+ "+...+",
+ "++.++"
+};
+
+static const char * const tb_extension_arrow_h_xpm[] = {
+ "8 5 3 1",
+ " c None",
+ ". c #000000",
+ "+ c none",
+ "..++..++",
+ "+..++..+",
+ "++..++..",
+ "+..++..+",
+ "..++..++",
+};
+
+static const char * const filedialog_start_xpm[]={
+ "16 15 8 1",
+ "a c #cec6bd",
+ "# c #000000",
+ "e c #ffff00",
+ "b c #999999",
+ "f c #cccccc",
+ "d c #dcdcdc",
+ "c c #ffffff",
+ ". c None",
+ ".....######aaaaa",
+ "...bb#cccc##aaaa",
+ "..bcc#cccc#d#aaa",
+ ".bcef#cccc#dd#aa",
+ ".bcfe#cccc#####a",
+ ".bcef#ccccccccc#",
+ "bbbbbbbbbbbbccc#",
+ "bccccccccccbbcc#",
+ "bcefefefefee#bc#",
+ ".bcefefefefef#c#",
+ ".bcfefefefefe#c#",
+ "..bcfefefefeeb##",
+ "..bbbbbbbbbbbbb#",
+ "...#############",
+ "................"};
+
+static const char * const filedialog_end_xpm[]={
+ "16 15 9 1",
+ "d c #a0a0a0",
+ "c c #c3c3c3",
+ "# c #cec6bd",
+ ". c #000000",
+ "f c #ffff00",
+ "e c #999999",
+ "g c #cccccc",
+ "b c #ffffff",
+ "a c None",
+ "......####aaaaaa",
+ ".bbbb..###aaaaaa",
+ ".bbbb.c.##aaaaaa",
+ ".bbbb....ddeeeea",
+ ".bbbbbbb.bbbbbe.",
+ ".bbbbbbb.bcfgfe.",
+ "eeeeeeeeeeeeefe.",
+ "ebbbbbbbbbbeege.",
+ "ebfgfgfgfgff.ee.",
+ "aebfgfgfgfgfg.e.",
+ "aebgfgfgfgfgf.e.",
+ "aaebgfgfgfgffe..",
+ "aaeeeeeeeeeeeee.",
+ "aaa.............",
+ "aaaaaaaaaaaaaaaa"};
+
+#endif // QT_NO_IMAGEFORMAT_XPM
diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp
new file mode 100644
index 0000000000..94cec208d0
--- /dev/null
+++ b/src/widgets/styles/qdrawutil.cpp
@@ -0,0 +1,1053 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdrawutil.h"
+#include "qbitmap.h"
+#include "qpixmapcache.h"
+#include "qpainter.h"
+#include "qpalette.h"
+#include <private/qpaintengineex_p.h>
+#include <qvarlengtharray.h>
+#include <qmath.h>
+#include <private/qhexstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \headerfile <qdrawutil.h>
+ \title Drawing Utility Functions
+
+ \sa QPainter
+*/
+
+/*!
+ \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2,
+ const QPalette &palette, bool sunken,
+ int lineWidth, int midLineWidth)
+ \relates <qdrawutil.h>
+
+ Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
+ shaded line using the given \a painter. Note that nothing is
+ drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is
+ neither horizontal nor vertical).
+
+ The provided \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The given \a midLineWidth specifies the width of
+ a middle line drawn in the QPalette::mid() color.
+
+ The line appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to
+ make widgets that follow the current GUI style.
+
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded line:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 0
+
+ \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
+*/
+
+void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth)
+{
+ if (!(p && lineWidth >= 0 && midLineWidth >= 0)) {
+ qWarning("qDrawShadeLine: Invalid parameters");
+ return;
+ }
+ int tlw = lineWidth*2 + midLineWidth; // total line width
+ QPen oldPen = p->pen(); // save pen
+ if (sunken)
+ p->setPen(pal.color(QPalette::Dark));
+ else
+ p->setPen(pal.light().color());
+ QPolygon a;
+ int i;
+ if (y1 == y2) { // horizontal line
+ int y = y1 - tlw/2;
+ if (x1 > x2) { // swap x1 and x2
+ int t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ x2--;
+ for (i=0; i<lineWidth; i++) { // draw top shadow
+ a.setPoints(3, x1+i, y+tlw-1-i,
+ x1+i, y+i,
+ x2-i, y+i);
+ p->drawPolyline(a);
+ }
+ if (midLineWidth > 0) {
+ p->setPen(pal.mid().color());
+ for (i=0; i<midLineWidth; i++) // draw lines in the middle
+ p->drawLine(x1+lineWidth, y+lineWidth+i,
+ x2-lineWidth, y+lineWidth+i);
+ }
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ for (i=0; i<lineWidth; i++) { // draw bottom shadow
+ a.setPoints(3, x1+i, y+tlw-i-1,
+ x2-i, y+tlw-i-1,
+ x2-i, y+i+1);
+ p->drawPolyline(a);
+ }
+ }
+ else if (x1 == x2) { // vertical line
+ int x = x1 - tlw/2;
+ if (y1 > y2) { // swap y1 and y2
+ int t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ y2--;
+ for (i=0; i<lineWidth; i++) { // draw left shadow
+ a.setPoints(3, x+i, y2,
+ x+i, y1+i,
+ x+tlw-1, y1+i);
+ p->drawPolyline(a);
+ }
+ if (midLineWidth > 0) {
+ p->setPen(pal.mid().color());
+ for (i=0; i<midLineWidth; i++) // draw lines in the middle
+ p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2);
+ }
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ for (i=0; i<lineWidth; i++) { // draw right shadow
+ a.setPoints(3, x+lineWidth, y2-i,
+ x+tlw-i-1, y2-i,
+ x+tlw-i-1, y1+lineWidth);
+ p->drawPolyline(a);
+ }
+ }
+ p->setPen(oldPen);
+}
+
+/*!
+ \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ int lineWidth, int midLineWidth,
+ const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the shaded rectangle beginning at (\a x, \a y) with the
+ given \a width and \a height using the provided \a painter.
+
+ The provide \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors. The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The \a midLineWidth specifies the width of a
+ middle line drawn in the QPalette::mid() color. The rectangle's
+ interior is filled with the \a fill brush unless \a fill is 0.
+
+ The rectangle appears sunken if \a sunken is true, otherwise
+ raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 1
+
+ \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
+*/
+
+void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth,
+ const QBrush *fill)
+{
+ if (w == 0 || h == 0)
+ return;
+ if (! (w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0)) {
+ qWarning("qDrawShadeRect: Invalid parameters");
+ return;
+ }
+ QPen oldPen = p->pen();
+ if (sunken)
+ p->setPen(pal.dark().color());
+ else
+ p->setPen(pal.light().color());
+ int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
+
+ if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle
+ p->drawRect(x1, y1, w-2, h-2);
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1),
+ QLineF(x1+1, y1+2, x1+1, y2-2),
+ QLineF(x1, y2, x2, y2),
+ QLineF(x2,y1, x2,y2-1) };
+ p->drawLines(lines, 4); // draw bottom/right lines
+ } else { // more complicated
+ int m = lineWidth+midLineWidth;
+ int i, j=0, k=m;
+ for (i=0; i<lineWidth; i++) { // draw top shadow
+ QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i),
+ QLineF(x1+i, y1+i, x2-i, y1+i),
+ QLineF(x1+k, y2-k, x2-k, y2-k),
+ QLineF(x2-k, y2-k, x2-k, y1+k) };
+ p->drawLines(lines, 4);
+ k++;
+ }
+ p->setPen(pal.mid().color());
+ j = lineWidth*2;
+ for (i=0; i<midLineWidth; i++) { // draw lines in the middle
+ p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1);
+ j += 2;
+ }
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ k = m;
+ for (i=0; i<lineWidth; i++) { // draw bottom shadow
+ QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i),
+ QLineF(x2-i, y2-i, x2-i, y1+i+1),
+ QLineF(x1+k, y2-k, x1+k, y1+k),
+ QLineF(x1+k, y1+k, x2-k, y1+k) };
+ p->drawLines(lines, 4);
+ k++;
+ }
+ }
+ if (fill) {
+ QBrush oldBrush = p->brush();
+ int tlw = lineWidth + midLineWidth;
+ p->setPen(Qt::NoPen);
+ p->setBrush(*fill);
+ p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw);
+ p->setBrush(oldBrush);
+ }
+ p->setPen(oldPen); // restore pen
+}
+
+
+/*!
+ \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the shaded panel beginning at (\a x, \a y) with the given \a
+ width and \a height using the provided \a painter and the given \a
+ lineWidth.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The panel's interior is filled
+ with the \a fill brush unless \a fill is 0.
+
+ The panel appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 2
+
+ \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
+*/
+
+void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ int lineWidth, const QBrush *fill)
+{
+ if (w == 0 || h == 0)
+ return;
+ if (!(w > 0 && h > 0 && lineWidth >= 0)) {
+ qWarning("qDrawShadePanel: Invalid parameters");
+ }
+ QColor shade = pal.dark().color();
+ QColor light = pal.light().color();
+ if (fill) {
+ if (fill->color() == shade)
+ shade = pal.shadow().color();
+ if (fill->color() == light)
+ light = pal.midlight().color();
+ }
+ QPen oldPen = p->pen(); // save pen
+ QVector<QLineF> lines;
+ lines.reserve(2*lineWidth);
+
+ if (sunken)
+ p->setPen(shade);
+ else
+ p->setPen(light);
+ int x1, y1, x2, y2;
+ int i;
+ x1 = x;
+ y1 = y2 = y;
+ x2 = x+w-2;
+ for (i=0; i<lineWidth; i++) { // top shadow
+ lines << QLineF(x1, y1++, x2--, y2++);
+ }
+ x2 = x1;
+ y1 = y+h-2;
+ for (i=0; i<lineWidth; i++) { // left shado
+ lines << QLineF(x1++, y1, x2++, y2--);
+ }
+ p->drawLines(lines);
+ lines.clear();
+ if (sunken)
+ p->setPen(light);
+ else
+ p->setPen(shade);
+ x1 = x;
+ y1 = y2 = y+h-1;
+ x2 = x+w-1;
+ for (i=0; i<lineWidth; i++) { // bottom shadow
+ lines << QLineF(x1++, y1--, x2, y2--);
+ }
+ x1 = x2;
+ y1 = y;
+ y2 = y+h-lineWidth-1;
+ for (i=0; i<lineWidth; i++) { // right shadow
+ lines << QLineF(x1--, y1++, x2--, y2);
+ }
+ p->drawLines(lines);
+ if (fill) // fill with fill color
+ p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
+ p->setPen(oldPen); // restore pen
+}
+
+
+/*!
+ \internal
+ This function draws a rectangle with two pixel line width.
+ It is called from qDrawWinButton() and qDrawWinPanel().
+
+ c1..c4 and fill are used:
+
+ 1 1 1 1 1 2
+ 1 3 3 3 4 2
+ 1 3 F F 4 2
+ 1 3 F F 4 2
+ 1 4 4 4 4 2
+ 2 2 2 2 2 2
+*/
+
+static void qDrawWinShades(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill)
+{
+ if (w < 2 || h < 2) // can't do anything with that
+ return;
+ QPen oldPen = p->pen();
+ QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
+ p->setPen(c1);
+ p->drawPolyline(a, 3);
+ QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
+ p->setPen(c2);
+ p->drawPolyline(b, 3);
+ if (w > 4 && h > 4) {
+ QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ p->setPen(c3);
+ p->drawPolyline(c, 3);
+ QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
+ p->setPen(c4);
+ p->drawPolyline(d, 3);
+ if (fill)
+ p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
+ }
+ p->setPen(oldPen);
+}
+
+
+/*!
+ \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the Windows-style button specified by the given point (\a x,
+ \a y}, \a width and \a height using the provided \a painter with a
+ line width of 2 pixels. The button's interior is filled with the
+ \a{fill} brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors).
+
+ The button appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style()-> Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawWinPanel(), QStyle
+*/
+
+void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ const QBrush *fill)
+{
+ if (sunken)
+ qDrawWinShades(p, x, y, w, h,
+ pal.shadow().color(), pal.light().color(), pal.dark().color(),
+ pal.button().color(), fill);
+ else
+ qDrawWinShades(p, x, y, w, h,
+ pal.light().color(), pal.shadow().color(), pal.button().color(),
+ pal.dark().color(), fill);
+}
+
+/*!
+ \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the Windows-style panel specified by the given point(\a x,
+ \a y), \a width and \a height using the provided \a painter with a
+ line width of 2 pixels. The button's interior is filled with the
+ \a fill brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors. The panel
+ appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 3
+
+ \sa qDrawShadePanel(), qDrawWinButton(), QStyle
+*/
+
+void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ const QBrush *fill)
+{
+ if (sunken)
+ qDrawWinShades(p, x, y, w, h,
+ pal.dark().color(), pal.light().color(), pal.shadow().color(),
+ pal.midlight().color(), fill);
+ else
+ qDrawWinShades(p, x, y, w, h,
+ pal.light().color(), pal.shadow().color(), pal.midlight().color(),
+ pal.dark().color(), fill);
+}
+
+/*!
+ \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor,
+ int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the plain rectangle beginning at (\a x, \a y) with the given
+ \a width and \a height, using the specified \a painter, \a lineColor
+ and \a lineWidth. The rectangle's interior is filled with the \a
+ fill brush unless \a fill is 0.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a plain rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 4
+
+ \sa qDrawShadeRect(), QStyle
+*/
+
+void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
+ int lineWidth, const QBrush *fill)
+{
+ if (w == 0 || h == 0)
+ return;
+ if (!(w > 0 && h > 0 && lineWidth >= 0)) {
+ qWarning("qDrawPlainRect: Invalid parameters");
+ }
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ p->setPen(c);
+ p->setBrush(Qt::NoBrush);
+ for (int i=0; i<lineWidth; i++)
+ p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
+ if (fill) { // fill with fill color
+ p->setPen(Qt::NoPen);
+ p->setBrush(*fill);
+ p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2);
+ }
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+}
+
+/*****************************************************************************
+ Overloaded functions.
+ *****************************************************************************/
+
+/*!
+ \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2,
+ const QPalette &palette, bool sunken, int lineWidth, int midLineWidth)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws a horizontal or vertical shaded line between \a p1 and \a p2
+ using the given \a painter. Note that nothing is drawn if the line
+ between the points would be neither horizontal nor vertical.
+
+ The provided \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The given \a midLineWidth specifies the width of
+ a middle line drawn in the QPalette::mid() color.
+
+ The line appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to
+ make widgets that follow the current GUI style.
+
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded line:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 5
+
+ \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
+*/
+
+void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth)
+{
+ qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
+ lineWidth, midLineWidth);
+}
+
+/*!
+ \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the shaded rectangle specified by \a rect using the given \a painter.
+
+ The provide \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors. The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The \a midLineWidth specifies the width of a
+ middle line drawn in the QPalette::mid() color. The rectangle's
+ interior is filled with the \a fill brush unless \a fill is 0.
+
+ The rectangle appears sunken if \a sunken is true, otherwise
+ raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 6
+
+ \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
+*/
+
+void qDrawShadeRect(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth,
+ const QBrush *fill)
+{
+ qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
+ lineWidth, midLineWidth, fill);
+}
+
+/*!
+ \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the shaded panel at the rectangle specified by \a rect using the
+ given \a painter and the given \a lineWidth.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The panel's interior is filled
+ with the \a fill brush unless \a fill is 0.
+
+ The panel appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 7
+
+ \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
+*/
+
+void qDrawShadePanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken,
+ int lineWidth, const QBrush *fill)
+{
+ qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
+ lineWidth, fill);
+}
+
+/*!
+ \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the Windows-style button at the rectangle specified by \a rect using
+ the given \a painter with a line width of 2 pixels. The button's interior
+ is filled with the \a{fill} brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors).
+
+ The button appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style()-> Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawWinPanel(), QStyle
+*/
+
+void qDrawWinButton(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken, const QBrush *fill)
+{
+ qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
+}
+
+/*!
+ \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, const QBrush *fill)
+ \overload
+
+ Draws the Windows-style panel at the rectangle specified by \a rect using
+ the given \a painter with a line width of 2 pixels. The button's interior
+ is filled with the \a fill brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors. The panel
+ appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 8
+
+ \sa qDrawShadePanel(), qDrawWinButton(), QStyle
+*/
+
+void qDrawWinPanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken, const QBrush *fill)
+{
+ qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
+}
+
+/*!
+ \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the plain rectangle specified by \a rect using the given \a painter,
+ \a lineColor and \a lineWidth. The rectangle's interior is filled with the
+ \a fill brush unless \a fill is 0.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a plain rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 9
+
+ \sa qDrawShadeRect(), QStyle
+*/
+
+void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
+ int lineWidth, const QBrush *fill)
+{
+ qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
+ lineWidth, fill);
+}
+
+
+/*!
+ \class QTileRules
+ \since 4.6
+
+ Holds the rules used to draw a pixmap or image split into nine segments,
+ similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}.
+
+ \sa Qt::TileRule, QMargins
+*/
+
+/*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
+ Constructs a QTileRules with the given \a horizontalRule and
+ \a verticalRule.
+ */
+
+/*! \fn QTileRules::QTileRules(Qt::TileRule rule)
+ Constructs a QTileRules with the given \a rule used for both
+ the horizontal rule and the vertical rule.
+ */
+
+/*!
+ \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap)
+ \relates <qdrawutil.h>
+ \since 4.6
+ \overload
+
+ \brief The qDrawBorderPixmap function is for drawing a pixmap into
+ the margins of a rectangle.
+
+ Draws the given \a pixmap into the given \a target rectangle, using the
+ given \a painter. The pixmap will be split into nine segments and drawn
+ according to the \a margins structure.
+*/
+
+typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray;
+
+/*!
+ \since 4.6
+
+ Draws the indicated \a sourceRect rectangle from the given \a pixmap into
+ the given \a targetRect rectangle, using the given \a painter. The pixmap
+ will be split into nine segments according to the given \a targetMargins
+ and \a sourceMargins structures. Finally, the pixmap will be drawn
+ according to the given \a rules.
+
+ This function is used to draw a scaled pixmap, similar to
+ \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}
+
+ \sa Qt::TileRule, QTileRules, QMargins
+*/
+
+void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins,
+ const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
+ const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
+{
+ QPainter::PixmapFragment d;
+ d.opacity = 1.0;
+ d.rotation = 0.0;
+
+ QPixmapFragmentsArray opaqueData;
+ QPixmapFragmentsArray translucentData;
+
+ // source center
+ const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
+ const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
+ const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
+ const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
+ const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
+ const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
+ // target center
+ const int targetCenterTop = targetRect.top() + targetMargins.top();
+ const int targetCenterLeft = targetRect.left() + targetMargins.left();
+ const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
+ const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
+ const int targetCenterWidth = targetCenterRight - targetCenterLeft;
+ const int targetCenterHeight = targetCenterBottom - targetCenterTop;
+
+ QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
+ QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
+
+ int columns = 3;
+ int rows = 3;
+ if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
+ columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
+ if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
+ rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
+
+ xTarget.resize(columns + 1);
+ yTarget.resize(rows + 1);
+
+ bool oldAA = painter->testRenderHint(QPainter::Antialiasing);
+ if (painter->paintEngine()->type() != QPaintEngine::OpenGL
+ && painter->paintEngine()->type() != QPaintEngine::OpenGL2
+ && oldAA && painter->combinedTransform().type() != QTransform::TxNone) {
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ }
+
+ xTarget[0] = targetRect.left();
+ xTarget[1] = targetCenterLeft;
+ xTarget[columns - 1] = targetCenterRight;
+ xTarget[columns] = targetRect.left() + targetRect.width();
+
+ yTarget[0] = targetRect.top();
+ yTarget[1] = targetCenterTop;
+ yTarget[rows - 1] = targetCenterBottom;
+ yTarget[rows] = targetRect.top() + targetRect.height();
+
+ qreal dx = targetCenterWidth;
+ qreal dy = targetCenterHeight;
+
+ switch (rules.horizontal) {
+ case Qt::StretchTile:
+ dx = targetCenterWidth;
+ break;
+ case Qt::RepeatTile:
+ dx = sourceCenterWidth;
+ break;
+ case Qt::RoundTile:
+ dx = targetCenterWidth / qreal(columns - 2);
+ break;
+ }
+
+ for (int i = 2; i < columns - 1; ++i)
+ xTarget[i] = xTarget[i - 1] + dx;
+
+ switch (rules.vertical) {
+ case Qt::StretchTile:
+ dy = targetCenterHeight;
+ break;
+ case Qt::RepeatTile:
+ dy = sourceCenterHeight;
+ break;
+ case Qt::RoundTile:
+ dy = targetCenterHeight / qreal(rows - 2);
+ break;
+ }
+
+ for (int i = 2; i < rows - 1; ++i)
+ yTarget[i] = yTarget[i - 1] + dy;
+
+ // corners
+ if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceRect.top();
+ d.width = sourceMargins.left();
+ d.height = sourceMargins.top();
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueTopLeft)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+ if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceRect.top();
+ d.width = sourceMargins.right();
+ d.height = sourceMargins.top();
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueTopRight)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+ if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceMargins.left();
+ d.height = sourceMargins.bottom();
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueBottomLeft)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+ if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceMargins.right();
+ d.height = sourceMargins.bottom();
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueBottomRight)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+
+ // horizontal edges
+ if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
+ if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceRect.top();
+ d.width = sourceCenterWidth;
+ d.height = sourceMargins.top();
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.scaleX = dx / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
+ for (int i = 1; i < columns - 1; ++i) {
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
+ }
+ if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceCenterWidth;
+ d.height = sourceMargins.bottom();
+ d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.scaleX = dx / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
+ for (int i = 1; i < columns - 1; ++i) {
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
+ }
+ }
+
+ // vertical edges
+ if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
+ if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceMargins.left();
+ d.height = sourceCenterHeight;
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = dy / d.height;
+ for (int i = 1; i < rows - 1; ++i) {
+ d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
+ data.append(d);
+ }
+ if (rules.vertical == Qt::RepeatTile)
+ data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
+ }
+ if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceMargins.right();
+ d.height = sourceCenterHeight;
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = dy / d.height;
+ for (int i = 1; i < rows - 1; ++i) {
+ d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
+ data.append(d);
+ }
+ if (rules.vertical == Qt::RepeatTile)
+ data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
+ }
+ }
+
+ // center
+ if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceCenterWidth;
+ d.height = sourceCenterHeight;
+ d.scaleX = dx / d.width;
+ d.scaleY = dy / d.height;
+
+ qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
+ qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
+
+ for (int j = 1; j < rows - 1; ++j) {
+ d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
+ for (int i = 1; i < columns - 1; ++i) {
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].width = repeatWidth;
+ }
+ if (rules.vertical == Qt::RepeatTile) {
+ for (int i = 1; i < columns - 1; ++i)
+ data[data.size() - i].height = repeatHeight;
+ }
+ }
+
+ if (opaqueData.size())
+ painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
+ if (translucentData.size())
+ painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
+
+ if (oldAA)
+ painter->setRenderHint(QPainter::Antialiasing, true);
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qdrawutil.h b/src/widgets/styles/qdrawutil.h
new file mode 100644
index 0000000000..01319c9427
--- /dev/null
+++ b/src/widgets/styles/qdrawutil.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDRAWUTIL_H
+#define QDRAWUTIL_H
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/qstring.h> // char*->QString conversion
+#include <QtCore/qmargins.h>
+#include <QtGui/qpixmap.h>
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPainter;
+class QPalette;
+class QPoint;
+class QColor;
+class QBrush;
+class QRect;
+
+//
+// Standard shade drawing
+//
+
+Q_GUI_EXPORT void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
+ const QPalette &pal, bool sunken = true,
+ int lineWidth = 1, int midLineWidth = 0);
+
+Q_GUI_EXPORT void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
+ const QPalette &pal, bool sunken = true,
+ int lineWidth = 1, int midLineWidth = 0);
+
+Q_GUI_EXPORT void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, int midLineWidth = 0,
+ const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawShadeRect(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, int midLineWidth = 0,
+ const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawShadePanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawWinButton(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawWinPanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+Q_GUI_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+
+
+struct QTileRules
+{
+ inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
+ : horizontal(horizontalRule), vertical(verticalRule) {}
+ inline QTileRules(Qt::TileRule rule = Qt::StretchTile)
+ : horizontal(rule), vertical(rule) {}
+ Qt::TileRule horizontal;
+ Qt::TileRule vertical;
+};
+
+#ifndef Q_QDOC
+// For internal use only.
+namespace QDrawBorderPixmap
+{
+ enum DrawingHint
+ {
+ OpaqueTopLeft = 0x0001,
+ OpaqueTop = 0x0002,
+ OpaqueTopRight = 0x0004,
+ OpaqueLeft = 0x0008,
+ OpaqueCenter = 0x0010,
+ OpaqueRight = 0x0020,
+ OpaqueBottomLeft = 0x0040,
+ OpaqueBottom = 0x0080,
+ OpaqueBottomRight = 0x0100,
+ OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight,
+ OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom,
+ OpaqueFrame = OpaqueCorners | OpaqueEdges,
+ OpaqueAll = OpaqueCenter | OpaqueFrame
+ };
+
+ Q_DECLARE_FLAGS(DrawingHints, DrawingHint)
+}
+#endif
+
+Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter,
+ const QRect &targetRect,
+ const QMargins &targetMargins,
+ const QPixmap &pixmap,
+ const QRect &sourceRect,
+ const QMargins &sourceMargins,
+ const QTileRules &rules = QTileRules()
+#ifndef Q_QDOC
+ , QDrawBorderPixmap::DrawingHints hints = 0
+#endif
+ );
+
+inline void qDrawBorderPixmap(QPainter *painter,
+ const QRect &target,
+ const QMargins &margins,
+ const QPixmap &pixmap)
+{
+ qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDRAWUTIL_H
diff --git a/src/widgets/styles/qgtkpainter.cpp b/src/widgets/styles/qgtkpainter.cpp
new file mode 100644
index 0000000000..373732f924
--- /dev/null
+++ b/src/widgets/styles/qgtkpainter.cpp
@@ -0,0 +1,716 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgtkpainter_p.h"
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+// This class is primarily a wrapper around the gtk painter functions
+// and takes care of converting all such calls into cached Qt pixmaps.
+
+#include <private/qstylehelper_p.h>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QStyleOption>
+#include <QtGui/QPixmapCache>
+
+QT_BEGIN_NAMESPACE
+
+#undef GTK_OBJECT_FLAGS
+#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
+
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+# define QT_RED 3
+# define QT_GREEN 2
+# define QT_BLUE 1
+# define QT_ALPHA 0
+#else
+# define QT_RED 0
+# define QT_GREEN 1
+# define QT_BLUE 2
+# define QT_ALPHA 3
+#endif
+# define GTK_RED 2
+# define GTK_GREEN 1
+# define GTK_BLUE 0
+# define GTK_ALPHA 3
+
+// To recover alpha we apply the gtk painting function two times to
+// white, and black window backgrounds. This can be used to
+// recover the premultiplied alpha channel
+QPixmap QGtkPainter::renderTheme(uchar *bdata, uchar *wdata, const QRect &rect)
+{
+ const int bytecount = rect.width() * rect.height() * 4;
+ for (int index = 0; index < bytecount ; index += 4) {
+ uchar val = bdata[index + GTK_BLUE];
+ if (m_alpha) {
+ int alphaval = qMax(bdata[index + GTK_BLUE] - wdata[index + GTK_BLUE],
+ bdata[index + GTK_GREEN] - wdata[index + GTK_GREEN]);
+ alphaval = qMax(alphaval, bdata[index + GTK_RED] - wdata[index + GTK_RED]) + 255;
+ bdata[index + QT_ALPHA] = alphaval;
+ }
+ bdata[index + QT_RED] = bdata[index + GTK_RED];
+ bdata[index + QT_GREEN] = bdata[index + GTK_GREEN];
+ bdata[index + QT_BLUE] = val;
+ }
+ QImage converted((const uchar*)bdata, rect.width(), rect.height(), m_alpha ?
+ QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+
+ if (m_hflipped || m_vflipped) {
+ return QPixmap::fromImage(converted.mirrored(m_hflipped, m_vflipped));
+ } else {
+ // on raster graphicssystem we need to do a copy here, because
+ // we intend to deallocate the qimage bits shortly after...
+ return QPixmap::fromImage(converted.copy());
+ }
+}
+
+// This macro is responsible for painting any GtkStyle painting function onto a QPixmap
+#define DRAW_TO_CACHE(draw_func) \
+ if (rect.width() > QWIDGETSIZE_MAX || rect.height() > QWIDGETSIZE_MAX) \
+ return; \
+ QRect pixmapRect(0, 0, rect.width(), rect.height()); \
+ { \
+ GdkPixmap *pixmap = QGtkStylePrivate::gdk_pixmap_new((GdkDrawable*)(m_window->window), \
+ rect.width(), rect.height(), -1); \
+ if (!pixmap) \
+ return; \
+ style = QGtkStylePrivate::gtk_style_attach (style, m_window->window); \
+ QGtkStylePrivate::gdk_draw_rectangle(pixmap, m_alpha ? style->black_gc : *style->bg_gc, true, \
+ 0, 0, rect.width(), rect.height()); \
+ draw_func; \
+ GdkPixbuf *imgb = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect.width(), rect.height());\
+ if (!imgb) \
+ return; \
+ imgb = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgb, pixmap, NULL, 0, 0, 0, 0, \
+ rect.width(), rect.height()); \
+ uchar* bdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgb); \
+ if (m_alpha) { \
+ QGtkStylePrivate::gdk_draw_rectangle(pixmap, style->white_gc, true, 0, 0, rect.width(), rect.height()); \
+ draw_func; \
+ GdkPixbuf *imgw = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect. \
+ width(), rect.height()); \
+ if (!imgw) \
+ return; \
+ imgw = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgw, pixmap, NULL, 0, 0, 0, 0, \
+ rect.width(), rect.height()); \
+ uchar* wdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgw); \
+ cache = renderTheme(bdata, wdata, rect); \
+ QGtkStylePrivate::gdk_pixbuf_unref(imgw); \
+ } else { \
+ cache = renderTheme(bdata, 0, rect); \
+ } \
+ QGtkStylePrivate::gdk_drawable_unref(pixmap); \
+ QGtkStylePrivate::gdk_pixbuf_unref(imgb); \
+ }
+
+QGtkPainter::QGtkPainter(QPainter *_painter)
+ : m_window(QGtkStylePrivate::gtkWidget("GtkWindow"))
+ , m_painter(_painter)
+ , m_alpha(true)
+ , m_hflipped(false)
+ , m_vflipped(false)
+ , m_usePixmapCache(true)
+{}
+
+
+static QString uniqueName(const QString &key, GtkStateType state, GtkShadowType shadow,
+ const QSize &size, GtkWidget *widget = 0)
+{
+ // Note the widget arg should ideally use the widget path, though would compromise performance
+ QString tmp = key
+ % HexString<uint>(state)
+ % HexString<uint>(shadow)
+ % HexString<uint>(size.width())
+ % HexString<uint>(size.height())
+ % HexString<quint64>(quint64(widget));
+ return tmp;
+}
+
+
+GtkStateType QGtkPainter::gtkState(const QStyleOption *option)
+
+{
+ GtkStateType state = GTK_STATE_NORMAL;
+ if (!(option->state & QStyle::State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & QStyle::State_MouseOver)
+ state = GTK_STATE_PRELIGHT;
+
+ return state;
+}
+
+
+GtkStyle* QGtkPainter::getStyle(GtkWidget *gtkWidget)
+
+{
+ Q_ASSERT(gtkWidget);
+ GtkStyle* style = gtkWidget->style;
+ Q_ASSERT(style);
+ return style;
+}
+
+QPixmap QGtkPainter::getIcon(const char* iconName, GtkIconSize size)
+{
+ GtkStyle *style = QGtkStylePrivate::gtkStyle();
+ GtkIconSet* iconSet = QGtkStylePrivate::gtk_icon_factory_lookup_default (iconName);
+ GdkPixbuf* icon = QGtkStylePrivate::gtk_icon_set_render_icon(iconSet,
+ style,
+ GTK_TEXT_DIR_LTR,
+ GTK_STATE_NORMAL,
+ size,
+ NULL,
+ "button");
+ uchar* data = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(icon);
+ int width = QGtkStylePrivate::gdk_pixbuf_get_width(icon);
+ int height = QGtkStylePrivate::gdk_pixbuf_get_height(icon);
+ QImage converted(width, height, QImage::Format_ARGB32);
+ uchar* tdata = (uchar*)converted.bits();
+
+ for ( int index = 0 ; index < height * width*4 ; index +=4 ) {
+ //int index = y * rowstride + x;
+ tdata[index + QT_RED] = data[index + GTK_RED];
+ tdata[index + QT_GREEN] = data[index + GTK_GREEN];
+ tdata[index + QT_BLUE] = data[index + GTK_BLUE];
+ tdata[index + QT_ALPHA] = data[index + GTK_ALPHA];
+ }
+
+ QGtkStylePrivate::gdk_pixbuf_unref(icon);
+
+ // should we free iconset?
+ return QPixmap::fromImage(converted);
+
+}
+
+// Note currently painted without alpha for performance reasons
+void QGtkPainter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &paintRect, GtkStateType state,
+ GtkShadowType shadow, GtkPositionType gap_side,
+ gint x, gint width,
+ GtkStyle *style)
+{
+ if (!paintRect.isValid())
+ return;
+
+ QPixmap cache;
+ QRect rect = paintRect;
+
+ // To avoid exhausting cache on large tabframes we cheat a bit by
+ // tiling the center part.
+
+ const int maxHeight = 256;
+ const int border = 16;
+ if (rect.height() > maxHeight && (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM))
+ rect.setHeight(2 * border + 1);
+
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
+ % HexString<uchar>(gap_side)
+ % HexString<gint>(width)
+ % HexString<gint>(x);
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box_gap (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ (gchar*)part,
+ 0, 0,
+ rect.width(),
+ rect.height(),
+ gap_side,
+ x,
+ width));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ if (rect.size() != paintRect.size()) {
+ // We assume we can stretch the middle tab part
+ // Note: the side effect of this is that pinstripe patterns will get fuzzy
+ const QSize size = cache.size();
+ // top part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
+ paintRect.width(), border), cache,
+ QRect(0, 0, size.width(), border));
+
+ // tiled center part
+ QPixmap tilePart(cache.width(), 1);
+ QPainter scanLinePainter(&tilePart);
+ scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
+ scanLinePainter.end();
+ m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
+ paintRect.width(), paintRect.height() - 2*border), tilePart);
+
+ // bottom part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
+ paintRect.width(), border), cache,
+ QRect(0, size.height() - border, size.width(), border));
+ } else
+ m_painter->drawPixmap(paintRect.topLeft(), cache);
+}
+
+void QGtkPainter::paintBox(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &paintRect, GtkStateType state,
+ GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey)
+{
+ if (!paintRect.isValid())
+ return;
+
+ QPixmap cache;
+ QRect rect = paintRect;
+
+ // To avoid exhausting cache on large tabframes we cheat a bit by
+ // tiling the center part.
+
+ const int maxHeight = 256;
+ const int maxArea = 256*512;
+ const int border = 32;
+ if (rect.height() > maxHeight && (rect.width()*rect.height() > maxArea))
+ rect.setHeight(2 * border + 1);
+
+ QString pixmapName = uniqueName(QLS(part), state, shadow,
+ rect.size(), gtkWidget) % pmKey;
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part,
+ 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ if (rect.size() != paintRect.size()) {
+ // We assume we can stretch the middle tab part
+ // Note: the side effect of this is that pinstripe patterns will get fuzzy
+ const QSize size = cache.size();
+ // top part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
+ paintRect.width(), border), cache,
+ QRect(0, 0, size.width(), border));
+
+ // tiled center part
+ QPixmap tilePart(cache.width(), 1);
+ QPainter scanLinePainter(&tilePart);
+ scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
+ scanLinePainter.end();
+ m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
+ paintRect.width(), paintRect.height() - 2*border), tilePart);
+
+ // bottom part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
+ paintRect.width(), border), cache,
+ QRect(0, size.height() - border, size.width(), border));
+ } else
+ m_painter->drawPixmap(paintRect.topLeft(), cache);
+}
+
+void QGtkPainter::paintHline(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkStyle *style, int x1, int x2, int y,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ % HexString<int>(x1)
+ % HexString<int>(x2)
+ % HexString<int>(y)
+ % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_hline (style,
+ pixmap,
+ state,
+ NULL,
+ gtkWidget,
+ part,
+ x1, x2, y));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintVline(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkStyle *style, int y1, int y2, int x,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ % HexString<int>(y1)
+ % HexString<int>(y2)
+ % HexString<int>(x)
+ % pmKey;
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_vline (style,
+ pixmap,
+ state,
+ NULL,
+ gtkWidget,
+ part,
+ y1, y2,
+ x));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintExpander(GtkWidget *gtkWidget,
+ const gchar* part, const QRect &rect,
+ GtkStateType state, GtkExpanderStyle expander_state,
+ GtkStyle *style, const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ % HexString<uchar>(expander_state)
+ % pmKey;
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_expander (style, pixmap,
+ state, NULL,
+ gtkWidget, part,
+ rect.width()/2,
+ rect.height()/2,
+ expander_state));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintFocus(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkStyle *style, const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_focus (style, pixmap, state, NULL,
+ gtkWidget,
+ part,
+ 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkShadowType shadow, GdkWindowEdge edge,
+ GtkStyle *style, const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_resize_grip (style, pixmap, state,
+ NULL, gtkWidget,
+ part, edge, 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintArrow(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &arrowrect, GtkArrowType arrow_type,
+ GtkStateType state, GtkShadowType shadow,
+ gboolean fill, GtkStyle *style, const QString &pmKey)
+{
+ QRect rect = m_cliprect.isValid() ? m_cliprect : arrowrect;
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
+ % HexString<uchar>(arrow_type)
+ % pmKey;
+
+ GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
+ int xOffset = m_cliprect.isValid() ? arrowrect.x() - m_cliprect.x() : 0;
+ int yOffset = m_cliprect.isValid() ? arrowrect.y() - m_cliprect.y() : 0;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_arrow (style, pixmap, state, shadow,
+ &gtkCliprect,
+ gtkWidget,
+ part,
+ arrow_type, fill,
+ xOffset, yOffset,
+ arrowrect.width(),
+ arrowrect.height()))
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkOrientation orientation, GtkStyle *style)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
+ % HexString<uchar>(orientation);
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_handle (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part, 0, 0,
+ rect.width(),
+ rect.height(),
+ orientation));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, GtkOrientation orientation,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_slider (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part,
+ 0, 0,
+ rect.width(),
+ rect.height(),
+ orientation));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey)
+
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_shadow(style, pixmap, state, shadow, NULL,
+ gtkWidget, part, 0, 0, rect.width(), rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_flat_box (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part, 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintExtention(GtkWidget *gtkWidget,
+ const gchar *part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkPositionType gap_pos, GtkStyle *style)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
+ % HexString<uchar>(gap_pos);
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_extension (style, pixmap, state, shadow,
+ NULL, gtkWidget,
+ (gchar*)part, 0, 0,
+ rect.width(),
+ rect.height(),
+ gap_pos));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, const QString &detail)
+
+{
+ QRect rect = m_cliprect.isValid() ? m_cliprect : radiorect;
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(detail, state, shadow, rect.size());
+ GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
+ int xOffset = m_cliprect.isValid() ? radiorect.x() - m_cliprect.x() : 0;
+ int yOffset = m_cliprect.isValid() ? radiorect.y() - m_cliprect.y() : 0;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_option(style, pixmap,
+ state, shadow,
+ &gtkCliprect,
+ gtkWidget,
+ detail.toLatin1(),
+ xOffset, yOffset,
+ radiorect.width(),
+ radiorect.height()));
+
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, const QString &detail)
+
+{
+ QRect rect = m_cliprect.isValid() ? m_cliprect : checkrect;
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(detail, state, shadow, rect.size());
+ GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
+ int xOffset = m_cliprect.isValid() ? checkrect.x() - m_cliprect.x() : 0;
+ int yOffset = m_cliprect.isValid() ? checkrect.y() - m_cliprect.y() : 0;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_check (style,
+ pixmap,
+ state,
+ shadow,
+ &gtkCliprect,
+ gtkWidget,
+ detail.toLatin1(),
+ xOffset, yOffset,
+ checkrect.width(),
+ checkrect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_STYLE_GTK)
diff --git a/src/widgets/styles/qgtkpainter_p.h b/src/widgets/styles/qgtkpainter_p.h
new file mode 100644
index 0000000000..a9d4dc0dcd
--- /dev/null
+++ b/src/widgets/styles/qgtkpainter_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGTKPAINTER_H
+#define QGTKPAINTER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <QtWidgets/QCleanlooksStyle>
+#include <QtGui/QPainter>
+#include <QtGui/QPalette>
+#include <QtGui/QFont>
+#include <private/qgtkstyle_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGtkPainter
+{
+
+public:
+ QGtkPainter(QPainter *painter);
+ GtkStyle *getStyle(GtkWidget *gtkWidget);
+ GtkStateType gtkState(const QStyleOption *option);
+
+ void setAlphaSupport(bool value) { m_alpha = value; }
+ void setClipRect(const QRect &rect) { m_cliprect = rect; }
+ void setFlipHorizontal(bool value) { m_hflipped = value; }
+ void setFlipVertical(bool value) { m_vflipped = value; }
+ void setUsePixmapCache(bool value) { m_usePixmapCache = value; }
+
+ void paintBoxGap(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow, GtkPositionType gap_side, gint x,
+ gint width, GtkStyle *style);
+ void paintBox(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey = QString());
+ void paintHline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
+ int x1, int x2, int y, const QString &pmKey = QString());
+ void paintVline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
+ int y1, int y2, int x, const QString &pmKey = QString());
+ void paintExpander(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state,
+ GtkExpanderStyle expander_state, GtkStyle *style, const QString &pmKey = QString());
+ void paintFocus(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
+ const QString &pmKey = QString());
+ void paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GdkWindowEdge edge, GtkStyle *style, const QString &pmKey = QString());
+ void paintArrow(GtkWidget *gtkWidget, const gchar* part, const QRect &arrowrect, GtkArrowType arrow_type, GtkStateType state, GtkShadowType shadow,
+ gboolean fill, GtkStyle *style, const QString &pmKey = QString());
+ void paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow, GtkOrientation orientation, GtkStyle *style);
+ void paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, GtkOrientation orientation, const QString &pmKey = QString());
+ void paintShadow(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, const QString &pmKey = QString());
+ void paintFlatBox(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString & = QString());
+ void paintExtention(GtkWidget *gtkWidget, const gchar *part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GtkPositionType gap_pos, GtkStyle *style);
+ void paintOption(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail);
+ void paintCheckbox(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail);
+
+ static QPixmap getIcon(const char* iconName, GtkIconSize size = GTK_ICON_SIZE_BUTTON);
+private:
+ QPixmap renderTheme(uchar *bdata, uchar *wdata, const QRect&);
+
+ GtkWidget *m_window;
+ QPainter *m_painter;
+ bool m_alpha;
+ bool m_hflipped;
+ bool m_vflipped;
+ bool m_usePixmapCache;
+ QRect m_cliprect;
+
+};
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_STYLE_QGTK)
+
+#endif // QGTKPAINTER_H
diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp
new file mode 100644
index 0000000000..32e04928da
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle.cpp
@@ -0,0 +1,3560 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qgtkstyle.h"
+
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <private/qapplication_p.h>
+#include <QtCore/QLibrary>
+#include <QtCore/QSettings>
+#include <QtWidgets/QDialogButtonBox>
+#include <QtWidgets/QStatusBar>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QListView>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QStyleOption>
+#include <QtWidgets/QPushButton>
+#include <QtGui/QPainter>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QToolBar>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QSpinBox>
+#include <QtWidgets/QScrollBar>
+#include <QtWidgets/QAbstractButton>
+#include <QtWidgets/QToolButton>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QRadioButton>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QTreeView>
+#include <QtWidgets/QStyledItemDelegate>
+#include <qpixmapcache.h>
+#undef signals // Collides with GTK stymbols
+#include <private/qgtkpainter_p.h>
+#include <private/qstylehelper_p.h>
+#include <private/qgtkstyle_p.h>
+#include <private/qcleanlooksstyle_p.h>
+
+
+QT_BEGIN_NAMESPACE
+
+static const char * const dock_widget_close_xpm[] =
+ {
+ "11 13 5 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #6C6A67",
+ "@ c #6C6A67",
+ "$ c #B5B0AC",
+ " ",
+ " @@@@@@@@@ ",
+ "@+ +@",
+ "@ +@ @+ @",
+ "@ @@@ @@@ @",
+ "@ @@@@@ @",
+ "@ @@@ @",
+ "@ @@@@@ @",
+ "@ @@@ @@@ @",
+ "@ +@ @+ @",
+ "@+ +@",
+ " @@@@@@@@@ ",
+ " "
+ };
+
+static const char * const dock_widget_restore_xpm[] =
+ {
+ "11 13 5 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #6C6A67",
+ "@ c #6C6A67",
+ "# c #6C6A67",
+ " ",
+ " @@@@@@@@@ ",
+ "@+ +@",
+ "@ #@@@# @",
+ "@ @ @ @",
+ "@ #@@@# @ @",
+ "@ @ @ @ @",
+ "@ @ @@@ @",
+ "@ @ @ @",
+ "@ #@@@@ @",
+ "@+ +@",
+ " @@@@@@@@@ ",
+ " "
+ };
+
+static const int groupBoxBottomMargin = 2; // space below the groupbox
+static const int groupBoxTitleMargin = 6; // space between contents and title
+static const int groupBoxTopMargin = 2;
+
+/*!
+ Returns the configuration string for \a value.
+ Returns \a fallback if \a value is not found.
+ */
+QString QGtkStyle::getGConfString(const QString &value, const QString &fallback)
+{
+ return QGtkStylePrivate::getGConfString(value, fallback);
+}
+
+/*!
+ Returns the configuration boolean for \a key.
+ Returns \a fallback if \a key is not found.
+ */
+bool QGtkStyle::getGConfBool(const QString &key, bool fallback)
+{
+ return QGtkStylePrivate::getGConfBool(key, fallback);
+}
+
+static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
+{
+ const int maxFactor = 100;
+ QColor tmp = colorA;
+ tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
+ tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
+ tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
+ return tmp;
+}
+
+static GdkColor fromQColor(const QColor &color)
+{
+ GdkColor retval;
+ retval.red = color.red() * 255;
+ retval.green = color.green() * 255;
+ retval.blue = color.blue() * 255;
+ return retval;
+}
+
+/*!
+ \class QGtkStyle
+ \brief The QGtkStyle class provides a widget style rendered by GTK+
+ \since 4.5
+
+ The QGtkStyle style provides a look and feel that integrates well
+ into GTK-based desktop environments such as the XFCe and GNOME.
+
+ It does this by making use of the GTK+ theme engine, ensuring
+ that Qt applications look and feel native on these platforms.
+
+ Note: The style requires GTK+ version 2.10 or later.
+ The Qt3-based "Qt" GTK+ theme engine will not work with QGtkStyle.
+
+ \sa {Cleanlooks Style Widget Gallery}, QWindowsXPStyle, QMacStyle, QWindowsStyle,
+ QCDEStyle, QMotifStyle, QPlastiqueStyle, QCleanlooksStyle
+*/
+
+/*!
+ Constructs a QGtkStyle object.
+*/
+QGtkStyle::QGtkStyle()
+ : QCleanlooksStyle(*new QGtkStylePrivate)
+{
+ Q_D(QGtkStyle);
+ d->init();
+}
+
+/*!
+ \internal
+
+ Constructs a QGtkStyle object.
+*/
+QGtkStyle::QGtkStyle(QGtkStylePrivate &dd)
+ : QCleanlooksStyle(dd)
+{
+ Q_D(QGtkStyle);
+ d->init();
+}
+
+
+/*!
+ Destroys the QGtkStyle object.
+*/
+QGtkStyle::~QGtkStyle()
+{
+}
+
+/*!
+ \reimp
+*/
+QPalette QGtkStyle::standardPalette() const
+{
+ Q_D(const QGtkStyle);
+
+ QPalette palette = QCleanlooksStyle::standardPalette();
+ if (d->isThemeAvailable()) {
+ GtkStyle *style = d->gtkStyle();
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ GtkWidget *gtkEntry = d->getTextColorWidget();
+ GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg, gdkaSbg, gdkaSfg;
+ QColor bg, base, text, fg, highlight, highlightText, inactiveHighlight, inactiveHighlightedTExt;
+ gdkBg = style->bg[GTK_STATE_NORMAL];
+ gdkForeground = gtkButton->style->fg[GTK_STATE_NORMAL];
+
+ // Our base and selected color is primarily used for text
+ // so we assume a gtkEntry will have the most correct value
+ gdkBase = gtkEntry->style->base[GTK_STATE_NORMAL];
+ gdkText = gtkEntry->style->text[GTK_STATE_NORMAL];
+ gdkSbg = gtkEntry->style->base[GTK_STATE_SELECTED];
+ gdkSfg = gtkEntry->style->text[GTK_STATE_SELECTED];
+
+ // The ACTIVE base color is really used for inactive windows
+ gdkaSbg = gtkEntry->style->base[GTK_STATE_ACTIVE];
+ gdkaSfg = gtkEntry->style->text[GTK_STATE_ACTIVE];
+
+ bg = QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ fg = QColor(gdkForeground.red>>8, gdkForeground.green>>8, gdkForeground.blue>>8);
+ base = QColor(gdkBase.red>>8, gdkBase.green>>8, gdkBase.blue>>8);
+ highlight = QColor(gdkSbg.red>>8, gdkSbg.green>>8, gdkSbg.blue>>8);
+ highlightText = QColor(gdkSfg.red>>8, gdkSfg.green>>8, gdkSfg.blue>>8);
+ inactiveHighlight = QColor(gdkaSbg.red>>8, gdkaSbg.green>>8, gdkaSbg.blue>>8);
+ inactiveHighlightedTExt = QColor(gdkaSfg.red>>8, gdkaSfg.green>>8, gdkaSfg.blue>>8);
+
+ palette.setColor(QPalette::HighlightedText, highlightText);
+
+
+ palette.setColor(QPalette::Light, bg.lighter(125));
+ palette.setColor(QPalette::Shadow, bg.darker(130));
+ palette.setColor(QPalette::Dark, bg.darker(120));
+ palette.setColor(QPalette::Text, text);
+ palette.setColor(QPalette::WindowText, fg);
+ palette.setColor(QPalette::ButtonText, fg);
+ palette.setColor(QPalette::Base, base);
+
+ QColor alternateRowColor = palette.base().color().lighter(93); // ref gtkstyle.c draw_flat_box
+ GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
+ GdkColor *gtkAltBase = NULL;
+ d->gtk_widget_style_get(gtkTreeView, "odd-row-color", &gtkAltBase, NULL);
+ if (gtkAltBase) {
+ alternateRowColor = QColor(gtkAltBase->red>>8, gtkAltBase->green>>8, gtkAltBase->blue>>8);
+ d->gdk_color_free(gtkAltBase);
+ }
+ palette.setColor(QPalette::AlternateBase, alternateRowColor);
+
+ palette.setColor(QPalette::Window, bg);
+ palette.setColor(QPalette::Button, bg);
+ palette.setColor(QPalette::Background, bg);
+ QColor disabled((fg.red() + bg.red()) / 2,
+ (fg.green() + bg.green())/ 2,
+ (fg.blue() + bg.blue()) / 2);
+ palette.setColor(QPalette::Disabled, QPalette::Text, disabled);
+ palette.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
+ palette.setColor(QPalette::Disabled, QPalette::Foreground, disabled);
+ palette.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
+ palette.setColor(QPalette::Highlight, highlight);
+ // calculate disabled colors by removing saturation
+ highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
+ highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
+ palette.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
+ palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
+
+ palette.setColor(QPalette::Inactive, QPalette::HighlightedText, inactiveHighlightedTExt);
+ palette.setColor(QPalette::Inactive, QPalette::Highlight, inactiveHighlight);
+
+ style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
+ d->gtk_window_get_type());
+ if (style) {
+ gdkText = style->fg[GTK_STATE_NORMAL];
+ text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ palette.setColor(QPalette::ToolTipText, text);
+ }
+ }
+ return palette;
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::polish(QPalette &palette)
+{
+ Q_D(QGtkStyle);
+
+ // QCleanlooksStyle will alter the palette, hence we do
+ // not want to polish the palette unless we are using it as
+ // the fallback
+ if (!d->isThemeAvailable())
+ QCleanlooksStyle::polish(palette);
+ else
+ palette = palette.resolve(standardPalette());
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::polish(QApplication *app)
+{
+ Q_D(QGtkStyle);
+
+ QCleanlooksStyle::polish(app);
+ // Custom fonts and palettes with QtConfig are intentionally
+ // not supported as these should be entirely determined by
+ // current Gtk settings
+ if (app->desktopSettingsAware() && d->isThemeAvailable()) {
+ QApplicationPrivate::setSystemPalette(standardPalette());
+ QApplicationPrivate::setSystemFont(d->getThemeFont());
+ d->applyCustomPaletteHash();
+ if (!d->isKDE4Session()) {
+ qt_filedialog_open_filename_hook = &QGtkStylePrivate::openFilename;
+ qt_filedialog_save_filename_hook = &QGtkStylePrivate::saveFilename;
+ qt_filedialog_open_filenames_hook = &QGtkStylePrivate::openFilenames;
+ qt_filedialog_existing_directory_hook = &QGtkStylePrivate::openDirectory;
+ qApp->installEventFilter(&d->filter);
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::unpolish(QApplication *app)
+{
+ Q_D(QGtkStyle);
+
+ QCleanlooksStyle::unpolish(app);
+ QPixmapCache::clear();
+
+ if (app->desktopSettingsAware() && d->isThemeAvailable()
+ && !d->isKDE4Session()) {
+ qt_filedialog_open_filename_hook = 0;
+ qt_filedialog_save_filename_hook = 0;
+ qt_filedialog_open_filenames_hook = 0;
+ qt_filedialog_existing_directory_hook = 0;
+ qApp->removeEventFilter(&d->filter);
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void QGtkStyle::polish(QWidget *widget)
+{
+ Q_D(QGtkStyle);
+
+ QCleanlooksStyle::polish(widget);
+ if (!d->isThemeAvailable())
+ return;
+ if (qobject_cast<QAbstractButton*>(widget)
+ || qobject_cast<QToolButton*>(widget)
+ || qobject_cast<QComboBox*>(widget)
+ || qobject_cast<QGroupBox*>(widget)
+ || qobject_cast<QScrollBar*>(widget)
+ || qobject_cast<QSlider*>(widget)
+ || qobject_cast<QAbstractSpinBox*>(widget)
+ || qobject_cast<QSpinBox*>(widget)
+ || qobject_cast<QHeaderView*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else if (QTreeView *tree = qobject_cast<QTreeView *> (widget))
+ tree->viewport()->setAttribute(Qt::WA_Hover);
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::unpolish(QWidget *widget)
+{
+ QCleanlooksStyle::unpolish(widget);
+}
+
+/*!
+ \reimp
+*/
+int QGtkStyle::pixelMetric(PixelMetric metric,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::pixelMetric(metric, option, widget);
+
+ switch (metric) {
+ case PM_DefaultFrameWidth:
+ if (qobject_cast<const QFrame*>(widget)) {
+ if (GtkStyle *style =
+ d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
+ "*.GtkScrolledWindow",
+ "*.GtkScrolledWindow",
+ d->gtk_window_get_type()))
+ return qMax(style->xthickness, style->ythickness);
+ }
+ return 2;
+
+ case PM_MenuButtonIndicator:
+ return 20;
+
+ case PM_TabBarBaseOverlap:
+ return 1;
+
+ case PM_ToolBarSeparatorExtent:
+ return 11;
+
+ case PM_ToolBarFrameWidth:
+ return 1;
+
+ case PM_ToolBarItemSpacing:
+ return 0;
+
+ case PM_ButtonShiftHorizontal: {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ guint horizontal_shift;
+ d->gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL);
+ return horizontal_shift;
+ }
+
+ case PM_ButtonShiftVertical: {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ guint vertical_shift;
+ d->gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL);
+ return vertical_shift;
+ }
+
+ case PM_MenuBarPanelWidth:
+ return 0;
+
+ case PM_MenuPanelWidth: {
+ GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
+ guint horizontal_padding = 0;
+ // horizontal-padding is used by Maemo to get thicker borders
+ if (!d->gtk_check_version(2, 10, 0))
+ d->gtk_widget_style_get(gtkMenu, "horizontal-padding", &horizontal_padding, NULL);
+ int padding = qMax<int>(gtkMenu->style->xthickness, horizontal_padding);
+ return padding;
+ }
+
+ case PM_ButtonIconSize: {
+ int retVal = 24;
+ GtkSettings *settings = d->gtk_settings_get_default();
+ gchararray icon_sizes;
+ g_object_get(settings, "gtk-icon-sizes", &icon_sizes, NULL);
+ QStringList values = QString(QLS(icon_sizes)).split(QLatin1Char(':'));
+ g_free(icon_sizes);
+ QChar splitChar(QLatin1Char(','));
+ foreach (const QString &value, values) {
+ if (value.startsWith(QLS("gtk-button="))) {
+ QString iconSize = value.right(value.size() - 11);
+
+ if (iconSize.contains(splitChar))
+ retVal = iconSize.split(splitChar)[0].toInt();
+ break;
+ }
+ }
+ return retVal;
+ }
+
+ case PM_MenuVMargin:
+
+ case PM_MenuHMargin:
+ return 0;
+
+ case PM_DockWidgetTitleMargin:
+ return 0;
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ return 5;
+
+ case PM_TabBarTabVSpace:
+ return 12;
+
+ case PM_TabBarTabHSpace:
+ return 14;
+
+ case PM_TabBarTabShiftVertical:
+ return 2;
+
+ case PM_ToolBarHandleExtent:
+ return 9;
+
+ case PM_SplitterWidth:
+ return 6;
+
+ case PM_SliderThickness:
+ case PM_SliderControlThickness: {
+ GtkWidget *gtkScale = d->gtkWidget("GtkHScale");
+ gint val;
+ d->gtk_widget_style_get(gtkScale, "slider-width", &val, NULL);
+ if (metric == PM_SliderControlThickness)
+ return val + 2*gtkScale->style->ythickness;
+ return val;
+ }
+
+ case PM_ScrollBarExtent: {
+ gint sliderLength;
+ gint trough_border;
+ GtkWidget *hScrollbar = d->gtkWidget("GtkHScrollbar");
+ d->gtk_widget_style_get(hScrollbar,
+ "trough-border", &trough_border,
+ "slider-width", &sliderLength,
+ NULL);
+ return sliderLength + trough_border*2;
+ }
+
+ case PM_ScrollBarSliderMin:
+ return 34;
+
+ case PM_SliderLength:
+ gint val;
+ d->gtk_widget_style_get(d->gtkWidget("GtkHScale"), "slider-length", &val, NULL);
+ return val;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ case PM_IndicatorWidth:
+ case PM_IndicatorHeight: {
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+ gint size, spacing;
+ d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL);
+ return size + 2 * spacing;
+ }
+
+ case PM_MenuBarVMargin: {
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+ return qMax(0, gtkMenubar->style->ythickness);
+ }
+ case PM_ScrollView_ScrollBarSpacing:
+ {
+ gint spacing = 3;
+ GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
+ Q_ASSERT(gtkScrollWindow);
+ d->gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL);
+ return spacing;
+ }
+ case PM_SubMenuOverlap: {
+ gint offset = 0;
+ GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
+ d->gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL);
+ return offset;
+ }
+ default:
+ return QCleanlooksStyle::pixelMetric(metric, option, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+
+ QStyleHintReturn *returnData = 0) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
+
+ switch (hint) {
+
+ case SH_DialogButtonLayout: {
+ int ret = QDialogButtonBox::GnomeLayout;
+ gboolean alternateOrder = 0;
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-alternative-button-order", &alternateOrder, NULL);
+
+ if (alternateOrder)
+ ret = QDialogButtonBox::WinLayout;
+
+ return ret;
+ }
+
+ break;
+
+ case SH_ToolButtonStyle:
+ {
+ if (d->isKDE4Session())
+ return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
+ GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
+ GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
+ g_object_get(gtkToolbar, "toolbar-style", &toolbar_style, NULL);
+ switch (toolbar_style) {
+ case GTK_TOOLBAR_TEXT:
+ return Qt::ToolButtonTextOnly;
+ case GTK_TOOLBAR_BOTH:
+ return Qt::ToolButtonTextUnderIcon;
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ return Qt::ToolButtonTextBesideIcon;
+ case GTK_TOOLBAR_ICONS:
+ default:
+ return Qt::ToolButtonIconOnly;
+ }
+ }
+ break;
+ case SH_SpinControls_DisableOnBounds:
+ return int(true);
+
+ case SH_DitherDisabledText:
+ return int(false);
+
+ case SH_ComboBox_Popup: {
+ GtkWidget *gtkComboBox = d->gtkWidget("GtkComboBox");
+ gboolean appears_as_list;
+ d->gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL);
+ return appears_as_list ? 0 : 1;
+ }
+
+ case SH_MenuBar_AltKeyNavigation:
+ return int(false);
+
+ case SH_EtchDisabledText:
+ return int(false);
+
+ case SH_Menu_SubMenuPopupDelay: {
+ gint delay = 225;
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-menu-popup-delay", &delay, NULL);
+ return delay;
+ }
+
+ case SH_ScrollView_FrameOnlyAroundContents: {
+ gboolean scrollbars_within_bevel = false;
+ if (widget && widget->isWindow())
+ scrollbars_within_bevel = true;
+ else if (!d->gtk_check_version(2, 12, 0)) {
+ GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
+ d->gtk_widget_style_get(gtkScrollWindow, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
+ }
+ return !scrollbars_within_bevel;
+ }
+
+ case SH_DialogButtonBox_ButtonsHaveIcons: {
+ static bool buttonsHaveIcons = d->getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons"));
+ return buttonsHaveIcons;
+ }
+
+ case SH_UnderlineShortcut: {
+ gboolean underlineShortcut = true;
+ if (!d->gtk_check_version(2, 12, 0)) {
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-enable-mnemonics", &underlineShortcut, NULL);
+ }
+ return underlineShortcut;
+ }
+
+ default:
+ return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawPrimitive(PrimitiveElement element,
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
+ QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+
+ GtkStyle* style = d->gtkStyle();
+ QGtkPainter gtkPainter(painter);
+
+ switch (element) {
+ case PE_Frame: {
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ QStyleOption copy = *option;
+ copy.state |= State_Raised;
+ proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
+ break;
+ }
+ // Drawing the entire itemview frame is very expensive, especially on the native X11 engine
+ // Instead we cheat a bit and draw a border image without the center part, hence only scaling
+ // thin rectangular images
+ const int pmSize = 64;
+ const int border = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ const QString pmKey = QLatin1Literal("windowframe") % HexString<uint>(option->state);
+
+ QPixmap pixmap;
+ QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize));
+
+ // Only draw through style once
+ if (!QPixmapCache::find(pmKey, pixmap)) {
+ pixmap = QPixmap(pmSize, pmSize);
+ pixmap.fill(Qt::transparent);
+ QPainter pmPainter(&pixmap);
+ QGtkPainter gtkFramePainter(&pmPainter);
+ gtkFramePainter.setUsePixmapCache(false); // Don't cache twice
+
+ GtkShadowType shadow_type = GTK_SHADOW_NONE;
+ if (option->state & State_Sunken)
+ shadow_type = GTK_SHADOW_IN;
+ else if (option->state & State_Raised)
+ shadow_type = GTK_SHADOW_OUT;
+
+ GtkStyle *style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
+ "*.GtkScrolledWindow", "*.GtkScrolledWindow", d->gtk_window_get_type());
+ if (style)
+ gtkFramePainter.paintShadow(d->gtkWidget("GtkFrame"), "viewport", pmRect,
+ option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ shadow_type, style);
+ QPixmapCache::insert(pmKey, pixmap);
+ }
+
+ QRect rect = option->rect;
+ const int rw = rect.width() - border;
+ const int rh = rect.height() - border;
+ const int pw = pmRect.width() - border;
+ const int ph = pmRect.height() - border;
+
+ // Sidelines
+ painter->drawPixmap(rect.adjusted(border, 0, -border, -rh), pixmap, pmRect.adjusted(border, 0, -border,-ph));
+ painter->drawPixmap(rect.adjusted(border, rh, -border, 0), pixmap, pmRect.adjusted(border, ph,-border,0));
+ painter->drawPixmap(rect.adjusted(0, border, -rw, -border), pixmap, pmRect.adjusted(0, border, -pw, -border));
+ painter->drawPixmap(rect.adjusted(rw, border, 0, -border), pixmap, pmRect.adjusted(pw, border, 0, -border));
+
+ // Corners
+ painter->drawPixmap(rect.adjusted(0, 0, -rw, -rh), pixmap, pmRect.adjusted(0, 0, -pw,-ph));
+ painter->drawPixmap(rect.adjusted(rw, 0, 0, -rh), pixmap, pmRect.adjusted(pw, 0, 0,-ph));
+ painter->drawPixmap(rect.adjusted(0, rh, -rw, 0), pixmap, pmRect.adjusted(0, ph, -pw,0));
+ painter->drawPixmap(rect.adjusted(rw, rh, 0, 0), pixmap, pmRect.adjusted(pw, ph, 0,0));
+ }
+ break;
+
+ case PE_PanelTipLabel: {
+ GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
+ style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
+ d->gtk_window_get_type());
+ gtkPainter.paintFlatBox(gtkWindow, "tooltip", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, style);
+ }
+ break;
+
+ case PE_PanelStatusBar: {
+ if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
+ option->palette.resolve() & (1 << QPalette::Window)) {
+ // Respect custom palette
+ painter->fillRect(option->rect, option->palette.window());
+ break;
+ }
+ GtkShadowType shadow_type;
+ GtkWidget *gtkStatusbarFrame = d->gtkWidget("GtkStatusbar.GtkFrame");
+ d->gtk_widget_style_get(gtkStatusbarFrame->parent, "shadow-type", &shadow_type, NULL);
+ gtkPainter.paintShadow(gtkStatusbarFrame, "frame", option->rect, GTK_STATE_NORMAL,
+ shadow_type, gtkStatusbarFrame->style);
+ }
+ break;
+
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ GtkWidget *gtkTreeHeader = d->gtkWidget("GtkTreeView.GtkButton");
+ GtkStateType state = gtkPainter.gtkState(option);
+ style = gtkTreeHeader->style;
+ GtkArrowType type = GTK_ARROW_UP;
+ QImage arrow;
+ // This sorting indicator inversion is intentional, and follows the GNOME HIG.
+ // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable
+ if (header->sortIndicator & QStyleOptionHeader::SortUp)
+ type = GTK_ARROW_UP;
+ else if (header->sortIndicator & QStyleOptionHeader::SortDown)
+ type = GTK_ARROW_DOWN;
+
+ gtkPainter.paintArrow(gtkTreeHeader, "button", option->rect.adjusted(1, 1, -1, -1), type, state,
+ GTK_SHADOW_NONE, FALSE, style);
+ }
+ break;
+
+ case PE_FrameFocusRect:
+ if (!widget || qobject_cast<const QAbstractItemView*>(widget))
+ QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
+ else {
+ // ### this mess should move to subcontrolrect
+ QRect frameRect = option->rect.adjusted(1, 1, -1, -2);
+
+ if (qobject_cast<const QTabBar*>(widget)) {
+ GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
+ style = gtkPainter.getStyle(gtkNotebook);
+ gtkPainter.paintFocus(gtkNotebook, "tab", frameRect.adjusted(-1, 1, 1, 1), GTK_STATE_ACTIVE, style);
+ } else {
+ gtkPainter.paintFocus(NULL, "tab", frameRect, GTK_STATE_ACTIVE, style);
+ }
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ if (option->state & State_Children) {
+ QRect rect = option->rect;
+ rect = QRect(0, 0, 12, 12);
+ rect.moveCenter(option->rect.center());
+ rect.translate(2, 0);
+ GtkExpanderStyle openState = GTK_EXPANDER_EXPANDED;
+ GtkExpanderStyle closedState = GTK_EXPANDER_COLLAPSED;
+ GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
+
+ GtkStateType state = GTK_STATE_NORMAL;
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_MouseOver)
+ state = GTK_STATE_PRELIGHT;
+
+ gtkPainter.paintExpander(gtkTreeView, "treeview", rect, state,
+ option->state & State_Open ? openState : closedState , gtkTreeView->style);
+ }
+ break;
+
+ case PE_PanelItemViewRow:
+ // This primitive is only used to draw selection behind selected expander arrows.
+ // We try not to decorate the tree branch background unless you inherit from StyledItemDelegate
+ // The reason for this is that a lot of code that relies on custom item delegates will look odd having
+ // a gradient on the branch but a flat shaded color on the item itself.
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ if (!option->state & State_Selected) {
+ break;
+ } else {
+ if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) {
+ if (!qobject_cast<QStyledItemDelegate*>(view->itemDelegate()))
+ break;
+ }
+ } // fall through
+
+ case PE_PanelItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ uint resolve_mask = vopt->palette.resolve();
+ if (vopt->backgroundBrush.style() != Qt::NoBrush
+ || (resolve_mask & (1 << QPalette::Base)))
+ {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(vopt->rect.topLeft());
+ painter->fillRect(vopt->rect, vopt->backgroundBrush);
+ painter->setBrushOrigin(oldBO);
+ if (!(option->state & State_Selected))
+ break;
+ }
+ if (GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView")) {
+ const char *detail = "cell_even_ruled";
+ if (vopt && vopt->features & QStyleOptionViewItemV2::Alternate)
+ detail = "cell_odd_ruled";
+ bool isActive = option->state & State_Active;
+ QString key;
+ if (isActive ) {
+ // Required for active/non-active window appearance
+ key = QLS("a");
+ GTK_WIDGET_SET_FLAGS(gtkTreeView, GTK_HAS_FOCUS);
+ }
+ bool isEnabled = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled));
+ gtkPainter.paintFlatBox(gtkTreeView, detail, option->rect,
+ option->state & State_Selected ? GTK_STATE_SELECTED :
+ isEnabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_OUT, gtkTreeView->style, key);
+ if (isActive )
+ GTK_WIDGET_UNSET_FLAGS(gtkTreeView, GTK_HAS_FOCUS);
+ }
+ }
+ break;
+ case PE_IndicatorToolBarSeparator:
+ {
+ const int margin = 6;
+ GtkWidget *gtkSeparator = d->gtkWidget("GtkToolbar.GtkSeparatorToolItem");
+ if (option->state & State_Horizontal) {
+ const int offset = option->rect.width()/2;
+ QRect rect = option->rect.adjusted(offset, margin, 0, -margin);
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ gtkPainter.paintVline( gtkSeparator, "vseparator",
+ rect, GTK_STATE_NORMAL, gtkSeparator->style,
+ 0, rect.height(), 0);
+ } else { //Draw vertical separator
+ const int offset = option->rect.height()/2;
+ QRect rect = option->rect.adjusted(margin, offset, -margin, 0);
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ gtkPainter.paintHline( gtkSeparator, "hseparator",
+ rect, GTK_STATE_NORMAL, gtkSeparator->style,
+ 0, rect.width(), 0);
+ }
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle: {
+ GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
+ GtkShadowType shadow_type;
+ d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
+ //Note when the toolbar is horizontal, the handle is vertical
+ painter->setClipRect(option->rect);
+ gtkPainter.paintHandle(gtkToolbar, "toolbar", option->rect.adjusted(-1, -1 ,0 ,1),
+ GTK_STATE_NORMAL, shadow_type, !(option->state & State_Horizontal) ?
+ GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, gtkToolbar->style);
+ }
+ break;
+
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowLeft:
+ case PE_IndicatorArrowRight: {
+
+
+ GtkArrowType type = GTK_ARROW_UP;
+
+ switch (element) {
+
+ case PE_IndicatorArrowDown:
+ type = GTK_ARROW_DOWN;
+ break;
+
+ case PE_IndicatorArrowLeft:
+ type = GTK_ARROW_LEFT;
+ break;
+
+ case PE_IndicatorArrowRight:
+ type = GTK_ARROW_RIGHT;
+ break;
+
+ default:
+ break;
+ }
+ int size = qMin(option->rect.height(), option->rect.width());
+ int border = (size > 9) ? (size/4) : 0; //Allow small arrows to have exact dimensions
+ int bsx = 0, bsy = 0;
+ if (option->state & State_Sunken) {
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ }
+ QRect arrowRect = option->rect.adjusted(border + bsx, border + bsy, -border + bsx, -border + bsy);
+ GtkShadowType shadow = option->state & State_Sunken ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ QColor arrowColor = option->palette.buttonText().color();
+ GtkWidget *gtkArrow = d->gtkWidget("GtkArrow");
+ GdkColor color = fromQColor(arrowColor);
+ d->gtk_widget_modify_fg (gtkArrow, state, &color);
+ gtkPainter.paintArrow(gtkArrow, "button", arrowRect,
+ type, state, shadow, FALSE, gtkArrow->style,
+ QString::number(arrowColor.rgba(), 16));
+ // Passing NULL will revert the color change
+ d->gtk_widget_modify_fg (gtkArrow, state, NULL);
+ }
+ break;
+
+ case PE_FrameGroupBox:
+ // Do nothing here, the GNOME groupboxes are flat
+ break;
+
+ case PE_PanelMenu: {
+ GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
+ gtkPainter.setAlphaSupport(false); // Note, alpha disabled for performance reasons
+ gtkPainter.paintBox(gtkMenu, "menu", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, gtkMenu->style, QString());
+ }
+ break;
+
+ case PE_FrameMenu:
+ //This is actually done by PE_Widget due to a clipping issue
+ //Otherwise Menu items will not be able to span the entire menu width
+
+ // This is only used by floating tool bars
+ if (qobject_cast<const QToolBar *>(widget)) {
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+ gtkPainter.paintBox( gtkMenubar, "toolbar", option->rect,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
+ gtkPainter.paintBox( gtkMenubar, "menu", option->rect,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
+ }
+ break;
+
+ case PE_FrameLineEdit: {
+ GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
+
+
+ gboolean interior_focus;
+ gint focus_line_width;
+ QRect rect = option->rect;
+ d->gtk_widget_style_get(gtkEntry,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_line_width, NULL);
+
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=405421 for info about this hack
+ g_object_set_data(G_OBJECT(gtkEntry), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
+
+ if (!interior_focus && option->state & State_HasFocus)
+ rect.adjust(focus_line_width, focus_line_width, -focus_line_width, -focus_line_width);
+
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+ gtkPainter.paintShadow(gtkEntry, "entry", rect, option->state & State_Enabled ?
+ GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_IN, gtkEntry->style,
+ option->state & State_HasFocus ? QLS("focus") : QString());
+ if (!interior_focus && option->state & State_HasFocus)
+ gtkPainter.paintShadow(gtkEntry, "entry", option->rect, option->state & State_Enabled ?
+ GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_IN, gtkEntry->style, QLS("GtkEntryShadowIn"));
+
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+ }
+ break;
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, option, painter, widget);
+ uint resolve_mask = option->palette.resolve();
+ QRect textRect = option->rect.adjusted(gtkEntry->style->xthickness, gtkEntry->style->ythickness,
+ -gtkEntry->style->xthickness, -gtkEntry->style->ythickness);
+
+ if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
+ resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
+ painter->fillRect(textRect, option->palette.base());
+ else
+ gtkPainter.paintFlatBox( gtkEntry, "entry_bg", textRect,
+ option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, gtkEntry->style);
+ }
+ break;
+
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option)) {
+ GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
+ style = gtkPainter.getStyle(gtkNotebook);
+ gtkPainter.setAlphaSupport(false);
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL; // Only state supported by gtknotebook
+ bool reverse = (option->direction == Qt::RightToLeft);
+ QGtkStylePrivate::gtk_widget_set_direction(gtkNotebook, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ if (const QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<const QStyleOptionTabWidgetFrameV2*>(option)) {
+ GtkPositionType frameType = GTK_POS_TOP;
+ QTabBar::Shape shape = frame->shape;
+ int gapStart = 0;
+ int gapSize = 0;
+ if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) {
+ frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM;
+ gapStart = tabframe->selectedTabRect.left();
+ gapSize = tabframe->selectedTabRect.width();
+ } else {
+ frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT;
+ gapStart = tabframe->selectedTabRect.y();
+ gapSize = tabframe->selectedTabRect.height();
+ }
+ gtkPainter.paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType,
+ gapStart, gapSize, style);
+ break; // done
+ }
+
+ // Note this is only the fallback option
+ gtkPainter.paintBox(gtkNotebook, "notebook", option->rect, state, shadow, style);
+ }
+ break;
+
+ case PE_PanelButtonCommand:
+ case PE_PanelButtonTool: {
+ bool isDefault = false;
+ bool isTool = (element == PE_PanelButtonTool);
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton*>(option))
+ isDefault = btn->features & QStyleOptionButton::DefaultButton;
+
+ // don't draw a frame for tool buttons that have the autoRaise flag and are not enabled or on
+ if (isTool && !(option->state & State_Enabled || option->state & State_On) && (option->state & State_AutoRaise))
+ break;
+ // don't draw a frame for dock widget buttons, unless we are hovering
+ if (widget && widget->inherits("QDockWidgetTitleButton") && !(option->state & State_MouseOver))
+ break;
+
+ GtkStateType state = gtkPainter.gtkState(option);
+ if (option->state & State_On || option->state & State_Sunken)
+ state = GTK_STATE_ACTIVE;
+ GtkWidget *gtkButton = isTool ? d->gtkWidget("GtkToolButton.GtkButton") : d->gtkWidget("GtkButton");
+ gint focusWidth, focusPad;
+ gboolean interiorFocus = false;
+ d->gtk_widget_style_get (gtkButton,
+ "focus-line-width", &focusWidth,
+ "focus-padding", &focusPad,
+ "interior-focus", &interiorFocus, NULL);
+
+ style = gtkButton->style;
+
+ QRect buttonRect = option->rect;
+
+ QString key;
+ if (isDefault) {
+ key += QLS("def");
+ GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_DEFAULT);
+ gtkPainter.paintBox(gtkButton, "buttondefault", buttonRect, state, GTK_SHADOW_IN,
+ style, isDefault ? QLS("d") : QString());
+ }
+
+ bool hasFocus = option->state & State_HasFocus;
+
+ if (hasFocus) {
+ key += QLS("def");
+ GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_FOCUS);
+ }
+
+ if (!interiorFocus)
+ buttonRect = buttonRect.adjusted(focusWidth, focusWidth, -focusWidth, -focusWidth);
+
+ GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
+ GTK_SHADOW_IN : GTK_SHADOW_OUT;
+
+ gtkPainter.paintBox(gtkButton, "button", buttonRect, state, shadow,
+ style, key);
+ if (isDefault)
+ GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_DEFAULT);
+ if (hasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_FOCUS);
+ }
+ break;
+
+ case PE_IndicatorRadioButton: {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (option->state & State_Sunken)
+ state = GTK_STATE_ACTIVE;
+
+ if (option->state & State_NoChange)
+ shadow = GTK_SHADOW_ETCHED_IN;
+ else if (option->state & State_On)
+ shadow = GTK_SHADOW_IN;
+ else
+ shadow = GTK_SHADOW_OUT;
+
+ GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
+ gint spacing;
+ d->gtk_widget_style_get(gtkRadioButton, "indicator-spacing", &spacing, NULL);
+ QRect buttonRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
+ gtkPainter.setClipRect(option->rect);
+ // ### Note: Ubuntulooks breaks when the proper widget is passed
+ // Murrine engine requires a widget not to get RGBA check - warnings
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+ QString key(QLS("radiobutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+ gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+ break;
+
+ case PE_IndicatorCheckBox: {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (option->state & State_Sunken)
+ state = GTK_STATE_ACTIVE;
+
+ if (option->state & State_NoChange)
+ shadow = GTK_SHADOW_ETCHED_IN;
+ else if (option->state & State_On)
+ shadow = GTK_SHADOW_IN;
+ else
+ shadow = GTK_SHADOW_OUT;
+
+ int spacing;
+
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+ QString key(QLS("checkbutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+
+ // Some styles such as aero-clone assume they can paint in the spacing area
+ gtkPainter.setClipRect(option->rect);
+
+ d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, NULL);
+
+ QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
+
+ gtkPainter.paintCheckbox(gtkCheckButton, checkRect, state, shadow, gtkCheckButton->style,
+ key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+
+ }
+ break;
+
+#ifndef QT_NO_TABBAR
+
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+ QRect tabRect = tbb->rect;
+ painter->save();
+ painter->setPen(QPen(option->palette.dark().color().dark(110), 0));
+ switch (tbb->shape) {
+
+ case QTabBar::RoundedNorth:
+ painter->drawLine(tabRect.topLeft(), tabRect.topRight());
+ break;
+
+ case QTabBar::RoundedWest:
+ painter->drawLine(tabRect.left(), tabRect.top(), tabRect.left(), tabRect.bottom());
+ break;
+
+ case QTabBar::RoundedSouth:
+ painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
+ tabRect.right(), tabRect.bottom());
+ break;
+
+ case QTabBar::RoundedEast:
+ painter->drawLine(tabRect.topRight(), tabRect.bottomRight());
+ break;
+
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ case QTabBar::TriangularSouth:
+ painter->restore();
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+
+ painter->restore();
+ }
+ return;
+
+#endif // QT_NO_TABBAR
+
+ case PE_Widget:
+ break;
+
+ default:
+ QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+
+ QPainter *painter, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
+ QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
+ return;
+ }
+
+ GtkStyle* style = d->gtkStyle();
+ QGtkPainter gtkPainter(painter);
+ QColor button = option->palette.button().color();
+ QColor dark;
+ QColor grooveColor;
+ QColor darkOutline;
+ dark.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
+ grooveColor.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*2.6)),
+ qMin(255, (int)(button.value()*0.9)));
+ darkOutline.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*3.0)),
+ qMin(255, (int)(button.value()*0.6)));
+
+ QColor alphaCornerColor;
+
+ if (widget)
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), darkOutline);
+ else
+ alphaCornerColor = mergedColors(option->palette.background().color(), darkOutline);
+
+ switch (control) {
+
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ // Since this is drawn by metacity and not Gtk we
+ // have to rely on Cleanlooks for a fallback
+ QStyleOptionTitleBar copyOpt = *tb;
+ QPalette pal = copyOpt.palette;
+ // Bg color is closer to the window selection than
+ // the base selection color
+ GdkColor gdkBg = style->bg[GTK_STATE_SELECTED];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ pal.setBrush(QPalette::Active, QPalette::Highlight, bgColor);
+ copyOpt.palette = pal;
+ QCleanlooksStyle::drawComplexControl(control, &copyOpt, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_GROUPBOX
+
+ case CC_GroupBox:
+ painter->save();
+
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ QRect textRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
+ QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxCheckBox, widget);
+ // Draw title
+
+ if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ // Draw prelight background
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+
+ if (option->state & State_MouseOver) {
+ QRect bgRect = textRect | checkBoxRect;
+ gtkPainter.paintFlatBox(gtkCheckButton, "checkbutton", bgRect.adjusted(0, 0, 0, -2),
+ GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, gtkCheckButton->style);
+ }
+
+ if (!groupBox->text.isEmpty()) {
+ int alignment = int(groupBox->textAlignment);
+ if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+ alignment |= Qt::TextHideMnemonic;
+ QColor textColor = groupBox->textColor; // Note: custom textColor is currently ignored
+ int labelState = GTK_STATE_INSENSITIVE;
+
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkCheckButton->style->fg[labelState];
+ textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ painter->setPen(textColor);
+ QFont font = painter->font();
+ font.setBold(true);
+ painter->setFont(font);
+ painter->drawText(textRect, Qt::TextShowMnemonic | Qt::AlignLeft| alignment, groupBox->text);
+
+ if (option->state & State_HasFocus)
+ gtkPainter.paintFocus( NULL, "tab", textRect.adjusted(-4, -1, 0, -3), GTK_STATE_ACTIVE, style);
+ }
+ }
+
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
+ }
+ }
+
+ painter->restore();
+ break;
+#endif // QT_NO_GROUPBOX
+
+#ifndef QT_NO_COMBOBOX
+
+ case CC_ComboBox:
+ // See: http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBox
+ // and http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBoxEntry
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
+ BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("cb-%0-%1").arg(sunken).arg(comboBox->editable));
+ QGtkPainter gtkCachedPainter(p);
+ gtkCachedPainter.setUsePixmapCache(false); // cached externally
+
+ bool isEnabled = (comboBox->state & State_Enabled);
+ bool focus = isEnabled && (comboBox->state & State_HasFocus);
+ GtkStateType state = gtkPainter.gtkState(option);
+ int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, comboBox, widget);
+ QStyleOptionComboBox comboBoxCopy = *comboBox;
+ comboBoxCopy.rect = option->rect;
+
+ bool reverse = (option->direction == Qt::RightToLeft);
+ QRect rect = option->rect;
+ QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
+ SC_ComboBoxArrow, widget);
+
+ GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
+ GTK_SHADOW_IN : GTK_SHADOW_OUT;
+ const QHashableLatin1Literal comboBoxPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry") : QHashableLatin1Literal("GtkComboBox");
+
+ // We use the gtk widget to position arrows and separators for us
+ GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath);
+ GtkAllocation geometry = {0, 0, option->rect.width(), option->rect.height()};
+ d->gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ d->gtk_widget_size_allocate(gtkCombo, &geometry);
+
+ QHashableLatin1Literal buttonPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
+ : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
+ GtkWidget *gtkToggleButton = d->gtkWidget(buttonPath);
+ d->gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ if (gtkToggleButton && (appears_as_list || comboBox->editable)) {
+ if (focus)
+ GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+ // Draw the combo box as a line edit with a button next to it
+ if (comboBox->editable || appears_as_list) {
+ GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state;
+ QHashableLatin1Literal entryPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkEntry") : QHashableLatin1Literal("GtkComboBox.GtkFrame");
+ GtkWidget *gtkEntry = d->gtkWidget(entryPath);
+ d->gtk_widget_set_direction(gtkEntry, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ QRect frameRect = option->rect;
+
+ if (reverse)
+ frameRect.setLeft(arrowButtonRect.right());
+ else
+ frameRect.setRight(arrowButtonRect.left());
+
+ // Fill the line edit background
+ // We could have used flat_box with "entry_bg" but that is probably not worth the overhead
+ uint resolve_mask = option->palette.resolve();
+ int xt = gtkEntry->style->xthickness;
+ int yt = gtkEntry->style->ythickness;
+ QRect contentRect = frameRect.adjusted(xt, yt, -xt, -yt);
+ // Required for inner blue highlight with clearlooks
+ if (focus)
+ GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+
+ if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
+ resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
+ p->fillRect(contentRect, option->palette.base().color());
+ else {
+ gtkCachedPainter.paintFlatBox(gtkEntry, "entry_bg", contentRect,
+ option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_NONE, gtkEntry->style, entryPath.toString() + QString::number(focus));
+ }
+
+ gtkCachedPainter.paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState,
+ GTK_SHADOW_IN, gtkEntry->style, entryPath.toString() +
+ QString::number(focus) + QString::number(comboBox->editable) +
+ QString::number(option->direction));
+ if (focus)
+ GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+ }
+
+ GtkStateType buttonState = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled))
+ buttonState = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_Sunken || option->state & State_On)
+ buttonState = GTK_STATE_ACTIVE;
+ else if (option->state & State_MouseOver && comboBox->activeSubControls & SC_ComboBoxArrow)
+ buttonState = GTK_STATE_PRELIGHT;
+
+ Q_ASSERT(gtkToggleButton);
+ gtkCachedPainter.paintBox( gtkToggleButton, "button", arrowButtonRect, buttonState,
+ shadow, gtkToggleButton->style, buttonPath.toString() +
+ QString::number(focus) + QString::number(option->direction));
+ if (focus)
+ GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+ } else {
+ // Draw combo box as a button
+ QRect buttonRect = option->rect;
+
+ if (focus) // Clearlooks actually check the widget for the default state
+ GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+ gtkCachedPainter.paintBox(gtkToggleButton, "button",
+ buttonRect, state,
+ shadow, gtkToggleButton->style,
+ buttonPath.toString() + QString::number(focus));
+ if (focus)
+ GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+
+
+ // Draw the separator between label and arrows
+ QHashableLatin1Literal vSeparatorPath = comboBox->editable
+ ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkVSeparator")
+ : QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkVSeparator");
+
+ if (GtkWidget *gtkVSeparator = d->gtkWidget(vSeparatorPath)) {
+ QRect vLineRect(gtkVSeparator->allocation.x,
+ gtkVSeparator->allocation.y,
+ gtkVSeparator->allocation.width,
+ gtkVSeparator->allocation.height);
+
+ gtkCachedPainter.paintVline( gtkVSeparator, "vseparator",
+ vLineRect, state, gtkVSeparator->style,
+ 0, vLineRect.height(), 0, vSeparatorPath.toString());
+
+
+ gint interiorFocus = true;
+ d->gtk_widget_style_get(gtkToggleButton, "interior-focus", &interiorFocus, NULL);
+ int xt = interiorFocus ? gtkToggleButton->style->xthickness : 0;
+ int yt = interiorFocus ? gtkToggleButton->style->ythickness : 0;
+ if (focus && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget)))
+ gtkCachedPainter.paintFocus(gtkToggleButton, "button",
+ option->rect.adjusted(xt, yt, -xt, -yt),
+ option->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
+ gtkToggleButton->style);
+ }
+ }
+
+ if (comboBox->subControls & SC_ComboBoxArrow) {
+ if (!isEnabled)
+ state = GTK_STATE_INSENSITIVE;
+ else if (sunken)
+ state = GTK_STATE_ACTIVE;
+ else if (option->state & State_MouseOver)
+ state = GTK_STATE_PRELIGHT;
+ else
+ state = GTK_STATE_NORMAL;
+
+ QHashableLatin1Literal arrowPath("");
+ if (comboBox->editable) {
+ if (appears_as_list)
+ arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkArrow");
+ else
+ arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkArrow");
+ } else {
+ if (appears_as_list)
+ arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkArrow");
+ else
+ arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow");
+ }
+
+ GtkWidget *gtkArrow = d->gtkWidget(arrowPath);
+ gfloat scale = 0.7;
+ gint minSize = 15;
+ QRect arrowWidgetRect;
+
+ if (gtkArrow && !d->gtk_check_version(2, 12, 0)) {
+ d->gtk_widget_style_get(gtkArrow, "arrow-scaling", &scale, NULL);
+ d->gtk_widget_style_get(gtkCombo, "arrow-size", &minSize, NULL);
+ }
+ if (gtkArrow) {
+ arrowWidgetRect = QRect(gtkArrow->allocation.x, gtkArrow->allocation.y,
+ gtkArrow->allocation.width, gtkArrow->allocation.height);
+ style = gtkArrow->style;
+ }
+
+ // Note that for some reason the arrow-size is not properly respected with Hildon
+ // Hence we enforce the minimum "arrow-size" ourselves
+ int arrowSize = qMax(qMin(rect.height() - gtkCombo->style->ythickness * 2, minSize),
+ qMin(arrowWidgetRect.width(), arrowWidgetRect.height()));
+ QRect arrowRect(0, 0, static_cast<int>(arrowSize * scale), static_cast<int>(arrowSize * scale));
+
+ arrowRect.moveCenter(arrowWidgetRect.center());
+
+ if (sunken) {
+ int xoff, yoff;
+ const QHashableLatin1Literal toggleButtonPath = comboBox->editable
+ ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
+ : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
+
+ GtkWidget *gtkButton = d->gtkWidget(toggleButtonPath);
+ d->gtk_widget_style_get(gtkButton, "child-displacement-x", &xoff, NULL);
+ d->gtk_widget_style_get(gtkButton, "child-displacement-y", &yoff, NULL);
+ arrowRect = arrowRect.adjusted(xoff, yoff, xoff, yoff);
+ }
+
+ // Some styles such as Nimbus paint outside the arrowRect
+ // hence we have provide the whole widget as the cliprect
+ if (gtkArrow) {
+ gtkCachedPainter.setClipRect(option->rect);
+ gtkCachedPainter.paintArrow( gtkArrow, "arrow", arrowRect,
+ GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, TRUE,
+ style, arrowPath.toString() + QString::number(option->direction));
+ }
+ }
+ END_STYLE_PIXMAPCACHE;
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_TOOLBUTTON
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(control, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+ State bflags = toolbutton->state & ~(State_Sunken | State_MouseOver);
+
+ if (bflags & State_AutoRaise)
+ if (!(bflags & State_MouseOver))
+ bflags &= ~State_Raised;
+
+ State mflags = bflags;
+
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ mflags |= State_Sunken;
+ } else if (toolbutton->state & State_MouseOver) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_MouseOver;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ mflags |= State_MouseOver;
+ }
+
+ QStyleOption tool(0);
+
+ tool.palette = toolbutton->palette;
+
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised | State_MouseOver)) {
+ tool.rect = button;
+ tool.state = bflags;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+ }
+
+ bool drawMenuArrow = toolbutton->features & QStyleOptionToolButton::HasMenu &&
+ !(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup);
+ int popupArrowSize = drawMenuArrow ? 7 : 0;
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect = proxy()->subControlRect(CC_ToolButton, toolbutton, SC_ToolButton, widget);
+ fr.rect.adjust(1, 1, -1, -1);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
+ }
+
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
+ QPalette pal = toolbutton->palette;
+ if (option->state & State_Enabled &&
+ option->state & State_MouseOver && !(widget && widget->testAttribute(Qt::WA_SetPalette))) {
+ GdkColor gdkText = gtkButton->style->fg[GTK_STATE_PRELIGHT];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
+ label.palette = pal;
+ }
+ label.rect = button.adjusted(style->xthickness, style->ythickness,
+ -style->xthickness - popupArrowSize, -style->ythickness);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, painter, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if ((mflags & State_Enabled && (mflags & (State_Sunken | State_Raised | State_MouseOver))) || !(mflags & State_AutoRaise))
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, painter, widget);
+
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+
+ } else if (drawMenuArrow) {
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() - popupArrowSize - style->xthickness - 3, ir.height()/2 - 1, popupArrowSize, popupArrowSize);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
+ }
+ }
+ break;
+
+#endif // QT_NO_TOOLBUTTON
+#ifndef QT_NO_SCROLLBAR
+
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ GtkWidget *gtkHScrollBar = d->gtkWidget("GtkHScrollbar");
+ GtkWidget *gtkVScrollBar = d->gtkWidget("GtkVScrollbar");
+
+ // Fill background in case the scrollbar is partially transparent
+ painter->fillRect(option->rect, option->palette.background());
+
+ QRect rect = scrollBar->rect;
+ QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
+ QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
+ QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
+ QRect grooveRect = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+ GtkWidget * scrollbarWidget = horizontal ? gtkHScrollBar : gtkVScrollBar;
+ style = scrollbarWidget->style;
+ gboolean trough_under_steppers = true;
+ gboolean trough_side_details = false;
+ gboolean activate_slider = false;
+ gboolean stepper_size = 14;
+ gint trough_border = 1;
+ if (!d->gtk_check_version(2, 10, 0)) {
+ d->gtk_widget_style_get((GtkWidget*)(scrollbarWidget),
+ "trough-border", &trough_border,
+ "trough-side-details", &trough_side_details,
+ "trough-under-steppers", &trough_under_steppers,
+ "activate-slider", &activate_slider,
+ "stepper-size", &stepper_size, NULL);
+ }
+ if (trough_under_steppers) {
+ scrollBarAddLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
+ scrollBarSubLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
+ scrollBarSlider.adjust(horizontal ? -trough_border : 0, horizontal ? 0 : -trough_border,
+ horizontal ? trough_border : 0, horizontal ? 0 : trough_border);
+ }
+
+ // Some styles check the position of scrollbars in order to determine
+ // if lines should be painted when the scrollbar is in max or min positions.
+ int maximum = 2;
+ int fakePos = 0;
+ bool reverse = (option->direction == Qt::RightToLeft);
+ if (scrollBar->minimum == scrollBar->maximum)
+ maximum = 0;
+ if (scrollBar->sliderPosition == scrollBar->maximum)
+ fakePos = maximum;
+ else if (scrollBar->sliderPosition > scrollBar->minimum)
+ fakePos = maximum - 1;
+
+
+ GtkRange *range = (GtkRange*)(horizontal ? gtkHScrollBar : gtkVScrollBar);
+ GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range);
+
+ if (adjustment) {
+ d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0);
+ } else {
+ adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
+ d->gtk_range_set_adjustment(range, adjustment);
+ }
+
+ if (scrollBar->subControls & SC_ScrollBarGroove) {
+ GtkStateType state = GTK_STATE_ACTIVE;
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+
+ if (trough_under_steppers)
+ grooveRect = option->rect;
+
+ gtkPainter.paintBox( scrollbarWidget, "trough", grooveRect, state, GTK_SHADOW_IN, style);
+ }
+
+ //paint slider
+ if (scrollBar->subControls & SC_ScrollBarSlider) {
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (activate_slider &&
+ option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSlider))
+ state = GTK_STATE_ACTIVE;
+ else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSlider))
+ state = GTK_STATE_PRELIGHT;
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+
+ if (trough_under_steppers) {
+ if (!horizontal)
+ scrollBarSlider.adjust(trough_border, 0, -trough_border, 0);
+ else
+ scrollBarSlider.adjust(0, trough_border, 0, -trough_border);
+ }
+
+ gtkPainter.paintSlider( scrollbarWidget, "slider", scrollBarSlider, state, shadow, style,
+
+ horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, QString(QLS("%0%1")).arg(fakePos).arg(maximum));
+ }
+
+ if (scrollBar->subControls & SC_ScrollBarAddLine) {
+ gtkVScrollBar->allocation.y = scrollBarAddLine.top();
+ gtkVScrollBar->allocation.height = scrollBarAddLine.height() - rect.height() + 6;
+ gtkHScrollBar->allocation.x = scrollBarAddLine.right();
+ gtkHScrollBar->allocation.width = scrollBarAddLine.width() - rect.width();
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled) || (fakePos == maximum))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarAddLine)) {
+ state = GTK_STATE_ACTIVE;
+ shadow = GTK_SHADOW_IN;
+
+ } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarAddLine))
+ state = GTK_STATE_PRELIGHT;
+
+ gtkPainter.paintBox( scrollbarWidget,
+ horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine,
+ state, shadow, style, QLS("add"));
+
+ gtkPainter.paintArrow( scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine.adjusted(4, 4, -4, -4),
+ horizontal ? (reverse ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT) :
+ GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, FALSE, style);
+ }
+
+ if (scrollBar->subControls & SC_ScrollBarSubLine) {
+ gtkVScrollBar->allocation.y = 0;
+ gtkVScrollBar->allocation.height = scrollBarSubLine.height();
+ gtkHScrollBar->allocation.x = 0;
+ gtkHScrollBar->allocation.width = scrollBarSubLine.width();
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled) || (fakePos == 0))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSubLine)) {
+ shadow = GTK_SHADOW_IN;
+ state = GTK_STATE_ACTIVE;
+
+ } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSubLine))
+ state = GTK_STATE_PRELIGHT;
+
+ gtkPainter.paintBox(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine,
+ state, shadow, style, QLS("sub"));
+
+ gtkPainter.paintArrow(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine.adjusted(4, 4, -4, -4),
+ horizontal ? (reverse ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT) :
+ GTK_ARROW_UP, state, GTK_SHADOW_NONE, FALSE, style);
+ }
+ }
+ break;
+
+#endif //QT_NO_SCROLLBAR
+#ifndef QT_NO_SPINBOX
+
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+
+ GtkWidget *gtkSpinButton = spinBox->buttonSymbols == QAbstractSpinBox::NoButtons
+ ? d->gtkWidget("GtkEntry")
+ : d->gtkWidget("GtkSpinButton");
+ bool isEnabled = (spinBox->state & State_Enabled);
+ bool hover = isEnabled && (spinBox->state & State_MouseOver);
+ bool sunken = (spinBox->state & State_Sunken);
+ bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
+ bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
+ bool reverse = (spinBox->direction == Qt::RightToLeft);
+
+ QRect editArea = option->rect;
+ QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget);
+ QRect upRect, downRect, buttonRect;
+ if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
+ upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
+ downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+
+ //### Move this to subControlRect
+ upRect.setTop(option->rect.top());
+
+ if (reverse)
+ upRect.setLeft(option->rect.left());
+ else
+ upRect.setRight(option->rect.right());
+
+ downRect.setBottom(option->rect.bottom());
+
+ if (reverse)
+ downRect.setLeft(option->rect.left());
+ else
+ downRect.setRight(option->rect.right());
+
+ buttonRect = upRect | downRect;
+
+ if (reverse)
+ editArea.setLeft(upRect.right());
+ else
+ editArea.setRight(upRect.left());
+ }
+ if (spinBox->frame) {
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_HasFocus)
+ state = GTK_STATE_NORMAL;
+ else if (state == GTK_STATE_PRELIGHT)
+ state = GTK_STATE_NORMAL;
+
+ style = gtkPainter.getStyle(gtkSpinButton);
+
+
+ QString key;
+
+ if (option->state & State_HasFocus) {
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS);
+ }
+
+ uint resolve_mask = option->palette.resolve();
+
+ if (resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
+ painter->fillRect(editRect, option->palette.base().color());
+ else
+ gtkPainter.paintFlatBox(gtkSpinButton, "entry_bg", editArea.adjusted(style->xthickness, style->ythickness,
+ -style->xthickness, -style->ythickness),
+ option->state & State_Enabled ?
+ GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, style, key);
+
+ gtkPainter.paintShadow(gtkSpinButton, "entry", editArea, state, GTK_SHADOW_IN, gtkSpinButton->style, key);
+ if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
+ gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key);
+
+ upRect.setSize(downRect.size());
+ if (!(option->state & State_Enabled))
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
+ else if (upIsActive && sunken)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
+ else if (upIsActive && hover)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
+ else
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
+
+ if (!(option->state & State_Enabled))
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
+ else if (downIsActive && sunken)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
+ else if (downIsActive && hover)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
+ else
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
+
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS);
+ }
+ }
+
+ if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
+ int centerX = upRect.center().x();
+ int centerY = upRect.center().y();
+ // plus/minus
+
+ if (spinBox->activeSubControls == SC_SpinBoxUp && sunken) {
+ painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
+ painter->drawLine(1 + centerX, 1 + centerY - 2, 1 + centerX, 1 + centerY + 2);
+
+ } else {
+ painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
+ painter->drawLine(centerX, centerY - 2, centerX, centerY + 2);
+ }
+ centerX = downRect.center().x();
+ centerY = downRect.center().y();
+
+ if (spinBox->activeSubControls == SC_SpinBoxDown && sunken) {
+ painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
+ } else {
+ painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
+ }
+
+ } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows) {
+ int size = d->getSpinboxArrowSize();
+ int w = size / 2 - 1;
+ w -= w % 2 - 1; // force odd
+ int h = (w + 1)/2;
+ QRect arrowRect(0, 0, w, h);
+ arrowRect.moveCenter(upRect.center());
+ // arrows
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled))
+ state = GTK_STATE_INSENSITIVE;
+
+ gtkPainter.paintArrow( gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_UP, state,
+ GTK_SHADOW_NONE, FALSE, style);
+
+ arrowRect.moveCenter(downRect.center());
+
+ if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled))
+ state = GTK_STATE_INSENSITIVE;
+
+ gtkPainter.paintArrow( gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_DOWN, state,
+ GTK_SHADOW_NONE, FALSE, style);
+ }
+ }
+ break;
+
+#endif // QT_NO_SPINBOX
+
+#ifndef QT_NO_SLIDER
+
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ GtkWidget *hScaleWidget = d->gtkWidget("GtkHScale");
+ GtkWidget *vScaleWidget = d->gtkWidget("GtkVScale");
+
+ QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
+ bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
+
+ QBrush oldBrush = painter->brush();
+ QPen oldPen = painter->pen();
+
+ QColor shadowAlpha(Qt::black);
+ shadowAlpha.setAlpha(10);
+ QColor highlightAlpha(Qt::white);
+ highlightAlpha.setAlpha(80);
+
+ QGtkStylePrivate::gtk_widget_set_direction(hScaleWidget, slider->upsideDown ?
+ GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ GtkWidget *scaleWidget = horizontal ? hScaleWidget : vScaleWidget;
+ style = scaleWidget->style;
+
+ if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
+
+ GtkRange *range = (GtkRange*)scaleWidget;
+ GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range);
+ if (adjustment) {
+ d->gtk_adjustment_configure(adjustment,
+ slider->sliderPosition,
+ slider->minimum,
+ slider->maximum,
+ slider->singleStep,
+ slider->singleStep,
+ slider->pageStep);
+ } else {
+ adjustment = (GtkAdjustment*)d->gtk_adjustment_new(slider->sliderPosition,
+ slider->minimum,
+ slider->maximum,
+ slider->singleStep,
+ slider->singleStep,
+ slider->pageStep);
+ d->gtk_range_set_adjustment(range, adjustment);
+ }
+
+ int outerSize;
+ d->gtk_range_set_inverted(range, !horizontal);
+ d->gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL);
+ outerSize++;
+
+ GtkStateType state = gtkPainter.gtkState(option);
+ int focusFrameMargin = 2;
+ QRect grooveRect = option->rect.adjusted(focusFrameMargin, outerSize + focusFrameMargin,
+ -focusFrameMargin, -outerSize - focusFrameMargin);
+
+ gboolean trough_side_details = false; // Indicates if the upper or lower scale background differs
+ if (!d->gtk_check_version(2, 10, 0))
+ d->gtk_widget_style_get((GtkWidget*)(scaleWidget), "trough-side-details", &trough_side_details, NULL);
+
+ if (!trough_side_details) {
+ gtkPainter.paintBox( scaleWidget, "trough", grooveRect, state,
+ GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
+ } else {
+ QRect upperGroove = grooveRect;
+ QRect lowerGroove = grooveRect;
+
+ if (horizontal) {
+ if (slider->upsideDown) {
+ lowerGroove.setLeft(handle.center().x());
+ upperGroove.setRight(handle.center().x());
+ } else {
+ upperGroove.setLeft(handle.center().x());
+ lowerGroove.setRight(handle.center().x());
+ }
+ } else {
+ if (!slider->upsideDown) {
+ lowerGroove.setBottom(handle.center().y());
+ upperGroove.setTop(handle.center().y());
+ } else {
+ upperGroove.setBottom(handle.center().y());
+ lowerGroove.setTop(handle.center().y());
+ }
+ }
+
+ gtkPainter.paintBox( scaleWidget, "trough-upper", upperGroove, state,
+ GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
+ gtkPainter.paintBox( scaleWidget, "trough-lower", lowerGroove, state,
+ GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
+ }
+ }
+
+ if (option->subControls & SC_SliderTickmarks) {
+ painter->setPen(darkOutline);
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+
+ if (interval <= 0) {
+ interval = slider->singleStep;
+
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+
+ if (interval <= 0)
+ interval = 1;
+
+ int v = slider->minimum;
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, (horizontal
+ ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown) + len / 2;
+ int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
+ if (horizontal) {
+ if (ticksAbove)
+ painter->drawLine(pos, slider->rect.top() + extra,
+ pos, slider->rect.top() + tickSize);
+ if (ticksBelow)
+ painter->drawLine(pos, slider->rect.bottom() - extra,
+ pos, slider->rect.bottom() - tickSize);
+
+ } else {
+ if (ticksAbove)
+ painter->drawLine(slider->rect.left() + extra, pos,
+ slider->rect.left() + tickSize, pos);
+ if (ticksBelow)
+ painter->drawLine(slider->rect.right() - extra, pos,
+ slider->rect.right() - tickSize, pos);
+ }
+
+ // In the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ }
+
+ // Draw slider handle
+ if (option->subControls & SC_SliderHandle) {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_MouseOver && option->activeSubControls & SC_SliderHandle)
+ state = GTK_STATE_PRELIGHT;
+
+ bool horizontal = option->state & State_Horizontal;
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = slider->rect.adjusted(-1, -1 ,1, 1);
+
+ if (horizontal) {
+ fropt.rect.setTop(handle.top() - 3);
+ fropt.rect.setBottom(handle.bottom() + 4);
+
+ } else {
+ fropt.rect.setLeft(handle.left() - 3);
+ fropt.rect.setRight(handle.right() + 3);
+ }
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ gtkPainter.paintSlider( scaleWidget, horizontal ? "hscale" : "vscale", handle, state, shadow, style,
+
+ horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
+ }
+ painter->setBrush(oldBrush);
+ painter->setPen(oldPen);
+ }
+ break;
+
+#endif // QT_NO_SLIDER
+
+ default:
+ QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
+
+ break;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawControl(ControlElement element,
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
+ QCleanlooksStyle::drawControl(element, option, painter, widget);
+ return;
+ }
+
+ GtkStyle* style = d->gtkStyle();
+ QGtkPainter gtkPainter(painter);
+
+ switch (element) {
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
+ if (!gtkProgressBar)
+ return;
+
+ QRect leftRect;
+ QRect rect = bar->rect;
+ GdkColor gdkText = gtkProgressBar->style->fg[GTK_STATE_NORMAL];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ gdkText = gtkProgressBar->style->fg[GTK_STATE_PRELIGHT];
+ QColor alternateTextColor= QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+
+ painter->save();
+ bool vertical = false, inverted = false;
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ }
+ if (vertical)
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() /
+ qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
+ if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
+ leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
+ if (vertical)
+ leftRect.translate(rect.width() - progressIndicatorPos, 0);
+
+ bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) ||
+ ((bar->direction == Qt::LeftToRight) && inverted)));
+
+ QRegion rightRect = rect;
+ rightRect = rightRect.subtracted(leftRect);
+ painter->setClipRegion(rightRect);
+ painter->setPen(flip ? alternateTextColor : textColor);
+ painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
+ if (!leftRect.isNull()) {
+ painter->setPen(flip ? textColor : alternateTextColor);
+ painter->setClipRect(leftRect);
+ painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
+ }
+ painter->restore();
+ }
+ break;
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ QRect ir = button->rect;
+ uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ QPoint buttonShift;
+
+ if (option->state & State_Sunken)
+ buttonShift = QPoint(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
+
+ if (proxy()->styleHint(SH_UnderlineShortcut, button, widget))
+ tf |= Qt::TextShowMnemonic;
+ else
+ tf |= Qt::TextHideMnemonic;
+
+ if (!button->icon.isNull()) {
+ //Center both icon and text
+ QPoint point;
+
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+
+ QIcon::State state = QIcon::Off;
+
+ if (button->state & State_On)
+ state = QIcon::On;
+
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int w = pixmap.width();
+ int h = pixmap.height();
+
+ if (!button->text.isEmpty())
+ w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 4;
+
+ point = QPoint(ir.x() + ir.width() / 2 - w / 2,
+ ir.y() + ir.height() / 2 - h / 2);
+
+ if (button->direction == Qt::RightToLeft)
+ point.rx() += pixmap.width();
+
+ painter->drawPixmap(visualPos(button->direction, button->rect, point + buttonShift), pixmap);
+
+ if (button->direction == Qt::RightToLeft)
+ ir.translate(-point.x() - 2, 0);
+ else
+ ir.translate(point.x() + pixmap.width() + 2, 0);
+
+ // left-align text if there is
+ if (!button->text.isEmpty())
+ tf |= Qt::AlignLeft;
+
+ } else {
+ tf |= Qt::AlignHCenter;
+ }
+
+ ir.translate(buttonShift);
+
+ if (button->features & QStyleOptionButton::HasMenu)
+ ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
+
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ QPalette pal = button->palette;
+ int labelState = GTK_STATE_INSENSITIVE;
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver && !(option->state & State_Sunken)) ?
+ GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkButton->style->fg[labelState];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ pal.setBrush(QPalette::ButtonText, textColor);
+ proxy()->drawItemText(painter, ir, tf, pal, (button->state & State_Enabled),
+ button->text, QPalette::ButtonText);
+ }
+ break;
+
+ case CE_RadioButton: // Fall through
+ case CE_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (element == CE_RadioButton);
+
+ // Draw prelight background
+ GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
+
+ if (option->state & State_MouseOver) {
+ gtkPainter.paintFlatBox(gtkRadioButton, "checkbutton", option->rect,
+ GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, gtkRadioButton->style);
+ }
+
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, painter, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+ // Get label text color
+ QPalette pal = subopt.palette;
+ int labelState = GTK_STATE_INSENSITIVE;
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkRadioButton->style->fg[labelState];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ pal.setBrush(QPalette::WindowText, textColor);
+ subopt.palette = pal;
+ proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
+
+ if (btn->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+ break;
+
+#ifndef QT_NO_COMBOBOX
+
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
+ bool appearsAsList = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, cb, widget);
+ painter->save();
+ painter->setClipRect(editRect);
+
+ if (!cb->currentIcon.isNull()) {
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width() + 4);
+
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+
+ if (cb->editable)
+ painter->fillRect(iconRect, option->palette.brush(QPalette::Base));
+
+ proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-4 - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + 4, 0);
+ }
+
+ if (!cb->currentText.isEmpty() && !cb->editable) {
+ GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
+ QPalette pal = cb->palette;
+ int labelState = GTK_STATE_INSENSITIVE;
+
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver && !appearsAsList) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkCombo->style->fg[labelState];
+
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+
+ pal.setBrush(QPalette::ButtonText, textColor);
+
+ proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
+ visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ pal, cb->state & State_Enabled, cb->currentText, QPalette::ButtonText);
+ }
+
+ painter->restore();
+ }
+ break;
+
+#endif // QT_NO_COMBOBOX
+
+ case CE_DockWidgetTitle:
+ painter->save();
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect rect = dwOpt->rect;
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget).adjusted(-2, 0, -2, 0);
+ QRect r = rect.adjusted(0, 0, -1, -1);
+ if (verticalTitleBar)
+ r.adjust(0, 0, 0, -1);
+
+ if (verticalTitleBar) {
+ QRect r = rect;
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+
+ painter->translate(r.left(), r.top() + r.width());
+ painter->rotate(-90);
+ painter->translate(-r.left(), -r.top());
+
+ rect = r;
+ }
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText
+ = painter->fontMetrics().elidedText(dwOpt->title,
+ Qt::ElideRight, titleRect.width());
+ proxy()->drawItemText(painter,
+ titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ }
+ painter->restore();
+ break;
+
+
+
+ case CE_HeaderSection:
+ painter->save();
+
+ // Draws the header in tables.
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ Q_UNUSED(header);
+ GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
+ // Get the middle column
+ GtkTreeViewColumn *column = d->gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1);
+ Q_ASSERT(column);
+
+ GtkWidget *gtkTreeHeader = column->button;
+ GtkStateType state = gtkPainter.gtkState(option);
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+
+ if (option->state & State_Sunken)
+ shadow = GTK_SHADOW_IN;
+
+ gtkPainter.paintBox(gtkTreeHeader, "button", option->rect.adjusted(-1, 0, 0, 0), state, shadow, gtkTreeHeader->style);
+ }
+
+ painter->restore();
+ break;
+
+#ifndef QT_NO_SIZEGRIP
+
+ case CE_SizeGrip: {
+ GtkWidget *gtkStatusbar = d->gtkWidget("GtkStatusbar.GtkFrame");
+ QRect gripRect = option->rect.adjusted(0, 0, -gtkStatusbar->style->xthickness, -gtkStatusbar->style->ythickness);
+ gtkPainter.paintResizeGrip( gtkStatusbar, "statusbar", gripRect, GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT, QApplication::isRightToLeft() ?
+ GDK_WINDOW_EDGE_SOUTH_WEST : GDK_WINDOW_EDGE_SOUTH_EAST,
+ gtkStatusbar->style);
+ }
+ break;
+
+#endif // QT_NO_SIZEGRIP
+
+ case CE_MenuBarEmptyArea: {
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+ GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
+ painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
+ if (widget) { // See CE_MenuBarItem
+ QRect menuBarRect = widget->rect();
+ QPixmap pixmap(menuBarRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pmPainter(&pixmap);
+ QGtkPainter gtkMenuBarPainter(&pmPainter);
+ GtkShadowType shadow_type;
+ d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
+ gtkMenuBarPainter.paintBox( gtkMenubar, "menubar", menuBarRect,
+ GTK_STATE_NORMAL, shadow_type, gtkMenubar->style);
+ pmPainter.end();
+ painter->drawPixmap(option->rect, pixmap, option->rect);
+ }
+ }
+ break;
+
+ case CE_MenuBarItem:
+ painter->save();
+
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ GtkWidget *gtkMenubarItem = d->gtkWidget("GtkMenuBar.GtkMenuItem");
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+
+ style = gtkMenubarItem->style;
+
+ if (widget) {
+ // Since Qt does not currently allow filling the entire background
+ // we use a hack for this by making a complete menubar each time and
+ // paint with the correct offset inside it. Pixmap caching should resolve
+ // most of the performance penalty.
+ QRect menuBarRect = widget->rect();
+ QPixmap pixmap(menuBarRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pmPainter(&pixmap);
+ QGtkPainter menubarPainter(&pmPainter);
+ GtkShadowType shadow_type;
+ d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
+ GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
+ painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
+ menubarPainter.paintBox(gtkMenubar, "menubar", menuBarRect,
+ GTK_STATE_NORMAL, shadow_type, gtkMenubar->style);
+ pmPainter.end();
+ painter->drawPixmap(option->rect, pixmap, option->rect);
+ }
+
+ QStyleOptionMenuItem item = *mbi;
+ bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
+ bool dis = !(mbi->state & State_Enabled);
+ item.rect = mbi->rect;
+ GdkColor gdkText = gtkMenubarItem->style->fg[dis ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL];
+ GdkColor gdkHText = gtkMenubarItem->style->fg[GTK_STATE_PRELIGHT];
+ QColor normalTextColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
+ item.palette.setBrush(QPalette::HighlightedText, highlightedTextColor);
+ item.palette.setBrush(QPalette::Text, normalTextColor);
+ item.palette.setBrush(QPalette::ButtonText, normalTextColor);
+ QCommonStyle::drawControl(element, &item, painter, widget);
+
+ if (act) {
+ GtkShadowType shadowType = GTK_SHADOW_NONE;
+ d->gtk_widget_style_get (gtkMenubarItem, "selected-shadow-type", &shadowType, NULL);
+ gtkPainter.paintBox(gtkMenubarItem, "menuitem", option->rect.adjusted(0, 0, 0, 3),
+ GTK_STATE_PRELIGHT, shadowType, gtkMenubarItem->style);
+ //draw text
+ QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ proxy()->drawItemText(painter, item.rect, alignment, item.palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+ }
+ painter->restore();
+ break;
+
+ case CE_Splitter: {
+ GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
+ gtkPainter.paintHandle(gtkWindow, "splitter", option->rect, gtkPainter.gtkState(option), GTK_SHADOW_NONE,
+ !(option->state & State_Horizontal) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
+ style);
+ }
+ break;
+
+#ifndef QT_NO_TOOLBAR
+
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ // Reserve the beveled appearance only for mainwindow toolbars
+ if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget())))
+ break;
+
+ QRect rect = option->rect;
+ // There is a 1 pixel gap between toolbar lines in some styles (i.e Human)
+ if (toolbar->positionWithinLine != QStyleOptionToolBar::End)
+ rect.adjust(0, 0, 1, 0);
+
+ GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
+ GtkShadowType shadow_type = GTK_SHADOW_NONE;
+ d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
+ gtkPainter.paintBox( gtkToolbar, "toolbar", rect,
+ GTK_STATE_NORMAL, shadow_type, gtkToolbar->style);
+ }
+ break;
+
+#endif // QT_NO_TOOLBAR
+
+ case CE_MenuItem:
+ painter->save();
+
+ // Draws one item in a popup menu.
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ const int windowsItemFrame = 2; // menu item frame width
+ const int windowsItemHMargin = 3; // menu item hor text margin
+ const int windowsItemVMargin = 26; // menu item ver text margin
+ const int windowsRightBorder = 15; // right border on windows
+ GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget("GtkMenu.GtkCheckMenuItem") :
+ d->gtkWidget("GtkMenu.GtkMenuItem");
+
+ style = gtkPainter.getStyle(gtkMenuItem);
+ QColor shadow = option->palette.dark().color();
+
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
+ painter->setPen(shadow.lighter(106));
+ gboolean wide_separators = 0;
+ gint separator_height = 0;
+ guint horizontal_padding = 3;
+ QRect separatorRect = option->rect;
+ if (!d->gtk_check_version(2, 10, 0)) {
+ d->gtk_widget_style_get(gtkMenuSeparator,
+ "wide-separators", &wide_separators,
+ "separator-height", &separator_height,
+ "horizontal-padding", &horizontal_padding,
+ NULL);
+ }
+ separatorRect.setHeight(option->rect.height() - 2 * gtkMenuSeparator->style->ythickness);
+ separatorRect.setWidth(option->rect.width() - 2 * (horizontal_padding + gtkMenuSeparator->style->xthickness));
+ separatorRect.moveCenter(option->rect.center());
+ if (wide_separators)
+ gtkPainter.paintBox( gtkMenuSeparator, "hseparator",
+ separatorRect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenuSeparator->style);
+ else
+ gtkPainter.paintHline( gtkMenuSeparator, "hseparator",
+ separatorRect, GTK_STATE_NORMAL, gtkMenuSeparator->style,
+ 0, option->rect.right() - 1, 1);
+ painter->restore();
+ break;
+ }
+
+ bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
+
+ if (selected) {
+ QRect rect = option->rect;
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox*>(widget))
+ rect = option->rect;
+#endif
+ gtkPainter.paintBox( gtkMenuItem, "menuitem", rect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style);
+ }
+
+ bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
+ bool checked = menuItem->checked;
+ bool enabled = menuItem->state & State_Enabled;
+ bool ignoreCheckMark = false;
+
+ gint checkSize;
+ d->gtk_widget_style_get(d->gtkWidget("GtkMenu.GtkCheckMenuItem"), "indicator-size", &checkSize, NULL);
+
+ int checkcol = qMax(menuItem->maxIconWidth, qMax(20, checkSize));
+
+#ifndef QT_NO_COMBOBOX
+
+ if (qobject_cast<const QComboBox*>(widget))
+ ignoreCheckMark = true; // Ignore the checkmarks provided by the QComboMenuDelegate
+
+#endif
+ if (!ignoreCheckMark) {
+ // Check
+ QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2 + 1, checkSize, checkSize);
+ checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
+
+ if (checkable && menuItem->icon.isNull()) {
+ // Some themes such as aero-clone draw slightly outside the paint rect
+ int spacing = 1; // ### Consider using gtkCheckBox : "indicator-spacing" instead
+
+ if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
+ // Radio button
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (selected)
+ state = GTK_STATE_PRELIGHT;
+ if (checked)
+ shadow = GTK_SHADOW_IN;
+
+ gtkPainter.setClipRect(checkRect.adjusted(-spacing, -spacing, spacing, spacing));
+ gtkPainter.paintOption(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
+ gtkMenuItem->style, QLS("option"));
+ gtkPainter.setClipRect(QRect());
+
+ } else {
+ // Check box
+ if (menuItem->icon.isNull()) {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (selected)
+ state = GTK_STATE_PRELIGHT;
+ if (checked)
+ shadow = GTK_SHADOW_IN;
+
+ gtkPainter.setClipRect(checkRect.adjusted(-spacing, -spacing, -spacing, -spacing));
+ gtkPainter.paintCheckbox(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
+ gtkMenuItem->style, QLS("check"));
+ gtkPainter.setClipRect(QRect());
+ }
+ }
+ }
+
+ } else {
+ // Ignore checkmark
+ if (menuItem->icon.isNull())
+ checkcol = 0;
+ else
+ checkcol = menuItem->maxIconWidth;
+ }
+
+ bool dis = !(menuItem->state & State_Enabled);
+ bool act = menuItem->state & State_Selected;
+ const QStyleOption *opt = option;
+ const QStyleOptionMenuItem *menuitem = menuItem;
+ QPainter *p = painter;
+ QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
+ QRect(menuitem->rect.x() + 3, menuitem->rect.y(),
+ checkcol, menuitem->rect.height()));
+
+ if (!menuItem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+
+ if (act && !dis)
+ mode = QIcon::Active;
+
+ QPixmap pixmap;
+ int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
+ QSize iconSize(smallIconSize, smallIconSize);
+
+#ifndef QT_NO_COMBOBOX
+ if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
+ iconSize = combo->iconSize();
+
+#endif // QT_NO_COMBOBOX
+ if (checked)
+ pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
+ else
+ pixmap = menuItem->icon.pixmap(iconSize, mode);
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center() - QPoint(0, 1));
+ painter->setPen(menuItem->palette.text().color());
+ if (!ignoreCheckMark && checkable && checked) {
+ QStyleOption opt = *option;
+
+ if (act) {
+ QColor activeColor = mergedColors(option->palette.background().color(),
+ option->palette.highlight().color());
+ opt.palette.setBrush(QPalette::Button, activeColor);
+ }
+ opt.state |= State_Sunken;
+ opt.rect = vCheckRect;
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
+ }
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ }
+
+ GdkColor gdkText = gtkMenuItem->style->fg[GTK_STATE_NORMAL];
+ GdkColor gdkDText = gtkMenuItem->style->fg[GTK_STATE_INSENSITIVE];
+ GdkColor gdkHText = gtkMenuItem->style->fg[GTK_STATE_PRELIGHT];
+ uint resolve_mask = option->palette.resolve();
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ QColor disabledTextColor = QColor(gdkDText.red>>8, gdkDText.green>>8, gdkDText.blue>>8);
+ if (resolve_mask & (1 << QPalette::ButtonText)) {
+ textColor = option->palette.buttonText().color();
+ disabledTextColor = option->palette.brush(QPalette::Disabled, QPalette::ButtonText).color();
+ }
+
+ QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
+ if (resolve_mask & (1 << QPalette::HighlightedText)) {
+ highlightedTextColor = option->palette.highlightedText().color();
+ }
+
+ if (selected)
+ painter->setPen(highlightedTextColor);
+ else
+ painter->setPen(textColor);
+
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm + 1;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+
+ if (!s.isEmpty()) { // Draw text
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+
+ // Draw shortcut right aligned
+ text_flags |= Qt::AlignRight;
+
+ if (t >= 0) {
+ int rightMargin = 12; // Hardcode for now
+ QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right() - rightMargin, textRect.bottom())));
+
+ if (dis)
+ p->setPen(disabledTextColor);
+ p->drawText(vShortcutRect, text_flags , s.mid(t + 1));
+ s = s.left(t);
+ }
+
+ text_flags &= ~Qt::AlignRight;
+ text_flags |= Qt::AlignLeft;
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+
+ if (dis)
+ p->setPen(disabledTextColor);
+ p->drawText(vTextRect, text_flags, s.left(t));
+ p->restore();
+ }
+
+ // Arrow
+ if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+
+ QFontMetrics fm(menuitem->font);
+ int arrow_size = fm.ascent() + fm.descent() - 2 * gtkMenuItem->style->ythickness;
+ gfloat arrow_scaling = 0.8;
+ int extra = 0;
+ if (!d->gtk_check_version(2, 16, 0)) {
+ // "arrow-scaling" is actually hardcoded and fails on hardy (see gtk+-2.12/gtkmenuitem.c)
+ // though the current documentation states otherwise
+ d->gtk_widget_style_get(gtkMenuItem, "arrow-scaling", &arrow_scaling, NULL);
+ // in versions < 2.16 ythickness was previously subtracted from the arrow_size
+ extra = 2 * gtkMenuItem->style->ythickness;
+ }
+
+ int horizontal_padding;
+ d->gtk_widget_style_get(gtkMenuItem, "horizontal-padding", &horizontal_padding, NULL);
+
+ const int dim = static_cast<int>(arrow_size * arrow_scaling) + extra;
+ int xpos = menuItem->rect.left() + menuItem->rect.width() - horizontal_padding - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
+ QRect(xpos, menuItem->rect.top() +
+ menuItem->rect.height() / 2 - dim / 2, dim, dim));
+ GtkStateType state = enabled ? (act ? GTK_STATE_PRELIGHT: GTK_STATE_NORMAL) : GTK_STATE_INSENSITIVE;
+ GtkShadowType shadowType = (state == GTK_STATE_PRELIGHT) ? GTK_SHADOW_OUT : GTK_SHADOW_IN;
+ gtkPainter.paintArrow(gtkMenuItem, "menuitem", vSubMenuRect, QApplication::isRightToLeft() ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT, state,
+ shadowType, FALSE, style);
+ }
+ }
+ painter->restore();
+ break;
+
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
+ gint interiorFocus = true;
+ d->gtk_widget_style_get(gtkButton, "interior-focus", &interiorFocus, NULL);
+ int xt = interiorFocus ? gtkButton->style->xthickness : 0;
+ int yt = interiorFocus ? gtkButton->style->ythickness : 0;
+
+ if (btn->features & QStyleOptionButton::Flat && btn->state & State_HasFocus)
+ // The normal button focus rect does not work well for flat buttons in Clearlooks
+ proxy()->drawPrimitive(PE_FrameFocusRect, option, painter, widget);
+ else if (btn->state & State_HasFocus)
+ gtkPainter.paintFocus(gtkButton, "button",
+ option->rect.adjusted(xt, yt, -xt, -yt),
+ btn->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
+ gtkButton->style);
+
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_TABBAR
+
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
+ style = gtkPainter.getStyle(gtkNotebook);
+
+ QRect rect = option->rect;
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_ACTIVE;
+ if (tab->state & State_Selected)
+ state = GTK_STATE_NORMAL;
+
+ bool selected = (tab->state & State_Selected);
+ bool first = false, last = false;
+ if (widget) {
+ // This is most accurate and avoids resizing tabs while moving
+ first = tab->rect.left() == widget->rect().left();
+ last = tab->rect.right() == widget->rect().right();
+ } else if (option->direction == Qt::RightToLeft) {
+ bool tmp = first;
+ first = last;
+ last = tmp;
+ }
+ int topIndent = 3;
+ int bottomIndent = 1;
+ int tabOverlap = 1;
+ painter->save();
+
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ if (!selected)
+ rect.adjust(first ? 0 : -tabOverlap, topIndent, last ? 0 : tabOverlap, -bottomIndent);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect,
+ state, shadow, GTK_POS_BOTTOM, style);
+ break;
+
+ case QTabBar::RoundedSouth:
+ if (!selected)
+ rect.adjust(first ? 0 : -tabOverlap, 0, last ? 0 : tabOverlap, -topIndent);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect.adjusted(0, 1, 0, 0),
+ state, shadow, GTK_POS_TOP, style);
+ break;
+
+ case QTabBar::RoundedWest:
+ if (!selected)
+ rect.adjust(topIndent, 0, -bottomIndent, 0);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect, state, shadow, GTK_POS_RIGHT, style);
+ break;
+
+ case QTabBar::RoundedEast:
+ if (!selected)
+ rect.adjust(bottomIndent, 0, -topIndent, 0);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect, state, shadow, GTK_POS_LEFT, style);
+ break;
+
+ default:
+ QCleanlooksStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+
+ painter->restore();
+ }
+
+ break;
+
+#endif //QT_NO_TABBAR
+
+ case CE_ProgressBarGroove:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ Q_UNUSED(bar);
+ GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
+ GtkStateType state = gtkPainter.gtkState(option);
+ gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, gtkProgressBar->style);
+ }
+
+ break;
+
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ GtkStateType state = option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
+ GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
+ style = gtkProgressBar->style;
+ gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, style);
+ int xt = style->xthickness;
+ int yt = style->ythickness;
+ QRect rect = bar->rect.adjusted(xt, yt, -xt, -yt);
+ bool vertical = false;
+ bool inverted = false;
+ bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
+ // Get extra style options if version 2
+
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ }
+
+ // If the orientation is vertical, we use a transform to rotate
+ // the progress bar 90 degrees clockwise. This way we can use the
+ // same rendering code for both orientations.
+ if (vertical) {
+ rect.translate(xt, -yt * 2);
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // Flip width and height
+ QTransform m = QTransform::fromTranslate(rect.height(), 0);
+ m.rotate(90.0);
+ painter->setTransform(m);
+ }
+
+ int maxWidth = rect.width();
+ int minWidth = 4;
+
+ qint64 progress = (qint64)qMax(bar->progress, bar->minimum); // Workaround for bug in QProgressBar
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth;
+ int progressBarWidth = (int(vc6_workaround) > minWidth ) ? int(vc6_workaround) : minWidth;
+ int width = indeterminate ? maxWidth : progressBarWidth;
+ bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
+
+ if (inverted)
+ reverse = !reverse;
+
+ int maximum = 2;
+ int fakePos = 0;
+ if (bar->minimum == bar->maximum)
+ maximum = 0;
+ if (bar->progress == bar->maximum)
+ fakePos = maximum;
+ else if (bar->progress > bar->minimum)
+ fakePos = maximum - 1;
+
+ d->gtk_progress_configure((GtkProgress*)gtkProgressBar, fakePos, 0, maximum);
+
+ QRect progressBar;
+
+ if (!indeterminate) {
+ if (!reverse)
+ progressBar.setRect(rect.left(), rect.top(), width, rect.height());
+ else
+ progressBar.setRect(rect.right() - width, rect.top(), width, rect.height());
+
+ } else {
+ Q_D(const QGtkStyle);
+ int slideWidth = ((rect.width() - 4) * 2) / 3;
+ int step = ((d->animateStep * slideWidth) / d->animationFps) % slideWidth;
+ if ((((d->animateStep * slideWidth) / d->animationFps) % (2 * slideWidth)) >= slideWidth)
+ step = slideWidth - step;
+ progressBar.setRect(rect.left() + step, rect.top(), slideWidth / 2, rect.height());
+ }
+
+ QString key = QString(QLS("%0")).arg(fakePos);
+ if (inverted) {
+ key += QLatin1String("inv");
+ gtkPainter.setFlipHorizontal(true);
+ }
+ gtkPainter.paintBox( gtkProgressBar, "bar", progressBar, GTK_STATE_SELECTED, GTK_SHADOW_OUT, style, key);
+ }
+
+ break;
+
+ default:
+ QCleanlooksStyle::drawControl(element, option, painter, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ QRect rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
+
+ switch (control) {
+ case CC_TitleBar:
+ return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
+
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ // Reserve space for outside focus rect
+ QStyleOptionSlider sliderCopy = *slider;
+ sliderCopy.rect = option->rect.adjusted(2, 2, -2, -2);
+ return QCleanlooksStyle::subControlRect(control, &sliderCopy, subControl, widget);
+ }
+
+ break;
+
+#ifndef QT_NO_GROUPBOX
+
+ case CC_GroupBox:
+ if (qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ rect = option->rect.adjusted(0, groupBoxTopMargin, 0, -groupBoxBottomMargin);
+ int topMargin = 0;
+ int topHeight = 0;
+ topHeight = 10;
+ QRect frameRect = rect;
+ frameRect.setTop(topMargin);
+
+ if (subControl == SC_GroupBoxFrame)
+ return rect;
+ else if (subControl == SC_GroupBoxContents) {
+ int margin = 0;
+ int leftMarginExtension = 8;
+ return frameRect.adjusted(leftMarginExtension + margin, margin + topHeight + groupBoxTitleMargin, -margin, -margin);
+ }
+
+ if (const QGroupBox *groupBoxWidget = qobject_cast<const QGroupBox *>(widget)) {
+ //Prepare metrics for a bold font
+ QFont font = widget->font();
+ font.setBold(true);
+ QFontMetrics fontMetrics(font);
+ QSize textRect = fontMetrics.boundingRect(groupBoxWidget->title()).size() + QSize(4, 4);
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
+ int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
+
+ if (subControl == SC_GroupBoxCheckBox) {
+ rect.setWidth(indicatorWidth);
+ rect.setHeight(indicatorHeight);
+ rect.moveTop((textRect.height() - indicatorHeight) / 2);
+
+ } else if (subControl == SC_GroupBoxLabel) {
+ if (groupBoxWidget->isCheckable())
+ rect.adjust(indicatorWidth + 4, 0, 0, 0);
+ rect.setSize(textRect);
+ }
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ }
+
+ return rect;
+
+#endif
+#ifndef QT_NO_SPINBOX
+
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ GtkWidget *gtkSpinButton = d->gtkWidget("GtkSpinButton");
+ int center = spinbox->rect.height() / 2;
+ int xt = spinbox->frame ? gtkSpinButton->style->xthickness : 0;
+ int yt = spinbox->frame ? gtkSpinButton->style->ythickness : 0;
+ int y = yt;
+
+ QSize bs;
+ bs.setHeight(qMax(8, spinbox->rect.height()/2 - y));
+ bs.setWidth(d->getSpinboxArrowSize());
+ int x, lx, rx;
+ x = spinbox->rect.width() - y - bs.width() + 2;
+ lx = xt;
+ rx = x - xt;
+
+ switch (subControl) {
+
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = QRect(x, xt, bs.width(), center - yt);
+ break;
+
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = QRect(x, center, bs.width(), spinbox->rect.bottom() - center - yt + 1);
+ break;
+
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ rect = QRect(lx, yt, spinbox->rect.width() - 2*xt, spinbox->rect.height() - 2*yt);
+ else
+ rect = QRect(lx, yt, rx - qMax(xt - 1, 0), spinbox->rect.height() - 2*yt);
+ break;
+
+ case SC_SpinBoxFrame:
+ rect = spinbox->rect;
+
+ default:
+ break;
+ }
+
+ rect = visualRect(spinbox->direction, spinbox->rect, rect);
+ }
+
+ break;
+
+#endif // Qt_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ // We employ the gtk widget to position arrows and separators for us
+ GtkWidget *gtkCombo = box->editable ? d->gtkWidget("GtkComboBoxEntry")
+ : d->gtkWidget("GtkComboBox");
+ d->gtk_widget_set_direction(gtkCombo, (option->direction == Qt::RightToLeft) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ GtkAllocation geometry = {0, 0, qMax(0, option->rect.width()), qMax(0, option->rect.height())};
+ d->gtk_widget_size_allocate(gtkCombo, &geometry);
+ int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, option, widget);
+ QHashableLatin1Literal arrowPath("GtkComboBoxEntry.GtkToggleButton");
+ if (!box->editable) {
+ if (appears_as_list)
+ arrowPath = "GtkComboBox.GtkToggleButton";
+ else
+ arrowPath = "GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow";
+ }
+
+ GtkWidget *arrowWidget = d->gtkWidget(arrowPath);
+ if (!arrowWidget)
+ return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
+
+ QRect buttonRect(option->rect.left() + arrowWidget->allocation.x,
+ option->rect.top() + arrowWidget->allocation.y,
+ arrowWidget->allocation.width, arrowWidget->allocation.height);
+
+ switch (subControl) {
+
+ case SC_ComboBoxArrow: // Note: this indicates the arrowbutton for editable combos
+ rect = buttonRect;
+ break;
+
+ case SC_ComboBoxEditField: {
+ rect = visualRect(option->direction, option->rect, rect);
+ int xMargin = box->editable ? 1 : 4, yMargin = 2;
+ rect.setRect(option->rect.left() + gtkCombo->style->xthickness + xMargin,
+ option->rect.top() + gtkCombo->style->ythickness + yMargin,
+ option->rect.width() - buttonRect.width() - 2*(gtkCombo->style->xthickness + xMargin),
+ option->rect.height() - 2*(gtkCombo->style->ythickness + yMargin));
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ break;
+
+#endif // QT_NO_COMBOBOX
+
+ default:
+ break;
+ }
+
+ return rect;
+}
+
+/*!
+ \reimp
+*/
+QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ QSize newSize = QCleanlooksStyle::sizeFromContents(type, option, size, widget);
+ if (!d->isThemeAvailable())
+ return newSize;
+
+ switch (type) {
+
+ case CT_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
+ newSize = size + QSize(2 * gtkButton->style->xthickness, 2 + 2 * gtkButton->style->ythickness);
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ QSize minSize(0, 25);
+ if (toolbutton->toolButtonStyle != Qt::ToolButtonTextOnly)
+ minSize = toolbutton->iconSize + QSize(12, 12);
+ newSize = newSize.expandedTo(minSize);
+ }
+
+ if (toolbutton->features & QStyleOptionToolButton::HasMenu)
+ newSize += QSize(6, 0);
+ }
+ break;
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ int textMargin = 8;
+
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
+ GtkRequisition sizeReq = {0, 0};
+ d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq);
+ newSize = QSize(size.width(), sizeReq.height);
+ break;
+ }
+
+ GtkWidget *gtkMenuItem = d->gtkWidget("GtkMenu.GtkCheckMenuItem");
+ GtkStyle* style = gtkMenuItem->style;
+
+ // Note we get the perfect height for the default font since we
+ // set a fake text label on the gtkMenuItem
+ // But if custom fonts are used on the widget we need a minimum size
+ GtkRequisition sizeReq = {0, 0};
+ d->gtk_widget_size_request(gtkMenuItem, &sizeReq);
+ newSize.setHeight(qMax(newSize.height() - 4, sizeReq.height));
+ newSize += QSize(textMargin + style->xthickness - 1, 0);
+
+ // Cleanlooks assumes a check column of 20 pixels so we need to
+ // expand it a bit
+ gint checkSize;
+ d->gtk_widget_style_get(gtkMenuItem, "indicator-size", &checkSize, NULL);
+ newSize.setWidth(newSize.width() + qMax(0, checkSize - 20));
+ }
+
+ break;
+
+ case CT_SpinBox:
+ // QSpinBox does some nasty things that depends on CT_LineEdit
+ newSize = size + QSize(0, -d->gtkWidget("GtkSpinButton")->style->ythickness * 2);
+ break;
+
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ gint focusPadding, focusWidth;
+ d->gtk_widget_style_get(gtkButton, "focus-padding", &focusPadding, NULL);
+ d->gtk_widget_style_get(gtkButton, "focus-line-width", &focusWidth, NULL);
+ newSize = size;
+ newSize += QSize(2*gtkButton->style->xthickness + 4, 2*gtkButton->style->ythickness);
+ newSize += QSize(2*(focusWidth + focusPadding + 2), 2*(focusWidth + focusPadding));
+
+ GtkWidget *gtkButtonBox = d->gtkWidget("GtkHButtonBox");
+ gint minWidth = 85, minHeight = 0;
+ d->gtk_widget_style_get(gtkButtonBox, "child-min-width", &minWidth,
+ "child-min-height", &minHeight, NULL);
+ if (!btn->text.isEmpty() && newSize.width() < minWidth)
+ newSize.setWidth(minWidth);
+ if (newSize.height() < minHeight)
+ newSize.setHeight(minHeight);
+ }
+
+ break;
+
+ case CT_Slider: {
+ GtkWidget *gtkSlider = d->gtkWidget("GtkHScale");
+ newSize = size + QSize(2*gtkSlider->style->xthickness, 2*gtkSlider->style->ythickness);
+ }
+ break;
+
+ case CT_LineEdit: {
+ GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
+ newSize = size + QSize(2*gtkEntry->style->xthickness, 2 + 2*gtkEntry->style->ythickness);
+ }
+ break;
+
+ case CT_ItemViewItem:
+ newSize += QSize(0, 2);
+ break;
+
+ case CT_ComboBox:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
+ QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, combo, SC_ComboBoxArrow, widget);
+ newSize = size + QSize(12 + arrowButtonRect.width() + 2*gtkCombo->style->xthickness, 4 + 2*gtkCombo->style->ythickness);
+
+ if (!(widget && qobject_cast<QToolBar *>(widget->parentWidget())))
+ newSize += QSize(0, 2);
+ }
+ break;
+
+ case CT_GroupBox:
+ newSize += QSize(4, groupBoxBottomMargin + groupBoxTopMargin + groupBoxTitleMargin); // Add some space below the groupbox
+ break;
+
+ case CT_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ if (!tab->icon.isNull())
+ newSize += QSize(6, 0);
+ }
+ newSize += QSize(1, 1);
+ break;
+
+ default:
+ break;
+ }
+
+ return newSize;
+}
+
+
+/*! \reimp */
+QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::standardPixmap(sp, option, widget);
+
+ QPixmap pixmap;
+ switch (sp) {
+
+ case SP_TitleBarNormalButton: {
+ QImage restoreButton((const char **)dock_widget_restore_xpm);
+ QColor alphaCorner = restoreButton.color(2);
+ alphaCorner.setAlpha(80);
+ restoreButton.setColor(2, alphaCorner.rgba());
+ alphaCorner.setAlpha(180);
+ restoreButton.setColor(4, alphaCorner.rgba());
+ return QPixmap::fromImage(restoreButton);
+ }
+ break;
+
+ case SP_TitleBarCloseButton: // Fall through
+ case SP_DockWidgetCloseButton: {
+
+ QImage closeButton((const char **)dock_widget_close_xpm);
+ QColor alphaCorner = closeButton.color(2);
+ alphaCorner.setAlpha(80);
+ closeButton.setColor(2, alphaCorner.rgba());
+ return QPixmap::fromImage(closeButton);
+ }
+ break;
+
+ case SP_DialogDiscardButton:
+ return QGtkPainter::getIcon(GTK_STOCK_DELETE);
+ case SP_DialogOkButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OK);
+ case SP_DialogCancelButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
+ case SP_DialogYesButton:
+ return QGtkPainter::getIcon(GTK_STOCK_YES);
+ case SP_DialogNoButton:
+ return QGtkPainter::getIcon(GTK_STOCK_NO);
+ case SP_DialogOpenButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OPEN);
+ case SP_DialogCloseButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
+ case SP_DialogApplyButton:
+ return QGtkPainter::getIcon(GTK_STOCK_APPLY);
+ case SP_DialogSaveButton:
+ return QGtkPainter::getIcon(GTK_STOCK_SAVE);
+ case SP_MessageBoxWarning:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxQuestion:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxInformation:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxCritical:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ default:
+ return QCleanlooksStyle::standardPixmap(sp, option, widget);
+ }
+ return pixmap;
+}
+
+/*!
+ \internal
+*/
+QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
+ switch (standardIcon) {
+ case SP_DialogDiscardButton:
+ return QGtkPainter::getIcon(GTK_STOCK_DELETE);
+ case SP_DialogOkButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OK);
+ case SP_DialogCancelButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
+ case SP_DialogYesButton:
+ return QGtkPainter::getIcon(GTK_STOCK_YES);
+ case SP_DialogNoButton:
+ return QGtkPainter::getIcon(GTK_STOCK_NO);
+ case SP_DialogOpenButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OPEN);
+ case SP_DialogCloseButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
+ case SP_DialogApplyButton:
+ return QGtkPainter::getIcon(GTK_STOCK_APPLY);
+ case SP_DialogSaveButton:
+ return QGtkPainter::getIcon(GTK_STOCK_SAVE);
+ case SP_MessageBoxWarning:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxQuestion:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxInformation:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxCritical:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ default:
+ return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+}
+
+
+/*! \reimp */
+QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ QRect r = QCleanlooksStyle::subElementRect(element, option, widget);
+ if (!d->isThemeAvailable())
+ return r;
+
+ switch (element) {
+ case SE_ProgressBarLabel:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarGroove:
+ return option->rect;
+ case SE_PushButtonContents:
+ if (!d->gtk_check_version(2, 10, 0)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ GtkBorder *border = 0;
+ d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL);
+ if (border) {
+ r = option->rect.adjusted(border->left, border->top, -border->right, -border->bottom);
+ d->gtk_border_free(border);
+ } else {
+ r = option->rect.adjusted(1, 1, -1, -1);
+ }
+ r = visualRect(option->direction, option->rect, r);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/*!
+ \reimp
+*/
+QRect QGtkStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
+{
+ return QCleanlooksStyle::itemPixmapRect(r, flags, pixmap);
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const
+{
+ QCleanlooksStyle::drawItemPixmap(painter, rect, alignment, pixmap);
+}
+
+/*!
+ \reimp
+*/
+QStyle::SubControl QGtkStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const
+{
+ return QCleanlooksStyle::hitTestComplexControl(cc, opt, pt, w);
+}
+
+/*!
+ \reimp
+*/
+QPixmap QGtkStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const
+{
+ return QCleanlooksStyle::generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ return QCleanlooksStyle::drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
+}
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_STYLE_QGTK)
diff --git a/src/widgets/styles/qgtkstyle.h b/src/widgets/styles/qgtkstyle.h
new file mode 100644
index 0000000000..56df2778e7
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGTKSTYLE_H
+#define QGTKSTYLE_H
+
+#include <QtWidgets/QCleanlooksStyle>
+#include <QtGui/QPalette>
+#include <QtGui/QFont>
+#include <QtWidgets/QFileDialog>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_GTK)
+
+class QPainterPath;
+class QGtkStylePrivate;
+
+class Q_GUI_EXPORT QGtkStyle : public QCleanlooksStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGtkStyle)
+
+public:
+ QGtkStyle();
+ QGtkStyle(QGtkStylePrivate &dd);
+
+ ~QGtkStyle();
+
+ QPalette standardPalette() const;
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawControl(ControlElement control, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
+ const QPixmap &pixmap) const;
+ void drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option,
+ const QWidget *widget, QStyleHintReturn *returnData) const;
+
+ QStyle::SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const;
+
+ QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const;
+ QRect subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const;
+ QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &palette);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+ static bool getGConfBool(const QString &key, bool fallback = 0);
+ static QString getGConfString(const QString &key, const QString &fallback = QString());
+
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+};
+
+#endif //!defined(QT_NO_STYLE_QGTK)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QGTKSTYLE_H
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
new file mode 100644
index 0000000000..35f022bac4
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -0,0 +1,1146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgtkstyle_p.h"
+
+// This file is responsible for resolving all GTK functions we use
+// dynamically. This is done to avoid link-time dependancy on GTK
+// as well as crashes occurring due to usage of the GTK_QT engines
+//
+// Additionally we create a map of common GTK widgets that we can pass
+// to the GTK theme engine as many engines resort to querying the
+// actual widget pointers for details that are not covered by the
+// state flags
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <QtCore/QEvent>
+#include <QtCore/QFile>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QHash>
+#include <QtCore/QUrl>
+#include <QtCore/QLibrary>
+#include <QtCore/QDebug>
+
+#include <private/qapplication_p.h>
+#include <private/qiconloader_p.h>
+
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QStyle>
+#include <QtWidgets/QApplication>
+#include <QtGui/QPixmapCache>
+#include <QtWidgets/QStatusBar>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QToolBar>
+#include <QtWidgets/QToolButton>
+#include <QtWidgets/QX11Info>
+
+#include <private/qt_x11_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool displayDepth = -1;
+Q_GLOBAL_STATIC(QGtkStyleUpdateScheduler, styleScheduler)
+
+Ptr_gtk_container_forall QGtkStylePrivate::gtk_container_forall = 0;
+Ptr_gtk_init QGtkStylePrivate::gtk_init = 0;
+Ptr_gtk_style_attach QGtkStylePrivate::gtk_style_attach = 0;
+Ptr_gtk_window_new QGtkStylePrivate::gtk_window_new = 0;
+Ptr_gtk_widget_destroy QGtkStylePrivate::gtk_widget_destroy = 0;
+Ptr_gtk_widget_realize QGtkStylePrivate::gtk_widget_realize = 0;
+Ptr_gtk_widget_set_default_direction QGtkStylePrivate::gtk_widget_set_default_direction = 0;
+Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_fg = 0;
+Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_bg = 0;
+Ptr_gtk_arrow_new QGtkStylePrivate::gtk_arrow_new = 0;
+Ptr_gtk_menu_item_new_with_label QGtkStylePrivate::gtk_menu_item_new_with_label = 0;
+Ptr_gtk_check_menu_item_new_with_label QGtkStylePrivate::gtk_check_menu_item_new_with_label = 0;
+Ptr_gtk_menu_bar_new QGtkStylePrivate::gtk_menu_bar_new = 0;
+Ptr_gtk_menu_new QGtkStylePrivate::gtk_menu_new = 0;
+Ptr_gtk_button_new QGtkStylePrivate::gtk_button_new = 0;
+Ptr_gtk_tool_button_new QGtkStylePrivate::gtk_tool_button_new = 0;
+Ptr_gtk_hbutton_box_new QGtkStylePrivate::gtk_hbutton_box_new = 0;
+Ptr_gtk_check_button_new QGtkStylePrivate::gtk_check_button_new = 0;
+Ptr_gtk_radio_button_new QGtkStylePrivate::gtk_radio_button_new = 0;
+Ptr_gtk_spin_button_new QGtkStylePrivate::gtk_spin_button_new = 0;
+Ptr_gtk_frame_new QGtkStylePrivate::gtk_frame_new = 0;
+Ptr_gtk_expander_new QGtkStylePrivate::gtk_expander_new = 0;
+Ptr_gtk_statusbar_new QGtkStylePrivate::gtk_statusbar_new = 0;
+Ptr_gtk_entry_new QGtkStylePrivate::gtk_entry_new = 0;
+Ptr_gtk_hscale_new QGtkStylePrivate::gtk_hscale_new = 0;
+Ptr_gtk_vscale_new QGtkStylePrivate::gtk_vscale_new = 0;
+Ptr_gtk_hscrollbar_new QGtkStylePrivate::gtk_hscrollbar_new = 0;
+Ptr_gtk_vscrollbar_new QGtkStylePrivate::gtk_vscrollbar_new = 0;
+Ptr_gtk_scrolled_window_new QGtkStylePrivate::gtk_scrolled_window_new = 0;
+Ptr_gtk_notebook_new QGtkStylePrivate::gtk_notebook_new = 0;
+Ptr_gtk_toolbar_new QGtkStylePrivate::gtk_toolbar_new = 0;
+Ptr_gtk_toolbar_insert QGtkStylePrivate::gtk_toolbar_insert = 0;
+Ptr_gtk_separator_tool_item_new QGtkStylePrivate::gtk_separator_tool_item_new = 0;
+Ptr_gtk_tree_view_new QGtkStylePrivate::gtk_tree_view_new = 0;
+Ptr_gtk_combo_box_new QGtkStylePrivate::gtk_combo_box_new = 0;
+Ptr_gtk_combo_box_entry_new QGtkStylePrivate::gtk_combo_box_entry_new = 0;
+Ptr_gtk_progress_bar_new QGtkStylePrivate::gtk_progress_bar_new = 0;
+Ptr_gtk_container_add QGtkStylePrivate::gtk_container_add = 0;
+Ptr_gtk_menu_shell_append QGtkStylePrivate::gtk_menu_shell_append = 0;
+Ptr_gtk_progress_configure QGtkStylePrivate::gtk_progress_configure = 0;
+Ptr_gtk_range_get_adjustment QGtkStylePrivate::gtk_range_get_adjustment = 0;
+Ptr_gtk_range_set_adjustment QGtkStylePrivate::gtk_range_set_adjustment = 0;
+Ptr_gtk_range_set_inverted QGtkStylePrivate::gtk_range_set_inverted = 0;
+Ptr_gtk_icon_factory_lookup_default QGtkStylePrivate::gtk_icon_factory_lookup_default = 0;
+Ptr_gtk_icon_theme_get_default QGtkStylePrivate::gtk_icon_theme_get_default = 0;
+Ptr_gtk_widget_style_get QGtkStylePrivate::gtk_widget_style_get = 0;
+Ptr_gtk_icon_set_render_icon QGtkStylePrivate::gtk_icon_set_render_icon = 0;
+Ptr_gtk_fixed_new QGtkStylePrivate::gtk_fixed_new = 0;
+Ptr_gtk_tree_view_column_new QGtkStylePrivate::gtk_tree_view_column_new = 0;
+Ptr_gtk_tree_view_get_column QGtkStylePrivate::gtk_tree_view_get_column = 0;
+Ptr_gtk_tree_view_append_column QGtkStylePrivate::gtk_tree_view_append_column = 0;
+Ptr_gtk_paint_check QGtkStylePrivate::gtk_paint_check = 0;
+Ptr_gtk_paint_box QGtkStylePrivate::gtk_paint_box = 0;
+Ptr_gtk_paint_box_gap QGtkStylePrivate::gtk_paint_box_gap = 0;
+Ptr_gtk_paint_flat_box QGtkStylePrivate::gtk_paint_flat_box = 0;
+Ptr_gtk_paint_option QGtkStylePrivate::gtk_paint_option = 0;
+Ptr_gtk_paint_extension QGtkStylePrivate::gtk_paint_extension = 0;
+Ptr_gtk_paint_slider QGtkStylePrivate::gtk_paint_slider = 0;
+Ptr_gtk_paint_shadow QGtkStylePrivate::gtk_paint_shadow = 0;
+Ptr_gtk_paint_resize_grip QGtkStylePrivate::gtk_paint_resize_grip = 0;
+Ptr_gtk_paint_focus QGtkStylePrivate::gtk_paint_focus = 0;
+Ptr_gtk_paint_arrow QGtkStylePrivate::gtk_paint_arrow = 0;
+Ptr_gtk_paint_handle QGtkStylePrivate::gtk_paint_handle = 0;
+Ptr_gtk_paint_expander QGtkStylePrivate::gtk_paint_expander = 0;
+Ptr_gtk_adjustment_configure QGtkStylePrivate::gtk_adjustment_configure = 0;
+Ptr_gtk_adjustment_new QGtkStylePrivate::gtk_adjustment_new = 0;
+Ptr_gtk_paint_hline QGtkStylePrivate::gtk_paint_hline = 0;
+Ptr_gtk_paint_vline QGtkStylePrivate::gtk_paint_vline = 0;
+Ptr_gtk_menu_item_set_submenu QGtkStylePrivate::gtk_menu_item_set_submenu = 0;
+Ptr_gtk_settings_get_default QGtkStylePrivate::gtk_settings_get_default = 0;
+Ptr_gtk_separator_menu_item_new QGtkStylePrivate::gtk_separator_menu_item_new = 0;
+Ptr_gtk_widget_size_allocate QGtkStylePrivate::gtk_widget_size_allocate = 0;
+Ptr_gtk_widget_size_request QGtkStylePrivate::gtk_widget_size_request = 0;
+Ptr_gtk_widget_set_direction QGtkStylePrivate::gtk_widget_set_direction = 0;
+Ptr_gtk_widget_path QGtkStylePrivate::gtk_widget_path = 0;
+Ptr_gtk_container_get_type QGtkStylePrivate::gtk_container_get_type = 0;
+Ptr_gtk_window_get_type QGtkStylePrivate::gtk_window_get_type = 0;
+Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0;
+Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0;
+Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0;
+Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0;
+Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0;
+Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0;
+Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0;
+Ptr_pango_font_description_get_style QGtkStylePrivate::pango_font_description_get_style = 0;
+
+Ptr_gtk_file_filter_new QGtkStylePrivate::gtk_file_filter_new = 0;
+Ptr_gtk_file_filter_set_name QGtkStylePrivate::gtk_file_filter_set_name = 0;
+Ptr_gtk_file_filter_add_pattern QGtkStylePrivate::gtk_file_filter_add_pattern = 0;
+Ptr_gtk_file_chooser_add_filter QGtkStylePrivate::gtk_file_chooser_add_filter = 0;
+Ptr_gtk_file_chooser_set_filter QGtkStylePrivate::gtk_file_chooser_set_filter = 0;
+Ptr_gtk_file_chooser_get_filter QGtkStylePrivate::gtk_file_chooser_get_filter = 0;
+Ptr_gtk_file_chooser_dialog_new QGtkStylePrivate::gtk_file_chooser_dialog_new = 0;
+Ptr_gtk_file_chooser_set_current_folder QGtkStylePrivate::gtk_file_chooser_set_current_folder = 0;
+Ptr_gtk_file_chooser_get_filename QGtkStylePrivate::gtk_file_chooser_get_filename = 0;
+Ptr_gtk_file_chooser_get_filenames QGtkStylePrivate::gtk_file_chooser_get_filenames = 0;
+Ptr_gtk_file_chooser_set_current_name QGtkStylePrivate::gtk_file_chooser_set_current_name = 0;
+Ptr_gtk_dialog_run QGtkStylePrivate::gtk_dialog_run = 0;
+Ptr_gtk_file_chooser_set_filename QGtkStylePrivate::gtk_file_chooser_set_filename = 0;
+
+Ptr_gdk_pixbuf_get_pixels QGtkStylePrivate::gdk_pixbuf_get_pixels = 0;
+Ptr_gdk_pixbuf_get_width QGtkStylePrivate::gdk_pixbuf_get_width = 0;
+Ptr_gdk_pixbuf_get_height QGtkStylePrivate::gdk_pixbuf_get_height = 0;
+Ptr_gdk_pixmap_new QGtkStylePrivate::gdk_pixmap_new = 0;
+Ptr_gdk_pixbuf_new QGtkStylePrivate::gdk_pixbuf_new = 0;
+Ptr_gdk_pixbuf_get_from_drawable QGtkStylePrivate::gdk_pixbuf_get_from_drawable = 0;
+Ptr_gdk_draw_rectangle QGtkStylePrivate::gdk_draw_rectangle = 0;
+Ptr_gdk_pixbuf_unref QGtkStylePrivate::gdk_pixbuf_unref = 0;
+Ptr_gdk_drawable_unref QGtkStylePrivate::gdk_drawable_unref = 0;
+Ptr_gdk_drawable_get_depth QGtkStylePrivate::gdk_drawable_get_depth = 0;
+Ptr_gdk_color_free QGtkStylePrivate::gdk_color_free = 0;
+Ptr_gdk_x11_window_set_user_time QGtkStylePrivate::gdk_x11_window_set_user_time = 0;
+Ptr_gdk_x11_drawable_get_xid QGtkStylePrivate::gdk_x11_drawable_get_xid = 0;
+Ptr_gdk_x11_drawable_get_xdisplay QGtkStylePrivate::gdk_x11_drawable_get_xdisplay = 0;
+
+Ptr_gconf_client_get_default QGtkStylePrivate::gconf_client_get_default = 0;
+Ptr_gconf_client_get_string QGtkStylePrivate::gconf_client_get_string = 0;
+Ptr_gconf_client_get_bool QGtkStylePrivate::gconf_client_get_bool = 0;
+
+Ptr_gnome_icon_lookup_sync QGtkStylePrivate::gnome_icon_lookup_sync = 0;
+Ptr_gnome_vfs_init QGtkStylePrivate::gnome_vfs_init = 0;
+
+typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QGtkStylePrivate*);
+
+QT_BEGIN_NAMESPACE
+
+static void gtkStyleSetCallback(GtkWidget*)
+{
+ qRegisterMetaType<QGtkStylePrivate *>();
+
+ // We have to let this function return and complete the event
+ // loop to ensure that all gtk widgets have been styled before
+ // updating
+ QMetaObject::invokeMethod(styleScheduler(), "updateTheme", Qt::QueuedConnection);
+}
+
+static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer)
+{
+ GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
+ g_object_get(gtkToolBar, "toolbar-style", &toolbar_style, NULL);
+ QWidgetList widgets = QApplication::allWidgets();
+ for (int i = 0; i < widgets.size(); ++i) {
+ QWidget *widget = widgets.at(i);
+ if (qobject_cast<QToolButton*>(widget)) {
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &event);
+ }
+ }
+}
+
+static QHashableLatin1Literal classPath(GtkWidget *widget)
+{
+ char *class_path;
+ QGtkStylePrivate::gtk_widget_path (widget, NULL, &class_path, NULL);
+
+ char *copy = class_path;
+ if (strncmp(copy, "GtkWindow.", 10) == 0)
+ copy += 10;
+ if (strncmp(copy, "GtkFixed.", 9) == 0)
+ copy += 9;
+
+ copy = strdup(copy);
+
+ g_free(class_path);
+
+ return QHashableLatin1Literal::fromData(copy);
+}
+
+
+
+bool QGtkStyleFilter::eventFilter(QObject *obj, QEvent *e)
+{
+ if (e->type() == QEvent::ApplicationPaletteChange) {
+ // Only do this the first time since this will also
+ // generate applicationPaletteChange events
+ if (!qt_app_palettes_hash() || qt_app_palettes_hash()->isEmpty()) {
+ stylePrivate->applyCustomPaletteHash();
+ }
+ }
+ return QObject::eventFilter(obj, e);
+}
+
+QList<QGtkStylePrivate *> QGtkStylePrivate::instances;
+QGtkStylePrivate::WidgetMap *QGtkStylePrivate::widgetMap = 0;
+
+QGtkStylePrivate::QGtkStylePrivate()
+ : QCleanlooksStylePrivate()
+ , filter(this)
+{
+ instances.append(this);
+}
+
+QGtkStylePrivate::~QGtkStylePrivate()
+{
+ instances.removeOne(this);
+}
+
+void QGtkStylePrivate::init()
+{
+ resolveGtk();
+ initGtkWidgets();
+}
+
+GtkWidget* QGtkStylePrivate::gtkWidget(const QHashableLatin1Literal &path)
+{
+ GtkWidget *widget = gtkWidgetMap()->value(path);
+ if (!widget) {
+ // Theme might have rearranged widget internals
+ widget = gtkWidgetMap()->value(path);
+ }
+ return widget;
+}
+
+GtkStyle* QGtkStylePrivate::gtkStyle(const QHashableLatin1Literal &path)
+{
+ if (GtkWidget *w = gtkWidgetMap()->value(path))
+ return w->style;
+ return 0;
+}
+
+/*! \internal
+ * Get references to gtk functions after we dynamically load the library.
+ */
+void QGtkStylePrivate::resolveGtk() const
+{
+ // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
+ QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
+
+ gtk_init = (Ptr_gtk_init)libgtk.resolve("gtk_init");
+ gtk_window_new = (Ptr_gtk_window_new)libgtk.resolve("gtk_window_new");
+ gtk_style_attach = (Ptr_gtk_style_attach)libgtk.resolve("gtk_style_attach");
+ gtk_widget_destroy = (Ptr_gtk_widget_destroy)libgtk.resolve("gtk_widget_destroy");
+ gtk_widget_realize = (Ptr_gtk_widget_realize)libgtk.resolve("gtk_widget_realize");
+
+ gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
+ gtk_file_filter_new = (Ptr_gtk_file_filter_new)libgtk.resolve("gtk_file_filter_new");
+ gtk_file_filter_set_name = (Ptr_gtk_file_filter_set_name)libgtk.resolve("gtk_file_filter_set_name");
+ gtk_file_filter_add_pattern = (Ptr_gtk_file_filter_add_pattern)libgtk.resolve("gtk_file_filter_add_pattern");
+ gtk_file_chooser_add_filter = (Ptr_gtk_file_chooser_add_filter)libgtk.resolve("gtk_file_chooser_add_filter");
+ gtk_file_chooser_set_filter = (Ptr_gtk_file_chooser_set_filter)libgtk.resolve("gtk_file_chooser_set_filter");
+ gtk_file_chooser_get_filter = (Ptr_gtk_file_chooser_get_filter)libgtk.resolve("gtk_file_chooser_get_filter");
+ gtk_file_chooser_dialog_new = (Ptr_gtk_file_chooser_dialog_new)libgtk.resolve("gtk_file_chooser_dialog_new");
+ gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
+ gtk_file_chooser_get_filename = (Ptr_gtk_file_chooser_get_filename)libgtk.resolve("gtk_file_chooser_get_filename");
+ gtk_file_chooser_get_filenames = (Ptr_gtk_file_chooser_get_filenames)libgtk.resolve("gtk_file_chooser_get_filenames");
+ gtk_file_chooser_set_current_name = (Ptr_gtk_file_chooser_set_current_name)libgtk.resolve("gtk_file_chooser_set_current_name");
+ gtk_dialog_run = (Ptr_gtk_dialog_run)libgtk.resolve("gtk_dialog_run");
+ gtk_file_chooser_set_filename = (Ptr_gtk_file_chooser_set_filename)libgtk.resolve("gtk_file_chooser_set_filename");
+
+ gdk_pixbuf_get_pixels = (Ptr_gdk_pixbuf_get_pixels)libgtk.resolve("gdk_pixbuf_get_pixels");
+ gdk_pixbuf_get_width = (Ptr_gdk_pixbuf_get_width)libgtk.resolve("gdk_pixbuf_get_width");
+ gdk_pixbuf_get_height = (Ptr_gdk_pixbuf_get_height)libgtk.resolve("gdk_pixbuf_get_height");
+ gdk_pixmap_new = (Ptr_gdk_pixmap_new)libgtk.resolve("gdk_pixmap_new");
+ gdk_pixbuf_new = (Ptr_gdk_pixbuf_new)libgtk.resolve("gdk_pixbuf_new");
+ gdk_pixbuf_get_from_drawable = (Ptr_gdk_pixbuf_get_from_drawable)libgtk.resolve("gdk_pixbuf_get_from_drawable");
+ gdk_draw_rectangle = (Ptr_gdk_draw_rectangle)libgtk.resolve("gdk_draw_rectangle");
+ gdk_pixbuf_unref = (Ptr_gdk_pixbuf_unref)libgtk.resolve("gdk_pixbuf_unref");
+ gdk_drawable_unref = (Ptr_gdk_drawable_unref)libgtk.resolve("gdk_drawable_unref");
+ gdk_drawable_get_depth = (Ptr_gdk_drawable_get_depth)libgtk.resolve("gdk_drawable_get_depth");
+ gdk_color_free = (Ptr_gdk_color_free)libgtk.resolve("gdk_color_free");
+ gdk_x11_window_set_user_time = (Ptr_gdk_x11_window_set_user_time)libgtk.resolve("gdk_x11_window_set_user_time");
+ gdk_x11_drawable_get_xid = (Ptr_gdk_x11_drawable_get_xid)libgtk.resolve("gdk_x11_drawable_get_xid");
+ gdk_x11_drawable_get_xdisplay = (Ptr_gdk_x11_drawable_get_xdisplay)libgtk.resolve("gdk_x11_drawable_get_xdisplay");
+
+ gtk_widget_set_default_direction = (Ptr_gtk_widget_set_default_direction)libgtk.resolve("gtk_widget_set_default_direction");
+ gtk_widget_modify_fg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_fg");
+ gtk_widget_modify_bg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_bg");
+ gtk_arrow_new = (Ptr_gtk_arrow_new)libgtk.resolve("gtk_arrow_new");
+ gtk_menu_item_new_with_label = (Ptr_gtk_menu_item_new_with_label)libgtk.resolve("gtk_menu_item_new_with_label");
+ gtk_check_menu_item_new_with_label = (Ptr_gtk_check_menu_item_new_with_label)libgtk.resolve("gtk_check_menu_item_new_with_label");
+ gtk_menu_bar_new = (Ptr_gtk_menu_bar_new)libgtk.resolve("gtk_menu_bar_new");
+ gtk_menu_new = (Ptr_gtk_menu_new)libgtk.resolve("gtk_menu_new");
+ gtk_toolbar_new = (Ptr_gtk_toolbar_new)libgtk.resolve("gtk_toolbar_new");
+ gtk_separator_tool_item_new = (Ptr_gtk_separator_tool_item_new)libgtk.resolve("gtk_separator_tool_item_new");
+ gtk_toolbar_insert = (Ptr_gtk_toolbar_insert)libgtk.resolve("gtk_toolbar_insert");
+ gtk_button_new = (Ptr_gtk_button_new)libgtk.resolve("gtk_button_new");
+ gtk_tool_button_new = (Ptr_gtk_tool_button_new)libgtk.resolve("gtk_tool_button_new");
+ gtk_hbutton_box_new = (Ptr_gtk_hbutton_box_new)libgtk.resolve("gtk_hbutton_box_new");
+ gtk_check_button_new = (Ptr_gtk_check_button_new)libgtk.resolve("gtk_check_button_new");
+ gtk_radio_button_new = (Ptr_gtk_radio_button_new)libgtk.resolve("gtk_radio_button_new");
+ gtk_notebook_new = (Ptr_gtk_notebook_new)libgtk.resolve("gtk_notebook_new");
+ gtk_progress_bar_new = (Ptr_gtk_progress_bar_new)libgtk.resolve("gtk_progress_bar_new");
+ gtk_spin_button_new = (Ptr_gtk_spin_button_new)libgtk.resolve("gtk_spin_button_new");
+ gtk_hscale_new = (Ptr_gtk_hscale_new)libgtk.resolve("gtk_hscale_new");
+ gtk_vscale_new = (Ptr_gtk_vscale_new)libgtk.resolve("gtk_vscale_new");
+ gtk_hscrollbar_new = (Ptr_gtk_hscrollbar_new)libgtk.resolve("gtk_hscrollbar_new");
+ gtk_vscrollbar_new = (Ptr_gtk_vscrollbar_new)libgtk.resolve("gtk_vscrollbar_new");
+ gtk_scrolled_window_new = (Ptr_gtk_scrolled_window_new)libgtk.resolve("gtk_scrolled_window_new");
+ gtk_menu_shell_append = (Ptr_gtk_menu_shell_append)libgtk.resolve("gtk_menu_shell_append");
+ gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new");
+ gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new");
+ gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new");
+ gtk_progress_configure = (Ptr_gtk_progress_configure)libgtk.resolve("gtk_progress_configure");
+ gtk_range_get_adjustment = (Ptr_gtk_range_get_adjustment)libgtk.resolve("gtk_range_get_adjustment");
+ gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment");
+ gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted");
+ gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add");
+ gtk_icon_factory_lookup_default = (Ptr_gtk_icon_factory_lookup_default)libgtk.resolve("gtk_icon_factory_lookup_default");
+ gtk_icon_theme_get_default = (Ptr_gtk_icon_theme_get_default)libgtk.resolve("gtk_icon_theme_get_default");
+ gtk_widget_style_get = (Ptr_gtk_widget_style_get)libgtk.resolve("gtk_widget_style_get");
+ gtk_icon_set_render_icon = (Ptr_gtk_icon_set_render_icon)libgtk.resolve("gtk_icon_set_render_icon");
+ gtk_fixed_new = (Ptr_gtk_fixed_new)libgtk.resolve("gtk_fixed_new");
+ gtk_tree_view_column_new = (Ptr_gtk_tree_view_column_new)libgtk.resolve("gtk_tree_view_column_new");
+ gtk_tree_view_append_column= (Ptr_gtk_tree_view_append_column )libgtk.resolve("gtk_tree_view_append_column");
+ gtk_tree_view_get_column = (Ptr_gtk_tree_view_get_column )libgtk.resolve("gtk_tree_view_get_column");
+ gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
+ gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
+ gtk_paint_flat_box = (Ptr_gtk_paint_flat_box)libgtk.resolve("gtk_paint_flat_box");
+ gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
+ gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
+ gtk_paint_resize_grip = (Ptr_gtk_paint_resize_grip)libgtk.resolve("gtk_paint_resize_grip");
+ gtk_paint_focus = (Ptr_gtk_paint_focus)libgtk.resolve("gtk_paint_focus");
+ gtk_paint_shadow = (Ptr_gtk_paint_shadow)libgtk.resolve("gtk_paint_shadow");
+ gtk_paint_slider = (Ptr_gtk_paint_slider)libgtk.resolve("gtk_paint_slider");
+ gtk_paint_expander = (Ptr_gtk_paint_expander)libgtk.resolve("gtk_paint_expander");
+ gtk_paint_handle = (Ptr_gtk_paint_handle)libgtk.resolve("gtk_paint_handle");
+ gtk_paint_option = (Ptr_gtk_paint_option)libgtk.resolve("gtk_paint_option");
+ gtk_paint_arrow = (Ptr_gtk_paint_arrow)libgtk.resolve("gtk_paint_arrow");
+ gtk_paint_box_gap = (Ptr_gtk_paint_box_gap)libgtk.resolve("gtk_paint_box_gap");
+ gtk_paint_extension = (Ptr_gtk_paint_extension)libgtk.resolve("gtk_paint_extension");
+ gtk_paint_hline = (Ptr_gtk_paint_hline)libgtk.resolve("gtk_paint_hline");
+ gtk_paint_vline = (Ptr_gtk_paint_vline)libgtk.resolve("gtk_paint_vline");
+ gtk_adjustment_configure = (Ptr_gtk_adjustment_configure)libgtk.resolve("gtk_adjustment_configure");
+ gtk_adjustment_new = (Ptr_gtk_adjustment_new)libgtk.resolve("gtk_adjustment_new");
+ gtk_menu_item_set_submenu = (Ptr_gtk_menu_item_set_submenu)libgtk.resolve("gtk_menu_item_set_submenu");
+ gtk_settings_get_default = (Ptr_gtk_settings_get_default)libgtk.resolve("gtk_settings_get_default");
+ gtk_separator_menu_item_new = (Ptr_gtk_separator_menu_item_new)libgtk.resolve("gtk_separator_menu_item_new");
+ gtk_frame_new = (Ptr_gtk_frame_new)libgtk.resolve("gtk_frame_new");
+ gtk_expander_new = (Ptr_gtk_expander_new)libgtk.resolve("gtk_expander_new");
+ gtk_statusbar_new = (Ptr_gtk_statusbar_new)libgtk.resolve("gtk_statusbar_new");
+ gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new");
+ gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall");
+ gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate");
+ gtk_widget_size_request =(Ptr_gtk_widget_size_request)libgtk.resolve("gtk_widget_size_request");
+ gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction");
+ gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path");
+ gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type");
+ gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type");
+ gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type");
+
+ gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths");
+ gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version");
+ gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free");
+ pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size");
+ pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
+ pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
+ pango_font_description_get_style = (Ptr_pango_font_description_get_style)libgtk.resolve("pango_font_description_get_style");
+
+ gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve(QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync");
+ gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve(QLS("gnomevfs-2"), 0, "gnome_vfs_init");
+}
+
+/* \internal
+ * Initializes a number of gtk menu widgets.
+ * The widgets are cached.
+ */
+void QGtkStylePrivate::initGtkMenu() const
+{
+ // Create menubar
+ GtkWidget *gtkMenuBar = QGtkStylePrivate::gtk_menu_bar_new();
+ setupGtkWidget(gtkMenuBar);
+
+ GtkWidget *gtkMenuBarItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
+ gtk_menu_shell_append((GtkMenuShell*)(gtkMenuBar), gtkMenuBarItem);
+ gtk_widget_realize(gtkMenuBarItem);
+
+ // Create menu
+ GtkWidget *gtkMenu = QGtkStylePrivate::gtk_menu_new();
+ gtk_menu_item_set_submenu((GtkMenuItem*)(gtkMenuBarItem), gtkMenu);
+ gtk_widget_realize(gtkMenu);
+
+ GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
+ gtk_widget_realize(gtkMenuItem);
+
+ GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new_with_label("X");
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem);
+ gtk_widget_realize(gtkCheckMenuItem);
+
+ GtkWidget *gtkMenuSeparator = QGtkStylePrivate::gtk_separator_menu_item_new();
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuSeparator);
+
+ addAllSubWidgets(gtkMenuBar);
+ addAllSubWidgets(gtkMenu);
+}
+
+
+void QGtkStylePrivate::initGtkTreeview() const
+{
+ GtkWidget *gtkTreeView = gtk_tree_view_new();
+ gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
+ gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
+ gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
+ addWidget(gtkTreeView);
+}
+
+
+/* \internal
+ * Initializes a number of gtk widgets that we can later on use to determine some of our styles.
+ * The widgets are cached.
+ */
+void QGtkStylePrivate::initGtkWidgets() const
+{
+ // From gtkmain.c
+ uid_t ruid = getuid ();
+ uid_t rgid = getgid ();
+ uid_t euid = geteuid ();
+ uid_t egid = getegid ();
+ if (ruid != euid || rgid != egid) {
+ qWarning("\nThis process is currently running setuid or setgid.\nGTK+ does not allow this "
+ "therefore Qt cannot use the GTK+ integration.\nTry launching your app using \'gksudo\', "
+ "\'kdesudo\' or a similar tool.\n\n"
+ "See http://www.gtk.org/setuid.html for more information.\n");
+ return;
+ }
+
+ static QString themeName;
+ if (!gtkWidgetMap()->contains("GtkWindow") && themeName.isEmpty()) {
+ themeName = getThemeName();
+
+ if (themeName.isEmpty()) {
+ qWarning("QGtkStyle was unable to detect the current GTK+ theme.");
+ return;
+ } else if (themeName == QLS("Qt") || themeName == QLS("Qt4")) {
+ // Due to namespace conflicts with Qt3 and obvious recursion with Qt4,
+ // we cannot support the GTK_Qt Gtk engine
+ qWarning("QGtkStyle cannot be used together with the GTK_Qt engine.");
+ return;
+ }
+ }
+
+ if (QGtkStylePrivate::gtk_init) {
+ // Gtk will set the Qt error handler so we have to reset it afterwards
+ x11ErrorHandler qt_x_errhandler = XSetErrorHandler(0);
+ QGtkStylePrivate::gtk_init (NULL, NULL);
+ XSetErrorHandler(qt_x_errhandler);
+
+ // make a window
+ GtkWidget* gtkWindow = QGtkStylePrivate::gtk_window_new(GTK_WINDOW_POPUP);
+ QGtkStylePrivate::gtk_widget_realize(gtkWindow);
+ if (displayDepth == -1)
+ displayDepth = QGtkStylePrivate::gdk_drawable_get_depth(gtkWindow->window);
+ QHashableLatin1Literal widgetPath = QHashableLatin1Literal::fromData(strdup("GtkWindow"));
+ removeWidgetFromMap(widgetPath);
+ gtkWidgetMap()->insert(widgetPath, gtkWindow);
+
+
+ // Make all other widgets. respect the text direction
+ if (qApp->layoutDirection() == Qt::RightToLeft)
+ QGtkStylePrivate::gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
+
+ if (!gtkWidgetMap()->contains("GtkButton")) {
+ GtkWidget *gtkButton = QGtkStylePrivate::gtk_button_new();
+ addWidget(gtkButton);
+ g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0);
+ addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, "Qt"));
+ addWidget(QGtkStylePrivate::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
+ addWidget(QGtkStylePrivate::gtk_hbutton_box_new());
+ addWidget(QGtkStylePrivate::gtk_check_button_new());
+ addWidget(QGtkStylePrivate::gtk_radio_button_new(NULL));
+ addWidget(QGtkStylePrivate::gtk_combo_box_new());
+ addWidget(QGtkStylePrivate::gtk_combo_box_entry_new());
+ addWidget(QGtkStylePrivate::gtk_entry_new());
+ addWidget(QGtkStylePrivate::gtk_frame_new(NULL));
+ addWidget(QGtkStylePrivate::gtk_expander_new(""));
+ addWidget(QGtkStylePrivate::gtk_statusbar_new());
+ addWidget(QGtkStylePrivate::gtk_hscale_new((GtkAdjustment*)(QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
+ addWidget(QGtkStylePrivate::gtk_hscrollbar_new(NULL));
+ addWidget(QGtkStylePrivate::gtk_scrolled_window_new(NULL, NULL));
+
+ initGtkMenu();
+ addWidget(QGtkStylePrivate::gtk_notebook_new());
+ addWidget(QGtkStylePrivate::gtk_progress_bar_new());
+ addWidget(QGtkStylePrivate::gtk_spin_button_new((GtkAdjustment*)
+ (QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0)), 0.1, 3));
+ GtkWidget *toolbar = gtk_toolbar_new();
+ g_signal_connect (toolbar, "notify::toolbar-style", G_CALLBACK (update_toolbar_style), toolbar);
+ gtk_toolbar_insert((GtkToolbar*)toolbar, gtk_separator_tool_item_new(), -1);
+ addWidget(toolbar);
+ initGtkTreeview();
+ addWidget(gtk_vscale_new((GtkAdjustment*)(QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
+ addWidget(gtk_vscrollbar_new(NULL));
+ }
+ else // Rebuild map
+ {
+ // When styles change subwidgets can get rearranged
+ // as with the combo box. We need to update the widget map
+ // to reflect this;
+ QHash<QHashableLatin1Literal, GtkWidget*> oldMap = *gtkWidgetMap();
+ gtkWidgetMap()->clear();
+ QHashIterator<QHashableLatin1Literal, GtkWidget*> it(oldMap);
+ while (it.hasNext()) {
+ it.next();
+ if (!strchr(it.key().data(), '.')) {
+ addAllSubWidgets(it.value());
+ }
+ free(const_cast<char *>(it.key().data()));
+ }
+ }
+ } else {
+ qWarning("QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries.");
+ }
+}
+
+/*! \internal
+ * destroys all previously buffered widgets.
+ */
+void QGtkStylePrivate::cleanupGtkWidgets()
+{
+ if (!widgetMap)
+ return;
+ if (widgetMap->contains("GtkWindow")) // Gtk will destroy all children
+ gtk_widget_destroy(widgetMap->value("GtkWindow"));
+ for (QHash<QHashableLatin1Literal, GtkWidget *>::const_iterator it = widgetMap->constBegin();
+ it != widgetMap->constEnd(); ++it)
+ free(const_cast<char *>(it.key().data()));
+}
+
+static bool resolveGConf()
+{
+ if (!QGtkStylePrivate::gconf_client_get_default) {
+ QGtkStylePrivate::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default");
+ QGtkStylePrivate::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string");
+ QGtkStylePrivate::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool");
+ }
+ return (QGtkStylePrivate::gconf_client_get_default !=0);
+}
+
+QString QGtkStylePrivate::getGConfString(const QString &value, const QString &fallback)
+{
+ QString retVal = fallback;
+ if (resolveGConf()) {
+ g_type_init();
+ GConfClient* client = gconf_client_get_default();
+ GError *err = 0;
+ char *str = gconf_client_get_string(client, qPrintable(value), &err);
+ if (!err) {
+ retVal = QString::fromUtf8(str);
+ g_free(str);
+ }
+ g_object_unref(client);
+ if (err)
+ g_error_free (err);
+ }
+ return retVal;
+}
+
+bool QGtkStylePrivate::getGConfBool(const QString &key, bool fallback)
+{
+ bool retVal = fallback;
+ if (resolveGConf()) {
+ g_type_init();
+ GConfClient* client = gconf_client_get_default();
+ GError *err = 0;
+ bool result = gconf_client_get_bool(client, qPrintable(key), &err);
+ g_object_unref(client);
+ if (!err)
+ retVal = result;
+ else
+ g_error_free (err);
+ }
+ return retVal;
+}
+
+QString QGtkStylePrivate::getThemeName()
+{
+ QString themeName;
+ // We try to parse the gtkrc file first
+ // primarily to avoid resolving Gtk functions if
+ // the KDE 3 "Qt" style is currently in use
+ QString rcPaths = QString::fromLocal8Bit(qgetenv("GTK2_RC_FILES"));
+ if (!rcPaths.isEmpty()) {
+ QStringList paths = rcPaths.split(QLS(":"));
+ foreach (const QString &rcPath, paths) {
+ if (!rcPath.isEmpty()) {
+ QFile rcFile(rcPath);
+ if (rcFile.exists() && rcFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&rcFile);
+ while(!in.atEnd()) {
+ QString line = in.readLine();
+ if (line.contains(QLS("gtk-theme-name"))) {
+ line = line.right(line.length() - line.indexOf(QLatin1Char('=')) - 1);
+ line.remove(QLatin1Char('\"'));
+ line = line.trimmed();
+ themeName = line;
+ break;
+ }
+ }
+ }
+ }
+ if (!themeName.isEmpty())
+ break;
+ }
+ }
+
+ // Fall back to gconf
+ if (themeName.isEmpty() && resolveGConf())
+ themeName = getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
+
+ return themeName;
+}
+
+// Get size of the arrow controls in a GtkSpinButton
+int QGtkStylePrivate::getSpinboxArrowSize() const
+{
+ const int MIN_ARROW_WIDTH = 6;
+ GtkWidget *spinButton = gtkWidget("GtkSpinButton");
+ GtkStyle *style = spinButton->style;
+ gint size = pango_font_description_get_size (style->font_desc);
+ gint arrow_size;
+ arrow_size = qMax(PANGO_PIXELS (size), MIN_ARROW_WIDTH) + style->xthickness;
+ arrow_size += arrow_size%2 + 1;
+ return arrow_size;
+}
+
+
+bool QGtkStylePrivate::isKDE4Session()
+{
+ static int version = -1;
+ if (version == -1)
+ version = qgetenv("KDE_SESSION_VERSION").toInt();
+ return (version == 4);
+}
+
+void QGtkStylePrivate::applyCustomPaletteHash()
+{
+ QPalette menuPal = gtkWidgetPalette("GtkMenu");
+ GdkColor gdkBg = gtkWidget("GtkMenu")->style->bg[GTK_STATE_NORMAL];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ menuPal.setBrush(QPalette::Base, bgColor);
+ menuPal.setBrush(QPalette::Window, bgColor);
+ qApp->setPalette(menuPal, "QMenu");
+
+ QPalette toolbarPal = gtkWidgetPalette("GtkToolbar");
+ qApp->setPalette(toolbarPal, "QToolBar");
+
+ QPalette menuBarPal = gtkWidgetPalette("GtkMenuBar");
+ qApp->setPalette(menuBarPal, "QMenuBar");
+}
+
+/*! \internal
+ * Returns the gtk Widget that should be used to determine text foreground and background colors.
+*/
+GtkWidget* QGtkStylePrivate::getTextColorWidget() const
+{
+ return gtkWidget("GtkEntry");
+}
+
+void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget)
+{
+ if (Q_GTK_IS_WIDGET(widget)) {
+ static GtkWidget* protoLayout = 0;
+ if (!protoLayout) {
+ protoLayout = QGtkStylePrivate::gtk_fixed_new();
+ QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value("GtkWindow")), protoLayout);
+ }
+ Q_ASSERT(protoLayout);
+
+ if (!widget->parent && !GTK_WIDGET_TOPLEVEL(widget))
+ QGtkStylePrivate::gtk_container_add((GtkContainer*)(protoLayout), widget);
+ QGtkStylePrivate::gtk_widget_realize(widget);
+ }
+}
+
+void QGtkStylePrivate::removeWidgetFromMap(const QHashableLatin1Literal &path)
+{
+ WidgetMap *map = gtkWidgetMap();
+ WidgetMap::iterator it = map->find(path);
+ if (it != map->end()) {
+ free(const_cast<char *>(it.key().data()));
+ map->erase(it);
+ }
+}
+
+void QGtkStylePrivate::addWidgetToMap(GtkWidget *widget)
+{
+ if (Q_GTK_IS_WIDGET(widget)) {
+ gtk_widget_realize(widget);
+ QHashableLatin1Literal widgetPath = classPath(widget);
+
+ removeWidgetFromMap(widgetPath);
+ gtkWidgetMap()->insert(widgetPath, widget);
+#ifdef DUMP_GTK_WIDGET_TREE
+ qWarning("Inserted Gtk Widget: %s", widgetPath.data());
+#endif
+ }
+ }
+
+void QGtkStylePrivate::addAllSubWidgets(GtkWidget *widget, gpointer v)
+{
+ Q_UNUSED(v);
+ addWidgetToMap(widget);
+ if (GTK_CHECK_TYPE ((widget), gtk_container_get_type()))
+ gtk_container_forall((GtkContainer*)widget, addAllSubWidgets, NULL);
+}
+
+// Updates window/windowtext palette based on the indicated gtk widget
+QPalette QGtkStylePrivate::gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const
+{
+ GtkWidget *gtkWidget = QGtkStylePrivate::gtkWidget(gtkWidgetName);
+ Q_ASSERT(gtkWidget);
+ QPalette pal = QApplication::palette();
+ GdkColor gdkBg = gtkWidget->style->bg[GTK_STATE_NORMAL];
+ GdkColor gdkText = gtkWidget->style->fg[GTK_STATE_NORMAL];
+ GdkColor gdkDisabledText = gtkWidget->style->fg[GTK_STATE_INSENSITIVE];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ QColor textColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ QColor disabledTextColor(gdkDisabledText.red>>8, gdkDisabledText.green>>8, gdkDisabledText.blue>>8);
+ pal.setBrush(QPalette::Window, bgColor);
+ pal.setBrush(QPalette::Button, bgColor);
+ pal.setBrush(QPalette::All, QPalette::WindowText, textColor);
+ pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor);
+ pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
+ pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor);
+ return pal;
+}
+
+
+void QGtkStyleUpdateScheduler::updateTheme()
+{
+ static QString oldTheme(QLS("qt_not_set"));
+ QPixmapCache::clear();
+
+ QFont font = QGtkStylePrivate::getThemeFont();
+ if (QApplication::font() != font)
+ qApp->setFont(font);
+
+ if (oldTheme != QGtkStylePrivate::getThemeName()) {
+ oldTheme = QGtkStylePrivate::getThemeName();
+ QPalette newPalette = qApp->style()->standardPalette();
+ QApplicationPrivate::setSystemPalette(newPalette);
+ QApplication::setPalette(newPalette);
+ if (!QGtkStylePrivate::instances.isEmpty()) {
+ QGtkStylePrivate::instances.last()->initGtkWidgets();
+ QGtkStylePrivate::instances.last()->applyCustomPaletteHash();
+ }
+ QList<QWidget*> widgets = QApplication::allWidgets();
+ // Notify all widgets that size metrics might have changed
+ foreach (QWidget *widget, widgets) {
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &e);
+ }
+ }
+ QIconLoader::instance()->updateSystemTheme();
+}
+
+void QGtkStylePrivate::addWidget(GtkWidget *widget)
+{
+ if (widget) {
+ setupGtkWidget(widget);
+ addAllSubWidgets(widget);
+ }
+}
+
+
+// Fetch the application font from the pango font description
+// contained in the theme.
+QFont QGtkStylePrivate::getThemeFont()
+{
+ QFont font;
+ GtkStyle *style = gtkStyle();
+ if (style && qApp->desktopSettingsAware())
+ {
+ PangoFontDescription *gtk_font = style->font_desc;
+ font.setPointSizeF((float)(pango_font_description_get_size(gtk_font))/PANGO_SCALE);
+
+ QString family = QString::fromLatin1(pango_font_description_get_family(gtk_font));
+ if (!family.isEmpty())
+ font.setFamily(family);
+
+ int weight = pango_font_description_get_weight(gtk_font);
+ if (weight >= PANGO_WEIGHT_HEAVY)
+ font.setWeight(QFont::Black);
+ else if (weight >= PANGO_WEIGHT_BOLD)
+ font.setWeight(QFont::Bold);
+ else if (weight >= PANGO_WEIGHT_SEMIBOLD)
+ font.setWeight(QFont::DemiBold);
+ else if (weight >= PANGO_WEIGHT_NORMAL)
+ font.setWeight(QFont::Normal);
+ else
+ font.setWeight(QFont::Light);
+
+ PangoStyle fontstyle = pango_font_description_get_style(gtk_font);
+ if (fontstyle == PANGO_STYLE_ITALIC)
+ font.setStyle(QFont::StyleItalic);
+ else if (fontstyle == PANGO_STYLE_OBLIQUE)
+ font.setStyle(QFont::StyleOblique);
+ else
+ font.setStyle(QFont::StyleNormal);
+ }
+ return font;
+}
+
+
+// ----------- Native file dialogs -----------
+
+// Extract filter list from expressions of type: foo (*.a *.b *.c)"
+QStringList QGtkStylePrivate::extract_filter(const QString &rawFilter)
+{
+ QString result = rawFilter;
+ QRegExp r(QString::fromLatin1("^([^()]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"));
+ int index = r.indexIn(result);
+ if (index >= 0)
+ result = r.cap(2);
+ return result.split(QLatin1Char(' '));
+}
+
+extern QStringList qt_make_filter_list(const QString &filter);
+
+void QGtkStylePrivate::setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
+ const QString &dir, const QString &filter, QString *selectedFilter,
+ QFileDialog::Options options, bool isSaveDialog,
+ QMap<GtkFileFilter *, QString> *filterMap)
+{
+ g_object_set(gtkFileChooser, "do-overwrite-confirmation", gboolean(!(options & QFileDialog::DontConfirmOverwrite)), NULL);
+ g_object_set(gtkFileChooser, "local_only", gboolean(true), NULL);
+ if (!filter.isEmpty()) {
+ QStringList filters = qt_make_filter_list(filter);
+ foreach (const QString &rawfilter, filters) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_filter_new ();
+ QString name = rawfilter.left(rawfilter.indexOf(QLatin1Char('(')));
+ QStringList extensions = extract_filter(rawfilter);
+ QGtkStylePrivate::gtk_file_filter_set_name(gtkFilter, qPrintable(name.isEmpty() ? extensions.join(QLS(", ")) : name));
+
+ foreach (const QString &fileExtension, extensions) {
+ // Note Gtk file dialogs are by default case sensitive
+ // and only supports basic glob syntax so we
+ // rewrite .xyz to .[xX][yY][zZ]
+ QString caseInsensitive;
+ for (int i = 0 ; i < fileExtension.length() ; ++i) {
+ QChar ch = fileExtension.at(i);
+ if (ch.isLetter()) {
+ caseInsensitive.append(
+ QLatin1Char('[') +
+ ch.toLower() +
+ ch.toUpper() +
+ QLatin1Char(']'));
+ } else {
+ caseInsensitive.append(ch);
+ }
+ }
+ QGtkStylePrivate::gtk_file_filter_add_pattern (gtkFilter, qPrintable(caseInsensitive));
+
+ }
+ if (filterMap)
+ filterMap->insert(gtkFilter, rawfilter);
+ QGtkStylePrivate::gtk_file_chooser_add_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
+ if (selectedFilter && (rawfilter == *selectedFilter))
+ QGtkStylePrivate::gtk_file_chooser_set_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
+ }
+ }
+
+ // Using the currently active window is not entirely correct, however
+ // it gives more sensible behavior for applications that do not provide a
+ // parent
+ QWidget *modalFor = parent ? parent->window() : qApp->activeWindow();
+ if (modalFor) {
+ QGtkStylePrivate::gtk_widget_realize(gtkFileChooser); // Creates X window
+ XSetTransientForHint(QGtkStylePrivate::gdk_x11_drawable_get_xdisplay(gtkFileChooser->window),
+ QGtkStylePrivate::gdk_x11_drawable_get_xid(gtkFileChooser->window),
+ modalFor->winId());
+ QGtkStylePrivate::gdk_x11_window_set_user_time (gtkFileChooser->window, QX11Info::appUserTime());
+
+ }
+
+ QFileInfo fileinfo(dir);
+ if (dir.isEmpty())
+ fileinfo.setFile(QDir::currentPath());
+ fileinfo.makeAbsolute();
+ if (fileinfo.isDir()) {
+ QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
+ } else if (isSaveDialog) {
+ QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.absolutePath()));
+ QGtkStylePrivate::gtk_file_chooser_set_current_name((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.fileName()));
+ } else {
+ QGtkStylePrivate::gtk_file_chooser_set_filename((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
+ }
+}
+
+QString QGtkStylePrivate::openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options)
+{
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
+
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString filename;
+ if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
+ filename = QString::fromUtf8(gtk_filename);
+ g_free (gtk_filename);
+ if (selectedFilter) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
+ *selectedFilter = filterMap.value(gtkFilter);
+ }
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filename;
+}
+
+
+QString QGtkStylePrivate::openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
+{
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ setupGtkFileChooser(gtkFileChooser, parent, dir, QString(), 0, options);
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString filename;
+ if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
+ filename = QString::fromUtf8(gtk_filename);
+ g_free (gtk_filename);
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filename;
+}
+
+QStringList QGtkStylePrivate::openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options)
+{
+ QStringList filenames;
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
+ g_object_set(gtkFileChooser, "select-multiple", gboolean(true), NULL);
+
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ if (gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ GSList *gtk_file_names = QGtkStylePrivate::gtk_file_chooser_get_filenames((GtkFileChooser*)gtkFileChooser);
+ for (GSList *iterator = gtk_file_names ; iterator; iterator = iterator->next)
+ filenames << QString::fromUtf8((const char*)iterator->data);
+ g_slist_free(gtk_file_names);
+ if (selectedFilter) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
+ *selectedFilter = filterMap.value(gtkFilter);
+ }
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filenames;
+}
+
+QString QGtkStylePrivate::saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options)
+{
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, true, &filterMap);
+
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString filename;
+ if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
+ filename = QString::fromUtf8(gtk_filename);
+ g_free (gtk_filename);
+ if (selectedFilter) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
+ *selectedFilter = filterMap.value(gtkFilter);
+ }
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filename;
+}
+
+QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
+{
+ QIcon icon;
+ if (gnome_vfs_init && gnome_icon_lookup_sync) {
+ gnome_vfs_init();
+ GtkIconTheme *theme = gtk_icon_theme_get_default();
+ QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
+ char * icon_name = gnome_icon_lookup_sync(theme,
+ NULL,
+ fileurl.data(),
+ NULL,
+ GNOME_ICON_LOOKUP_FLAGS_NONE,
+ NULL);
+ QString iconName = QString::fromUtf8(icon_name);
+ g_free(icon_name);
+ if (iconName.startsWith(QLatin1Char('/')))
+ return QIcon(iconName);
+ return QIcon::fromTheme(iconName);
+ }
+ return icon;
+}
+
+bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2)
+{
+ return l1.size() == l2.size() || qstrcmp(l1.data(), l2.data()) == 0;
+}
+
+// copied from qHash.cpp
+uint qHash(const QHashableLatin1Literal &key)
+{
+ int n = key.size();
+ const uchar *p = reinterpret_cast<const uchar *>(key.data());
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + *p++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/widgets/styles/qgtkstyle_p.h b/src/widgets/styles/qgtkstyle_p.h
new file mode 100644
index 0000000000..07d2a503de
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle_p.h
@@ -0,0 +1,531 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGTKSTYLE_P_H
+#define QGTKSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <QtCore/qstring.h>
+#include <QtCore/qstringbuilder.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QtWidgets/QFileDialog>
+
+#include <QtWidgets/QGtkStyle>
+#include <private/qcleanlooksstyle_p.h>
+
+#undef signals // Collides with GTK stymbols
+#include <gtk/gtk.h>
+
+typedef unsigned long XID;
+
+#undef GTK_OBJECT_FLAGS
+#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
+#define Q_GTK_IS_WIDGET(widget) widget && GTK_CHECK_TYPE ((widget), QGtkStylePrivate::gtk_widget_get_type())
+
+#define QLS(x) QLatin1String(x)
+
+QT_BEGIN_NAMESPACE
+
+// ### Qt 4.7 - merge with QLatin1Literal
+class QHashableLatin1Literal
+{
+public:
+ int size() const { return m_size; }
+ const char *data() const { return m_data; }
+
+#ifdef __SUNPRO_CC
+ QHashableLatin1Literal(const char* str)
+ : m_size(strlen(str)), m_data(str) {}
+#else
+ template <int N>
+ QHashableLatin1Literal(const char (&str)[N])
+ : m_size(N - 1), m_data(str) {}
+#endif
+
+ QHashableLatin1Literal(const QHashableLatin1Literal &other)
+ : m_size(other.m_size), m_data(other.m_data)
+ {}
+
+ QHashableLatin1Literal &operator=(const QHashableLatin1Literal &other)
+ {
+ if (this == &other)
+ return *this;
+ *const_cast<int *>(&m_size) = other.m_size;
+ *const_cast<char **>(&m_data) = const_cast<char *>(other.m_data);
+ return *this;
+ }
+
+ QString toString() const { return QString::fromLatin1(m_data, m_size); }
+
+ static QHashableLatin1Literal fromData(const char *str)
+ {
+ return QHashableLatin1Literal(str, qstrlen(str));
+ }
+
+private:
+ QHashableLatin1Literal(const char *str, int length)
+ : m_size(length), m_data(str)
+ {}
+
+ const int m_size;
+ const char *m_data;
+};
+
+bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2);
+inline bool operator!=(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2) { return !operator==(l1, l2); }
+uint qHash(const QHashableLatin1Literal &key);
+
+QT_END_NAMESPACE
+
+class GConf;
+class GConfClient;
+
+typedef GConfClient* (*Ptr_gconf_client_get_default)();
+typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
+typedef bool (*Ptr_gconf_client_get_bool)(GConfClient*, const char*, GError **);
+
+typedef void (*Ptr_gtk_init)(int *, char ***);
+typedef GtkWidget* (*Ptr_gtk_window_new) (GtkWindowType);
+typedef GtkStyle* (*Ptr_gtk_style_attach)(GtkStyle *, GdkWindow *);
+typedef void (*Ptr_gtk_widget_destroy) (GtkWidget *);
+typedef void (*Ptr_gtk_widget_realize) (GtkWidget *);
+typedef void (*Ptr_gtk_widget_set_default_direction) (GtkTextDirection);
+typedef void (*Ptr_gtk_widget_modify_color)(GtkWidget *widget, GtkStateType state, const GdkColor *color);
+typedef GtkWidget* (*Ptr_gtk_arrow_new)(GtkArrowType, GtkShadowType);
+typedef GtkWidget* (*Ptr_gtk_menu_item_new_with_label)(const gchar *);
+typedef GtkWidget* (*Ptr_gtk_separator_menu_item_new)(void);
+typedef GtkWidget* (*Ptr_gtk_check_menu_item_new_with_label)(const gchar *);
+typedef GtkWidget* (*Ptr_gtk_menu_bar_new)(void);
+typedef GtkWidget* (*Ptr_gtk_menu_new)(void);
+typedef GtkWidget* (*Ptr_gtk_combo_box_entry_new)(void);
+typedef GtkWidget* (*Ptr_gtk_toolbar_new)(void);
+typedef GtkWidget* (*Ptr_gtk_spin_button_new)(GtkAdjustment*, double, int);
+typedef GtkWidget* (*Ptr_gtk_button_new)(void);
+typedef GtkWidget* (*Ptr_gtk_tool_button_new)(GtkWidget *, const gchar *);
+typedef GtkWidget* (*Ptr_gtk_hbutton_box_new)(void);
+typedef GtkWidget* (*Ptr_gtk_check_button_new)(void);
+typedef GtkWidget* (*Ptr_gtk_radio_button_new)(GSList *);
+typedef GtkWidget* (*Ptr_gtk_notebook_new)(void);
+typedef GtkWidget* (*Ptr_gtk_progress_bar_new)(void);
+typedef GtkWidget* (*Ptr_gtk_hscale_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_vscale_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_hscrollbar_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_vscrollbar_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_scrolled_window_new)(GtkAdjustment*, GtkAdjustment*);
+typedef gchar* (*Ptr_gtk_check_version)(guint, guint, guint);
+typedef GtkToolItem* (*Ptr_gtk_separator_tool_item_new) (void);
+typedef GtkWidget* (*Ptr_gtk_entry_new)(void);
+typedef GtkWidget* (*Ptr_gtk_tree_view_new)(void);
+typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_get_column)(GtkTreeView *, gint);
+typedef GtkWidget* (*Ptr_gtk_combo_box_new)(void);
+typedef GtkWidget* (*Ptr_gtk_frame_new)(const gchar *);
+typedef GtkWidget* (*Ptr_gtk_expander_new)(const gchar*);
+typedef GtkWidget* (*Ptr_gtk_statusbar_new)(void);
+typedef GtkSettings* (*Ptr_gtk_settings_get_default)(void);
+typedef GtkAdjustment* (*Ptr_gtk_range_get_adjustment)(GtkRange *);
+typedef void (*Ptr_gtk_range_set_adjustment)(GtkRange *, GtkAdjustment *);
+typedef void (*Ptr_gtk_progress_configure)(GtkProgress *, double, double, double);
+typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool);
+typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget);
+typedef GtkIconSet* (*Ptr_gtk_icon_factory_lookup_default) (const gchar*);
+typedef GtkIconTheme* (*Ptr_gtk_icon_theme_get_default) (void);
+typedef void (*Ptr_gtk_widget_style_get)(GtkWidget *, const gchar *first_property_name, ...);
+typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_column_new)(void);
+typedef GtkWidget* (*Ptr_gtk_fixed_new)(void);
+typedef GdkPixbuf* (*Ptr_gtk_icon_set_render_icon)(GtkIconSet *, GtkStyle *, GtkTextDirection, GtkStateType, GtkIconSize, GtkWidget *,const char *);
+typedef void (*Ptr_gtk_tree_view_append_column) (GtkTreeView*, GtkTreeViewColumn*);
+typedef void (*Ptr_gtk_paint_check) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_box_gap) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint , gint, GtkPositionType, gint gap_x, gint gap_width);
+typedef void (*Ptr_gtk_paint_resize_grip) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, GdkWindowEdge, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_focus) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_shadow) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_slider) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
+typedef void (*Ptr_gtk_paint_expander) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , GtkExpanderStyle );
+typedef void (*Ptr_gtk_paint_handle) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
+typedef void (*Ptr_gtk_paint_arrow) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, GtkArrowType, gboolean, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_option) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_flat_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_extension) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint, gint, GtkPositionType);
+typedef void (*Ptr_gtk_adjustment_configure) (GtkAdjustment *, double, double, double, double, double, double);
+typedef GtkObject* (*Ptr_gtk_adjustment_new) (double, double, double, double, double, double);
+typedef void (*Ptr_gtk_paint_hline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint y);
+typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint);
+typedef void (*Ptr_gtk_menu_item_set_submenu) (GtkMenuItem *, GtkWidget *);
+typedef void (*Ptr_gtk_container_forall) (GtkContainer *, GtkCallback, gpointer);
+typedef void (*Ptr_gtk_widget_size_allocate) (GtkWidget *, GtkAllocation*);
+typedef void (*Ptr_gtk_widget_size_request) (GtkWidget *widget, GtkRequisition *requisition);
+typedef void (*Ptr_gtk_widget_set_direction) (GtkWidget *, GtkTextDirection);
+typedef void (*Ptr_gtk_widget_path) (GtkWidget *, guint *, gchar **, gchar**);
+
+typedef void (*Ptr_gtk_toolbar_insert) (GtkToolbar *toolbar, GtkToolItem *item, int pos);
+typedef void (*Ptr_gtk_menu_shell_append)(GtkMenuShell *, GtkWidget *);
+typedef GtkType (*Ptr_gtk_container_get_type) (void);
+typedef GtkType (*Ptr_gtk_window_get_type) (void);
+typedef GtkType (*Ptr_gtk_widget_get_type) (void);
+typedef GtkStyle* (*Ptr_gtk_rc_get_style_by_paths) (GtkSettings *, const char *, const char *, GType);
+typedef gint (*Ptr_pango_font_description_get_size) (const PangoFontDescription *);
+typedef PangoWeight (*Ptr_pango_font_description_get_weight) (const PangoFontDescription *);
+typedef const char* (*Ptr_pango_font_description_get_family) (const PangoFontDescription *);
+typedef PangoStyle (*Ptr_pango_font_description_get_style) (const PangoFontDescription *desc);
+typedef gboolean (*Ptr_gtk_file_chooser_set_current_folder)(GtkFileChooser *, const gchar *);
+typedef GtkFileFilter* (*Ptr_gtk_file_filter_new)(void);
+typedef void (*Ptr_gtk_file_filter_set_name)(GtkFileFilter *, const gchar *);
+typedef void (*Ptr_gtk_file_filter_add_pattern)(GtkFileFilter *filter, const gchar *pattern);
+typedef void (*Ptr_gtk_file_chooser_add_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
+typedef void (*Ptr_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
+typedef GtkFileFilter* (*Ptr_gtk_file_chooser_get_filter)(GtkFileChooser *chooser);
+typedef gchar* (*Ptr_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
+typedef GSList* (*Ptr_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+typedef GtkWidget* (*Ptr_gtk_file_chooser_dialog_new)(const gchar *title,
+ GtkWindow *parent,
+ GtkFileChooserAction action,
+ const gchar *first_button_text,
+ ...);
+typedef void (*Ptr_gtk_file_chooser_set_current_name) (GtkFileChooser *, const gchar *);
+typedef gboolean (*Ptr_gtk_file_chooser_set_filename) (GtkFileChooser *chooser, const gchar *name);
+typedef gint (*Ptr_gtk_dialog_run) (GtkDialog*);
+typedef void (*Ptr_gtk_border_free)(GtkBorder *);
+
+typedef guchar* (*Ptr_gdk_pixbuf_get_pixels) (const GdkPixbuf *pixbuf);
+typedef int (*Ptr_gdk_pixbuf_get_width) (const GdkPixbuf *pixbuf);
+typedef void (*Ptr_gdk_color_free) (const GdkColor *);
+typedef int (*Ptr_gdk_pixbuf_get_height) (const GdkPixbuf *pixbuf);
+typedef GdkPixbuf* (*Ptr_gdk_pixbuf_get_from_drawable) (GdkPixbuf *dest, GdkDrawable *src,
+ GdkColormap *cmap, int src_x,
+ int src_y, int dest_x, int dest_y,
+ int width, int height);
+typedef GdkPixmap* (*Ptr_gdk_pixmap_new) (GdkDrawable *drawable, gint width, gint height, gint depth);
+typedef GdkPixbuf* (*Ptr_gdk_pixbuf_new) (GdkColorspace colorspace, gboolean has_alpha,
+ int bits_per_sample, int width, int height);
+typedef void (*Ptr_gdk_draw_rectangle) (GdkDrawable *drawable, GdkGC *gc,
+ gboolean filled, gint x, gint y, gint width, gint height);
+typedef void (*Ptr_gdk_pixbuf_unref)(GdkPixbuf *);
+typedef void (*Ptr_gdk_drawable_unref)(GdkDrawable *);
+typedef gint (*Ptr_gdk_drawable_get_depth)(GdkDrawable *);
+typedef void (*Ptr_gdk_x11_window_set_user_time) (GdkWindow *window, guint32);
+typedef XID (*Ptr_gdk_x11_drawable_get_xid) (GdkDrawable *);
+typedef Display* (*Ptr_gdk_x11_drawable_get_xdisplay) ( GdkDrawable *);
+
+
+QT_BEGIN_NAMESPACE
+
+typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+typedef QString (*_qt_filedialog_open_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+typedef QString (*_qt_filedialog_save_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir,
+ QFileDialog::Options options);
+
+extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
+extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
+extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
+extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
+
+class QGtkStylePrivate;
+
+class QGtkStyleFilter : public QObject
+{
+public:
+ QGtkStyleFilter(QGtkStylePrivate* sp)
+ : stylePrivate(sp)
+ {}
+private:
+ QGtkStylePrivate* stylePrivate;
+ bool eventFilter(QObject *obj, QEvent *e);
+};
+
+typedef enum {
+ GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
+ GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
+ GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
+ GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
+} GnomeIconLookupFlags;
+
+typedef enum {
+ GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0,
+ GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0
+} GnomeIconLookupResultFlags;
+
+struct GnomeThumbnailFactory;
+typedef gboolean (*Ptr_gnome_vfs_init) (void);
+typedef char* (*Ptr_gnome_icon_lookup_sync) (
+ GtkIconTheme *icon_theme,
+ GnomeThumbnailFactory *,
+ const char *file_uri,
+ const char *custom_icon,
+ GnomeIconLookupFlags flags,
+ GnomeIconLookupResultFlags *result);
+
+class QGtkStylePrivate : public QCleanlooksStylePrivate
+{
+ Q_DECLARE_PUBLIC(QGtkStyle)
+public:
+ QGtkStylePrivate();
+ ~QGtkStylePrivate();
+
+ QGtkStyleFilter filter;
+
+ static GtkWidget* gtkWidget(const QHashableLatin1Literal &path);
+ static GtkStyle* gtkStyle(const QHashableLatin1Literal &path = QHashableLatin1Literal("GtkWindow"));
+
+ virtual void resolveGtk() const;
+ virtual void initGtkMenu() const;
+ virtual void initGtkTreeview() const;
+ virtual void initGtkWidgets() const;
+
+ static void cleanupGtkWidgets();
+
+ static bool isKDE4Session();
+ void applyCustomPaletteHash();
+ static QFont getThemeFont();
+ static bool isThemeAvailable() { return gtkStyle() != 0; }
+
+ static bool getGConfBool(const QString &key, bool fallback = 0);
+ static QString getGConfString(const QString &key, const QString &fallback = QString());
+
+ static QString getThemeName();
+ virtual int getSpinboxArrowSize() const;
+
+ static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
+ const QString &dir, const QString &filter, QString *selectedFilter,
+ QFileDialog::Options options, bool isSaveDialog = false,
+ QMap<GtkFileFilter *, QString> *filterMap = 0);
+
+ static QString openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options);
+ static QString saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options);
+ static QString openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
+ static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options);
+ static QIcon getFilesystemIcon(const QFileInfo &);
+
+ static Ptr_gtk_container_forall gtk_container_forall;
+ static Ptr_gtk_init gtk_init;
+ static Ptr_gtk_style_attach gtk_style_attach;
+ static Ptr_gtk_window_new gtk_window_new;
+ static Ptr_gtk_widget_destroy gtk_widget_destroy;
+ static Ptr_gtk_widget_realize gtk_widget_realize;
+ static Ptr_gtk_widget_set_default_direction gtk_widget_set_default_direction;
+ static Ptr_gtk_widget_modify_color gtk_widget_modify_fg;
+ static Ptr_gtk_widget_modify_color gtk_widget_modify_bg;
+ static Ptr_gtk_menu_item_new_with_label gtk_menu_item_new_with_label;
+ static Ptr_gtk_arrow_new gtk_arrow_new;
+ static Ptr_gtk_check_menu_item_new_with_label gtk_check_menu_item_new_with_label;
+ static Ptr_gtk_menu_bar_new gtk_menu_bar_new;
+ static Ptr_gtk_menu_new gtk_menu_new;
+ static Ptr_gtk_expander_new gtk_expander_new;
+ static Ptr_gtk_button_new gtk_button_new;
+ static Ptr_gtk_tool_button_new gtk_tool_button_new;
+ static Ptr_gtk_hbutton_box_new gtk_hbutton_box_new;
+ static Ptr_gtk_check_button_new gtk_check_button_new;
+ static Ptr_gtk_radio_button_new gtk_radio_button_new;
+ static Ptr_gtk_spin_button_new gtk_spin_button_new;
+ static Ptr_gtk_separator_tool_item_new gtk_separator_tool_item_new;
+ static Ptr_gtk_toolbar_insert gtk_toolbar_insert;
+ static Ptr_gtk_frame_new gtk_frame_new;
+ static Ptr_gtk_statusbar_new gtk_statusbar_new;
+ static Ptr_gtk_entry_new gtk_entry_new;
+ static Ptr_gtk_hscale_new gtk_hscale_new;
+ static Ptr_gtk_vscale_new gtk_vscale_new;
+ static Ptr_gtk_hscrollbar_new gtk_hscrollbar_new;
+ static Ptr_gtk_vscrollbar_new gtk_vscrollbar_new;
+ static Ptr_gtk_scrolled_window_new gtk_scrolled_window_new;
+ static Ptr_gtk_notebook_new gtk_notebook_new;
+ static Ptr_gtk_toolbar_new gtk_toolbar_new;
+ static Ptr_gtk_tree_view_new gtk_tree_view_new;
+ static Ptr_gtk_tree_view_get_column gtk_tree_view_get_column;
+ static Ptr_gtk_combo_box_new gtk_combo_box_new;
+ static Ptr_gtk_combo_box_entry_new gtk_combo_box_entry_new;
+ static Ptr_gtk_progress_bar_new gtk_progress_bar_new;
+ static Ptr_gtk_container_add gtk_container_add;
+ static Ptr_gtk_menu_shell_append gtk_menu_shell_append;
+ static Ptr_gtk_progress_configure gtk_progress_configure;
+ static Ptr_gtk_range_get_adjustment gtk_range_get_adjustment;
+ static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment;
+ static Ptr_gtk_range_set_inverted gtk_range_set_inverted;
+ static Ptr_gtk_icon_factory_lookup_default gtk_icon_factory_lookup_default;
+ static Ptr_gtk_icon_theme_get_default gtk_icon_theme_get_default;
+ static Ptr_gtk_widget_style_get gtk_widget_style_get;
+ static Ptr_gtk_icon_set_render_icon gtk_icon_set_render_icon;
+ static Ptr_gtk_fixed_new gtk_fixed_new;
+ static Ptr_gtk_tree_view_column_new gtk_tree_view_column_new;
+ static Ptr_gtk_tree_view_append_column gtk_tree_view_append_column;
+ static Ptr_gtk_paint_check gtk_paint_check;
+ static Ptr_gtk_paint_box gtk_paint_box;
+ static Ptr_gtk_paint_box_gap gtk_paint_box_gap;
+ static Ptr_gtk_paint_flat_box gtk_paint_flat_box;
+ static Ptr_gtk_paint_option gtk_paint_option;
+ static Ptr_gtk_paint_extension gtk_paint_extension;
+ static Ptr_gtk_paint_slider gtk_paint_slider;
+ static Ptr_gtk_paint_shadow gtk_paint_shadow;
+ static Ptr_gtk_paint_resize_grip gtk_paint_resize_grip;
+ static Ptr_gtk_paint_focus gtk_paint_focus;
+ static Ptr_gtk_paint_arrow gtk_paint_arrow;
+ static Ptr_gtk_paint_handle gtk_paint_handle;
+ static Ptr_gtk_paint_expander gtk_paint_expander;
+ static Ptr_gtk_adjustment_configure gtk_adjustment_configure;
+ static Ptr_gtk_adjustment_new gtk_adjustment_new;
+ static Ptr_gtk_paint_vline gtk_paint_vline;
+ static Ptr_gtk_paint_hline gtk_paint_hline;
+ static Ptr_gtk_menu_item_set_submenu gtk_menu_item_set_submenu;
+ static Ptr_gtk_settings_get_default gtk_settings_get_default;
+ static Ptr_gtk_separator_menu_item_new gtk_separator_menu_item_new;
+ static Ptr_gtk_widget_size_allocate gtk_widget_size_allocate;
+ static Ptr_gtk_widget_size_request gtk_widget_size_request;
+ static Ptr_gtk_widget_set_direction gtk_widget_set_direction;
+ static Ptr_gtk_widget_path gtk_widget_path;
+ static Ptr_gtk_container_get_type gtk_container_get_type;
+ static Ptr_gtk_window_get_type gtk_window_get_type;
+ static Ptr_gtk_widget_get_type gtk_widget_get_type;
+ static Ptr_gtk_rc_get_style_by_paths gtk_rc_get_style_by_paths;
+ static Ptr_gtk_check_version gtk_check_version;
+ static Ptr_gtk_border_free gtk_border_free;
+
+ static Ptr_pango_font_description_get_size pango_font_description_get_size;
+ static Ptr_pango_font_description_get_weight pango_font_description_get_weight;
+ static Ptr_pango_font_description_get_family pango_font_description_get_family;
+ static Ptr_pango_font_description_get_style pango_font_description_get_style;
+
+ static Ptr_gtk_file_filter_new gtk_file_filter_new;
+ static Ptr_gtk_file_filter_set_name gtk_file_filter_set_name;
+ static Ptr_gtk_file_filter_add_pattern gtk_file_filter_add_pattern;
+ static Ptr_gtk_file_chooser_add_filter gtk_file_chooser_add_filter;
+ static Ptr_gtk_file_chooser_set_filter gtk_file_chooser_set_filter;
+ static Ptr_gtk_file_chooser_get_filter gtk_file_chooser_get_filter;
+ static Ptr_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new;
+ static Ptr_gtk_file_chooser_set_current_folder gtk_file_chooser_set_current_folder;
+ static Ptr_gtk_file_chooser_get_filename gtk_file_chooser_get_filename;
+ static Ptr_gtk_file_chooser_get_filenames gtk_file_chooser_get_filenames;
+ static Ptr_gtk_file_chooser_set_current_name gtk_file_chooser_set_current_name;
+ static Ptr_gtk_dialog_run gtk_dialog_run;
+ static Ptr_gtk_file_chooser_set_filename gtk_file_chooser_set_filename;
+
+ static Ptr_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels;
+ static Ptr_gdk_pixbuf_get_width gdk_pixbuf_get_width;
+ static Ptr_gdk_pixbuf_get_height gdk_pixbuf_get_height;
+ static Ptr_gdk_pixmap_new gdk_pixmap_new;
+ static Ptr_gdk_pixbuf_new gdk_pixbuf_new;
+ static Ptr_gdk_pixbuf_get_from_drawable gdk_pixbuf_get_from_drawable;
+ static Ptr_gdk_draw_rectangle gdk_draw_rectangle;
+ static Ptr_gdk_pixbuf_unref gdk_pixbuf_unref;
+ static Ptr_gdk_drawable_unref gdk_drawable_unref;
+ static Ptr_gdk_drawable_get_depth gdk_drawable_get_depth;
+ static Ptr_gdk_color_free gdk_color_free;
+ static Ptr_gdk_x11_window_set_user_time gdk_x11_window_set_user_time;
+ static Ptr_gdk_x11_drawable_get_xid gdk_x11_drawable_get_xid;
+ static Ptr_gdk_x11_drawable_get_xdisplay gdk_x11_drawable_get_xdisplay;
+
+ static Ptr_gconf_client_get_default gconf_client_get_default;
+ static Ptr_gconf_client_get_string gconf_client_get_string;
+ static Ptr_gconf_client_get_bool gconf_client_get_bool;
+
+ static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
+ static Ptr_gnome_vfs_init gnome_vfs_init;
+
+ virtual QPalette gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const;
+
+protected:
+ typedef QHash<QHashableLatin1Literal, GtkWidget*> WidgetMap;
+
+ static inline void destroyWidgetMap()
+ {
+ cleanupGtkWidgets();
+ delete widgetMap;
+ widgetMap = 0;
+ }
+
+ static inline WidgetMap *gtkWidgetMap()
+ {
+ if (!widgetMap) {
+ widgetMap = new WidgetMap();
+ qAddPostRoutine(destroyWidgetMap);
+ }
+ return widgetMap;
+ }
+
+ static QStringList extract_filter(const QString &rawFilter);
+
+ virtual GtkWidget* getTextColorWidget() const;
+ static void setupGtkWidget(GtkWidget* widget);
+ static void addWidgetToMap(GtkWidget* widget);
+ static void addAllSubWidgets(GtkWidget *widget, gpointer v = 0);
+ static void addWidget(GtkWidget *widget);
+ static void removeWidgetFromMap(const QHashableLatin1Literal &path);
+
+ virtual void init();
+
+private:
+ static QList<QGtkStylePrivate *> instances;
+ static WidgetMap *widgetMap;
+ friend class QGtkStyleUpdateScheduler;
+};
+
+// Helper to ensure that we have polished all our gtk widgets
+// before updating our own palettes
+class QGtkStyleUpdateScheduler : public QObject
+{
+ Q_OBJECT
+public slots:
+ void updateTheme();
+};
+
+QT_END_NAMESPACE
+
+#endif // !QT_NO_STYLE_GTK
+#endif // QGTKSTYLE_P_H
diff --git a/src/widgets/styles/qmacstyle.qdoc b/src/widgets/styles/qmacstyle.qdoc
new file mode 100644
index 0000000000..e6cb79cc53
--- /dev/null
+++ b/src/widgets/styles/qmacstyle.qdoc
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+/*!
+ \class QMacStyle
+ \brief The QMacStyle class provides a Mac OS X style using the Apple Appearance Manager.
+
+ \ingroup appearance
+
+ This class is implemented as a wrapper to the HITheme
+ APIs, allowing applications to be styled according to the current
+ theme in use on Mac OS X. This is done by having primitives
+ in QStyle implemented in terms of what Mac OS X would normally theme.
+
+ \warning This style is only available on Mac OS X because it relies on the
+ HITheme APIs.
+
+ There are additional issues that should be taken
+ into consideration to make an application compatible with the
+ \link http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html
+ Apple Human Interface Guidelines \endlink. Some of these issues are outlined
+ below.
+
+ \list
+
+ \i Layout - The restrictions on window layout are such that some
+ aspects of layout that are style-dependent cannot be achieved
+ using QLayout. Changes are being considered (and feedback would be
+ appreciated) to make layouts QStyle-able. Some of the restrictions
+ involve horizontal and vertical widget alignment and widget size
+ (covered below).
+
+ \i Widget size - Mac OS X allows widgets to have specific fixed sizes. Qt
+ does not fully implement this behavior so as to maintain cross-platform
+ compatibility. As a result some widgets sizes may be inappropriate (and
+ subsequently not rendered correctly by the HITheme APIs).The
+ QWidget::sizeHint() will return the appropriate size for many
+ managed widgets (widgets enumerated in \l QStyle::ContentsType).
+
+ \i Effects - QMacStyle uses HITheme for performing most of the drawing, but
+ also uses emulation in a few cases where HITheme does not provide the
+ required functionality (for example, tab bars on Panther, the toolbar
+ separator, etc). We tried to make the emulation as close to the original as
+ possible. Please report any issues you see in effects or non-standard
+ widgets.
+
+ \endlist
+
+ There are other issues that need to be considered in the feel of
+ your application (including the general color scheme to match the
+ Aqua colors). The Guidelines mentioned above will remain current
+ with new advances and design suggestions for Mac OS X.
+
+ Note that the functions provided by QMacStyle are
+ reimplementations of QStyle functions; see QStyle for their
+ documentation.
+
+ \img qmacstyle.png
+ \sa QWindowsXPStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
+*/
+
+
+/*!
+ \enum QMacStyle::WidgetSizePolicy
+
+ \value SizeSmall
+ \value SizeLarge
+ \value SizeMini
+ \value SizeDefault
+ \omitvalue SizeNone
+*/
+
+/*! \fn QMacStyle::QMacStyle()
+ Constructs a QMacStyle object.
+*/
+
+/*! \fn QMacStyle::~QMacStyle()
+ Destructs a QMacStyle object.
+*/
+
+/*! \fn void QMacStyle::polish(QPalette &pal)
+ \reimp
+*/
+
+/*! \fn void QMacStyle::polish(QApplication *)
+ \reimp
+*/
+
+/*! \fn void QMacStyle::unpolish(QApplication *)
+ \reimp
+*/
+
+/*! \fn void QMacStyle::polish(QWidget* w)
+ \reimp
+*/
+
+/*! \fn void QMacStyle::unpolish(QWidget* w)
+ \reimp
+*/
+
+/*! \fn int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const
+ \reimp
+*/
+
+/*! \fn QPalette QMacStyle::standardPalette() const
+ \reimp
+*/
+
+/*! \fn int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w, QStyleHintReturn *hret) const
+ \reimp
+*/
+
+/*! \fn QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
+ \reimp
+*/
+
+/*! \fn QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
+ \reimp
+*/
+
+/*!
+ \enum QMacStyle::FocusRectPolicy
+
+ This type is used to signify a widget's focus rectangle policy.
+
+ \value FocusEnabled show a focus rectangle when the widget has focus.
+ \value FocusDisabled never show a focus rectangle for the widget.
+ \value FocusDefault show a focus rectangle when the widget has
+ focus and the widget is a QSpinWidget, QDateTimeEdit, QLineEdit,
+ QListBox, QListView, editable QTextEdit, or one of their
+ subclasses.
+*/
+
+/*! \fn void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy)
+ \obsolete
+ Sets the focus rectangle policy of \a w. The \a policy can be one of
+ \l{QMacStyle::FocusRectPolicy}.
+
+ This is now simply an interface to the Qt::WA_MacShowFocusRect attribute and the
+ FocusDefault value does nothing anymore. If you want to set a widget back
+ to its default value, you must save the old value of the attribute before
+ you change it.
+
+ \sa focusRectPolicy() QWidget::setAttribute()
+*/
+
+/*! \fn QMacStyle::FocusRectPolicy QMacStyle::focusRectPolicy(const QWidget *w)
+ \obsolete
+ Returns the focus rectangle policy for the widget \a w.
+
+ The focus rectangle policy can be one of \l{QMacStyle::FocusRectPolicy}.
+
+ In 4.3 and up this function will simply test for the
+ Qt::WA_MacShowFocusRect attribute and will never return
+ QMacStyle::FocusDefault.
+
+ \sa setFocusRectPolicy(), QWidget::testAttribute()
+*/
+
+/*! \fn void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy)
+
+ \obsolete
+
+ Call QWidget::setAttribute() with Qt::WA_MacMiniSize, Qt::WA_MacSmallSize,
+ or Qt::WA_MacNormalSize instead.
+*/
+
+/*! \fn QMacStyle::WidgetSizePolicy QMacStyle::widgetSizePolicy(const QWidget *widget)
+ \obsolete
+
+ Call QWidget::testAttribute() with Qt::WA_MacMiniSize, Qt::WA_MacSmallSize,
+ or Qt::WA_MacNormalSize instead.
+*/
+
+/*! \fn void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const
+
+ \reimp
+*/
+
+/*! \fn void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w) const
+
+ \reimp
+*/
+
+/*! \fn QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
+
+ \reimp
+*/
+
+/*! \fn void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const
+ \reimp
+*/
+
+/*! \fn QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *widget) const
+ \reimp
+*/
+
+/*! \fn QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const
+ \reimp
+*/
+
+/*! \fn QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz, const QWidget *widget) const
+ \reimp
+*/
+
+/*! \fn void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole) const
+ \reimp
+*/
+
+/*! \fn bool QMacStyle::event(QEvent *e)
+ \reimp
+*/
+
+/*! \fn QIcon QMacStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt, const QWidget *widget) const
+ \internal
+*/
+
+/*! \fn int QMacStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const
+
+ \internal
+*/
+
diff --git a/src/widgets/styles/qmacstyle_mac.h b/src/widgets/styles/qmacstyle_mac.h
new file mode 100644
index 0000000000..ec4fed76eb
--- /dev/null
+++ b/src/widgets/styles/qmacstyle_mac.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACSTYLE_MAC_H
+#define QMACSTYLE_MAC_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+
+class QPalette;
+
+#if defined(QT_PLUGIN)
+#define Q_GUI_EXPORT_STYLE_MAC
+#else
+#define Q_GUI_EXPORT_STYLE_MAC Q_GUI_EXPORT
+#endif
+
+class QPushButton;
+class QStyleOptionButton;
+class QMacStylePrivate;
+class Q_GUI_EXPORT_STYLE_MAC QMacStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QMacStyle();
+ virtual ~QMacStyle();
+
+ void polish(QWidget *w);
+ void unpolish(QWidget *w);
+
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+
+ void polish(QPalette &pal);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *w = 0) const;
+
+ int pixelMetric(PixelMetric pm, const QStyleOption *opt = 0, const QWidget *widget = 0) const;
+
+ QPalette standardPalette() const;
+
+ virtual int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+
+ enum FocusRectPolicy { FocusEnabled, FocusDisabled, FocusDefault };
+ static void setFocusRectPolicy(QWidget *w, FocusRectPolicy policy);
+ static FocusRectPolicy focusRectPolicy(const QWidget *w);
+
+ enum WidgetSizePolicy { SizeSmall, SizeLarge, SizeMini, SizeDefault
+#ifdef QT3_SUPPORT
+ , SizeNone = SizeDefault
+#endif
+ };
+ static void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy);
+ static WidgetSizePolicy widgetSizePolicy(const QWidget *w);
+
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+
+ virtual void drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
+ bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+
+ bool event(QEvent *e);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QMacStyle)
+
+ QMacStylePrivate *d;
+
+ friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
+};
+
+#endif // Q_WS_MAC
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMACSTYLE_H
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
new file mode 100644
index 0000000000..40c28f6674
--- /dev/null
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -0,0 +1,6042 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ Note: The qdoc comments for QMacStyle are contained in
+ .../doc/src/qstyles.qdoc.
+*/
+
+#include "qmacstyle_mac.h"
+
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+#define QMAC_QAQUASTYLE_SIZE_CONSTRAIN
+//#define DEBUG_SIZE_CONSTRAINT
+
+#include <private/qapplication_p.h>
+#include <private/qcombobox_p.h>
+#include <private/qmacstylepixmaps_mac_p.h>
+#include <private/qpaintengine_mac_p.h>
+#include <private/qpainter_p.h>
+#include <private/qprintengine_mac_p.h>
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qdialogbuttonbox.h>
+#include <qdockwidget.h>
+#include <qevent.h>
+#include <qfocusframe.h>
+#include <qformlayout.h>
+#include <qgroupbox.h>
+#include <qhash.h>
+#include <qheaderview.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlistview.h>
+#include <qmainwindow.h>
+#include <qmap.h>
+#include <qmenubar.h>
+#include <qpaintdevice.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <qpointer.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qrubberband.h>
+#include <qsizegrip.h>
+#include <qspinbox.h>
+#include <qsplitter.h>
+#include <qstyleoption.h>
+#include <qtextedit.h>
+#include <qtextstream.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qtableview.h>
+#include <qwizard.h>
+#include <qdebug.h>
+#include <qlibrary.h>
+#include <qdatetimeedit.h>
+#include <qmath.h>
+#include <QtGui/qgraphicsproxywidget.h>
+#include <QtGui/qgraphicsview.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include "qmacstyle_mac_p.h"
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// The following constants are used for adjusting the size
+// of push buttons so that they are drawn inside their bounds.
+const int QMacStylePrivate::PushButtonLeftOffset = 6;
+const int QMacStylePrivate::PushButtonTopOffset = 4;
+const int QMacStylePrivate::PushButtonRightOffset = 12;
+const int QMacStylePrivate::PushButtonBottomOffset = 12;
+const int QMacStylePrivate::MiniButtonH = 26;
+const int QMacStylePrivate::SmallButtonH = 30;
+const int QMacStylePrivate::BevelButtonW = 50;
+const int QMacStylePrivate::BevelButtonH = 22;
+const int QMacStylePrivate::PushButtonContentPadding = 6;
+
+// These colors specify the titlebar gradient colors on
+// Leopard. Ideally we should get them from the system.
+static const QColor titlebarGradientActiveBegin(220, 220, 220);
+static const QColor titlebarGradientActiveEnd(151, 151, 151);
+static const QColor titlebarSeparatorLineActive(111, 111, 111);
+static const QColor titlebarGradientInactiveBegin(241, 241, 241);
+static const QColor titlebarGradientInactiveEnd(207, 207, 207);
+static const QColor titlebarSeparatorLineInactive(131, 131, 131);
+
+// Gradient colors used for the dock widget title bar and
+// non-unifed tool bar bacground.
+static const QColor mainWindowGradientBegin(240, 240, 240);
+static const QColor mainWindowGradientEnd(200, 200, 200);
+
+static const int DisclosureOffset = 4;
+
+// Resolve these at run-time, since the functions was moved in Leopard.
+typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *);
+static PtrHIShapeGetBounds ptrHIShapeGetBounds = 0;
+
+static int closeButtonSize = 12;
+
+extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
+
+static bool isVerticalTabs(const QTabBar::Shape shape) {
+ return (shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularEast
+ || shape == QTabBar::RoundedWest
+ || shape == QTabBar::TriangularWest);
+}
+
+void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
+{
+ // draw background circle
+ p->setRenderHints(QPainter::Antialiasing);
+ QRect rect(0, 0, closeButtonSize, closeButtonSize);
+ QColor background;
+ if (hover) {
+ background = QColor(124, 124, 124);
+ } else {
+ if (active) {
+ if (selected)
+ background = QColor(104, 104, 104);
+ else
+ background = QColor(83, 83, 83);
+ } else {
+ if (selected)
+ background = QColor(144, 144, 144);
+ else
+ background = QColor(114, 114, 114);
+ }
+ }
+ p->setPen(Qt::transparent);
+ p->setBrush(background);
+ p->drawEllipse(rect);
+
+ // draw cross
+ int min = 3;
+ int max = 9;
+ QPen crossPen;
+ crossPen.setColor(QColor(194, 194, 194));
+ crossPen.setWidthF(1.3);
+ crossPen.setCapStyle(Qt::FlatCap);
+ p->setPen(crossPen);
+ p->drawLine(min, min, max, max);
+ p->drawLine(min, max, max, min);
+}
+
+QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
+{
+ if (isVerticalTabs(shape)) {
+ int newX, newY, newRot;
+ if (shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularEast) {
+ newX = tabRect.width();
+ newY = tabRect.y();
+ newRot = 90;
+ } else {
+ newX = 0;
+ newY = tabRect.y() + tabRect.height();
+ newRot = -90;
+ }
+ tabRect.setRect(0, 0, tabRect.height(), tabRect.width());
+ QMatrix m;
+ m.translate(newX, newY);
+ m.rotate(newRot);
+ p->setMatrix(m, true);
+ }
+ return tabRect;
+}
+
+void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
+{
+ QRect r = tabOpt->rect;
+ p->translate(tabOpt->rect.x(), tabOpt->rect.y());
+ r.moveLeft(0);
+ r.moveTop(0);
+ QRect tabRect = rotateTabPainter(p, tabOpt->shape, r);
+
+ int width = tabRect.width();
+ int height = 20;
+ bool active = (tabOpt->state & QStyle::State_Active);
+ bool selected = (tabOpt->state & QStyle::State_Selected);
+
+ if (selected) {
+ QRect rect(1, 0, width - 2, height);
+
+ // fill body
+ if (active) {
+ int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
+ p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
+ } else {
+ int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 9 : 0;
+ QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
+ gradient.setColorAt(0, QColor(207 + d, 207 + d, 207 + d));
+ gradient.setColorAt(0.5, QColor(206 + d, 206 + d, 206 + d));
+ gradient.setColorAt(1, QColor(201 + d, 201 + d, 201 + d));
+ p->fillRect(rect, gradient);
+ }
+
+ // draw border
+ QColor borderSides;
+ QColor borderBottom;
+ if (active) {
+ borderSides = QColor(88, 88, 88);
+ borderBottom = QColor(88, 88, 88);
+ } else {
+ borderSides = QColor(121, 121, 121);
+ borderBottom = QColor(116, 116, 116);
+ }
+
+ p->setPen(borderSides);
+
+ int bottom = height;
+ // left line
+ p->drawLine(0, 1, 0, bottom-2);
+ // right line
+ p->drawLine(width-1, 1, width-1, bottom-2);
+
+ // bottom line
+ if (active) {
+ p->setPen(QColor(168, 168, 168));
+ p->drawLine(3, bottom-1, width-3, bottom-1);
+ }
+ p->setPen(borderBottom);
+ p->drawLine(2, bottom, width-2, bottom);
+
+ int w = 3;
+ QRectF rectangleLeft(1, height - w, w, w);
+ QRectF rectangleRight(width - 2, height - 1, w, w);
+ int startAngle = 180 * 16;
+ int spanAngle = 90 * 16;
+ p->setRenderHint(QPainter::Antialiasing);
+ p->drawArc(rectangleLeft, startAngle, spanAngle);
+ p->drawArc(rectangleRight, startAngle, -spanAngle);
+ } else {
+ // when the mouse is over non selected tabs they get a new color
+ bool hover = (tabOpt->state & QStyle::State_MouseOver);
+ if (hover) {
+ QRect rect(1, 2, width - 1, height - 1);
+ p->fillRect(rect, QColor(110, 110, 110));
+ }
+
+ // seperator lines between tabs
+ bool west = (tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest);
+ bool drawOnRight = !west;
+ if ((!drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)
+ || (drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)) {
+ QColor borderColor;
+ QColor borderHighlightColor;
+ if (active) {
+ borderColor = QColor(64, 64, 64);
+ borderHighlightColor = QColor(140, 140, 140);
+ } else {
+ borderColor = QColor(135, 135, 135);
+ borderHighlightColor = QColor(178, 178, 178);
+ }
+
+ int x = drawOnRight ? width : 0;
+
+ // tab seperator line
+ p->setPen(borderColor);
+ p->drawLine(x, 2, x, height + 1);
+
+ // tab seperator highlight
+ p->setPen(borderHighlightColor);
+ p->drawLine(x-1, 2, x-1, height + 1);
+ p->drawLine(x+1, 2, x+1, height + 1);
+ }
+ }
+}
+
+void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget *w)
+{
+ QRect r = tbb->rect;
+ if (isVerticalTabs(tbb->shape)) {
+ r.setWidth(w->width());
+ } else {
+ r.setHeight(w->height());
+ }
+ QRect tabRect = rotateTabPainter(p, tbb->shape, r);
+ int width = tabRect.width();
+ int height = tabRect.height();
+ bool active = (tbb->state & QStyle::State_Active);
+
+ // top border lines
+ QColor borderHighlightTop;
+ QColor borderTop;
+ if (active) {
+ borderTop = QColor(64, 64, 64);
+ borderHighlightTop = QColor(174, 174, 174);
+ } else {
+ borderTop = QColor(135, 135, 135);
+ borderHighlightTop = QColor(207, 207, 207);
+ }
+ p->setPen(borderHighlightTop);
+ p->drawLine(tabRect.x(), 0, width, 0);
+ p->setPen(borderTop);
+ p->drawLine(tabRect.x(), 1, width, 1);
+
+ // center block
+ QRect centralRect(tabRect.x(), 2, width, height - 2);
+ if (active) {
+ QColor mainColor = QColor(120, 120, 120);
+ p->fillRect(centralRect, mainColor);
+ } else {
+ QLinearGradient gradient(centralRect.topLeft(), centralRect.bottomLeft());
+ gradient.setColorAt(0, QColor(165, 165, 165));
+ gradient.setColorAt(0.5, QColor(164, 164, 164));
+ gradient.setColorAt(1, QColor(158, 158, 158));
+ p->fillRect(centralRect, gradient);
+ }
+
+ // bottom border lines
+ QColor borderHighlightBottom;
+ QColor borderBottom;
+ if (active) {
+ borderHighlightBottom = QColor(153, 153, 153);
+ borderBottom = QColor(64, 64, 64);
+ } else {
+ borderHighlightBottom = QColor(177, 177, 177);
+ borderBottom = QColor(127, 127, 127);
+ }
+ p->setPen(borderHighlightBottom);
+ p->drawLine(tabRect.x(), height - 2, width, height - 2);
+ p->setPen(borderBottom);
+ p->drawLine(tabRect.x(), height - 1, width, height - 1);
+}
+
+static int getControlSize(const QStyleOption *option, const QWidget *widget)
+{
+ if (option) {
+ if (option->state & (QStyle::State_Small | QStyle::State_Mini))
+ return (option->state & QStyle::State_Mini) ? QAquaSizeMini : QAquaSizeSmall;
+ } else if (widget) {
+ switch (QMacStyle::widgetSizePolicy(widget)) {
+ case QMacStyle::SizeSmall:
+ return QAquaSizeSmall;
+ case QMacStyle::SizeMini:
+ return QAquaSizeMini;
+ default:
+ break;
+ }
+ }
+ return QAquaSizeLarge;
+}
+
+
+static inline bool isTreeView(const QWidget *widget)
+{
+ return (widget && widget->parentWidget() &&
+ (qobject_cast<const QTreeView *>(widget->parentWidget())
+#ifdef QT3_SUPPORT
+ || widget->parentWidget()->inherits("Q3ListView")
+#endif
+ ));
+}
+
+QString qt_mac_removeMnemonics(const QString &original)
+{
+ QString returnText(original.size(), 0);
+ int finalDest = 0;
+ int currPos = 0;
+ int l = original.length();
+ while (l) {
+ if (original.at(currPos) == QLatin1Char('&')
+ && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
+ ++currPos;
+ --l;
+ if (l == 0)
+ break;
+ }
+ returnText[finalDest] = original.at(currPos);
+ ++currPos;
+ ++finalDest;
+ --l;
+ }
+ returnText.truncate(finalDest);
+ return returnText;
+}
+
+static inline ThemeTabDirection getTabDirection(QTabBar::Shape shape)
+{
+ ThemeTabDirection ttd;
+ switch (shape) {
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ ttd = kThemeTabSouth;
+ break;
+ default: // Added to remove the warning, since all values are taken care of, really!
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ ttd = kThemeTabNorth;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ ttd = kThemeTabWest;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ ttd = kThemeTabEast;
+ break;
+ }
+ return ttd;
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "moc_qmacstyle_mac.cpp"
+#include "moc_qmacstyle_mac_p.cpp"
+QT_END_INCLUDE_NAMESPACE
+
+/*****************************************************************************
+ External functions
+ *****************************************************************************/
+extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp
+extern QRegion qt_mac_convert_mac_region(HIShapeRef); //qregion_mac.cpp
+void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
+extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp
+
+/*****************************************************************************
+ QMacCGStyle globals
+ *****************************************************************************/
+const int qt_mac_hitheme_version = 0; //the HITheme version we speak
+const int macItemFrame = 2; // menu item frame width
+const int macItemHMargin = 3; // menu item hor text margin
+const int macItemVMargin = 2; // menu item ver text margin
+const int macRightBorder = 12; // right border on mac
+const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar.
+QPixmap *qt_mac_backgroundPattern = 0; // stores the standard widget background.
+
+/*****************************************************************************
+ QMacCGStyle utility functions
+ *****************************************************************************/
+static inline int qt_mac_hitheme_tab_version()
+{
+ return 1;
+}
+
+static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
+{
+ return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
+ convertRect.width() - rect.width(), convertRect.height() - rect.height());
+}
+
+static inline const QRect qt_qrectForHIRect(const HIRect &hirect)
+{
+ return QRect(QPoint(int(hirect.origin.x), int(hirect.origin.y)),
+ QSize(int(hirect.size.width), int(hirect.size.height)));
+}
+
+inline bool qt_mac_is_metal(const QWidget *w)
+{
+ for (; w; w = w->parentWidget()) {
+ if (w->testAttribute(Qt::WA_MacBrushedMetal))
+ return true;
+ if (w->isWindow() && w->testAttribute(Qt::WA_WState_Created)) { // If not created will fall through to the opaque check and be fine anyway.
+ return macWindowIsTextured(qt_mac_window_for(w));
+ }
+ if (w->d_func()->isOpaque)
+ break;
+ }
+ return false;
+}
+
+static int qt_mac_aqua_get_metric(ThemeMetric met)
+{
+ SInt32 ret;
+ GetThemeMetric(met, &ret);
+ return ret;
+}
+
+static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg, QSize szHint,
+ QAquaWidgetSize sz)
+{
+ QSize ret(-1, -1);
+ if (sz != QAquaSizeSmall && sz != QAquaSizeLarge && sz != QAquaSizeMini) {
+ qDebug("Not sure how to return this...");
+ return ret;
+ }
+ if ((widg && widg->testAttribute(Qt::WA_SetFont)) || !QApplication::desktopSettingsAware()) {
+ // If you're using a custom font and it's bigger than the default font,
+ // then no constraints for you. If you are smaller, we can try to help you out
+ QFont font = qt_app_fonts_hash()->value(widg->metaObject()->className(), QFont());
+ if (widg->font().pointSize() > font.pointSize())
+ return ret;
+ }
+
+ if (ct == QStyle::CT_CustomBase && widg) {
+ if (qobject_cast<const QPushButton *>(widg))
+ ct = QStyle::CT_PushButton;
+ else if (qobject_cast<const QRadioButton *>(widg))
+ ct = QStyle::CT_RadioButton;
+ else if (qobject_cast<const QCheckBox *>(widg))
+ ct = QStyle::CT_CheckBox;
+ else if (qobject_cast<const QComboBox *>(widg))
+ ct = QStyle::CT_ComboBox;
+ else if (qobject_cast<const QToolButton *>(widg))
+ ct = QStyle::CT_ToolButton;
+ else if (qobject_cast<const QSlider *>(widg))
+ ct = QStyle::CT_Slider;
+ else if (qobject_cast<const QProgressBar *>(widg))
+ ct = QStyle::CT_ProgressBar;
+ else if (qobject_cast<const QLineEdit *>(widg))
+ ct = QStyle::CT_LineEdit;
+ else if (qobject_cast<const QHeaderView *>(widg)
+#ifdef QT3_SUPPORT
+ || widg->inherits("Q3Header")
+#endif
+ )
+ ct = QStyle::CT_HeaderSection;
+ else if (qobject_cast<const QMenuBar *>(widg)
+#ifdef QT3_SUPPORT
+ || widg->inherits("Q3MenuBar")
+#endif
+ )
+ ct = QStyle::CT_MenuBar;
+ else if (qobject_cast<const QSizeGrip *>(widg))
+ ct = QStyle::CT_SizeGrip;
+ else
+ return ret;
+ }
+
+ switch (ct) {
+ case QStyle::CT_PushButton: {
+ const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
+ // If this comparison is false, then the widget was not a push button.
+ // This is bad and there's very little we can do since we were requested to find a
+ // sensible size for a widget that pretends to be a QPushButton but is not.
+ if(psh) {
+ QString buttonText = qt_mac_removeMnemonics(psh->text());
+ if (buttonText.contains(QLatin1Char('\n')))
+ ret = QSize(-1, -1);
+ else if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
+
+ if (!psh->icon().isNull()){
+ // If the button got an icon, and the icon is larger than the
+ // button, we can't decide on a default size
+ ret.setWidth(-1);
+ if (ret.height() < psh->iconSize().height())
+ ret.setHeight(-1);
+ }
+ else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
+ // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
+ // However, this doesn't work for German, therefore only do it for English,
+ // I suppose it would be better to do some sort of lookups for languages
+ // that like to have really long words.
+ ret.setWidth(77 - 8);
+ }
+ } else {
+ // The only sensible thing to do is to return whatever the style suggests...
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
+ else
+ // Since there's no default size we return the large size...
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+ }
+#if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
+ } else if (ct == QStyle::CT_RadioButton) {
+ QRadioButton *rdo = static_cast<QRadioButton *>(widg);
+ // Exception for case where multiline radio button text requires no size constrainment
+ if (rdo->text().find('\n') != -1)
+ return ret;
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricRadioButtonHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallRadioButtonHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniRadioButtonHeight));
+ } else if (ct == QStyle::CT_CheckBox) {
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricCheckBoxHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallCheckBoxHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniCheckBoxHeight));
+#endif
+ break;
+ }
+ case QStyle::CT_SizeGrip:
+ if (sz == QAquaSizeLarge || sz == QAquaSizeSmall) {
+ HIRect r;
+ HIPoint p = { 0, 0 };
+ HIThemeGrowBoxDrawInfo gbi;
+ gbi.version = 0;
+ gbi.state = kThemeStateActive;
+ gbi.kind = kHIThemeGrowBoxKindNormal;
+ gbi.direction = QApplication::isRightToLeft() ? kThemeGrowLeft | kThemeGrowDown
+ : kThemeGrowRight | kThemeGrowDown;
+ gbi.size = sz == QAquaSizeSmall ? kHIThemeGrowBoxSizeSmall : kHIThemeGrowBoxSizeNormal;
+ if (HIThemeGetGrowBoxBounds(&p, &gbi, &r) == noErr)
+ ret = QSize(r.size.width, r.size.height);
+ }
+ break;
+ case QStyle::CT_ComboBox:
+ switch (sz) {
+ case QAquaSizeLarge:
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPopupButtonHeight));
+ break;
+ case QAquaSizeSmall:
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPopupButtonHeight));
+ break;
+ case QAquaSizeMini:
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPopupButtonHeight));
+ break;
+ default:
+ break;
+ }
+ break;
+ case QStyle::CT_ToolButton:
+ if (sz == QAquaSizeSmall) {
+ int width = 0, height = 0;
+ if (szHint == QSize(-1, -1)) { //just 'guess'..
+ const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
+ // If this conversion fails then the widget was not what it claimed to be.
+ if(bt) {
+ if (!bt->icon().isNull()) {
+ QSize iconSize = bt->iconSize();
+ QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
+ width = qMax(width, qMax(iconSize.width(), pmSize.width()));
+ height = qMax(height, qMax(iconSize.height(), pmSize.height()));
+ }
+ if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
+ int text_width = bt->fontMetrics().width(bt->text()),
+ text_height = bt->fontMetrics().height();
+ if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
+ width = qMax(width, text_width);
+ height += text_height;
+ } else {
+ width += text_width;
+ width = qMax(height, text_height);
+ }
+ }
+ } else {
+ // Let's return the size hint...
+ width = szHint.width();
+ height = szHint.height();
+ }
+ } else {
+ width = szHint.width();
+ height = szHint.height();
+ }
+ width = qMax(20, width + 5); //border
+ height = qMax(20, height + 5); //border
+ ret = QSize(width, height);
+ }
+ break;
+ case QStyle::CT_Slider: {
+ int w = -1;
+ const QSlider *sld = qobject_cast<const QSlider *>(widg);
+ // If this conversion fails then the widget was not what it claimed to be.
+ if(sld) {
+ if (sz == QAquaSizeLarge) {
+ if (sld->orientation() == Qt::Horizontal) {
+ w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
+ } else {
+ w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
+ }
+ } else if (sz == QAquaSizeSmall) {
+ if (sld->orientation() == Qt::Horizontal) {
+ w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
+ } else {
+ w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
+ }
+ } else if (sz == QAquaSizeMini) {
+ if (sld->orientation() == Qt::Horizontal) {
+ w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
+ } else {
+ w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
+ }
+ }
+ } else {
+ // This is tricky, we were requested to find a size for a slider which is not
+ // a slider. We don't know if this is vertical or horizontal or if we need to
+ // have tick marks or not.
+ // For this case we will return an horizontal slider without tick marks.
+ w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
+ w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
+ }
+ if (sld->orientation() == Qt::Horizontal)
+ ret.setHeight(w);
+ else
+ ret.setWidth(w);
+ break;
+ }
+ case QStyle::CT_ProgressBar: {
+ int finalValue = -1;
+ Qt::Orientation orient = Qt::Horizontal;
+ if (const QProgressBar *pb = qobject_cast<const QProgressBar *>(widg))
+ orient = pb->orientation();
+
+ if (sz == QAquaSizeLarge)
+ finalValue = qt_mac_aqua_get_metric(kThemeMetricLargeProgressBarThickness)
+ + qt_mac_aqua_get_metric(kThemeMetricProgressBarShadowOutset);
+ else
+ finalValue = qt_mac_aqua_get_metric(kThemeMetricNormalProgressBarThickness)
+ + qt_mac_aqua_get_metric(kThemeMetricSmallProgressBarShadowOutset);
+ if (orient == Qt::Horizontal)
+ ret.setHeight(finalValue);
+ else
+ ret.setWidth(finalValue);
+ break;
+ }
+ case QStyle::CT_LineEdit:
+ if (!widg || !qobject_cast<QComboBox *>(widg->parentWidget())) {
+ //should I take into account the font dimentions of the lineedit? -Sam
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, 22);
+ else
+ ret = QSize(-1, 19);
+ }
+ break;
+ case QStyle::CT_HeaderSection:
+ if (isTreeView(widg))
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricListHeaderHeight));
+ break;
+ case QStyle::CT_MenuBar:
+ if (sz == QAquaSizeLarge) {
+#ifndef QT_MAC_USE_COCOA
+ SInt16 size;
+ if (!GetThemeMenuBarHeight(&size))
+ ret = QSize(-1, size);
+#else
+ ret = QSize(-1, [[NSApp mainMenu] menuBarHeight]);
+ // In the qt_mac_set_native_menubar(false) case,
+ // we come it here with a zero-height main menu,
+ // preventing the in-window menu from displaying.
+ // Use 22 pixels for the height, by observation.
+ if (ret.height() <= 0)
+ ret.setHeight(22);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+
+#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
+static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini)
+{
+ if (large == QSize(-1, -1)) {
+ if (small != QSize(-1, -1))
+ return QAquaSizeSmall;
+ if (mini != QSize(-1, -1))
+ return QAquaSizeMini;
+ return QAquaSizeUnknown;
+ } else if (small == QSize(-1, -1)) {
+ if (mini != QSize(-1, -1))
+ return QAquaSizeMini;
+ return QAquaSizeLarge;
+ } else if (mini == QSize(-1, -1)) {
+ return QAquaSizeLarge;
+ }
+
+#ifndef QT_NO_MAINWINDOW
+ if (qobject_cast<QDockWidget *>(widg->window()) || !qgetenv("QWIDGET_ALL_SMALL").isNull()) {
+ //if (small.width() != -1 || small.height() != -1)
+ return QAquaSizeSmall;
+ } else if (!qgetenv("QWIDGET_ALL_MINI").isNull()) {
+ return QAquaSizeMini;
+ }
+#endif
+
+#if 0
+ /* Figure out which size we're closer to, I just hacked this in, I haven't
+ tested it as it would probably look pretty strange to have some widgets
+ big and some widgets small in the same window?? -Sam */
+ int large_delta=0;
+ if (large.width() != -1) {
+ int delta = large.width() - widg->width();
+ large_delta += delta * delta;
+ }
+ if (large.height() != -1) {
+ int delta = large.height() - widg->height();
+ large_delta += delta * delta;
+ }
+ int small_delta=0;
+ if (small.width() != -1) {
+ int delta = small.width() - widg->width();
+ small_delta += delta * delta;
+ }
+ if (small.height() != -1) {
+ int delta = small.height() - widg->height();
+ small_delta += delta * delta;
+ }
+ int mini_delta=0;
+ if (mini.width() != -1) {
+ int delta = mini.width() - widg->width();
+ mini_delta += delta * delta;
+ }
+ if (mini.height() != -1) {
+ int delta = mini.height() - widg->height();
+ mini_delta += delta * delta;
+ }
+ if (mini_delta < small_delta && mini_delta < large_delta)
+ return QAquaSizeMini;
+ else if (small_delta < large_delta)
+ return QAquaSizeSmall;
+#endif
+ return QAquaSizeLarge;
+}
+#endif
+
+QAquaWidgetSize QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
+ QStyle::ContentsType ct, QSize szHint, QSize *insz) const
+{
+#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
+ if (option) {
+ if (option->state & QStyle::State_Small)
+ return QAquaSizeSmall;
+ if (option->state & QStyle::State_Mini)
+ return QAquaSizeMini;
+ }
+
+ if (!widg) {
+ if (insz)
+ *insz = QSize();
+ if (!qgetenv("QWIDGET_ALL_SMALL").isNull())
+ return QAquaSizeSmall;
+ if (!qgetenv("QWIDGET_ALL_MINI").isNull())
+ return QAquaSizeMini;
+ return QAquaSizeUnknown;
+ }
+ QSize large = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeLarge),
+ small = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeSmall),
+ mini = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeMini);
+ bool guess_size = false;
+ QAquaWidgetSize ret = QAquaSizeUnknown;
+ QMacStyle::WidgetSizePolicy wsp = q->widgetSizePolicy(widg);
+ if (wsp == QMacStyle::SizeDefault)
+ guess_size = true;
+ else if (wsp == QMacStyle::SizeMini)
+ ret = QAquaSizeMini;
+ else if (wsp == QMacStyle::SizeSmall)
+ ret = QAquaSizeSmall;
+ else if (wsp == QMacStyle::SizeLarge)
+ ret = QAquaSizeLarge;
+ if (guess_size)
+ ret = qt_aqua_guess_size(widg, large, small, mini);
+
+ QSize *sz = 0;
+ if (ret == QAquaSizeSmall)
+ sz = &small;
+ else if (ret == QAquaSizeLarge)
+ sz = &large;
+ else if (ret == QAquaSizeMini)
+ sz = &mini;
+ if (insz)
+ *insz = sz ? *sz : QSize(-1, -1);
+#ifdef DEBUG_SIZE_CONSTRAINT
+ if (sz) {
+ const char *size_desc = "Unknown";
+ if (sz == &small)
+ size_desc = "Small";
+ else if (sz == &large)
+ size_desc = "Large";
+ else if (sz == &mini)
+ size_desc = "Mini";
+ qDebug("%s - %s: %s taken (%d, %d) [%d, %d]",
+ widg ? widg->objectName().toLatin1().constData() : "*Unknown*",
+ widg ? widg->metaObject()->className() : "*Unknown*", size_desc, widg->width(), widg->height(),
+ sz->width(), sz->height());
+ }
+#endif
+ return ret;
+#else
+ if (insz)
+ *insz = QSize();
+ Q_UNUSED(widg);
+ Q_UNUSED(ct);
+ Q_UNUSED(szHint);
+ return QAquaSizeUnknown;
+#endif
+}
+
+/**
+ Returns the free space awailable for contents inside the
+ button (and not the size of the contents itself)
+*/
+HIRect QMacStylePrivate::pushButtonContentBounds(const QStyleOptionButton *btn,
+ const HIThemeButtonDrawInfo *bdi) const
+{
+ HIRect outerBounds = qt_hirectForQRect(btn->rect);
+ // Adjust the bounds to correct for
+ // carbon not calculating the content bounds fully correct
+ if (bdi->kind == kThemePushButton || bdi->kind == kThemePushButtonSmall){
+ outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ outerBounds.size.height -= QMacStylePrivate::PushButtonBottomOffset;
+ } else if (bdi->kind == kThemePushButtonMini) {
+ outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ }
+
+ HIRect contentBounds;
+ HIThemeGetButtonContentBounds(&outerBounds, bdi, &contentBounds);
+ return contentBounds;
+}
+
+/**
+ Calculates the size of the button contents.
+ This includes both the text and the icon.
+*/
+QSize QMacStylePrivate::pushButtonSizeFromContents(const QStyleOptionButton *btn) const
+{
+ QSize csz(0, 0);
+ QSize iconSize = btn->icon.isNull() ? QSize(0, 0)
+ : (btn->iconSize + QSize(QMacStylePrivate::PushButtonContentPadding, 0));
+ QRect textRect = btn->text.isEmpty() ? QRect(0, 0, 1, 1)
+ : btn->fontMetrics.boundingRect(QRect(), Qt::AlignCenter, btn->text);
+ csz.setWidth(iconSize.width() + textRect.width()
+ + ((btn->features & QStyleOptionButton::HasMenu)
+ ? q->proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, 0) : 0));
+ csz.setHeight(qMax(iconSize.height(), textRect.height()));
+ return csz;
+}
+
+/**
+ Checks if the actual contents of btn fits inside the free content bounds of
+ 'buttonKindToCheck'. Meant as a helper function for 'initHIThemePushButton'
+ for determining which button kind to use for drawing.
+*/
+bool QMacStylePrivate::contentFitsInPushButton(const QStyleOptionButton *btn,
+ HIThemeButtonDrawInfo *bdi,
+ ThemeButtonKind buttonKindToCheck) const
+{
+ ThemeButtonKind tmp = bdi->kind;
+ bdi->kind = buttonKindToCheck;
+ QSize contentSize = pushButtonSizeFromContents(btn);
+ QRect freeContentRect = qt_qrectForHIRect(pushButtonContentBounds(btn, bdi));
+ bdi->kind = tmp;
+ return freeContentRect.contains(QRect(freeContentRect.x(), freeContentRect.y(),
+ contentSize.width(), contentSize.height()));
+}
+
+/**
+ Creates a HIThemeButtonDrawInfo structure that specifies the correct button
+ kind and other details to use for drawing the given push button. Which
+ button kind depends on the size of the button, the size of the contents,
+ explicit user style settings, etc.
+*/
+void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn,
+ const QWidget *widget,
+ const ThemeDrawState tds,
+ HIThemeButtonDrawInfo *bdi) const
+{
+ bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
+ ThemeDrawState tdsModified = tds;
+ if (btn->state & QStyle::State_On)
+ tdsModified = kThemeStatePressed;
+ bdi->version = qt_mac_hitheme_version;
+ bdi->state = tdsModified;
+ bdi->value = kThemeButtonOff;
+
+ if (drawColorless && tdsModified == kThemeStateInactive)
+ bdi->state = kThemeStateActive;
+ if (btn->state & QStyle::State_HasFocus)
+ bdi->adornment = kThemeAdornmentFocus;
+ else
+ bdi->adornment = kThemeAdornmentNone;
+
+
+ if (btn->features & (QStyleOptionButton::Flat)) {
+ bdi->kind = kThemeBevelButton;
+ } else {
+ switch (aquaSizeConstrain(btn, widget)) {
+ case QAquaSizeSmall:
+ bdi->kind = kThemePushButtonSmall;
+ break;
+ case QAquaSizeMini:
+ bdi->kind = kThemePushButtonMini;
+ break;
+ case QAquaSizeLarge:
+ // ... We should honor if the user is explicit about using the
+ // large button. But right now Qt will specify the large button
+ // as default rather than QAquaSizeUnknown.
+ // So we treat it like QAquaSizeUnknown
+ // to get the dynamic choosing of button kind.
+ case QAquaSizeUnknown:
+ // Choose the button kind that closest match the button rect, but at the
+ // same time displays the button contents without clipping.
+ bdi->kind = kThemeBevelButton;
+ if (btn->rect.width() >= QMacStylePrivate::BevelButtonW && btn->rect.height() >= QMacStylePrivate::BevelButtonH){
+ if (widget && widget->testAttribute(Qt::WA_MacVariableSize)) {
+ if (btn->rect.height() <= QMacStylePrivate::MiniButtonH){
+ if (contentFitsInPushButton(btn, bdi, kThemePushButtonMini))
+ bdi->kind = kThemePushButtonMini;
+ } else if (btn->rect.height() <= QMacStylePrivate::SmallButtonH){
+ if (contentFitsInPushButton(btn, bdi, kThemePushButtonSmall))
+ bdi->kind = kThemePushButtonSmall;
+ } else if (contentFitsInPushButton(btn, bdi, kThemePushButton)) {
+ bdi->kind = kThemePushButton;
+ }
+ } else {
+ bdi->kind = kThemePushButton;
+ }
+ }
+ }
+ }
+}
+
+bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option)
+{
+ QMacStyle *macStyle = qobject_cast<QMacStyle *>(pushButton->style());
+ if (!macStyle)
+ return false;
+ HIThemeButtonDrawInfo bdi;
+ macStyle->d->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi);
+ return bdi.kind == kThemeBevelButton;
+}
+
+/**
+ Creates a HIThemeButtonDrawInfo structure that specifies the correct button
+ kind and other details to use for drawing the given combobox. Which button
+ kind depends on the size of the combo, wether or not it is editable,
+ explicit user style settings, etc.
+*/
+void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
+ const QWidget *widget, const ThemeDrawState &tds)
+{
+ bdi->version = qt_mac_hitheme_version;
+ bdi->adornment = kThemeAdornmentArrowLeftArrow;
+ bdi->value = kThemeButtonOff;
+ if (combo->state & QStyle::State_HasFocus)
+ bdi->adornment = kThemeAdornmentFocus;
+ bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
+ if (combo->activeSubControls & QStyle::SC_ComboBoxArrow)
+ bdi->state = kThemeStatePressed;
+ else if (drawColorless)
+ bdi->state = kThemeStateActive;
+ else
+ bdi->state = tds;
+
+ QAquaWidgetSize aSize = aquaSizeConstrain(combo, widget);
+ switch (aSize) {
+ case QAquaSizeMini:
+ bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxMini)
+ : ThemeButtonKind(kThemePopupButtonMini);
+ break;
+ case QAquaSizeSmall:
+ bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxSmall)
+ : ThemeButtonKind(kThemePopupButtonSmall);
+ break;
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ // Unless the user explicitly specified large buttons, determine the
+ // kind by looking at the combox size.
+ // ... specifying small and mini-buttons it not a current feature of
+ // Qt (e.g. QWidget::getAttribute(WA_ButtonSize)). But when it is, add
+ // an extra check here before using the mini and small buttons.
+ int h = combo->rect.size().height();
+ if (combo->editable){
+ if (h < 21)
+ bdi->kind = kThemeComboBoxMini;
+ else if (h < 26)
+ bdi->kind = kThemeComboBoxSmall;
+ else
+ bdi->kind = kThemeComboBox;
+ } else {
+ // Even if we specify that we want the kThemePopupButton, Carbon
+ // will use the kThemePopupButtonSmall if the size matches. So we
+ // do the same size check explicit to have the size of the inner
+ // text field be correct. Therefore, do this even if the user specifies
+ // the use of LargeButtons explicit.
+ if (h < 21)
+ bdi->kind = kThemePopupButtonMini;
+ else if (h < 26)
+ bdi->kind = kThemePopupButtonSmall;
+ else
+ bdi->kind = kThemePopupButton;
+ }
+ break;
+ }
+}
+
+/**
+ Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain
+ the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds.
+*/
+HIRect QMacStylePrivate::comboboxInnerBounds(const HIRect &outerBounds, int buttonKind)
+{
+ HIRect innerBounds = outerBounds;
+ // Carbon draw parts of the view outside the rect.
+ // So make the rect a bit smaller to compensate
+ // (I wish HIThemeGetButtonBackgroundBounds worked)
+ switch (buttonKind){
+ case kThemePopupButton:
+ innerBounds.origin.x += 2;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 5;
+ innerBounds.size.height -= 6;
+ break;
+ case kThemePopupButtonSmall:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 6;
+ innerBounds.size.height -= 7;
+ break;
+ case kThemePopupButtonMini:
+ innerBounds.origin.x += 2;
+ innerBounds.origin.y += 2;
+ innerBounds.size.width -= 5;
+ innerBounds.size.height -= 6;
+ break;
+ case kThemeComboBox:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 6;
+ innerBounds.size.height -= 6;
+ break;
+ case kThemeComboBoxSmall:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 7;
+ innerBounds.size.height -= 8;
+ break;
+ case kThemeComboBoxMini:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 4;
+ innerBounds.size.height -= 8;
+ break;
+ default:
+ break;
+ }
+ return innerBounds;
+}
+
+/**
+ Inside a combobox Qt places a line edit widget. The size of this widget should depend on the kind
+ of combobox we choose to draw. This function calculates and returns this size.
+*/
+QRect QMacStylePrivate::comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi)
+{
+ QRect ret = outerBounds;
+ switch (bdi.kind){
+ case kThemeComboBox:
+ ret.adjust(5, 8, -21, -4);
+ break;
+ case kThemeComboBoxSmall:
+ ret.adjust(4, 5, -18, 0);
+ ret.setHeight(16);
+ break;
+ case kThemeComboBoxMini:
+ ret.adjust(4, 5, -16, 0);
+ ret.setHeight(13);
+ break;
+ case kThemePopupButton:
+ ret.adjust(10, 3, -23, -3);
+ break;
+ case kThemePopupButtonSmall:
+ ret.adjust(9, 3, -20, -3);
+ break;
+ case kThemePopupButtonMini:
+ ret.adjust(8, 3, -19, 0);
+ ret.setHeight(13);
+ break;
+ }
+ return ret;
+}
+
+/**
+ Carbon comboboxes don't scale (sight). If the size of the combo suggest a scaled version,
+ create it manually by drawing a small Carbon combo onto a pixmap (use pixmap cache), chop
+ it up, and copy it back onto the widget. Othervise, draw the combobox supplied by Carbon directly.
+*/
+void QMacStylePrivate::drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p)
+{
+ if (!(bdi.kind == kThemeComboBox && outerBounds.size.height > 28)){
+ // We have an unscaled combobox, or popup-button; use Carbon directly.
+ HIRect innerBounds = QMacStylePrivate::comboboxInnerBounds(outerBounds, bdi.kind);
+ HIThemeDrawButton(&innerBounds, &bdi, QMacCGContext(p), kHIThemeOrientationNormal, 0);
+ } else {
+ QPixmap buffer;
+ QString key = QString(QLatin1String("$qt_cbox%1-%2")).arg(int(bdi.state)).arg(int(bdi.adornment));
+ if (!QPixmapCache::find(key, buffer)) {
+ HIRect innerBoundsSmallCombo = {{3, 3}, {29, 25}};
+ buffer = QPixmap(35, 28);
+ buffer.fill(Qt::transparent);
+ QPainter buffPainter(&buffer);
+ HIThemeDrawButton(&innerBoundsSmallCombo, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
+ buffPainter.end();
+ QPixmapCache::insert(key, buffer);
+ }
+
+ const int bwidth = 20;
+ const int fwidth = 10;
+ const int fheight = 10;
+ int w = qRound(outerBounds.size.width);
+ int h = qRound(outerBounds.size.height);
+ int bstart = w - bwidth;
+ int blower = fheight + 1;
+ int flower = h - fheight;
+ int sheight = flower - fheight;
+ int center = qRound(outerBounds.size.height + outerBounds.origin.y) / 2;
+
+ // Draw upper and lower gap
+ p->drawPixmap(fwidth, 0, bstart - fwidth, fheight, buffer, fwidth, 0, 1, fheight);
+ p->drawPixmap(fwidth, flower, bstart - fwidth, fheight, buffer, fwidth, buffer.height() - fheight, 1, fheight);
+ // Draw left and right gap. Right gap is drawn top and bottom separatly
+ p->drawPixmap(0, fheight, fwidth, sheight, buffer, 0, fheight, fwidth, 1);
+ p->drawPixmap(bstart, fheight, bwidth, center - fheight, buffer, buffer.width() - bwidth, fheight - 1, bwidth, 1);
+ p->drawPixmap(bstart, center, bwidth, sheight / 2, buffer, buffer.width() - bwidth, fheight + 6, bwidth, 1);
+ // Draw arrow
+ p->drawPixmap(bstart, center - 4, bwidth - 3, 6, buffer, buffer.width() - bwidth, fheight, bwidth - 3, 6);
+ // Draw corners
+ p->drawPixmap(0, 0, fwidth, fheight, buffer, 0, 0, fwidth, fheight);
+ p->drawPixmap(bstart, 0, bwidth, fheight, buffer, buffer.width() - bwidth, 0, bwidth, fheight);
+ p->drawPixmap(0, flower, fwidth, fheight, buffer, 0, buffer.height() - fheight, fwidth, fheight);
+ p->drawPixmap(bstart, h - blower, bwidth, blower, buffer, buffer.width() - bwidth, buffer.height() - blower, bwidth, blower);
+ }
+}
+
+/**
+ Carbon tableheaders don't scale (sight). So create it manually by drawing a small Carbon header
+ onto a pixmap (use pixmap cache), chop it up, and copy it back onto the widget.
+*/
+void QMacStylePrivate::drawTableHeader(const HIRect &outerBounds,
+ bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p)
+{
+ static SInt32 headerHeight = 0;
+ static OSStatus err = GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight);
+ Q_UNUSED(err);
+
+ QPixmap buffer;
+ QString key = QString(QLatin1String("$qt_tableh%1-%2-%3")).arg(int(bdi.state)).arg(int(bdi.adornment)).arg(int(bdi.value));
+ if (!QPixmapCache::find(key, buffer)) {
+ HIRect headerNormalRect = {{0., 0.}, {16., CGFloat(headerHeight)}};
+ buffer = QPixmap(headerNormalRect.size.width, headerNormalRect.size.height);
+ buffer.fill(Qt::transparent);
+ QPainter buffPainter(&buffer);
+ HIThemeDrawButton(&headerNormalRect, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
+ buffPainter.end();
+ QPixmapCache::insert(key, buffer);
+ }
+ const int buttonw = qRound(outerBounds.size.width);
+ const int buttonh = qRound(outerBounds.size.height);
+ const int framew = 1;
+ const int frameh_n = 4;
+ const int frameh_s = 3;
+ const int transh = buffer.height() - frameh_n - frameh_s;
+ int center = buttonh - frameh_s - int(transh / 2.0f) + 1; // Align bottom;
+
+ int skipTopBorder = 0;
+ if (!drawTopBorder)
+ skipTopBorder = 1;
+
+ p->translate(outerBounds.origin.x, outerBounds.origin.y);
+
+ p->drawPixmap(QRect(QRect(0, -skipTopBorder, buttonw - framew , frameh_n)), buffer, QRect(framew, 0, 1, frameh_n));
+ p->drawPixmap(QRect(0, buttonh - frameh_s, buttonw - framew, frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, frameh_s));
+ // Draw upper and lower center blocks
+ p->drawPixmap(QRect(0, frameh_n - skipTopBorder, buttonw - framew, center - frameh_n + skipTopBorder), buffer, QRect(framew, frameh_n, 1, 1));
+ p->drawPixmap(QRect(0, center, buttonw - framew, buttonh - center - frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, 1));
+ // Draw right center block borders
+ p->drawPixmap(QRect(buttonw - framew, frameh_n - skipTopBorder, framew, center - frameh_n), buffer, QRect(buffer.width() - framew, frameh_n, framew, 1));
+ p->drawPixmap(QRect(buttonw - framew, center, framew, buttonh - center - 1), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, 1));
+ // Draw right corners
+ p->drawPixmap(QRect(buttonw - framew, -skipTopBorder, framew, frameh_n), buffer, QRect(buffer.width() - framew, 0, framew, frameh_n));
+ p->drawPixmap(QRect(buttonw - framew, buttonh - frameh_s, framew, frameh_s), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, frameh_s));
+ // Draw center transition block
+ p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), buttonw - framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(framew, frameh_n + 1, 1, transh));
+ // Draw right center transition block border
+ p->drawPixmap(QRect(buttonw - framew, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(buffer.width() - framew, frameh_n + 1, framew, transh));
+ if (drawLeftBorder){
+ // Draw left center block borders
+ p->drawPixmap(QRect(0, frameh_n - skipTopBorder, framew, center - frameh_n + skipTopBorder), buffer, QRect(0, frameh_n, framew, 1));
+ p->drawPixmap(QRect(0, center, framew, buttonh - center - 1), buffer, QRect(0, buffer.height() - frameh_s, framew, 1));
+ // Draw left corners
+ p->drawPixmap(QRect(0, -skipTopBorder, framew, frameh_n), buffer, QRect(0, 0, framew, frameh_n));
+ p->drawPixmap(QRect(0, buttonh - frameh_s, framew, frameh_s), buffer, QRect(0, buffer.height() - frameh_s, framew, frameh_s));
+ // Draw left center transition block border
+ p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(0, frameh_n + 1, framew, transh));
+ }
+
+ p->translate(-outerBounds.origin.x, -outerBounds.origin.y);
+}
+
+/*
+ Returns cutoff sizes for scroll bars.
+ thumbIndicatorCutoff is the smallest size where the thumb indicator is drawn.
+ scrollButtonsCutoff is the smallest size where the up/down buttons is drawn.
+*/
+enum ScrollBarCutoffType { thumbIndicatorCutoff = 0, scrollButtonsCutoff = 1 };
+static int scrollButtonsCutoffSize(ScrollBarCutoffType cutoffType, QMacStyle::WidgetSizePolicy widgetSize)
+{
+ // Mini scroll bars do not exist as of version 10.4.
+ if (widgetSize == QMacStyle::SizeMini)
+ return 0;
+
+ const int sizeIndex = (widgetSize == QMacStyle::SizeSmall) ? 1 : 0;
+ static const int sizeTable[2][2] = { { 61, 56 }, { 49, 44 } };
+ return sizeTable[sizeIndex][cutoffType];
+}
+
+void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
+ HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe)
+{
+ memset(tdi, 0, sizeof(HIThemeTrackDrawInfo)); // We don't get it all for some reason or another...
+ tdi->version = qt_mac_hitheme_version;
+ tdi->reserved = 0;
+ tdi->filler1 = 0;
+ bool isScrollbar = (cc == QStyle::CC_ScrollBar);
+ switch (aquaSizeConstrain(0, needToRemoveMe)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ if (isScrollbar)
+ tdi->kind = kThemeMediumScrollBar;
+ else
+ tdi->kind = kThemeMediumSlider;
+ break;
+ case QAquaSizeMini:
+ if (isScrollbar)
+ tdi->kind = kThemeSmallScrollBar; // should be kThemeMiniScrollBar, but not implemented
+ else
+ tdi->kind = kThemeMiniSlider;
+ break;
+ case QAquaSizeSmall:
+ if (isScrollbar)
+ tdi->kind = kThemeSmallScrollBar;
+ else
+ tdi->kind = kThemeSmallSlider;
+ break;
+ }
+ tdi->bounds = qt_hirectForQRect(slider->rect);
+ tdi->min = slider->minimum;
+ tdi->max = slider->maximum;
+ tdi->value = slider->sliderPosition;
+ tdi->attributes = kThemeTrackShowThumb;
+ if (slider->upsideDown)
+ tdi->attributes |= kThemeTrackRightToLeft;
+ if (slider->orientation == Qt::Horizontal) {
+ tdi->attributes |= kThemeTrackHorizontal;
+ if (isScrollbar && slider->direction == Qt::RightToLeft) {
+ if (!slider->upsideDown)
+ tdi->attributes |= kThemeTrackRightToLeft;
+ else
+ tdi->attributes &= ~kThemeTrackRightToLeft;
+ }
+ }
+
+ // Tiger broke reverse scroll bars so put them back and "fake it"
+ if (isScrollbar && (tdi->attributes & kThemeTrackRightToLeft)) {
+ tdi->attributes &= ~kThemeTrackRightToLeft;
+ tdi->value = tdi->max - slider->sliderPosition;
+ }
+
+ tdi->enableState = (slider->state & QStyle::State_Enabled) ? kThemeTrackActive
+ : kThemeTrackDisabled;
+ if (!(slider->state & QStyle::State_Active))
+ tdi->enableState = kThemeTrackInactive;
+ if (!isScrollbar) {
+ if (slider->state & QStyle::QStyle::State_HasFocus)
+ tdi->attributes |= kThemeTrackHasFocus;
+ if (slider->tickPosition == QSlider::NoTicks || slider->tickPosition == QSlider::TicksBothSides)
+ tdi->trackInfo.slider.thumbDir = kThemeThumbPlain;
+ else if (slider->tickPosition == QSlider::TicksAbove)
+ tdi->trackInfo.slider.thumbDir = kThemeThumbUpward;
+ else
+ tdi->trackInfo.slider.thumbDir = kThemeThumbDownward;
+ } else {
+ tdi->trackInfo.scrollbar.viewsize = slider->pageStep;
+ }
+}
+#endif
+
+QMacStylePrivate::QMacStylePrivate(QMacStyle *style)
+ : timerID(-1), progressFrame(0), q(style), mouseDown(false)
+{
+ defaultButtonStart = CFAbsoluteTimeGetCurrent();
+ memset(&buttonState, 0, sizeof(ButtonState));
+
+ if (ptrHIShapeGetBounds == 0) {
+ QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
+ library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
+ ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
+ }
+
+}
+
+bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QWidget *w) const
+{
+ if (!w)
+ return false;
+
+ if (as == AquaPushButton) {
+ QPushButton *pb = const_cast<QPushButton *>(static_cast<const QPushButton *>(w));
+ if (w->window()->isActiveWindow() && pb && !mouseDown) {
+ if (static_cast<const QPushButton *>(w) != defaultButton) {
+ // Changed on its own, update the value.
+ const_cast<QMacStylePrivate *>(this)->stopAnimate(as, defaultButton);
+ const_cast<QMacStylePrivate *>(this)->startAnimate(as, pb);
+ }
+ return true;
+ }
+ } else if (as == AquaProgressBar) {
+ if (progressBars.contains((const_cast<QWidget *>(w))))
+ return true;
+ }
+ return false;
+}
+
+void QMacStylePrivate::stopAnimate(QMacStylePrivate::Animates as, QWidget *w)
+{
+ if (as == AquaPushButton && defaultButton) {
+ QPushButton *tmp = defaultButton;
+ defaultButton = 0;
+ tmp->update();
+ } else if (as == AquaProgressBar) {
+ progressBars.removeAll(w);
+ }
+}
+
+void QMacStylePrivate::startAnimate(QMacStylePrivate::Animates as, QWidget *w)
+{
+ if (as == AquaPushButton)
+ defaultButton = static_cast<QPushButton *>(w);
+ else if (as == AquaProgressBar)
+ progressBars.append(w);
+ startAnimationTimer();
+}
+
+void QMacStylePrivate::startAnimationTimer()
+{
+ if ((defaultButton || !progressBars.isEmpty()) && timerID <= -1)
+ timerID = startTimer(animateSpeed(AquaListViewItemOpen));
+}
+
+bool QMacStylePrivate::addWidget(QWidget *w)
+{
+ //already knew of it
+ if (static_cast<QPushButton*>(w) == defaultButton
+ || progressBars.contains(static_cast<QProgressBar*>(w)))
+ return false;
+
+ if (QPushButton *btn = qobject_cast<QPushButton *>(w)) {
+ btn->installEventFilter(this);
+ if (btn->isDefault() || (btn->autoDefault() && btn->hasFocus()))
+ startAnimate(AquaPushButton, btn);
+ return true;
+ } else {
+ bool isProgressBar = (qobject_cast<QProgressBar *>(w)
+#ifdef QT3_SUPPORT
+ || w->inherits("Q3ProgressBar")
+#endif
+ );
+ if (isProgressBar) {
+ w->installEventFilter(this);
+ startAnimate(AquaProgressBar, w);
+ return true;
+ }
+ }
+ if (w->isWindow()) {
+ w->installEventFilter(this);
+ return true;
+ }
+ return false;
+}
+
+void QMacStylePrivate::removeWidget(QWidget *w)
+{
+ QPushButton *btn = qobject_cast<QPushButton *>(w);
+ if (btn && btn == defaultButton) {
+ stopAnimate(AquaPushButton, btn);
+ } else if (qobject_cast<QProgressBar *>(w)
+#ifdef QT3_SUPPORT
+ || w->inherits("Q3ProgressBar")
+#endif
+ ) {
+ stopAnimate(AquaProgressBar, w);
+ }
+}
+
+ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
+{
+ ThemeDrawState tds = kThemeStateActive;
+ if (flags & QStyle::State_Sunken) {
+ tds = kThemeStatePressed;
+ } else if (flags & QStyle::State_Active) {
+ if (!(flags & QStyle::State_Enabled))
+ tds = kThemeStateUnavailable;
+ } else {
+ if (flags & QStyle::State_Enabled)
+ tds = kThemeStateInactive;
+ else
+ tds = kThemeStateUnavailableInactive;
+ }
+ return tds;
+}
+
+void QMacStylePrivate::timerEvent(QTimerEvent *)
+{
+ int animated = 0;
+ if (defaultButton && defaultButton->isEnabled() && defaultButton->window()->isActiveWindow()
+ && defaultButton->isVisibleTo(0) && (defaultButton->isDefault()
+ || (defaultButton->autoDefault() && defaultButton->hasFocus()))
+ && doAnimate(AquaPushButton)) {
+ ++animated;
+ defaultButton->update();
+ }
+ if (!progressBars.isEmpty()) {
+ int i = 0;
+ while (i < progressBars.size()) {
+ QWidget *maybeProgress = progressBars.at(i);
+ if (!maybeProgress) {
+ progressBars.removeAt(i);
+ } else {
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(maybeProgress)) {
+ if (pb->maximum() == 0 || (pb->value() > 0 && pb->value() < pb->maximum())) {
+ if (doAnimate(AquaProgressBar))
+ pb->update();
+ }
+ }
+#ifdef QT3_SUPPORT
+ else {
+ // Watch me now...
+ QVariant progress = maybeProgress->property("progress");
+ QVariant totalSteps = maybeProgress->property("totalSteps");
+ if (progress.isValid() && totalSteps.isValid()) {
+ int intProgress = progress.toInt();
+ int intTotalSteps = totalSteps.toInt();
+ if (intTotalSteps == 0 || intProgress > 0 && intProgress < intTotalSteps) {
+ if (doAnimate(AquaProgressBar))
+ maybeProgress->update();
+ }
+ }
+ }
+#endif
+ ++i;
+ }
+ }
+ if (i > 0) {
+ ++progressFrame;
+ animated += i;
+ }
+ }
+ if (animated <= 0) {
+ killTimer(timerID);
+ timerID = -1;
+ }
+}
+
+bool QMacStylePrivate::eventFilter(QObject *o, QEvent *e)
+{
+ //animate
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(o)) {
+ switch (e->type()) {
+ default:
+ break;
+ case QEvent::Show:
+ if (!progressBars.contains(pb))
+ startAnimate(AquaProgressBar, pb);
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ progressBars.removeAll(pb);
+ }
+ } else if (QPushButton *btn = qobject_cast<QPushButton *>(o)) {
+ switch (e->type()) {
+ default:
+ break;
+ case QEvent::FocusIn:
+ if (btn->autoDefault())
+ startAnimate(AquaPushButton, btn);
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ if (btn == defaultButton)
+ stopAnimate(AquaPushButton, btn);
+ break;
+ case QEvent::MouseButtonPress:
+ // It is very confusing to keep the button pulsing, so just stop the animation.
+ if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
+ mouseDown = true;
+ stopAnimate(AquaPushButton, btn);
+ break;
+ case QEvent::MouseButtonRelease:
+ if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
+ mouseDown = false;
+ // fall through
+ case QEvent::FocusOut:
+ case QEvent::Show:
+ case QEvent::WindowActivate: {
+ QList<QPushButton *> list = btn->window()->findChildren<QPushButton *>();
+ for (int i = 0; i < list.size(); ++i) {
+ QPushButton *pBtn = list.at(i);
+ if ((e->type() == QEvent::FocusOut
+ && (pBtn->isDefault() || (pBtn->autoDefault() && pBtn->hasFocus()))
+ && pBtn != btn)
+ || ((e->type() == QEvent::Show || e->type() == QEvent::MouseButtonRelease
+ || e->type() == QEvent::WindowActivate)
+ && pBtn->isDefault())) {
+ if (pBtn->window()->isActiveWindow()) {
+ startAnimate(AquaPushButton, pBtn);
+ }
+ break;
+ }
+ }
+ break; }
+ }
+ }
+ return false;
+}
+
+bool QMacStylePrivate::doAnimate(QMacStylePrivate::Animates as)
+{
+ if (as == AquaPushButton) {
+ } else if (as == AquaProgressBar) {
+ // something for later...
+ } else if (as == AquaListViewItemOpen) {
+ // To be revived later...
+ }
+ return true;
+}
+
+void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
+ QPainter *p, const QStyleOption *opt) const
+{
+ int xoff = 0,
+ yoff = 0,
+ extraWidth = 0,
+ extraHeight = 0,
+ finalyoff = 0;
+
+ const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt);
+ int width = int(macRect.size.width) + extraWidth;
+ int height = int(macRect.size.height) + extraHeight;
+
+ if (width <= 0 || height <= 0)
+ return; // nothing to draw
+
+ QString key = QLatin1String("$qt_mac_style_ctb_") + QString::number(bdi->kind) + QLatin1Char('_')
+ + QString::number(bdi->value) + QLatin1Char('_') + QString::number(width)
+ + QLatin1Char('_') + QString::number(height);
+ QPixmap pm;
+ if (!QPixmapCache::find(key, pm)) {
+ QPixmap activePixmap(width, height);
+ activePixmap.fill(Qt::transparent);
+ {
+ if (combo){
+ // Carbon combos don't scale. Therefore we draw it
+ // ourselves, if a scaled version is needed.
+ QPainter tmpPainter(&activePixmap);
+ QMacStylePrivate::drawCombobox(macRect, *bdi, &tmpPainter);
+ }
+ else {
+ QMacCGContext cg(&activePixmap);
+ HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
+ HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+
+ if (!combo && bdi->value == kThemeButtonOff) {
+ pm = activePixmap;
+ } else if (combo) {
+ QImage image = activePixmap.toImage();
+
+ for (int y = 0; y < height; ++y) {
+ QRgb *scanLine = reinterpret_cast<QRgb *>(image.scanLine(y));
+
+ for (int x = 0; x < width; ++x) {
+ QRgb &pixel = scanLine[x];
+
+ int darkest = qRed(pixel);
+ int mid = qGreen(pixel);
+ int lightest = qBlue(pixel);
+
+ if (darkest > mid)
+ qSwap(darkest, mid);
+ if (mid > lightest)
+ qSwap(mid, lightest);
+ if (darkest > mid)
+ qSwap(darkest, mid);
+
+ int gray = (mid + 2 * lightest) / 3;
+ pixel = qRgba(gray, gray, gray, qAlpha(pixel));
+ }
+ }
+ pm = QPixmap::fromImage(image);
+ } else {
+ QImage activeImage = activePixmap.toImage();
+ QImage colorlessImage;
+ {
+ QPixmap colorlessPixmap(width, height);
+ colorlessPixmap.fill(Qt::transparent);
+
+ QMacCGContext cg(&colorlessPixmap);
+ HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
+ int oldValue = bdi->value;
+ bdi->value = kThemeButtonOff;
+ HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
+ bdi->value = oldValue;
+ colorlessImage = colorlessPixmap.toImage();
+ }
+
+ for (int y = 0; y < height; ++y) {
+ QRgb *colorlessScanLine = reinterpret_cast<QRgb *>(colorlessImage.scanLine(y));
+ const QRgb *activeScanLine = reinterpret_cast<const QRgb *>(activeImage.scanLine(y));
+
+ for (int x = 0; x < width; ++x) {
+ QRgb &colorlessPixel = colorlessScanLine[x];
+ QRgb activePixel = activeScanLine[x];
+
+ if (activePixel != colorlessPixel) {
+ int max = qMax(qMax(qRed(activePixel), qGreen(activePixel)),
+ qBlue(activePixel));
+ QRgb newPixel = qRgba(max, max, max, qAlpha(activePixel));
+ if (qGray(newPixel) < qGray(colorlessPixel)
+ || qAlpha(newPixel) > qAlpha(colorlessPixel))
+ colorlessPixel = newPixel;
+ }
+ }
+ }
+ pm = QPixmap::fromImage(colorlessImage);
+ }
+ QPixmapCache::insert(key, pm);
+ }
+ p->drawPixmap(int(macRect.origin.x), int(macRect.origin.y) + finalyoff, width, height, pm);
+}
+
+QMacStyle::QMacStyle()
+ : QWindowsStyle()
+{
+ d = new QMacStylePrivate(this);
+}
+
+QMacStyle::~QMacStyle()
+{
+ delete qt_mac_backgroundPattern;
+ qt_mac_backgroundPattern = 0;
+ delete d;
+}
+
+/*! \internal
+ Generates the standard widget background pattern.
+*/
+QPixmap QMacStylePrivate::generateBackgroundPattern() const
+{
+ QPixmap px(4, 4);
+ QMacCGContext cg(&px);
+ HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationNormal);
+ const CGRect cgRect = CGRectMake(0, 0, px.width(), px.height());
+ CGContextFillRect(cg, cgRect);
+ return px;
+}
+
+/*! \internal
+ Fills the given \a rect with the pattern stored in \a brush. As an optimization,
+ HIThemeSetFill us used directly if we are filling with the standard background.
+*/
+void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
+{
+ QPoint dummy;
+ const QPaintDevice *target = painter->device();
+ const QPaintDevice *redirected = QPainter::redirected(target, &dummy);
+ const bool usePainter = redirected && redirected != target;
+
+ if (!usePainter && qt_mac_backgroundPattern
+ && qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) {
+
+ painter->setClipRegion(rgn);
+
+ QCFType<CGContextRef> cg = qt_mac_cg_context(target);
+ CGContextSaveGState(cg);
+ HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted);
+
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect rect(rects.at(i));
+ // Anchor the pattern to the top so it stays put when the window is resized.
+ CGContextSetPatternPhase(cg, CGSizeMake(rect.width(), rect.height()));
+ CGRect mac_rect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
+ CGContextFillRect(cg, mac_rect);
+ }
+
+ CGContextRestoreGState(cg);
+ } else {
+ const QRect rect(rgn.boundingRect());
+ painter->setClipRegion(rgn);
+ painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
+ }
+}
+
+void QMacStyle::polish(QPalette &pal)
+{
+ if (!qt_mac_backgroundPattern) {
+ if (!qApp)
+ return;
+ qt_mac_backgroundPattern = new QPixmap(d->generateBackgroundPattern());
+ }
+
+ QColor pc(Qt::black);
+ pc = qcolorForTheme(kThemeBrushDialogBackgroundActive);
+ QBrush background(pc, *qt_mac_backgroundPattern);
+ pal.setBrush(QPalette::All, QPalette::Window, background);
+ pal.setBrush(QPalette::All, QPalette::Button, background);
+
+ QCFString theme;
+ const OSErr err = CopyThemeIdentifier(&theme);
+ if (err == noErr && CFStringCompare(theme, kThemeAppearanceAquaGraphite, 0) == kCFCompareEqualTo) {
+ pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(240, 240, 240));
+ } else {
+ pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(237, 243, 254));
+ }
+}
+
+void QMacStyle::polish(QApplication *)
+{
+}
+
+void QMacStyle::unpolish(QApplication *)
+{
+}
+
+void QMacStyle::polish(QWidget* w)
+{
+ d->addWidget(w);
+ if (qt_mac_is_metal(w) && !w->testAttribute(Qt::WA_SetPalette)) {
+ // Set a clear brush so that the metal shines through.
+ QPalette pal = w->palette();
+ QBrush background(Qt::transparent);
+ pal.setBrush(QPalette::All, QPalette::Window, background);
+ pal.setBrush(QPalette::All, QPalette::Button, background);
+ w->setPalette(pal);
+ w->setAttribute(Qt::WA_SetPalette, false);
+ }
+
+ if (qobject_cast<QMenu*>(w) || qobject_cast<QComboBoxPrivateContainer *>(w)) {
+ w->setWindowOpacity(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 ? 0.985 : 0.94);
+ if (!w->testAttribute(Qt::WA_SetPalette)) {
+ QPixmap px(64, 64);
+ px.fill(Qt::white);
+ HIThemeMenuDrawInfo mtinfo;
+ mtinfo.version = qt_mac_hitheme_version;
+ mtinfo.menuType = kThemeMenuTypePopUp;
+ HIRect rect = CGRectMake(0, 0, px.width(), px.height());
+ HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType<CGContextRef>(qt_mac_cg_context(&px)),
+ kHIThemeOrientationNormal);
+ QPalette pal = w->palette();
+ QBrush background(px);
+ pal.setBrush(QPalette::All, QPalette::Window, background);
+ pal.setBrush(QPalette::All, QPalette::Button, background);
+ w->setPalette(pal);
+ w->setAttribute(Qt::WA_SetPalette, false);
+ }
+ }
+
+ if (QTabBar *tb = qobject_cast<QTabBar*>(w)) {
+ if (tb->documentMode()) {
+ w->setAttribute(Qt::WA_Hover);
+ w->setFont(qt_app_fonts_hash()->value("QSmallFont", QFont()));
+ QPalette p = w->palette();
+ p.setColor(QPalette::WindowText, QColor(17, 17, 17));
+ w->setPalette(p);
+ }
+ }
+
+ QWindowsStyle::polish(w);
+
+ if (QRubberBand *rubber = qobject_cast<QRubberBand*>(w)) {
+ rubber->setWindowOpacity(0.25);
+ rubber->setAttribute(Qt::WA_PaintOnScreen, false);
+ rubber->setAttribute(Qt::WA_NoSystemBackground, false);
+ }
+}
+
+void QMacStyle::unpolish(QWidget* w)
+{
+ d->removeWidget(w);
+ if ((qobject_cast<QMenu*>(w) || qt_mac_is_metal(w)) && !w->testAttribute(Qt::WA_SetPalette)) {
+ QPalette pal = qApp->palette(w);
+ w->setPalette(pal);
+ w->setAttribute(Qt::WA_SetPalette, false);
+ w->setWindowOpacity(1.0);
+ }
+
+ if (QComboBox *combo = qobject_cast<QComboBox *>(w)) {
+ if (!combo->isEditable()) {
+ if (QWidget *widget = combo->findChild<QComboBoxPrivateContainer *>())
+ widget->setWindowOpacity(1.0);
+ }
+ }
+
+ if (QRubberBand *rubber = ::qobject_cast<QRubberBand*>(w)) {
+ rubber->setWindowOpacity(1.0);
+ rubber->setAttribute(Qt::WA_PaintOnScreen, true);
+ rubber->setAttribute(Qt::WA_NoSystemBackground, true);
+ }
+
+ if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w))
+ frame->setAttribute(Qt::WA_NoSystemBackground, true);
+
+ QWindowsStyle::unpolish(w);
+}
+
+int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const
+{
+ int controlSize = getControlSize(opt, widget);
+ SInt32 ret = 0;
+
+ switch (metric) {
+ case PM_TabCloseIndicatorWidth:
+ case PM_TabCloseIndicatorHeight:
+ ret = closeButtonSize;
+ break;
+ case PM_ToolBarIconSize:
+ ret = proxy()->pixelMetric(PM_LargeIconSize);
+ break;
+ case PM_FocusFrameVMargin:
+ case PM_FocusFrameHMargin:
+ GetThemeMetric(kThemeMetricFocusRectOutset, &ret);
+ break;
+ case PM_DialogButtonsSeparator:
+ ret = -5;
+ break;
+ case PM_DialogButtonsButtonHeight: {
+ QSize sz;
+ ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
+ if (sz == QSize(-1, -1))
+ ret = 32;
+ else
+ ret = sz.height();
+ break; }
+ case PM_CheckListButtonSize: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
+ break;
+ }
+ break; }
+ case PM_DialogButtonsButtonWidth: {
+ QSize sz;
+ ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
+ if (sz == QSize(-1, -1))
+ ret = 70;
+ else
+ ret = sz.width();
+ break; }
+
+ case PM_MenuBarHMargin:
+ ret = 8;
+ break;
+
+ case PM_MenuBarVMargin:
+ ret = 0;
+ break;
+
+ case QStyle::PM_MenuDesktopFrameWidth:
+ ret = 5;
+ break;
+
+ case PM_CheckBoxLabelSpacing:
+ case PM_RadioButtonLabelSpacing:
+ ret = 2;
+ break;
+ case PM_MenuScrollerHeight:
+#if 0
+ SInt16 ash, asw;
+ GetThemeMenuItemExtra(kThemeMenuItemScrollUpArrow, &ash, &asw);
+ ret = ash;
+#else
+ ret = 15; // I hate having magic numbers in here...
+#endif
+ break;
+ case PM_DefaultFrameWidth:
+#ifndef QT_NO_MAINWINDOW
+ if (widget && (widget->isWindow() || !widget->parentWidget()
+ || (qobject_cast<const QMainWindow*>(widget->parentWidget())
+ && static_cast<QMainWindow *>(widget->parentWidget())->centralWidget() == widget))
+ && (qobject_cast<const QAbstractScrollArea *>(widget)
+#ifdef QT3_SUPPORT
+ || widget->inherits("QScrollView")
+#endif
+ || widget->inherits("QWorkspaceChild")))
+ ret = 0;
+ else
+#endif
+ // The combo box popup has no frame.
+ if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
+ ret = 0;
+ // Frame of mac style line edits is two pixels on top and one on the bottom
+ else if (qobject_cast<const QLineEdit *>(widget) != 0)
+ ret = 2;
+ else
+ ret = 1;
+ break;
+ case PM_MaximumDragDistance:
+ ret = -1;
+ break;
+ case PM_ScrollBarSliderMin:
+ ret = 24;
+ break;
+ case PM_SpinBoxFrameWidth:
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &ret);
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ default:
+ ret += 2;
+ break;
+ case QAquaSizeMini:
+ ret += 1;
+ break;
+ }
+ break;
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+ case PM_SliderLength:
+ ret = 17;
+ break;
+ case PM_ButtonDefaultIndicator:
+ ret = 0;
+ break;
+ case PM_TitleBarHeight:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ HIThemeWindowDrawInfo wdi;
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = kThemeStateActive;
+ wdi.windowType = QtWinType;
+ if (tb->titleBarState)
+ wdi.attributes = kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
+ | kThemeWindowHasCollapseBox;
+ else if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ wdi.attributes = kThemeWindowHasCloseBox;
+ else
+ wdi.attributes = 0;
+ wdi.titleHeight = tb->rect.height();
+ wdi.titleWidth = tb->rect.width();
+ QCFType<HIShapeRef> region;
+ HIRect hirect = qt_hirectForQRect(tb->rect);
+ if (hirect.size.width <= 0)
+ hirect.size.width = 100;
+ if (hirect.size.height <= 0)
+ hirect.size.height = 30;
+
+ HIThemeGetWindowShape(&hirect, &wdi, kWindowTitleBarRgn, &region);
+ HIRect rect;
+ ptrHIShapeGetBounds(region, &rect);
+ ret = int(rect.size.height);
+ ret += 4;
+ }
+ break;
+ case PM_TabBarTabVSpace:
+ ret = 4;
+ break;
+ case PM_TabBarTabShiftHorizontal:
+ case PM_TabBarTabShiftVertical:
+ ret = 0;
+ break;
+ case PM_TabBarBaseHeight:
+ ret = 0;
+ break;
+ case PM_TabBarTabOverlap:
+ ret = 0;
+ break;
+ case PM_TabBarBaseOverlap:
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ ret = 11;
+ break;
+ case QAquaSizeSmall:
+ ret = 8;
+ break;
+ case QAquaSizeMini:
+ ret = 7;
+ break;
+ }
+ break;
+ case PM_ScrollBarExtent: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricScrollBarWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallScrollBarWidth, &ret);
+ break;
+ }
+ break; }
+ case PM_IndicatorHeight: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricCheckBoxHeight, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniCheckBoxHeight, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallCheckBoxHeight, &ret);
+ break;
+ }
+ break; }
+ case PM_IndicatorWidth: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
+ break;
+ }
+ ++ret;
+ break; }
+ case PM_ExclusiveIndicatorHeight: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricRadioButtonHeight, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniRadioButtonHeight, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallRadioButtonHeight, &ret);
+ break;
+ }
+ break; }
+ case PM_ExclusiveIndicatorWidth: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricRadioButtonWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniRadioButtonWidth, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallRadioButtonWidth, &ret);
+ break;
+ }
+ ++ret;
+ break; }
+ case PM_MenuVMargin:
+ ret = 4;
+ break;
+ case PM_MenuPanelWidth:
+ ret = 0;
+ break;
+ case PM_ToolTipLabelFrameWidth:
+ ret = 0;
+ break;
+ case PM_SizeGripSize: {
+ QAquaWidgetSize aSize;
+ if (widget && widget->window()->windowType() == Qt::Tool)
+ aSize = QAquaSizeSmall;
+ else
+ aSize = QAquaSizeLarge;
+ const QSize size = qt_aqua_get_known_size(CT_SizeGrip, widget, QSize(), aSize);
+ ret = size.width();
+ break; }
+ case PM_MdiSubWindowFrameWidth:
+ ret = 1;
+ break;
+ case PM_DockWidgetFrameWidth:
+ ret = 2;
+ break;
+ case PM_DockWidgetTitleMargin:
+ ret = 0;
+ break;
+ case PM_DockWidgetSeparatorExtent:
+ ret = 1;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = 11;
+ break;
+ case PM_ToolBarItemMargin:
+ ret = 0;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 4;
+ break;
+ case PM_SplitterWidth:
+ ret = qMax(7, QApplication::globalStrut().width());
+ break;
+ case PM_LayoutLeftMargin:
+ case PM_LayoutTopMargin:
+ case PM_LayoutRightMargin:
+ case PM_LayoutBottomMargin:
+ {
+ bool isWindow = false;
+ if (opt) {
+ isWindow = (opt->state & State_Window);
+ } else if (widget) {
+ isWindow = widget->isWindow();
+ }
+
+ if (isWindow) {
+ bool isMetal = widget && widget->testAttribute(Qt::WA_MacBrushedMetal);
+ if (isMetal) {
+ if (metric == PM_LayoutTopMargin) {
+ return_SIZE(9 /* AHIG */, 6 /* guess */, 6 /* guess */);
+ } else if (metric == PM_LayoutBottomMargin) {
+ return_SIZE(18 /* AHIG */, 15 /* guess */, 13 /* guess */);
+ } else {
+ return_SIZE(14 /* AHIG */, 11 /* guess */, 9 /* guess */);
+ }
+ } else {
+ /*
+ AHIG would have (20, 8, 10) here but that makes
+ no sense. It would also have 14 for the top margin
+ but this contradicts both Builder and most
+ applications.
+ */
+ return_SIZE(20, 10, 10); // AHIG
+ }
+ } else {
+ // hack to detect QTabWidget
+ if (widget && widget->parentWidget()
+ && widget->parentWidget()->sizePolicy().controlType() == QSizePolicy::TabWidget) {
+ if (metric == PM_LayoutTopMargin) {
+ /*
+ Builder would have 14 (= 20 - 6) instead of 12,
+ but that makes the tab look disproportionate.
+ */
+ return_SIZE(12, 6, 6); // guess
+ } else {
+ return_SIZE(20 /* Builder */, 8 /* guess */, 8 /* guess */);
+ }
+ } else {
+ /*
+ Child margins are highly inconsistent in AHIG and Builder.
+ */
+ return_SIZE(12, 8, 6); // guess
+ }
+ }
+ }
+ case PM_LayoutHorizontalSpacing:
+ case PM_LayoutVerticalSpacing:
+ return -1;
+ case QStyle::PM_TabBarTabHSpace:
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeLarge:
+ case QAquaSizeUnknown:
+ ret = QWindowsStyle::pixelMetric(metric, opt, widget);
+ break;
+ case QAquaSizeSmall:
+ ret = 20;
+ break;
+ case QAquaSizeMini:
+ ret = 16;
+ break;
+ }
+ break;
+ case PM_MenuHMargin:
+ ret = 0;
+ break;
+ case PM_ToolBarFrameWidth:
+ ret = 1;
+ if (widget) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
+ if (mainWindow->unifiedTitleAndToolBarOnMac())
+ ret = 0;
+ }
+ break;
+ default:
+ ret = QWindowsStyle::pixelMetric(metric, opt, widget);
+ break;
+ }
+ return ret;
+}
+
+QPalette QMacStyle::standardPalette() const
+{
+ QPalette pal = QWindowsStyle::standardPalette();
+ pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
+ pal.setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
+ pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
+ return pal;
+}
+
+int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
+ QStyleHintReturn *hret) const
+{
+ SInt32 ret = 0;
+ switch (sh) {
+ case SH_Menu_SelectionWrap:
+ ret = false;
+ break;
+ case SH_Menu_KeyboardSearch:
+ ret = true;
+ break;
+ case SH_Menu_SpaceActivatesItem:
+ ret = true;
+ break;
+ case SH_Slider_AbsoluteSetButtons:
+ ret = Qt::LeftButton|Qt::MidButton;
+ break;
+ case SH_Slider_PageSetButtons:
+ ret = 0;
+ break;
+ case SH_ScrollBar_ContextMenu:
+ ret = false;
+ break;
+ case SH_TitleBar_AutoRaise:
+ ret = true;
+ break;
+ case SH_Menu_AllowActiveAndDisabled:
+ ret = false;
+ break;
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 100;
+ break;
+ case SH_ScrollBar_LeftClickAbsolutePosition: {
+ extern bool qt_scrollbar_jump_to_pos; //qapplication_mac.cpp
+ if(QApplication::keyboardModifiers() & Qt::AltModifier)
+ ret = !qt_scrollbar_jump_to_pos;
+ else
+ ret = qt_scrollbar_jump_to_pos;
+ break; }
+ case SH_TabBar_PreferNoArrows:
+ ret = true;
+ break;
+ case SH_LineEdit_PasswordCharacter:
+ ret = kBulletUnicode;
+ break;
+ /*
+ case SH_DialogButtons_DefaultButton:
+ ret = QDialogButtons::Reject;
+ break;
+ */
+ case SH_Menu_SloppySubMenus:
+ ret = true;
+ break;
+ case SH_GroupBox_TextLabelVerticalAlignment:
+ ret = Qt::AlignTop;
+ break;
+ case SH_ScrollView_FrameOnlyAroundContents:
+ if (w && (w->isWindow() || !w->parentWidget() || w->parentWidget()->isWindow())
+ && (w->inherits("QWorkspaceChild")
+#ifdef QT3_SUPPORT
+ || w->inherits("QScrollView")
+#endif
+ ))
+ ret = true;
+ else
+ ret = QWindowsStyle::styleHint(sh, opt, w, hret);
+ break;
+ case SH_Menu_FillScreenWithScroll:
+ ret = false;
+ break;
+ case SH_Menu_Scrollable:
+ ret = true;
+ break;
+ case SH_RichText_FullWidthSelection:
+ ret = true;
+ break;
+ case SH_BlinkCursorWhenTextSelected:
+ ret = false;
+ break;
+ case SH_ScrollBar_StopMouseOverSlider:
+ ret = true;
+ break;
+ case SH_Q3ListViewExpand_SelectMouseType:
+ ret = QEvent::MouseButtonRelease;
+ break;
+ case SH_TabBar_SelectMouseType:
+ if (const QStyleOptionTabBarBaseV2 *opt2 = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
+ ret = opt2->documentMode ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
+ } else {
+ ret = QEvent::MouseButtonRelease;
+ }
+ break;
+ case SH_ComboBox_Popup:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt))
+ ret = !cmb->editable;
+ else
+ ret = 0;
+ break;
+ case SH_Workspace_FillSpaceOnMaximize:
+ ret = true;
+ break;
+ case SH_Widget_ShareActivation:
+ ret = true;
+ break;
+ case SH_Header_ArrowAlignment:
+ ret = Qt::AlignRight;
+ break;
+ case SH_TabBar_Alignment: {
+ if (const QTabWidget *tab = qobject_cast<const QTabWidget*>(w)) {
+ if (tab->documentMode()) {
+ ret = Qt::AlignLeft;
+ break;
+ }
+ }
+ if (const QTabBar *tab = qobject_cast<const QTabBar*>(w)) {
+ if (tab->documentMode()) {
+ ret = Qt::AlignLeft;
+ break;
+ }
+ }
+ ret = Qt::AlignCenter;
+ } break;
+ case SH_UnderlineShortcut:
+ ret = false;
+ break;
+ case SH_ToolTipLabel_Opacity:
+ ret = 242; // About 95%
+ break;
+ case SH_Button_FocusPolicy:
+ ret = Qt::TabFocus;
+ break;
+ case SH_EtchDisabledText:
+ ret = false;
+ break;
+ case SH_FocusFrame_Mask: {
+ ret = true;
+ if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
+ const uchar fillR = 192, fillG = 191, fillB = 190;
+ QImage img;
+
+ QSize pixmapSize = opt->rect.size();
+ if (pixmapSize.isValid()) {
+ QPixmap pix(pixmapSize);
+ pix.fill(QColor(fillR, fillG, fillB));
+ QPainter pix_paint(&pix);
+ proxy()->drawControl(CE_FocusFrame, opt, &pix_paint, w);
+ pix_paint.end();
+ img = pix.toImage();
+ }
+
+ const QRgb *sptr = (QRgb*)img.bits(), *srow;
+ const int sbpl = img.bytesPerLine();
+ const int w = sbpl/4, h = img.height();
+
+ QImage img_mask(img.width(), img.height(), QImage::Format_ARGB32);
+ QRgb *dptr = (QRgb*)img_mask.bits(), *drow;
+ const int dbpl = img_mask.bytesPerLine();
+
+ for (int y = 0; y < h; ++y) {
+ srow = sptr+((y*sbpl)/4);
+ drow = dptr+((y*dbpl)/4);
+ for (int x = 0; x < w; ++x) {
+ const int diff = (((qRed(*srow)-fillR)*(qRed(*srow)-fillR)) +
+ ((qGreen(*srow)-fillG)*((qGreen(*srow)-fillG))) +
+ ((qBlue(*srow)-fillB)*((qBlue(*srow)-fillB))));
+ (*drow++) = (diff < 100) ? 0xffffffff : 0xff000000;
+ ++srow;
+ }
+ }
+ QBitmap qmask = QBitmap::fromImage(img_mask);
+ mask->region = QRegion(qmask);
+ }
+ break; }
+ case SH_TitleBar_NoBorder:
+ ret = 1;
+ break;
+ case SH_RubberBand_Mask:
+ ret = 0;
+ break;
+ case SH_ComboBox_LayoutDirection:
+ ret = Qt::LeftToRight;
+ break;
+ case SH_ItemView_EllipsisLocation:
+ ret = Qt::AlignHCenter;
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+ ret = true;
+ break;
+ case SH_TitleBar_ModifyNotification:
+ ret = false;
+ break;
+ case SH_ScrollBar_RollBetweenButtons:
+ ret = true;
+ break;
+ case SH_WindowFrame_Mask:
+ ret = 1;
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(hret)) {
+ mask->region = opt->rect;
+ mask->region -= QRect(opt->rect.left(), opt->rect.top(), 5, 1);
+ mask->region -= QRect(opt->rect.left(), opt->rect.top() + 1, 3, 1);
+ mask->region -= QRect(opt->rect.left(), opt->rect.top() + 2, 2, 1);
+ mask->region -= QRect(opt->rect.left(), opt->rect.top() + 3, 1, 2);
+
+ mask->region -= QRect(opt->rect.right() - 4, opt->rect.top(), 5, 1);
+ mask->region -= QRect(opt->rect.right() - 2, opt->rect.top() + 1, 3, 1);
+ mask->region -= QRect(opt->rect.right() - 1, opt->rect.top() + 2, 2, 1);
+ mask->region -= QRect(opt->rect.right() , opt->rect.top() + 3, 1, 2);
+ }
+ break;
+ case SH_TabBar_ElideMode:
+ ret = Qt::ElideRight;
+ break;
+ case SH_DialogButtonLayout:
+ ret = QDialogButtonBox::MacLayout;
+ break;
+ case SH_FormLayoutWrapPolicy:
+ ret = QFormLayout::DontWrapRows;
+ break;
+ case SH_FormLayoutFieldGrowthPolicy:
+ ret = QFormLayout::FieldsStayAtSizeHint;
+ break;
+ case SH_FormLayoutFormAlignment:
+ ret = Qt::AlignHCenter | Qt::AlignTop;
+ break;
+ case SH_FormLayoutLabelAlignment:
+ ret = Qt::AlignRight;
+ break;
+ case SH_ComboBox_PopupFrameStyle:
+ ret = QFrame::NoFrame | QFrame::Plain;
+ break;
+ case SH_MessageBox_TextInteractionFlags:
+ ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard;
+ break;
+ case SH_SpellCheckUnderlineStyle:
+ ret = QTextCharFormat::DashUnderline;
+ break;
+ case SH_MessageBox_CenterButtons:
+ ret = false;
+ break;
+ case SH_MenuBar_AltKeyNavigation:
+ ret = false;
+ break;
+ case SH_ItemView_MovementWithoutUpdatingSelection:
+ ret = false;
+ break;
+ case SH_FocusFrame_AboveWidget:
+ ret = true;
+ break;
+ case SH_WizardStyle:
+ ret = QWizard::MacStyle;
+ break;
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = false;
+ break;
+ case SH_Menu_FlashTriggeredItem:
+ ret = true;
+ break;
+ case SH_Menu_FadeOutOnHide:
+ ret = true;
+ break;
+ case SH_Menu_Mask:
+ if (opt) {
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
+ ret = true;
+ HIRect menuRect = CGRectMake(opt->rect.x(), opt->rect.y() + 4,
+ opt->rect.width(), opt->rect.height() - 8);
+ HIThemeMenuDrawInfo mdi;
+ mdi.version = 0;
+ if (w && qobject_cast<QMenu *>(w->parentWidget()))
+ mdi.menuType = kThemeMenuTypeHierarchical;
+ else
+ mdi.menuType = kThemeMenuTypePopUp;
+ QCFType<HIShapeRef> shape;
+ HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape);
+ mask->region = QRegion::fromHIShapeRef(shape);
+ }
+ }
+ break;
+ case SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
+ ret = true;
+ break;
+ case SH_TabBar_CloseButtonPosition:
+ ret = QTabBar::LeftSide;
+ break;
+ case SH_DockWidget_ButtonsHaveFrame:
+ ret = false;
+ break;
+ default:
+ ret = QWindowsStyle::styleHint(sh, opt, w, hret);
+ break;
+ }
+ return ret;
+}
+
+QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const
+{
+ switch (iconMode) {
+ case QIcon::Disabled: {
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ int imgh = img.height();
+ int imgw = img.width();
+ QRgb pixel;
+ for (int y = 0; y < imgh; ++y) {
+ for (int x = 0; x < imgw; ++x) {
+ pixel = img.pixel(x, y);
+ img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel),
+ qAlpha(pixel) / 2));
+ }
+ }
+ return QPixmap::fromImage(img);
+ }
+ default:
+ ;
+ }
+ return QWindowsStyle::generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+
+QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ // The default implementation of QStyle::standardIconImplementation() is to call standardPixmap()
+ // I don't want infinite recursion so if we do get in that situation, just return the Window's
+ // standard pixmap instead (since there is no mac-specific icon then). This should be fine until
+ // someone changes how Windows standard
+ // pixmap works.
+ static bool recursionGuard = false;
+
+ if (recursionGuard)
+ return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
+
+ recursionGuard = true;
+ QIcon icon = standardIconImplementation(standardPixmap, opt, widget);
+ recursionGuard = false;
+ int size;
+ switch (standardPixmap) {
+ default:
+ size = 32;
+ break;
+ case SP_MessageBoxCritical:
+ case SP_MessageBoxQuestion:
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxWarning:
+ size = 64;
+ break;
+ }
+ return icon.pixmap(size, size);
+}
+
+void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy)
+{
+ switch (policy) {
+ case FocusDefault:
+ break;
+ case FocusEnabled:
+ case FocusDisabled:
+ w->setAttribute(Qt::WA_MacShowFocusRect, policy == FocusEnabled);
+ break;
+ }
+}
+
+QMacStyle::FocusRectPolicy QMacStyle::focusRectPolicy(const QWidget *w)
+{
+ return w->testAttribute(Qt::WA_MacShowFocusRect) ? FocusEnabled : FocusDisabled;
+}
+
+void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy)
+{
+ QWidget *wadget = const_cast<QWidget *>(widget);
+ wadget->setAttribute(Qt::WA_MacNormalSize, policy == SizeLarge);
+ wadget->setAttribute(Qt::WA_MacSmallSize, policy == SizeSmall);
+ wadget->setAttribute(Qt::WA_MacMiniSize, policy == SizeMini);
+}
+
+QMacStyle::WidgetSizePolicy QMacStyle::widgetSizePolicy(const QWidget *widget)
+{
+ while (widget) {
+ if (widget->testAttribute(Qt::WA_MacMiniSize)) {
+ return SizeMini;
+ } else if (widget->testAttribute(Qt::WA_MacSmallSize)) {
+ return SizeSmall;
+ } else if (widget->testAttribute(Qt::WA_MacNormalSize)) {
+ return SizeLarge;
+ }
+ widget = widget->parentWidget();
+ }
+ return SizeDefault;
+}
+
+void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ QMacCGContext cg(p);
+ switch (pe) {
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft: {
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ int xOffset = opt->direction == Qt::LeftToRight ? 2 : -1;
+ QMatrix matrix;
+ matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
+ QPainterPath path;
+ switch(pe) {
+ default:
+ case PE_IndicatorArrowDown:
+ break;
+ case PE_IndicatorArrowUp:
+ matrix.rotate(180);
+ break;
+ case PE_IndicatorArrowLeft:
+ matrix.rotate(90);
+ break;
+ case PE_IndicatorArrowRight:
+ matrix.rotate(-90);
+ break;
+ }
+ path.moveTo(0, 5);
+ path.lineTo(-4, -3);
+ path.lineTo(4, -3);
+ p->setMatrix(matrix);
+ p->setPen(Qt::NoPen);
+ p->setBrush(QColor(0, 0, 0, 135));
+ p->drawPath(path);
+ p->restore();
+ break; }
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBaseV2 *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
+ if (tbb->documentMode) {
+ p->save();
+ drawTabBase(p, tbb, w);
+ p->restore();
+ return;
+ }
+
+ QRegion region(tbb->rect);
+ region -= tbb->tabBarRect;
+ p->save();
+ p->setClipRegion(region);
+ QStyleOptionTabWidgetFrame twf;
+ twf.QStyleOption::operator=(*tbb);
+ twf.shape = tbb->shape;
+ switch (getTabDirection(twf.shape)) {
+ case kThemeTabNorth:
+ twf.rect = twf.rect.adjusted(0, 0, 0, 10);
+ break;
+ case kThemeTabSouth:
+ twf.rect = twf.rect.adjusted(0, -10, 0, 0);
+ break;
+ case kThemeTabWest:
+ twf.rect = twf.rect.adjusted(0, 0, 10, 0);
+ break;
+ case kThemeTabEast:
+ twf.rect = twf.rect.adjusted(0, -10, 0, 0);
+ break;
+ }
+ proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p, w);
+ p->restore();
+ }
+ break;
+ case PE_PanelTipLabel:
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::ToolTipBase));
+ break;
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrame *groupBox = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt);
+ if (frame2 && frame2->features & QStyleOptionFrameV2::Flat) {
+ QWindowsStyle::drawPrimitive(pe, groupBox, p, w);
+ } else {
+ HIThemeGroupBoxDrawInfo gdi;
+ gdi.version = qt_mac_hitheme_version;
+ gdi.state = tds;
+ if (w && qobject_cast<QGroupBox *>(w->parentWidget()))
+ gdi.kind = kHIThemeGroupBoxKindSecondary;
+ else
+ gdi.kind = kHIThemeGroupBoxKindPrimary;
+ HIRect hirect = qt_hirectForQRect(opt->rect);
+ HIThemeDrawGroupBox(&hirect, &gdi, cg, kHIThemeOrientationNormal);
+ }
+ }
+ break;
+ case PE_IndicatorToolBarSeparator: {
+ QPainterPath path;
+ if (opt->state & State_Horizontal) {
+ int xpoint = opt->rect.center().x();
+ path.moveTo(xpoint + 0.5, opt->rect.top() + 1);
+ path.lineTo(xpoint + 0.5, opt->rect.bottom());
+ } else {
+ int ypoint = opt->rect.center().y();
+ path.moveTo(opt->rect.left() + 2 , ypoint + 0.5);
+ path.lineTo(opt->rect.right() + 1, ypoint + 0.5);
+ }
+ QPainterPathStroker theStroker;
+ theStroker.setCapStyle(Qt::FlatCap);
+ theStroker.setDashPattern(QVector<qreal>() << 1 << 2);
+ path = theStroker.createStroke(path);
+ p->fillPath(path, QColor(0, 0, 0, 119));
+ }
+ break;
+ case PE_FrameWindow:
+ break;
+ case PE_IndicatorDockWidgetResizeHandle: {
+ // The docwidget resize handle is drawn as a one-pixel wide line.
+ p->save();
+ if (opt->state & State_Horizontal) {
+ p->setPen(QColor(160, 160, 160));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ } else {
+ p->setPen(QColor(145, 145, 145));
+ p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
+ }
+ p->restore();
+ } break;
+ case PE_IndicatorToolBarHandle: {
+ p->save();
+ QPainterPath path;
+ int x = opt->rect.x() + 6;
+ int y = opt->rect.y() + 5;
+ static const int RectHeight = 2;
+ if (opt->state & State_Horizontal) {
+ while (y < opt->rect.height() - RectHeight - 6) {
+ path.moveTo(x, y);
+ path.addRect(x, y, RectHeight, RectHeight);
+ y += 6;
+ }
+ } else {
+ while (x < opt->rect.width() - RectHeight - 6) {
+ path.moveTo(x, y);
+ path.addRect(x, y, RectHeight, RectHeight);
+ x += 6;
+ }
+ }
+ p->setPen(Qt::NoPen);
+ QColor dark = opt->palette.dark().color();
+ dark.setAlphaF(0.75);
+ QColor light = opt->palette.light().color();
+ light.setAlphaF(0.6);
+ p->fillPath(path, light);
+ p->save();
+ p->translate(1, 1);
+ p->fillPath(path, dark);
+ p->restore();
+ p->translate(3, 3);
+ p->fillPath(path, light);
+ p->translate(1, 1);
+ p->fillPath(path, dark);
+ p->restore();
+
+ break;
+ }
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ // In HITheme, up is down, down is up and hamburgers eat people.
+ if (header->sortIndicator != QStyleOptionHeader::None)
+ proxy()->drawPrimitive(
+ (header->sortIndicator == QStyleOptionHeader::SortDown) ?
+ PE_IndicatorArrowUp : PE_IndicatorArrowDown, header, p, w);
+ }
+ break;
+ case PE_IndicatorMenuCheckMark: {
+ const int checkw = 8;
+ const int checkh = 8;
+ const int xoff = qMax(0, (opt->rect.width() - checkw) / 2);
+ const int yoff = qMax(0, (opt->rect.width() - checkh) / 2);
+ const int x1 = xoff + opt->rect.x();
+ const int y1 = yoff + opt->rect.y() + checkw/2;
+ const int x2 = xoff + opt->rect.x() + checkw/4;
+ const int y2 = yoff + opt->rect.y() + checkh;
+ const int x3 = xoff + opt->rect.x() + checkw;
+ const int y3 = yoff + opt->rect.y();
+
+ QVector<QLineF> a(2);
+ a << QLineF(x1, y1, x2, y2);
+ a << QLineF(x2, y2, x3, y3);
+ if (opt->palette.currentColorGroup() == QPalette::Active)
+ p->setPen(QPen(Qt::white, 3));
+ else
+ p->setPen(QPen(QColor(100, 100, 100), 3));
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ p->drawLines(a);
+ p->restore();
+ break; }
+ case PE_IndicatorViewItemCheck:
+ case PE_Q3CheckListExclusiveIndicator:
+ case PE_Q3CheckListIndicator:
+ case PE_IndicatorRadioButton:
+ case PE_IndicatorCheckBox: {
+ bool drawColorless = (!(opt->state & State_Active))
+ && opt->palette.currentColorGroup() == QPalette::Active;
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = tds;
+ if (drawColorless && tds == kThemeStateInactive)
+ bdi.state = kThemeStateActive;
+ bdi.adornment = kThemeDrawIndicatorOnly;
+ if (opt->state & State_HasFocus)
+ bdi.adornment |= kThemeAdornmentFocus;
+ bool isRadioButton = (pe == PE_Q3CheckListExclusiveIndicator
+ || pe == PE_IndicatorRadioButton);
+ switch (d->aquaSizeConstrain(opt, w)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ if (isRadioButton)
+ bdi.kind = kThemeRadioButton;
+ else
+ bdi.kind = kThemeCheckBox;
+ break;
+ case QAquaSizeMini:
+ if (isRadioButton)
+ bdi.kind = kThemeMiniRadioButton;
+ else
+ bdi.kind = kThemeMiniCheckBox;
+ break;
+ case QAquaSizeSmall:
+ if (isRadioButton)
+ bdi.kind = kThemeSmallRadioButton;
+ else
+ bdi.kind = kThemeSmallCheckBox;
+ break;
+ }
+ if (opt->state & State_NoChange)
+ bdi.value = kThemeButtonMixed;
+ else if (opt->state & State_On)
+ bdi.value = kThemeButtonOn;
+ else
+ bdi.value = kThemeButtonOff;
+ HIRect macRect;
+ if (pe == PE_Q3CheckListExclusiveIndicator || pe == PE_Q3CheckListIndicator)
+ macRect = qt_hirectForQRect(opt->rect);
+ else
+ macRect = qt_hirectForQRect(opt->rect);
+ if (!drawColorless)
+ HIThemeDrawButton(&macRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ else
+ d->drawColorlessButton(macRect, &bdi, p, opt);
+ break; }
+ case PE_FrameFocusRect:
+ // Use the our own focus widget stuff.
+ break;
+ case PE_IndicatorBranch: {
+ if (!(opt->state & State_Children))
+ break;
+ HIThemeButtonDrawInfo bi;
+ bi.version = qt_mac_hitheme_version;
+ bi.state = tds;
+ if (tds == kThemeStateInactive && opt->palette.currentColorGroup() == QPalette::Active)
+ bi.state = kThemeStateActive;
+ if (opt->state & State_Sunken)
+ bi.state |= kThemeStatePressed;
+ bi.kind = kThemeDisclosureButton;
+ if (opt->state & State_Open)
+ bi.value = kThemeDisclosureDown;
+ else
+ bi.value = opt->direction == Qt::LeftToRight ? kThemeDisclosureRight : kThemeDisclosureLeft;
+ bi.adornment = kThemeAdornmentNone;
+ HIRect hirect = qt_hirectForQRect(opt->rect.adjusted(DisclosureOffset,0,-DisclosureOffset,0));
+ HIThemeDrawButton(&hirect, &bi, cg, kHIThemeOrientationNormal, 0);
+ break; }
+
+ case PE_Frame: {
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.base().color().darker(140));
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(opt->palette.base().color().darker(180));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->setPen(oldPen);
+ break; }
+
+ case PE_FrameLineEdit:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (frame->state & State_Sunken) {
+ QColor baseColor(frame->palette.background().color());
+ HIThemeFrameDrawInfo fdi;
+ fdi.version = qt_mac_hitheme_version;
+ fdi.state = tds;
+ SInt32 frame_size;
+ if (pe == PE_FrameLineEdit) {
+ fdi.kind = kHIThemeFrameTextFieldSquare;
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
+ if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled))
+ fdi.state = kThemeStateInactive;
+ } else {
+ baseColor = QColor(150, 150, 150); //hardcoded since no query function --Sam
+ fdi.kind = kHIThemeFrameListBox;
+ GetThemeMetric(kThemeMetricListBoxFrameOutset, &frame_size);
+ }
+ fdi.isFocused = (frame->state & State_HasFocus);
+ int lw = frame->lineWidth;
+ if (lw <= 0)
+ lw = proxy()->pixelMetric(PM_DefaultFrameWidth, frame, w);
+ { //clear to base color
+ p->save();
+ p->setPen(QPen(baseColor, lw));
+ p->setBrush(Qt::NoBrush);
+ p->drawRect(frame->rect);
+ p->restore();
+ }
+ HIRect hirect = qt_hirectForQRect(frame->rect,
+ QRect(frame_size, frame_size,
+ frame_size * 2, frame_size * 2));
+
+ HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
+ } else {
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ }
+ }
+ break;
+ case PE_PanelLineEdit:
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ // Draw the focus frame for widgets other than QLineEdit (e.g. for line edits in Webkit).
+ // Focus frame is drawn outside the rectangle passed in the option-rect.
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if ((opt->state & State_HasFocus) && !qobject_cast<const QLineEdit*>(w)) {
+ int vmargin = pixelMetric(QStyle::PM_FocusFrameVMargin);
+ int hmargin = pixelMetric(QStyle::PM_FocusFrameHMargin);
+ QStyleOptionFrame focusFrame = *panel;
+ focusFrame.rect = panel->rect.adjusted(-hmargin, -vmargin, hmargin, vmargin);
+ drawControl(CE_FocusFrame, &focusFrame, p, w);
+ }
+ }
+
+ break;
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ HIRect hirect = qt_hirectForQRect(twf->rect);
+ HIThemeTabPaneDrawInfo tpdi;
+ tpdi.version = qt_mac_hitheme_tab_version();
+ tpdi.state = tds;
+ tpdi.direction = getTabDirection(twf->shape);
+ tpdi.size = kHIThemeTabSizeNormal;
+ tpdi.kind = kHIThemeTabKindNormal;
+ tpdi.adornment = kHIThemeTabPaneAdornmentNormal;
+ HIThemeDrawTabPane(&hirect, &tpdi, cg, kHIThemeOrientationNormal);
+ }
+ break;
+ case PE_PanelScrollAreaCorner: {
+ const QBrush brush(opt->palette.brush(QPalette::Base));
+ p->fillRect(opt->rect, brush);
+ p->setPen(QPen(QColor(217, 217, 217)));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
+ } break;
+ case PE_FrameStatusBarItem:
+ break;
+ case PE_IndicatorTabClose: {
+ bool hover = (opt->state & State_MouseOver);
+ bool selected = (opt->state & State_Selected);
+ bool active = (opt->state & State_Active);
+ drawTabCloseButton(p, hover, active, selected);
+ } break;
+ case PE_PanelStatusBar: {
+ if (QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4) {
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+ // Use the Leopard style only if the status bar is the status bar for a
+ // QMainWindow with a unifed toolbar.
+ if (w == 0 || w->parent() == 0 || qobject_cast<QMainWindow *>(w->parent()) == 0 ||
+ qobject_cast<QMainWindow *>(w->parent())->unifiedTitleAndToolBarOnMac() == false ) {
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+
+ // Fill the status bar with the titlebar gradient.
+ QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
+ if (opt->state & QStyle::State_Active) {
+ linearGrad.setColorAt(0, titlebarGradientActiveBegin);
+ linearGrad.setColorAt(1, titlebarGradientActiveEnd);
+ } else {
+ linearGrad.setColorAt(0, titlebarGradientInactiveBegin);
+ linearGrad.setColorAt(1, titlebarGradientInactiveEnd);
+ }
+ p->fillRect(opt->rect, linearGrad);
+
+ // Draw the black separator line at the top of the status bar.
+ if (opt->state & QStyle::State_Active)
+ p->setPen(titlebarSeparatorLineActive);
+ else
+ p->setPen(titlebarSeparatorLineInactive);
+ p->drawLine(opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.top());
+
+ break;
+ }
+
+ default:
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+}
+
+static inline QPixmap darkenPixmap(const QPixmap &pixmap)
+{
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ int imgh = img.height();
+ int imgw = img.width();
+ int h, s, v, a;
+ QRgb pixel;
+ for (int y = 0; y < imgh; ++y) {
+ for (int x = 0; x < imgw; ++x) {
+ pixel = img.pixel(x, y);
+ a = qAlpha(pixel);
+ QColor hsvColor(pixel);
+ hsvColor.getHsv(&h, &s, &v);
+ s = qMin(100, s * 2);
+ v = v / 2;
+ hsvColor.setHsv(h, s, v);
+ pixel = hsvColor.rgb();
+ img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a));
+ }
+ }
+ return QPixmap::fromImage(img);
+}
+
+
+
+void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ QMacCGContext cg(p);
+ switch (ce) {
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ State flags = header->state;
+ QRect ir = header->rect;
+ bdi.kind = kThemeListHeaderButton;
+ bdi.adornment = kThemeAdornmentNone;
+ bdi.state = kThemeStateActive;
+
+ if (flags & State_On)
+ bdi.value = kThemeButtonOn;
+ else
+ bdi.value = kThemeButtonOff;
+
+ if (header->orientation == Qt::Horizontal){
+ switch (header->position) {
+ case QStyleOptionHeader::Beginning:
+ ir.adjust(-1, -1, 0, 0);
+ break;
+ case QStyleOptionHeader::Middle:
+ ir.adjust(-1, -1, 0, 0);
+ break;
+ case QStyleOptionHeader::OnlyOneSection:
+ case QStyleOptionHeader::End:
+ ir.adjust(-1, -1, 1, 0);
+ break;
+ default:
+ break;
+ }
+
+ if (header->position != QStyleOptionHeader::Beginning
+ && header->position != QStyleOptionHeader::OnlyOneSection) {
+ bdi.adornment = header->direction == Qt::LeftToRight
+ ? kThemeAdornmentHeaderButtonLeftNeighborSelected
+ : kThemeAdornmentHeaderButtonRightNeighborSelected;
+ }
+ }
+
+ if (flags & State_Active) {
+ if (!(flags & State_Enabled))
+ bdi.state = kThemeStateUnavailable;
+ else if (flags & State_Sunken)
+ bdi.state = kThemeStatePressed;
+ } else {
+ if (flags & State_Enabled)
+ bdi.state = kThemeStateInactive;
+ else
+ bdi.state = kThemeStateUnavailableInactive;
+ }
+
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ bdi.value = kThemeButtonOn;
+ if (header->sortIndicator == QStyleOptionHeader::SortDown)
+ bdi.adornment = kThemeAdornmentHeaderButtonSortUp;
+ }
+ if (flags & State_HasFocus)
+ bdi.adornment = kThemeAdornmentFocus;
+
+ ir = visualRect(header->direction, header->rect, ir);
+ HIRect bounds = qt_hirectForQRect(ir);
+
+ bool noVerticalHeader = true;
+ if (w)
+ if (const QTableView *table = qobject_cast<const QTableView *>(w->parentWidget()))
+ noVerticalHeader = !table->verticalHeader()->isVisible();
+
+ bool drawTopBorder = header->orientation == Qt::Horizontal;
+ bool drawLeftBorder = header->orientation == Qt::Vertical
+ || header->position == QStyleOptionHeader::OnlyOneSection
+ || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader);
+ d->drawTableHeader(bounds, drawTopBorder, drawLeftBorder, bdi, p);
+ }
+ break;
+ case CE_HeaderLabel:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRect textr = header->rect;
+ if (!header->icon.isNull()) {
+ QIcon::Mode mode = QIcon::Disabled;
+ if (opt->state & State_Enabled)
+ mode = QIcon::Normal;
+ QPixmap pixmap = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), mode);
+
+ QRect pixr = header->rect;
+ pixr.setY(header->rect.center().y() - (pixmap.height() - 1) / 2);
+ proxy()->drawItemPixmap(p, pixr, Qt::AlignVCenter, pixmap);
+ textr.translate(pixmap.width() + 2, 0);
+ }
+
+ proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette,
+ header->state & State_Enabled, header->text, QPalette::ButtonText);
+ }
+ break;
+ case CE_ToolButtonLabel:
+ if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QStyleOptionToolButton myTb = *tb;
+ myTb.state &= ~State_AutoRaise;
+ if (w && qobject_cast<QToolBar *>(w->parentWidget())) {
+ QRect cr = tb->rect;
+ int shiftX = 0;
+ int shiftY = 0;
+ bool needText = false;
+ int alignment = 0;
+ bool down = tb->state & (State_Sunken | State_On);
+ if (down) {
+ shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, w);
+ shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, tb, w);
+ }
+ // The down state is special for QToolButtons in a toolbar on the Mac
+ // The text is a bit bolder and gets a drop shadow and the icons are also darkened.
+ // This doesn't really fit into any particular case in QIcon, so we
+ // do the majority of the work ourselves.
+ if (!(tb->features & QStyleOptionToolButton::Arrow)) {
+ Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle;
+ if (tb->icon.isNull() && !tb->text.isEmpty())
+ tbstyle = Qt::ToolButtonTextOnly;
+
+ switch (tbstyle) {
+ case Qt::ToolButtonTextOnly: {
+ needText = true;
+ alignment = Qt::AlignCenter;
+ break; }
+ case Qt::ToolButtonIconOnly:
+ case Qt::ToolButtonTextBesideIcon:
+ case Qt::ToolButtonTextUnderIcon: {
+ QRect pr = cr;
+ QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal
+ : QIcon::Disabled;
+ QIcon::State iconState = (tb->state & State_On) ? QIcon::On
+ : QIcon::Off;
+ QPixmap pixmap = tb->icon.pixmap(tb->rect.size().boundedTo(tb->iconSize), iconMode, iconState);
+
+ // Draw the text if it's needed.
+ if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
+ needText = true;
+ if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
+ QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
+ if (mw && mw->unifiedTitleAndToolBarOnMac()) {
+ pr.setHeight(pixmap.size().height());
+ cr.adjust(0, pr.bottom() + 1, 0, 1);
+ } else {
+ pr.setHeight(pixmap.size().height() + 6);
+ cr.adjust(0, pr.bottom(), 0, -3);
+ }
+ alignment |= Qt::AlignCenter;
+ } else {
+ pr.setWidth(pixmap.width() + 8);
+ cr.adjust(pr.right(), 0, 0, 0);
+ alignment |= Qt::AlignLeft | Qt::AlignVCenter;
+ }
+ }
+ if (opt->state & State_Sunken) {
+ pr.translate(shiftX, shiftY);
+ pixmap = darkenPixmap(pixmap);
+ }
+ proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pixmap);
+ break; }
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ if (needText) {
+ QPalette pal = tb->palette;
+ QPalette::ColorRole role = QPalette::NoRole;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, tb, w))
+ alignment |= Qt::TextHideMnemonic;
+ if (down)
+ cr.translate(shiftX, shiftY);
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5
+ && (tbstyle == Qt::ToolButtonTextOnly
+ || (tbstyle != Qt::ToolButtonTextOnly && !down))) {
+ QPen pen = p->pen();
+ QColor light = down ? Qt::black : Qt::white;
+ light.setAlphaF(0.375f);
+ p->setPen(light);
+ p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text);
+ p->setPen(pen);
+ if (down && tbstyle == Qt::ToolButtonTextOnly) {
+ pal = QApplication::palette("QMenu");
+ pal.setCurrentColorGroup(tb->palette.currentColorGroup());
+ role = QPalette::HighlightedText;
+ }
+ }
+ proxy()->drawItemText(p, cr, alignment, pal,
+ tb->state & State_Enabled, tb->text, role);
+ if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 &&
+ (tb->state & State_Sunken)) {
+ // Draw a "drop shadow" in earlier versions.
+ proxy()->drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment,
+ tb->palette, tb->state & State_Enabled, tb->text);
+ }
+ }
+ } else {
+ QWindowsStyle::drawControl(ce, &myTb, p, w);
+ }
+ } else {
+ QWindowsStyle::drawControl(ce, &myTb, p, w);
+ }
+ }
+ break;
+ case CE_ToolBoxTabShape:
+ QCommonStyle::drawControl(ce, opt, p, w);
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = ::qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (!(btn->state & (State_Raised | State_Sunken | State_On)))
+ break;
+
+ if (btn->features & QStyleOptionButton::CommandLinkButton) {
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ break;
+ }
+
+ HIThemeButtonDrawInfo bdi;
+ d->initHIThemePushButton(btn, w, tds, &bdi);
+ if (btn->features & QStyleOptionButton::DefaultButton
+ && d->animatable(QMacStylePrivate::AquaPushButton, w)) {
+ bdi.adornment |= kThemeAdornmentDefault;
+ bdi.animation.time.start = d->defaultButtonStart;
+ bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
+ if (d->timerID <= -1)
+ QMetaObject::invokeMethod(d, "startAnimationTimer", Qt::QueuedConnection);
+ }
+ // Unlike Carbon, we want the button to always be drawn inside its bounds.
+ // Therefore, make the button a bit smaller, so that even if it got focus,
+ // the focus 'shadow' will be inside.
+ HIRect newRect = qt_hirectForQRect(btn->rect);
+ if (bdi.kind == kThemePushButton || bdi.kind == kThemePushButtonSmall) {
+ newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset;
+ newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ newRect.size.width -= QMacStylePrivate::PushButtonRightOffset;
+ newRect.size.height -= QMacStylePrivate::PushButtonBottomOffset;
+ } else if (bdi.kind == kThemePushButtonMini) {
+ newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset - 2;
+ newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4;
+ }
+ HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
+ QRect ir = btn->rect;
+ HIRect arrowRect = CGRectMake(ir.right() - mbi - QMacStylePrivate::PushButtonRightOffset,
+ ir.height() / 2 - 4, mbi, ir.height() / 2);
+ bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
+ if (drawColorless && tds == kThemeStateInactive)
+ tds = kThemeStateActive;
+
+ HIThemePopupArrowDrawInfo pdi;
+ pdi.version = qt_mac_hitheme_version;
+ pdi.state = tds;
+ pdi.orientation = kThemeArrowDown;
+ if (arrowRect.size.width < 8.)
+ pdi.size = kThemeArrow5pt;
+ else
+ pdi.size = kThemeArrow9pt;
+ HIThemeDrawPopupArrow(&arrowRect, &pdi, cg, kHIThemeOrientationNormal);
+ }
+ }
+ break;
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ // We really don't want the label to be drawn the same as on
+ // windows style if it has an icon and text, then it should be more like a
+ // tab. So, cheat a little here. However, if it *is* only an icon
+ // the windows style works great, so just use that implementation.
+ bool hasMenu = btn->features & QStyleOptionButton::HasMenu;
+ bool hasIcon = !btn->icon.isNull();
+ bool hasText = !btn->text.isEmpty();
+ if (!hasIcon && !hasMenu) {
+ // ### this is really overly difficult, simplify.
+ // It basically tries to get the right font for "small" and "mini" icons.
+ QFont oldFont = p->font();
+ QFont newFont = qt_app_fonts_hash()->value("QPushButton", QFont());
+ ThemeFontID themeId = kThemePushButtonFont;
+ if (oldFont == newFont) { // Yes, use HITheme to draw the text for small sizes.
+ switch (d->aquaSizeConstrain(opt, w)) {
+ default:
+ break;
+ case QAquaSizeSmall:
+ themeId = kThemeSmallSystemFont;
+ break;
+ case QAquaSizeMini:
+ themeId = kThemeMiniSystemFont;
+ break;
+ }
+ }
+ if (themeId == kThemePushButtonFont) {
+ QWindowsStyle::drawControl(ce, btn, p, w);
+ } else {
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ QColor textColor = btn->palette.buttonText().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ tti.fontID = themeId;
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + btn->text.count(QLatin1Char('\n'));
+ QCFString buttonText = qt_mac_removeMnemonics(btn->text);
+ QRect r = btn->rect;
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(buttonText, &bounds, &tti,
+ cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ } else {
+ if (hasIcon && !hasText) {
+ QWindowsStyle::drawControl(ce, btn, p, w);
+ } else {
+ QRect freeContentRect = btn->rect;
+ QRect textRect = itemTextRect(
+ btn->fontMetrics, freeContentRect, Qt::AlignCenter, btn->state & State_Enabled, btn->text);
+ if (hasMenu)
+ textRect.adjust(-1, 0, -1, 0);
+ // Draw the icon:
+ if (hasIcon) {
+ int contentW = textRect.width();
+ if (hasMenu)
+ contentW += proxy()->pixelMetric(PM_MenuButtonIndicator) + 4;
+ QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && btn->state & State_HasFocus)
+ mode = QIcon::Active;
+ // Decide if the icon is should be on or off:
+ QIcon::State state = QIcon::Off;
+ if (btn->state & State_On)
+ state = QIcon::On;
+ QPixmap pixmap = btn->icon.pixmap(btn->iconSize, mode, state);
+ contentW += pixmap.width() + QMacStylePrivate::PushButtonContentPadding;
+ int iconLeftOffset = freeContentRect.x() + (freeContentRect.width() - contentW) / 2;
+ int iconTopOffset = freeContentRect.y() + (freeContentRect.height() - pixmap.height()) / 2;
+ QRect iconDestRect(iconLeftOffset, iconTopOffset, pixmap.width(), pixmap.height());
+ QRect visualIconDestRect = visualRect(btn->direction, freeContentRect, iconDestRect);
+ proxy()->drawItemPixmap(p, visualIconDestRect, Qt::AlignLeft | Qt::AlignVCenter, pixmap);
+ int newOffset = iconDestRect.x() + iconDestRect.width()
+ + QMacStylePrivate::PushButtonContentPadding - textRect.x();
+ textRect.adjust(newOffset, 0, newOffset, 0);
+ }
+ // Draw the text:
+ if (hasText) {
+ textRect = visualRect(btn->direction, freeContentRect, textRect);
+ proxy()->drawItemText(p, textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, btn->palette,
+ (btn->state & State_Enabled), btn->text, QPalette::ButtonText);
+ }
+ }
+ }
+ }
+ break;
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QStyleOptionComboBox comboCopy = *cb;
+ comboCopy.direction = Qt::LeftToRight;
+ QWindowsStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
+ }
+ break;
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tabOpt = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+
+ if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
+ if (tabOptV3->documentMode) {
+ p->save();
+ QRect tabRect = tabOptV3->rect;
+ drawTabShape(p, tabOptV3);
+ p->restore();
+ return;
+ }
+ }
+ HIThemeTabDrawInfo tdi;
+ tdi.version = 1;
+ tdi.style = kThemeTabNonFront;
+ tdi.direction = getTabDirection(tabOpt->shape);
+ switch (d->aquaSizeConstrain(opt, w)) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tdi.size = kHIThemeTabSizeNormal;
+ break;
+ case QAquaSizeSmall:
+ tdi.size = kHIThemeTabSizeSmall;
+ break;
+ case QAquaSizeMini:
+ tdi.size = kHIThemeTabSizeMini;
+ break;
+ }
+ bool verticalTabs = tdi.direction == kThemeTabWest || tdi.direction == kThemeTabEast;
+ QRect tabRect = tabOpt->rect;
+
+ bool selected = tabOpt->state & State_Selected;
+ if (selected) {
+ if (!(tabOpt->state & State_Active))
+ tdi.style = kThemeTabFrontUnavailable;
+ else if (!(tabOpt->state & State_Enabled))
+ tdi.style = kThemeTabFrontInactive;
+ else
+ tdi.style = kThemeTabFront;
+ } else if (!(tabOpt->state & State_Active)) {
+ tdi.style = kThemeTabNonFrontUnavailable;
+ } else if (!(tabOpt->state & State_Enabled)) {
+ tdi.style = kThemeTabNonFrontInactive;
+ } else if (tabOpt->state & State_Sunken) {
+ tdi.style = kThemeTabFrontInactive; // (should be kThemeTabNonFrontPressed)
+ }
+ if (tabOpt->state & State_HasFocus)
+ tdi.adornment = kHIThemeTabAdornmentFocus;
+ else
+ tdi.adornment = kHIThemeTabAdornmentNone;
+ tdi.kind = kHIThemeTabKindNormal;
+ if (!verticalTabs)
+ tabRect.setY(tabRect.y() - 1);
+ else
+ tabRect.setX(tabRect.x() - 1);
+ QStyleOptionTab::TabPosition tp = tabOpt->position;
+ QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition;
+ if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) {
+ if (sp == QStyleOptionTab::NextIsSelected)
+ sp = QStyleOptionTab::PreviousIsSelected;
+ else if (sp == QStyleOptionTab::PreviousIsSelected)
+ sp = QStyleOptionTab::NextIsSelected;
+ switch (tp) {
+ case QStyleOptionTab::Beginning:
+ tp = QStyleOptionTab::End;
+ break;
+ case QStyleOptionTab::End:
+ tp = QStyleOptionTab::Beginning;
+ break;
+ default:
+ break;
+ }
+ }
+ bool stretchTabs = (!verticalTabs && tabRect.height() > 22) || (verticalTabs && tabRect.width() > 22);
+
+ switch (tp) {
+ case QStyleOptionTab::Beginning:
+ tdi.position = kHIThemeTabPositionFirst;
+ if (sp != QStyleOptionTab::NextIsSelected || stretchTabs)
+ tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
+ break;
+ case QStyleOptionTab::Middle:
+ tdi.position = kHIThemeTabPositionMiddle;
+ if (selected)
+ tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
+ if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) // Also when we're selected.
+ tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
+ break;
+ case QStyleOptionTab::End:
+ tdi.position = kHIThemeTabPositionLast;
+ if (selected)
+ tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
+ break;
+ case QStyleOptionTab::OnlyOneTab:
+ tdi.position = kHIThemeTabPositionOnly;
+ break;
+ }
+ // HITheme doesn't stretch its tabs. Therefore we have to cheat and do the job ourselves.
+ if (stretchTabs) {
+ HIRect hirect = CGRectMake(0, 0, 23, 23);
+ QPixmap pm(23, 23);
+ pm.fill(Qt::transparent);
+ {
+ QMacCGContext pmcg(&pm);
+ HIThemeDrawTab(&hirect, &tdi, pmcg, kHIThemeOrientationNormal, 0);
+ }
+ QStyleHelper::drawBorderPixmap(pm, p, tabRect, 7, 7, 7, 7);
+ } else {
+ HIRect hirect = qt_hirectForQRect(tabRect);
+ HIThemeDrawTab(&hirect, &tdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+ break;
+ case CE_TabBarTabLabel:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ QStyleOptionTabV3 myTab = *tab;
+ ThemeTabDirection ttd = getTabDirection(myTab.shape);
+ bool verticalTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
+
+ // Check to see if we use have the same as the system font
+ // (QComboMenuItem is internal and should never be seen by the
+ // outside world, unless they read the source, in which case, it's
+ // their own fault).
+ bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem");
+ if (verticalTabs || nonDefaultFont || !tab->icon.isNull()
+ || !myTab.leftButtonSize.isNull() || !myTab.rightButtonSize.isNull()) {
+ int heightOffset = 0;
+ if (verticalTabs) {
+ heightOffset = -1;
+ } else if (nonDefaultFont) {
+ if (p->fontMetrics().height() == myTab.rect.height())
+ heightOffset = 2;
+ }
+ myTab.rect.setHeight(myTab.rect.height() + heightOffset);
+
+ if (myTab.documentMode) {
+ p->save();
+ rotateTabPainter(p, myTab.shape, myTab.rect);
+
+ QPalette np = tab->palette;
+ np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
+ QRect nr = subElementRect(SE_TabBarTabText, opt, w);
+ nr.moveTop(-1);
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
+ proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
+ tab->text, QPalette::WindowText);
+ p->restore();
+ }
+
+ QCommonStyle::drawControl(ce, &myTab, p, w);
+ } else {
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ QColor textColor = myTab.palette.windowText().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ switch (d->aquaSizeConstrain(opt, w)) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tti.fontID = kThemeSystemFont;
+ break;
+ case QAquaSizeSmall:
+ tti.fontID = kThemeSmallSystemFont;
+ break;
+ case QAquaSizeMini:
+ tti.fontID = kThemeMiniSystemFont;
+ break;
+ }
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = verticalTabs ? kHIThemeTextBoxOptionStronglyVertical : kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + myTab.text.count(QLatin1Char('\n'));
+ QCFString tabText = qt_mac_removeMnemonics(myTab.text);
+ QRect r = myTab.rect.adjusted(0, 0, 0, -1);
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(tabText, &bounds, &tti, cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ }
+ break;
+ case CE_DockWidgetTitle:
+ if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(w)) {
+ bool floating = dockWidget->isFloating();
+ if (floating) {
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ HIThemeWindowDrawInfo wdi;
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = tds;
+ wdi.windowType = kThemeMovableDialogWindow;
+ wdi.titleHeight = opt->rect.height();
+ wdi.titleWidth = opt->rect.width();
+ wdi.attributes = 0;
+
+ HIRect titleBarRect;
+ HIRect tmpRect = qt_hirectForQRect(opt->rect);
+ {
+ QCFType<HIShapeRef> titleRegion;
+ QRect newr = opt->rect.adjusted(0, 0, 2, 0);
+ HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
+ ptrHIShapeGetBounds(titleRegion, &tmpRect);
+ newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
+ titleBarRect = qt_hirectForQRect(newr);
+ }
+ QMacCGContext cg(p);
+ HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
+ } else {
+ // fill title bar background
+ QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
+ linearGrad.setColorAt(0, mainWindowGradientBegin);
+ linearGrad.setColorAt(1, mainWindowGradientEnd);
+ p->fillRect(opt->rect, linearGrad);
+
+ // draw horizontal lines at top and bottom
+ p->save();
+ p->setPen(mainWindowGradientBegin.lighter(114));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->setPen(mainWindowGradientEnd.darker(114));
+ p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
+ p->restore();
+ }
+ }
+
+ // Draw the text...
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
+ if (!dwOpt->title.isEmpty()) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, w);
+ if (verticalTitleBar) {
+ QRect rect = dwOpt->rect;
+ QRect r = rect;
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ QFont oldFont = p->font();
+ p->setFont(qt_app_fonts_hash()->value("QToolButton", p->font()));
+ QString text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
+ titleRect.width());
+ drawItemText(p, titleRect,
+ Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, text,
+ QPalette::WindowText);
+ p->setFont(oldFont);
+ }
+ }
+ break;
+ case CE_FocusFrame: {
+ int xOff = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, w) + 1;
+ int yOff = proxy()->pixelMetric(PM_FocusFrameVMargin, opt, w) + 1;
+ HIRect hirect = CGRectMake(xOff+opt->rect.x(), yOff+opt->rect.y(), opt->rect.width() - 2 * xOff,
+ opt->rect.height() - 2 * yOff);
+ HIThemeDrawFocusRect(&hirect, true, QMacCGContext(p), kHIThemeOrientationNormal);
+ break; }
+ case CE_MenuItem:
+ case CE_MenuEmptyArea:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ p->fillRect(mi->rect, opt->palette.background());
+ QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, w);
+ int tabwidth = mi->tabWidth;
+ int maxpmw = mi->maxIconWidth;
+ bool active = mi->state & State_Selected;
+ bool enabled = mi->state & State_Enabled;
+ HIRect menuRect = qt_hirectForQRect(mi->menuRect);
+ HIRect itemRect = qt_hirectForQRect(mi->rect);
+ HIThemeMenuItemDrawInfo mdi;
+ mdi.version = qt_mac_hitheme_version;
+ mdi.itemType = kThemeMenuItemPlain;
+ if (!mi->icon.isNull())
+ mdi.itemType |= kThemeMenuItemHasIcon;
+ if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ mdi.itemType |= kThemeMenuItemHierarchical | kThemeMenuItemHierBackground;
+ else
+ mdi.itemType |= kThemeMenuItemPopUpBackground;
+ if (enabled)
+ mdi.state = kThemeMenuActive;
+ else
+ mdi.state = kThemeMenuDisabled;
+ if (active)
+ mdi.state |= kThemeMenuSelected;
+ QRect contentRect;
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ // First arg should be &menurect, but wacky stuff happens then.
+ HIThemeDrawMenuSeparator(&itemRect, &itemRect, &mdi,
+ cg, kHIThemeOrientationNormal);
+ break;
+ } else {
+ HIRect cr;
+ bool needAlpha = mi->palette.color(QPalette::Button) == Qt::transparent;
+ if (needAlpha) {
+ needAlpha = true;
+ CGContextSaveGState(cg);
+ CGContextSetAlpha(cg, 0.0);
+ }
+ HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
+ cg, kHIThemeOrientationNormal, &cr);
+ if (needAlpha)
+ CGContextRestoreGState(cg);
+ if (ce == CE_MenuEmptyArea)
+ break;
+ contentRect = qt_qrectForHIRect(cr);
+ }
+ int xpos = contentRect.x() + 18;
+ int checkcol = maxpmw;
+ if (!enabled)
+ p->setPen(mi->palette.text().color());
+ else if (active)
+ p->setPen(mi->palette.highlightedText().color());
+ else
+ p->setPen(mi->palette.buttonText().color());
+
+ if (mi->checked) {
+ // Use the HIThemeTextInfo foo to draw the check mark correctly, if we do it,
+ // we somehow need to use a special encoding as it doesn't look right with our
+ // drawText().
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ QColor textColor = p->pen().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ if (active && enabled)
+ tti.state = kThemeStatePressed;
+ switch (widgetSize) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tti.fontID = kThemeMenuItemMarkFont;
+ break;
+ case QAquaSizeSmall:
+ tti.fontID = kThemeSmallSystemFont;
+ break;
+ case QAquaSizeMini:
+ tti.fontID = kThemeMiniSystemFont;
+ break;
+ }
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushLeft;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1;
+ QCFString checkmark;
+#if 0
+ if (mi->checkType == QStyleOptionMenuItem::Exclusive)
+ checkmark = QString(QChar(kDiamondUnicode));
+ else
+#endif
+ checkmark = QString(QChar(kCheckUnicode));
+ int mw = checkcol + macItemFrame;
+ int mh = contentRect.height() - 2 * macItemFrame;
+ int xp = contentRect.x();
+ xp += macItemFrame;
+ CGFloat outWidth, outHeight, outBaseline;
+ HIThemeGetTextDimensions(checkmark, 0, &tti, &outWidth, &outHeight,
+ &outBaseline);
+ if (widgetSize == QAquaSizeMini)
+ outBaseline += 1;
+ QRect r(xp, contentRect.y(), mw, mh);
+ r.translate(0, p->fontMetrics().ascent() - int(outBaseline) + 1);
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(checkmark, &bounds, &tti,
+ cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ if (!mi->icon.isNull()) {
+ QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal
+ : QIcon::Disabled;
+ // Always be normal or disabled to follow the Mac style.
+ int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize);
+ QSize iconSize(smallIconSize, smallIconSize);
+ if (const QComboBox *comboBox = qobject_cast<const QComboBox *>(w)) {
+ iconSize = comboBox->iconSize();
+ }
+ QPixmap pixmap = mi->icon.pixmap(iconSize, mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect cr(xpos, contentRect.y(), checkcol, contentRect.height());
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(cr.center());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ xpos += pixw + 6;
+ }
+
+ QString s = mi->text;
+ if (!s.isEmpty()) {
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignRight | Qt::AlignVCenter | Qt::TextHideMnemonic
+ | Qt::TextSingleLine | Qt::AlignAbsolute;
+ int yPos = contentRect.y();
+ if (widgetSize == QAquaSizeMini)
+ yPos += 1;
+ p->save();
+ if (t >= 0) {
+ p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
+ int xp = contentRect.right() - tabwidth - macRightBorder
+ - macItemHMargin - macItemFrame + 1;
+ p->drawText(xp, yPos, tabwidth, contentRect.height(), text_flags,
+ s.mid(t + 1));
+ s = s.left(t);
+ }
+
+ const int xm = macItemFrame + maxpmw + macItemHMargin;
+ QFont myFont = mi->font;
+ // myFont may not have any "hard" flags set. We override
+ // the point size so that when it is resolved against the device, this font will win.
+ // This is mainly to handle cases where someone sets the font on the window
+ // and then the combo inherits it and passes it onward. At that point the resolve mask
+ // is very, very weak. This makes it stonger.
+ myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
+ p->setFont(myFont);
+ p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
+ contentRect.height(), text_flags ^ Qt::AlignRight, s);
+ p->restore();
+ }
+ }
+ break;
+ case CE_MenuHMargin:
+ case CE_MenuVMargin:
+ case CE_MenuTearoff:
+ case CE_MenuScroller:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ p->fillRect(mi->rect, opt->palette.background());
+
+ HIRect menuRect = qt_hirectForQRect(mi->menuRect);
+ HIRect itemRect = qt_hirectForQRect(mi->rect);
+ HIThemeMenuItemDrawInfo mdi;
+ mdi.version = qt_mac_hitheme_version;
+ if (!(opt->state & State_Enabled))
+ mdi.state = kThemeMenuDisabled;
+ else if (opt->state & State_Selected)
+ mdi.state = kThemeMenuSelected;
+ else
+ mdi.state = kThemeMenuActive;
+ if (ce == CE_MenuScroller) {
+ if (opt->state & State_DownArrow)
+ mdi.itemType = kThemeMenuItemScrollDownArrow;
+ else
+ mdi.itemType = kThemeMenuItemScrollUpArrow;
+ } else {
+ mdi.itemType = kThemeMenuItemPlain;
+ }
+ HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
+ cg,
+ kHIThemeOrientationNormal, 0);
+ if (ce == CE_MenuTearoff) {
+ p->setPen(QPen(mi->palette.dark().color(), 1, Qt::DashLine));
+ p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2 - 1,
+ mi->rect.x() + mi->rect.width() - 4,
+ mi->rect.y() + mi->rect.height() / 2 - 1);
+ p->setPen(QPen(mi->palette.light().color(), 1, Qt::DashLine));
+ p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2,
+ mi->rect.x() + mi->rect.width() - 4,
+ mi->rect.y() + mi->rect.height() / 2);
+ }
+ }
+ break;
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ HIRect menuRect = qt_hirectForQRect(mi->menuRect);
+ HIRect itemRect = qt_hirectForQRect(mi->rect);
+
+ if ((opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken)){
+ // Draw a selected menu item background:
+ HIThemeMenuItemDrawInfo mdi;
+ mdi.version = qt_mac_hitheme_version;
+ mdi.state = kThemeMenuSelected;
+ mdi.itemType = kThemeMenuItemPlain;
+ HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi, cg, kHIThemeOrientationNormal, 0);
+ } else {
+ // Draw the toolbar background:
+ HIThemeMenuBarDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeMenuBarNormal;
+ bdi.attributes = 0;
+ HIThemeDrawMenuBarBackground(&menuRect, &bdi, cg, kHIThemeOrientationNormal);
+ }
+
+ if (!mi->icon.isNull()) {
+ drawItemPixmap(p, mi->rect,
+ Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine,
+ mi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize),
+ (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled));
+ } else {
+ drawItemText(p, mi->rect,
+ Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine,
+ mi->palette, mi->state & State_Enabled,
+ mi->text, QPalette::ButtonText);
+ }
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ HIThemeMenuBarDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeMenuBarNormal;
+ bdi.attributes = 0;
+ HIRect hirect = qt_hirectForQRect(mi->rect);
+ HIThemeDrawMenuBarBackground(&hirect, &bdi, cg,
+ kHIThemeOrientationNormal);
+ break;
+ }
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ tdi.version = qt_mac_hitheme_version;
+ tdi.reserved = 0;
+ bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0);
+ bool vertical = false;
+ bool inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+ bool reverse = (!vertical && (pb->direction == Qt::RightToLeft));
+ if (inverted)
+ reverse = !reverse;
+ switch (d->aquaSizeConstrain(opt, w)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tdi.kind = !isIndeterminate ? kThemeLargeProgressBar
+ : kThemeLargeIndeterminateBar;
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ tdi.kind = !isIndeterminate ? kThemeProgressBar : kThemeIndeterminateBar;
+ break;
+ }
+ tdi.bounds = qt_hirectForQRect(pb->rect);
+ tdi.max = pb->maximum;
+ tdi.min = pb->minimum;
+ tdi.value = pb->progress;
+ tdi.attributes = vertical ? 0 : kThemeTrackHorizontal;
+ tdi.trackInfo.progress.phase = d->progressFrame;
+ if (!(pb->state & State_Active))
+ tdi.enableState = kThemeTrackInactive;
+ else if (!(pb->state & State_Enabled))
+ tdi.enableState = kThemeTrackDisabled;
+ else
+ tdi.enableState = kThemeTrackActive;
+ HIThemeOrientation drawOrientation = kHIThemeOrientationNormal;
+ if (reverse) {
+ if (vertical) {
+ drawOrientation = kHIThemeOrientationInverted;
+ } else {
+ CGContextSaveGState(cg);
+ CGContextTranslateCTM(cg, pb->rect.width(), 0);
+ CGContextScaleCTM(cg, -1, 1);
+ }
+ }
+ HIThemeDrawTrack(&tdi, 0, cg, drawOrientation);
+ if (reverse && !vertical)
+ CGContextRestoreGState(cg);
+ }
+ break;
+ case CE_ProgressBarLabel:
+ case CE_ProgressBarGroove:
+ break;
+ case CE_SizeGrip: {
+ if (w && w->testAttribute(Qt::WA_MacOpaqueSizeGrip)) {
+ HIThemeGrowBoxDrawInfo gdi;
+ gdi.version = qt_mac_hitheme_version;
+ gdi.state = tds;
+ gdi.kind = kHIThemeGrowBoxKindNormal;
+ gdi.direction = kThemeGrowRight | kThemeGrowDown;
+ gdi.size = kHIThemeGrowBoxSizeNormal;
+ HIPoint pt = CGPointMake(opt->rect.x(), opt->rect.y());
+ HIThemeDrawGrowBox(&pt, &gdi, cg, kHIThemeOrientationNormal);
+ } else {
+ // It isn't possible to draw a transparent size grip with the
+ // native API, so we do it ourselves here.
+ const bool metal = qt_mac_is_metal(w);
+ QPen lineColor = metal ? QColor(236, 236, 236) : QColor(82, 82, 82, 192);
+ QPen metalHighlight = QColor(5, 5, 5, 192);
+ lineColor.setWidth(1);
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ p->setPen(lineColor);
+ const Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : qApp->layoutDirection();
+ const int NumLines = metal ? 4 : 3;
+ for (int l = 0; l < NumLines; ++l) {
+ const int offset = (l * 4 + (metal ? 2 : 3));
+ QPoint start, end;
+ if (layoutDirection == Qt::LeftToRight) {
+ start = QPoint(opt->rect.width() - offset, opt->rect.height() - 1);
+ end = QPoint(opt->rect.width() - 1, opt->rect.height() - offset);
+ } else {
+ start = QPoint(offset, opt->rect.height() - 1);
+ end = QPoint(1, opt->rect.height() - offset);
+ }
+ p->drawLine(start, end);
+ if (metal) {
+ p->setPen(metalHighlight);
+ p->setRenderHint(QPainter::Antialiasing, false);
+ p->drawLine(start + QPoint(0, -1), end + QPoint(0, -1));
+ p->setRenderHint(QPainter::Antialiasing, true);
+ p->setPen(lineColor);
+ }
+ }
+ p->restore();
+ }
+ break;
+ }
+ case CE_Splitter: {
+ HIThemeSplitterDrawInfo sdi;
+ sdi.version = qt_mac_hitheme_version;
+ sdi.state = tds;
+ sdi.adornment = qt_mac_is_metal(w) ? kHIThemeSplitterAdornmentMetal
+ : kHIThemeSplitterAdornmentNone;
+ HIRect hirect = qt_hirectForQRect(opt->rect);
+ HIThemeDrawPaneSplitter(&hirect, &sdi, cg, kHIThemeOrientationNormal);
+ break; }
+ case CE_RubberBand:
+ if (const QStyleOptionRubberBand *rubber = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ QColor fillColor(opt->palette.color(QPalette::Disabled, QPalette::Highlight));
+ if (!rubber->opaque) {
+ QColor strokeColor;
+ // I retrieved these colors from the Carbon-Dev mailing list
+ strokeColor.setHsvF(0, 0, 0.86, 1.0);
+ fillColor.setHsvF(0, 0, 0.53, 0.25);
+ if (opt->rect.width() * opt->rect.height() <= 3) {
+ p->fillRect(opt->rect, strokeColor);
+ } else {
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ QPen pen(strokeColor);
+ p->setPen(pen);
+ p->setBrush(fillColor);
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+ }
+ } else {
+ p->fillRect(opt->rect, fillColor);
+ }
+ }
+ break;
+ case CE_ToolBar: {
+ // For unified tool bars, draw nothing.
+ if (w) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
+ if (mainWindow->unifiedTitleAndToolBarOnMac())
+ break;
+ }
+ }
+
+ // draw background gradient
+ QLinearGradient linearGrad;
+ if (opt->state & State_Horizontal)
+ linearGrad = QLinearGradient(0, opt->rect.top(), 0, opt->rect.bottom());
+ else
+ linearGrad = QLinearGradient(opt->rect.left(), 0, opt->rect.right(), 0);
+
+ linearGrad.setColorAt(0, mainWindowGradientBegin);
+ linearGrad.setColorAt(1, mainWindowGradientEnd);
+ p->fillRect(opt->rect, linearGrad);
+
+ p->save();
+ if (opt->state & State_Horizontal) {
+ p->setPen(mainWindowGradientBegin.lighter(114));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->setPen(mainWindowGradientEnd.darker(114));
+ p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
+
+ } else {
+ p->setPen(mainWindowGradientBegin.lighter(114));
+ p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
+ p->setPen(mainWindowGradientEnd.darker(114));
+ p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
+ }
+ p->restore();
+
+
+ } break;
+ default:
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ break;
+ }
+}
+
+static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir)
+{
+ if (dir == Qt::RightToLeft) {
+ rect->adjust(-right, top, -left, bottom);
+ } else {
+ rect->adjust(left, top, right, bottom);
+ }
+}
+
+QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ QRect rect;
+ int controlSize = getControlSize(opt, widget);
+
+ switch (sr) {
+ case SE_ItemViewItemText:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, widget);
+ // We add the focusframeargin between icon and text in commonstyle
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ if (vopt->features & QStyleOptionViewItemV2::HasDecoration)
+ rect.adjust(-fw, 0, 0, 0);
+ }
+ break;
+ case SE_ToolBoxTabContents:
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ break;
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ // Unlike Carbon, we want the button to always be drawn inside its bounds.
+ // Therefore, the button is a bit smaller, so that even if it got focus,
+ // the focus 'shadow' will be inside. Adjust the content rect likewise.
+ HIThemeButtonDrawInfo bdi;
+ d->initHIThemePushButton(btn, widget, d->getDrawState(opt->state), &bdi);
+ HIRect contentRect = d->pushButtonContentBounds(btn, &bdi);
+ rect = qt_qrectForHIRect(contentRect);
+ }
+ break;
+ case SE_HeaderLabel:
+ if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ if (widget && widget->height() <= 22){
+ // We need to allow the text a bit more space when the header is
+ // small, otherwise it gets clipped:
+ rect.setY(0);
+ rect.setHeight(widget->height());
+ }
+ }
+ break;
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarLabel:
+ break;
+ case SE_ProgressBarContents:
+ rect = opt->rect;
+ break;
+ case SE_TreeViewDisclosureItem: {
+ HIRect inRect = CGRectMake(opt->rect.x(), opt->rect.y(),
+ opt->rect.width(), opt->rect.height());
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeStateActive;
+ bdi.kind = kThemeDisclosureButton;
+ bdi.value = kThemeDisclosureRight;
+ bdi.adornment = kThemeAdornmentNone;
+ HIRect contentRect;
+ HIThemeGetButtonContentBounds(&inRect, &bdi, &contentRect);
+ QCFType<HIShapeRef> shape;
+ HIRect outRect;
+ HIThemeGetButtonShape(&inRect, &bdi, &shape);
+ ptrHIShapeGetBounds(shape, &outRect);
+ rect = QRect(int(outRect.origin.x + DisclosureOffset), int(outRect.origin.y),
+ int(contentRect.origin.x - outRect.origin.x + DisclosureOffset),
+ int(outRect.size.height));
+ break;
+ }
+ case SE_TabWidgetLeftCorner:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ rect = QRect(QPoint(0, 0), twf->leftCornerWidgetSize);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ rect = QRect(QPoint(0, twf->rect.height() - twf->leftCornerWidgetSize.height()),
+ twf->leftCornerWidgetSize);
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(twf->direction, twf->rect, rect);
+ }
+ break;
+ case SE_TabWidgetRightCorner:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), 0),
+ twf->rightCornerWidgetSize);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(),
+ twf->rect.height() - twf->rightCornerWidgetSize.height()),
+ twf->rightCornerWidgetSize);
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(twf->direction, twf->rect, rect);
+ }
+ break;
+ case SE_TabWidgetTabContents:
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ if (twf->lineWidth != 0) {
+ switch (getTabDirection(twf->shape)) {
+ case kThemeTabNorth:
+ rect.adjust(+1, +14, -1, -1);
+ break;
+ case kThemeTabSouth:
+ rect.adjust(+1, +1, -1, -14);
+ break;
+ case kThemeTabWest:
+ rect.adjust(+14, +1, -1, -1);
+ break;
+ case kThemeTabEast:
+ rect.adjust(+1, +1, -14, -1);
+ }
+ }
+ }
+ break;
+ case SE_LineEditContents:
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ if(widget->parentWidget() && qobject_cast<const QComboBox*>(widget->parentWidget()))
+ rect.adjust(-1, -2, 0, 0);
+ else
+ rect.adjust(-1, 0, 0, +1);
+ break;
+ case SE_CheckBoxLayoutItem:
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ setLayoutItemMargins(+2, +3, -9, -4, &rect, opt->direction);
+ } else if (controlSize == QAquaSizeSmall) {
+ setLayoutItemMargins(+1, +5, 0 /* fix */, -6, &rect, opt->direction);
+ } else {
+ setLayoutItemMargins(0, +7, 0 /* fix */, -6, &rect, opt->direction);
+ }
+ break;
+ case SE_ComboBoxLayoutItem:
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ // Do nothing, because QToolbar needs the entire widget rect.
+ // Otherwise it will be clipped. Equivalent to
+ // widget->setAttribute(Qt::WA_LayoutUsesWidgetRect), but without
+ // all the hassle.
+ } else {
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ rect.adjust(+3, +2, -3, -4);
+ } else if (controlSize == QAquaSizeSmall) {
+ setLayoutItemMargins(+2, +1, -3, -4, &rect, opt->direction);
+ } else {
+ setLayoutItemMargins(+1, 0, -2, 0, &rect, opt->direction);
+ }
+ }
+ break;
+ case SE_LabelLayoutItem:
+ rect = opt->rect;
+ setLayoutItemMargins(+1, 0 /* SHOULD be -1, done for alignment */, 0, 0 /* SHOULD be -1, done for alignment */, &rect, opt->direction);
+ break;
+ case SE_ProgressBarLayoutItem: {
+ rect = opt->rect;
+ int bottom = SIZE(3, 8, 8);
+ if (opt->state & State_Horizontal) {
+ rect.adjust(0, +1, 0, -bottom);
+ } else {
+ setLayoutItemMargins(+1, 0, -bottom, 0, &rect, opt->direction);
+ }
+ break;
+ }
+ case SE_PushButtonLayoutItem:
+ if (const QStyleOptionButton *buttonOpt
+ = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if ((buttonOpt->features & QStyleOptionButton::Flat))
+ break; // leave rect alone
+ }
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ rect.adjust(+6, +4, -6, -8);
+ } else if (controlSize == QAquaSizeSmall) {
+ rect.adjust(+5, +4, -5, -6);
+ } else {
+ rect.adjust(+1, 0, -1, -2);
+ }
+ break;
+ case SE_RadioButtonLayoutItem:
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ setLayoutItemMargins(+2, +2 /* SHOULD BE +3, done for alignment */,
+ 0, -4 /* SHOULD BE -3, done for alignment */, &rect, opt->direction);
+ } else if (controlSize == QAquaSizeSmall) {
+ rect.adjust(0, +6, 0 /* fix */, -5);
+ } else {
+ rect.adjust(0, +6, 0 /* fix */, -7);
+ }
+ break;
+ case SE_SliderLayoutItem:
+ if (const QStyleOptionSlider *sliderOpt
+ = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ rect = opt->rect;
+ if (sliderOpt->tickPosition == QSlider::NoTicks) {
+ int above = SIZE(3, 0, 2);
+ int below = SIZE(4, 3, 0);
+ if (sliderOpt->orientation == Qt::Horizontal) {
+ rect.adjust(0, +above, 0, -below);
+ } else {
+ rect.adjust(+above, 0, -below, 0); //### Seems that QSlider flip the position of the ticks in reverse mode.
+ }
+ } else if (sliderOpt->tickPosition == QSlider::TicksAbove) {
+ int below = SIZE(3, 2, 0);
+ if (sliderOpt->orientation == Qt::Horizontal) {
+ rect.setHeight(rect.height() - below);
+ } else {
+ rect.setWidth(rect.width() - below);
+ }
+ } else if (sliderOpt->tickPosition == QSlider::TicksBelow) {
+ int above = SIZE(3, 2, 0);
+ if (sliderOpt->orientation == Qt::Horizontal) {
+ rect.setTop(rect.top() + above);
+ } else {
+ rect.setLeft(rect.left() + above);
+ }
+ }
+ }
+ break;
+ case SE_FrameLayoutItem:
+ // hack because QStyleOptionFrameV2 doesn't have a frameStyle member
+ if (const QFrame *frame = qobject_cast<const QFrame *>(widget)) {
+ rect = opt->rect;
+ switch (frame->frameStyle() & QFrame::Shape_Mask) {
+ case QFrame::HLine:
+ rect.adjust(0, +1, 0, -1);
+ break;
+ case QFrame::VLine:
+ rect.adjust(+1, 0, -1, 0);
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+ case SE_GroupBoxLayoutItem:
+ rect = opt->rect;
+ if (const QStyleOptionGroupBox *groupBoxOpt =
+ qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ /*
+ AHIG is very inconsistent when it comes to group boxes.
+ Basically, we make sure that (non-checkable) group boxes
+ and tab widgets look good when laid out side by side.
+ */
+ if (groupBoxOpt->subControls & (QStyle::SC_GroupBoxCheckBox
+ | QStyle::SC_GroupBoxLabel)) {
+ int delta;
+ if (groupBoxOpt->subControls & QStyle::SC_GroupBoxCheckBox) {
+ delta = SIZE(8, 4, 4); // guess
+ } else {
+ delta = SIZE(15, 12, 12); // guess
+ }
+ rect.setTop(rect.top() + delta);
+ }
+ }
+ rect.setBottom(rect.bottom() - 1);
+ break;
+ case SE_TabWidgetLayoutItem:
+ if (const QStyleOptionTabWidgetFrame *tabWidgetOpt =
+ qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ /*
+ AHIG specifies "12 or 14" as the distance from the window
+ edge. We choose 14 and since the default top margin is 20,
+ the overlap is 6.
+ */
+ rect = tabWidgetOpt->rect;
+ if (tabWidgetOpt->shape == QTabBar::RoundedNorth)
+ rect.setTop(rect.top() + SIZE(6 /* AHIG */, 3 /* guess */, 2 /* AHIG */));
+ }
+ break;
+ default:
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ break;
+ }
+ return rect;
+}
+
+static inline void drawToolbarButtonArrow(const QRect &toolButtonRect, ThemeDrawState tds, CGContextRef cg)
+{
+ QRect arrowRect = QRect(toolButtonRect.right() - 9, toolButtonRect.bottom() - 9, 7, 5);
+ HIThemePopupArrowDrawInfo padi;
+ padi.version = qt_mac_hitheme_version;
+ padi.state = tds;
+ padi.orientation = kThemeArrowDown;
+ padi.size = kThemeArrow7pt;
+ HIRect hirect = qt_hirectForQRect(arrowRect);
+ HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
+}
+
+void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ QMacCGContext cg(p);
+ switch (cc) {
+ case CC_Slider:
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, slider, &tdi, widget);
+ if (slider->state & State_Sunken) {
+ if (cc == CC_Slider) {
+ if (slider->activeSubControls == SC_SliderHandle)
+ tdi.trackInfo.slider.pressState = kThemeThumbPressed;
+ else if (slider->activeSubControls == SC_SliderGroove)
+ tdi.trackInfo.slider.pressState = kThemeLeftTrackPressed;
+ } else {
+ if (slider->activeSubControls == SC_ScrollBarSubLine
+ || slider->activeSubControls == SC_ScrollBarAddLine) {
+ // This test looks complex but it basically boils down
+ // to the following: The "RTL look" on the mac also
+ // changed the directions of the controls, that's not
+ // what people expect (an arrow is an arrow), so we
+ // kind of fake and say the opposite button is hit.
+ // This works great, up until 10.4 which broke the
+ // scroll bars, so I also have actually do something
+ // similar when I have an upside down scroll bar
+ // because on Tiger I only "fake" the reverse stuff.
+ bool reverseHorizontal = (slider->direction == Qt::RightToLeft
+ && slider->orientation == Qt::Horizontal);
+ if ((reverseHorizontal
+ && slider->activeSubControls == SC_ScrollBarAddLine)
+ || (!reverseHorizontal
+ && slider->activeSubControls == SC_ScrollBarSubLine)) {
+ tdi.trackInfo.scrollbar.pressState = kThemeRightInsideArrowPressed
+ | kThemeLeftOutsideArrowPressed;
+ } else {
+ tdi.trackInfo.scrollbar.pressState = kThemeLeftInsideArrowPressed
+ | kThemeRightOutsideArrowPressed;
+ }
+ } else if (slider->activeSubControls == SC_ScrollBarAddPage) {
+ tdi.trackInfo.scrollbar.pressState = kThemeRightTrackPressed;
+ } else if (slider->activeSubControls == SC_ScrollBarSubPage) {
+ tdi.trackInfo.scrollbar.pressState = kThemeLeftTrackPressed;
+ } else if (slider->activeSubControls == SC_ScrollBarSlider) {
+ tdi.trackInfo.scrollbar.pressState = kThemeThumbPressed;
+ }
+ }
+ }
+ HIRect macRect;
+ bool tracking = slider->sliderPosition == slider->sliderValue;
+ if (!tracking) {
+ // Small optimization, the same as q->subControlRect
+ QCFType<HIShapeRef> shape;
+ HIThemeGetTrackThumbShape(&tdi, &shape);
+ ptrHIShapeGetBounds(shape, &macRect);
+ tdi.value = slider->sliderValue;
+ }
+
+ // Remove controls from the scroll bar if it is to short to draw them correctly.
+ // This is done in two stages: first the thumb indicator is removed when it is
+ // no longer possible to move it, second the up/down buttons are removed when
+ // there is not enough space for them.
+ if (cc == CC_ScrollBar) {
+ const int scrollBarLength = (slider->orientation == Qt::Horizontal)
+ ? slider->rect.width() : slider->rect.height();
+ const QMacStyle::WidgetSizePolicy sizePolicy = widgetSizePolicy(widget);
+ if (scrollBarLength < scrollButtonsCutoffSize(thumbIndicatorCutoff, sizePolicy))
+ tdi.attributes &= ~kThemeTrackShowThumb;
+ if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, sizePolicy))
+ tdi.enableState = kThemeTrackNothingToScroll;
+ } else {
+ if (!(slider->subControls & SC_SliderHandle))
+ tdi.attributes &= ~kThemeTrackShowThumb;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (!(slider->subControls & SC_SliderGroove))
+ tdi.attributes |= kThemeTrackHideTrack;
+#endif
+ }
+
+ HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg,
+ kHIThemeOrientationNormal);
+ if (cc == CC_Slider && slider->subControls & SC_SliderTickmarks) {
+ if (qt_mac_is_metal(widget)) {
+ if (tdi.enableState == kThemeTrackInactive)
+ tdi.enableState = kThemeTrackActive; // Looks more Cocoa-like
+ }
+ int interval = slider->tickInterval;
+ if (interval == 0) {
+ interval = slider->pageStep;
+ if (interval == 0)
+ interval = slider->singleStep;
+ if (interval == 0)
+ interval = 1;
+ }
+ int numMarks = 1 + ((slider->maximum - slider->minimum) / interval);
+
+ if (tdi.trackInfo.slider.thumbDir == kThemeThumbPlain) {
+ // They asked for both, so we'll give it to them.
+ tdi.trackInfo.slider.thumbDir = kThemeThumbDownward;
+ HIThemeDrawTrackTickMarks(&tdi, numMarks,
+ cg,
+ kHIThemeOrientationNormal);
+ tdi.trackInfo.slider.thumbDir = kThemeThumbUpward;
+ HIThemeDrawTrackTickMarks(&tdi, numMarks,
+ cg,
+ kHIThemeOrientationNormal);
+ } else {
+ HIThemeDrawTrackTickMarks(&tdi, numMarks,
+ cg,
+ kHIThemeOrientationNormal);
+
+ }
+ }
+ }
+ break;
+ case CC_Q3ListView:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (lv->subControls & SC_Q3ListView)
+ QWindowsStyle::drawComplexControl(cc, lv, p, widget);
+ if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
+ int y = lv->rect.y();
+ int h = lv->rect.height();
+ int x = lv->rect.right() - 10;
+ for (int i = 1; i < lv->items.size() && y < h; ++i) {
+ QStyleOptionQ3ListViewItem item = lv->items.at(i);
+ if (y + item.height > 0 && (item.childCount > 0
+ || (item.features & (QStyleOptionQ3ListViewItem::Expandable
+ | QStyleOptionQ3ListViewItem::Visible))
+ == (QStyleOptionQ3ListViewItem::Expandable
+ | QStyleOptionQ3ListViewItem::Visible))) {
+ QStyleOption treeOpt(0);
+ treeOpt.rect.setRect(x, y + item.height / 2 - 4, 9, 9);
+ treeOpt.palette = lv->palette;
+ treeOpt.state = lv->state;
+ treeOpt.state |= State_Children;
+ if (item.state & State_Open)
+ treeOpt.state |= State_Open;
+ proxy()->drawPrimitive(PE_IndicatorBranch, &treeOpt, p, widget);
+ }
+ y += item.totalHeight;
+ }
+ }
+ }
+ break;
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox newSB = *sb;
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ SInt32 frame_size;
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
+
+ QRect lineeditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
+ lineeditRect.adjust(-frame_size, -frame_size, +frame_size, +frame_size);
+
+ HIThemeFrameDrawInfo fdi;
+ fdi.version = qt_mac_hitheme_version;
+ fdi.state = tds;
+ fdi.kind = kHIThemeFrameTextFieldSquare;
+ fdi.isFocused = false;
+ HIRect hirect = qt_hirectForQRect(lineeditRect);
+ HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
+ }
+ if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ QAquaWidgetSize aquaSize = d->aquaSizeConstrain(opt, widget);
+ switch (aquaSize) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ bdi.kind = kThemeIncDecButton;
+ break;
+ case QAquaSizeMini:
+ bdi.kind = kThemeIncDecButtonMini;
+ break;
+ case QAquaSizeSmall:
+ bdi.kind = kThemeIncDecButtonSmall;
+ break;
+ }
+ if (!(sb->stepEnabled & (QAbstractSpinBox::StepUpEnabled
+ | QAbstractSpinBox::StepDownEnabled)))
+ tds = kThemeStateUnavailable;
+ if (sb->activeSubControls == SC_SpinBoxDown
+ && (sb->state & State_Sunken))
+ tds = kThemeStatePressedDown;
+ else if (sb->activeSubControls == SC_SpinBoxUp
+ && (sb->state & State_Sunken))
+ tds = kThemeStatePressedUp;
+ bdi.state = tds;
+ if (!(sb->state & State_Active)
+ && sb->palette.currentColorGroup() == QPalette::Active
+ && tds == kThemeStateInactive)
+ bdi.state = kThemeStateActive;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+
+ QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
+
+ updown |= proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+ HIRect newRect = qt_hirectForQRect(updown);
+ QRect off_rct;
+ HIRect outRect;
+ HIThemeGetButtonBackgroundBounds(&newRect, &bdi, &outRect);
+ off_rct.setRect(int(newRect.origin.x - outRect.origin.x),
+ int(newRect.origin.y - outRect.origin.y),
+ int(outRect.size.width - newRect.size.width),
+ int(outRect.size.height - newRect.size.height));
+
+ newRect = qt_hirectForQRect(updown, off_rct);
+ HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+ break;
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
+ HIThemeButtonDrawInfo bdi;
+ d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
+ bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
+ if (!drawColorless)
+ QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
+ else
+ d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
+ }
+ break;
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *titlebar
+ = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ if (titlebar->state & State_Active) {
+ if (titlebar->titleBarState & State_Active)
+ tds = kThemeStateActive;
+ else
+ tds = kThemeStateInactive;
+ } else {
+ tds = kThemeStateInactive;
+ }
+
+ HIThemeWindowDrawInfo wdi;
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = tds;
+ wdi.windowType = QtWinType;
+ wdi.titleHeight = titlebar->rect.height();
+ wdi.titleWidth = titlebar->rect.width();
+ wdi.attributes = kThemeWindowHasTitleText;
+ // It seems HIThemeDrawTitleBarWidget is not able to draw a dirty
+ // close button, so use HIThemeDrawWindowFrame instead.
+ if (widget && widget->isWindowModified() && titlebar->subControls & SC_TitleBarCloseButton)
+ wdi.attributes |= kThemeWindowHasCloseBox | kThemeWindowHasDirty;
+
+ HIRect titleBarRect;
+ HIRect tmpRect = qt_hirectForQRect(titlebar->rect);
+ {
+ QCFType<HIShapeRef> titleRegion;
+ QRect newr = titlebar->rect.adjusted(0, 0, 2, 0);
+ HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
+ ptrHIShapeGetBounds(titleRegion, &tmpRect);
+ newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
+ titleBarRect = qt_hirectForQRect(newr);
+ }
+ HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
+ if (titlebar->subControls & (SC_TitleBarCloseButton
+ | SC_TitleBarMaxButton
+ | SC_TitleBarMinButton
+ | SC_TitleBarNormalButton)) {
+ HIThemeWindowWidgetDrawInfo wwdi;
+ wwdi.version = qt_mac_hitheme_version;
+ wwdi.widgetState = tds;
+ if (titlebar->state & State_MouseOver)
+ wwdi.widgetState = kThemeStateRollover;
+ wwdi.windowType = QtWinType;
+ wwdi.attributes = wdi.attributes | kThemeWindowHasFullZoom | kThemeWindowHasCloseBox | kThemeWindowHasCollapseBox;
+ wwdi.windowState = wdi.state;
+ wwdi.titleHeight = wdi.titleHeight;
+ wwdi.titleWidth = wdi.titleWidth;
+ ThemeDrawState savedControlState = wwdi.widgetState;
+ uint sc = SC_TitleBarMinButton;
+ ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox;
+ bool active = titlebar->state & State_Active;
+ if (qMacVersion() < QSysInfo::MV_10_6) {
+ int border = 2;
+ titleBarRect.origin.x += border;
+ titleBarRect.origin.y -= border;
+ }
+
+ while (sc <= SC_TitleBarCloseButton) {
+ if (sc & titlebar->subControls) {
+ uint tmp = sc;
+ wwdi.widgetState = savedControlState;
+ wwdi.widgetType = tbw;
+ if (sc == SC_TitleBarMinButton)
+ tmp |= SC_TitleBarNormalButton;
+ if (active && (titlebar->activeSubControls & tmp)
+ && (titlebar->state & State_Sunken))
+ wwdi.widgetState = kThemeStatePressed;
+ // Draw all sub controllers except the dirty close button
+ // (it is already handled by HIThemeDrawWindowFrame).
+ if (!(widget && widget->isWindowModified() && tbw == kThemeWidgetCloseBox)) {
+ HIThemeDrawTitleBarWidget(&titleBarRect, &wwdi, cg, kHIThemeOrientationNormal);
+ p->paintEngine()->syncState();
+ }
+ }
+ sc = sc << 1;
+ tbw = tbw >> 1;
+ }
+ }
+ p->paintEngine()->syncState();
+ if (titlebar->subControls & SC_TitleBarLabel) {
+ int iw = 0;
+ if (!titlebar->icon.isNull()) {
+ QCFType<HIShapeRef> titleRegion2;
+ HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleProxyIconRgn,
+ &titleRegion2);
+ ptrHIShapeGetBounds(titleRegion2, &tmpRect);
+ if (tmpRect.size.width != 1) {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ iw = titlebar->icon.actualSize(QSize(iconExtent, iconExtent)).width();
+ }
+ }
+ if (!titlebar->text.isEmpty()) {
+ p->save();
+ QCFType<HIShapeRef> titleRegion3;
+ HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleTextRgn, &titleRegion3);
+ ptrHIShapeGetBounds(titleRegion3, &tmpRect);
+ p->setClipRect(qt_qrectForHIRect(tmpRect));
+ QRect br = p->clipRegion().boundingRect();
+ int x = br.x(),
+ y = br.y() + (titlebar->rect.height() / 2 - p->fontMetrics().height() / 2);
+ if (br.width() <= (p->fontMetrics().width(titlebar->text) + iw * 2))
+ x += iw;
+ else
+ x += br.width() / 2 - p->fontMetrics().width(titlebar->text) / 2;
+ if (iw)
+ p->drawPixmap(x - iw, y,
+ titlebar->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), QIcon::Normal));
+ drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive,
+ titlebar->text, QPalette::Text);
+ p->restore();
+ }
+ }
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+
+ QStyleOptionGroupBox groupBoxCopy(*groupBox);
+ if ((widget && !widget->testAttribute(Qt::WA_SetFont))
+ && QApplication::desktopSettingsAware())
+ groupBoxCopy.subControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
+ QWindowsStyle::drawComplexControl(cc, &groupBoxCopy, p, widget);
+ if (groupBoxCopy.subControls != groupBox->subControls) {
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ QColor textColor = groupBox->palette.windowText().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
+ QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
+ QRect r = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(groupText, &bounds, &tti, cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ }
+ break;
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tb
+ = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ if (tb->subControls & SC_ToolButtonMenu) {
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
+ arrowOpt.rect.setY(arrowOpt.rect.y() + arrowOpt.rect.height() / 2);
+ arrowOpt.rect.setHeight(arrowOpt.rect.height() / 2);
+ arrowOpt.state = tb->state;
+ arrowOpt.palette = tb->palette;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
+ } else if ((tb->features & QStyleOptionToolButton::HasMenu)
+ && (tb->toolButtonStyle != Qt::ToolButtonTextOnly && !tb->icon.isNull())) {
+ drawToolbarButtonArrow(tb->rect, tds, cg);
+ }
+ if (tb->state & State_On) {
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ static QPixmap pm(QLatin1String(":/trolltech/mac/style/images/leopard-unified-toolbar-on.png"));
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);
+ } else {
+ QPen oldPen = p->pen();
+ p->setPen(QColor(0, 0, 0, 0x3a));
+ p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
+ p->drawLine(tb->rect.left() + 1, tb->rect.top(),
+ tb->rect.right() - 1, tb->rect.top());
+ p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
+ tb->rect.right() - 1, tb->rect.bottom());
+ p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
+ p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
+ p->setPen(oldPen);
+ }
+ }
+ proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget);
+ } else {
+ ThemeButtonKind bkind = kThemeBevelButton;
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ bkind = kThemeBevelButton;
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ bkind = kThemeSmallBevelButton;
+ break;
+ }
+
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
+ State bflags = tb->state,
+ mflags = tb->state;
+ if (tb->subControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (tb->subControls & SC_ToolButtonMenu)
+ mflags |= State_Sunken;
+
+ if (tb->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised)) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = tds;
+ bdi.adornment = kThemeAdornmentNone;
+ bdi.kind = bkind;
+ bdi.value = kThemeButtonOff;
+ if (tb->state & State_HasFocus)
+ bdi.adornment = kThemeAdornmentFocus;
+ if (tb->state & State_Sunken)
+ bdi.state = kThemeStatePressed;
+ if (tb->state & State_On)
+ bdi.value = kThemeButtonOn;
+
+ QRect off_rct(0, 0, 0, 0);
+ HIRect myRect, macRect;
+ myRect = CGRectMake(tb->rect.x(), tb->rect.y(),
+ tb->rect.width(), tb->rect.height());
+ HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
+ off_rct.setRect(int(myRect.origin.x - macRect.origin.x),
+ int(myRect.origin.y - macRect.origin.y),
+ int(macRect.size.width - myRect.size.width),
+ int(macRect.size.height - myRect.size.height));
+
+ myRect = qt_hirectForQRect(button, off_rct);
+ HIThemeDrawButton(&myRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+
+ if (tb->subControls & SC_ToolButtonMenu) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = tds;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+ bdi.kind = bkind;
+ if (tb->state & State_HasFocus)
+ bdi.adornment = kThemeAdornmentFocus;
+ if (tb->state & (State_On | State_Sunken)
+ || (tb->activeSubControls & SC_ToolButtonMenu))
+ bdi.state = kThemeStatePressed;
+ HIRect hirect = qt_hirectForQRect(menuarea);
+ HIThemeDrawButton(&hirect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ QRect r(menuarea.x() + ((menuarea.width() / 2) - 3), menuarea.height() - 8, 8, 8);
+ HIThemePopupArrowDrawInfo padi;
+ padi.version = qt_mac_hitheme_version;
+ padi.state = tds;
+ padi.orientation = kThemeArrowDown;
+ padi.size = kThemeArrow7pt;
+ hirect = qt_hirectForQRect(r);
+ HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
+ } else if (tb->features & QStyleOptionToolButton::HasMenu) {
+ drawToolbarButtonArrow(tb->rect, tds, cg);
+ }
+ QRect buttonRect = proxy()->subControlRect(CC_ToolButton, tb, SC_ToolButton, widget);
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ QStyleOptionToolButton label = *tb;
+ label.rect = buttonRect.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+ }
+ }
+ break;
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+ QStyleHelper::drawDial(dial, p);
+ break;
+ default:
+ QWindowsStyle::drawComplexControl(cc, opt, p, widget);
+ break;
+ }
+}
+
+QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc,
+ const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *widget) const
+{
+ SubControl sc = QStyle::SC_None;
+ switch (cc) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ sc = QWindowsStyle::hitTestComplexControl(cc, cmb, pt, widget);
+ if (!cmb->editable && sc != QStyle::SC_None)
+ sc = SC_ComboBoxArrow; // A bit of a lie, but what we want
+ }
+ break;
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, slider, &tdi, widget);
+ ControlPartCode part;
+ HIPoint pos = CGPointMake(pt.x(), pt.y());
+ if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
+ if (part == kControlPageUpPart || part == kControlPageDownPart)
+ sc = SC_SliderGroove;
+ else
+ sc = SC_SliderHandle;
+ }
+ }
+ break;
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIScrollBarTrackInfo sbi;
+ sbi.version = qt_mac_hitheme_version;
+ if (!(sb->state & State_Active))
+ sbi.enableState = kThemeTrackInactive;
+ else if (sb->state & State_Enabled)
+ sbi.enableState = kThemeTrackActive;
+ else
+ sbi.enableState = kThemeTrackDisabled;
+
+ // The arrow buttons are not drawn if the scroll bar is to short,
+ // exclude them from the hit test.
+ const int scrollBarLength = (sb->orientation == Qt::Horizontal)
+ ? sb->rect.width() : sb->rect.height();
+ if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, widgetSizePolicy(widget)))
+ sbi.enableState = kThemeTrackNothingToScroll;
+
+ sbi.viewsize = sb->pageStep;
+ HIPoint pos = CGPointMake(pt.x(), pt.y());
+
+ HIRect macSBRect = qt_hirectForQRect(sb->rect);
+ ControlPartCode part;
+ bool reverseHorizontal = (sb->direction == Qt::RightToLeft
+ && sb->orientation == Qt::Horizontal
+ && (!sb->upsideDown ||
+ (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4
+ && sb->upsideDown)));
+ if (HIThemeHitTestScrollBarArrows(&macSBRect, &sbi, sb->orientation == Qt::Horizontal,
+ &pos, 0, &part)) {
+ if (part == kControlUpButtonPart)
+ sc = reverseHorizontal ? SC_ScrollBarAddLine : SC_ScrollBarSubLine;
+ else if (part == kControlDownButtonPart)
+ sc = reverseHorizontal ? SC_ScrollBarSubLine : SC_ScrollBarAddLine;
+ } else {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, sb, &tdi, widget);
+ if(tdi.enableState == kThemeTrackInactive)
+ tdi.enableState = kThemeTrackActive;
+ if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
+ if (part == kControlPageUpPart)
+ sc = reverseHorizontal ? SC_ScrollBarAddPage
+ : SC_ScrollBarSubPage;
+ else if (part == kControlPageDownPart)
+ sc = reverseHorizontal ? SC_ScrollBarSubPage
+ : SC_ScrollBarAddPage;
+ else
+ sc = SC_ScrollBarSlider;
+ }
+ }
+ }
+ break;
+/*
+ I don't know why, but we only get kWindowContentRgn here, which isn't what we want at all.
+ It would be very nice if this would work.
+ case QStyle::CC_TitleBar:
+ if (const QStyleOptionTitleBar *tbar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ HIThemeWindowDrawInfo wdi;
+ memset(&wdi, 0, sizeof(wdi));
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = kThemeStateActive;
+ wdi.windowType = QtWinType;
+ wdi.titleWidth = tbar->rect.width();
+ wdi.titleHeight = tbar->rect.height();
+ if (tbar->titleBarState)
+ wdi.attributes |= kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
+ | kThemeWindowHasCollapseBox;
+ else if (tbar->titleBarFlags & Qt::WindowSystemMenuHint)
+ wdi.attributes |= kThemeWindowHasCloseBox;
+ QRect tmpRect = tbar->rect;
+ tmpRect.setHeight(tmpRect.height() + 100);
+ HIRect hirect = qt_hirectForQRect(tmpRect);
+ WindowRegionCode hit;
+ HIPoint hipt = CGPointMake(pt.x(), pt.y());
+ if (HIThemeGetWindowRegionHit(&hirect, &wdi, &hipt, &hit)) {
+ switch (hit) {
+ case kWindowCloseBoxRgn:
+ sc = QStyle::SC_TitleBarCloseButton;
+ break;
+ case kWindowCollapseBoxRgn:
+ sc = QStyle::SC_TitleBarMinButton;
+ break;
+ case kWindowZoomBoxRgn:
+ sc = QStyle::SC_TitleBarMaxButton;
+ break;
+ case kWindowTitleTextRgn:
+ sc = QStyle::SC_TitleBarLabel;
+ break;
+ default:
+ qDebug("got something else %d", hit);
+ break;
+ }
+ }
+ }
+ break;
+*/
+ default:
+ sc = QWindowsStyle::hitTestComplexControl(cc, opt, pt, widget);
+ break;
+ }
+ return sc;
+}
+
+QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *widget) const
+{
+ QRect ret;
+ switch (cc) {
+ case CC_Slider:
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, slider, &tdi, widget);
+ HIRect macRect;
+ QCFType<HIShapeRef> shape;
+ bool scrollBar = cc == CC_ScrollBar;
+ if ((scrollBar && sc == SC_ScrollBarSlider)
+ || (!scrollBar && sc == SC_SliderHandle)) {
+ HIThemeGetTrackThumbShape(&tdi, &shape);
+ ptrHIShapeGetBounds(shape, &macRect);
+ } else if (!scrollBar && sc == SC_SliderGroove) {
+ HIThemeGetTrackBounds(&tdi, &macRect);
+ } else if (sc == SC_ScrollBarGroove) { // Only scroll bar parts available...
+ HIThemeGetTrackDragRect(&tdi, &macRect);
+ } else {
+ ControlPartCode cpc;
+ if (sc == SC_ScrollBarSubPage || sc == SC_ScrollBarAddPage) {
+ cpc = sc == SC_ScrollBarSubPage ? kControlPageDownPart
+ : kControlPageUpPart;
+ } else {
+ cpc = sc == SC_ScrollBarSubLine ? kControlUpButtonPart
+ : kControlDownButtonPart;
+ if (slider->direction == Qt::RightToLeft
+ && slider->orientation == Qt::Horizontal) {
+ if (cpc == kControlDownButtonPart)
+ cpc = kControlUpButtonPart;
+ else if (cpc == kControlUpButtonPart)
+ cpc = kControlDownButtonPart;
+ }
+ }
+ HIThemeGetTrackPartBounds(&tdi, cpc, &macRect);
+ }
+ ret = qt_qrectForHIRect(macRect);
+
+ // Tweak: the dark line between the sub/add line buttons belong to only one of the buttons
+ // when doing hit-testing, but both of them have to repaint it. Extend the rect to cover
+ // the line in the cases where HIThemeGetTrackPartBounds returns a rect that doesn't.
+ if (slider->orientation == Qt::Horizontal) {
+ if (slider->direction == Qt::LeftToRight && sc == SC_ScrollBarSubLine)
+ ret.adjust(0, 0, 1, 0);
+ else if (slider->direction == Qt::RightToLeft && sc == SC_ScrollBarAddLine)
+ ret.adjust(-1, 0, 1, 0);
+ } else if (sc == SC_ScrollBarAddLine) {
+ ret.adjust(0, -1, 0, 1);
+ }
+ }
+ break;
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *titlebar
+ = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ HIThemeWindowDrawInfo wdi;
+ memset(&wdi, 0, sizeof(wdi));
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = kThemeStateActive;
+ wdi.windowType = QtWinType;
+ wdi.titleHeight = titlebar->rect.height();
+ wdi.titleWidth = titlebar->rect.width();
+ wdi.attributes = kThemeWindowHasTitleText;
+ if (titlebar->subControls & SC_TitleBarCloseButton)
+ wdi.attributes |= kThemeWindowHasCloseBox;
+ if (titlebar->subControls & SC_TitleBarMaxButton
+ | SC_TitleBarNormalButton)
+ wdi.attributes |= kThemeWindowHasFullZoom;
+ if (titlebar->subControls & SC_TitleBarMinButton)
+ wdi.attributes |= kThemeWindowHasCollapseBox;
+ WindowRegionCode wrc = kWindowGlobalPortRgn;
+
+ if (sc == SC_TitleBarCloseButton)
+ wrc = kWindowCloseBoxRgn;
+ else if (sc == SC_TitleBarMinButton)
+ wrc = kWindowCollapseBoxRgn;
+ else if (sc == SC_TitleBarMaxButton)
+ wrc = kWindowZoomBoxRgn;
+ else if (sc == SC_TitleBarLabel)
+ wrc = kWindowTitleTextRgn;
+ else if (sc == SC_TitleBarSysMenu)
+ ret.setRect(-1024, -1024, 10, proxy()->pixelMetric(PM_TitleBarHeight,
+ titlebar, widget));
+ if (wrc != kWindowGlobalPortRgn) {
+ QCFType<HIShapeRef> region;
+ QRect tmpRect = titlebar->rect;
+ HIRect titleRect = qt_hirectForQRect(tmpRect);
+ HIThemeGetWindowShape(&titleRect, &wdi, kWindowTitleBarRgn, &region);
+ ptrHIShapeGetBounds(region, &titleRect);
+ CFRelease(region);
+ tmpRect.translate(tmpRect.x() - int(titleRect.origin.x),
+ tmpRect.y() - int(titleRect.origin.y));
+ titleRect = qt_hirectForQRect(tmpRect);
+ HIThemeGetWindowShape(&titleRect, &wdi, wrc, &region);
+ ptrHIShapeGetBounds(region, &titleRect);
+ ret = qt_qrectForHIRect(titleRect);
+ }
+ }
+ break;
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ HIThemeButtonDrawInfo bdi;
+ d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
+
+ switch (sc) {
+ case SC_ComboBoxEditField:{
+ ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ // hack to posistion the edit feld correctly for QDateTimeEdits
+ // in calendarPopup mode.
+ if (qobject_cast<const QDateTimeEdit *>(widget)) {
+ ret.moveTop(ret.top() - 2);
+ ret.setHeight(ret.height() +1);
+ }
+ break; }
+ case SC_ComboBoxArrow:{
+ ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ ret.setX(ret.x() + ret.width());
+ ret.setWidth(combo->rect.right() - ret.right());
+ break; }
+ case SC_ComboBoxListBoxPopup:{
+ if (combo->editable) {
+ HIRect inner = QMacStylePrivate::comboboxInnerBounds(qt_hirectForQRect(combo->rect), bdi.kind);
+ QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ const int comboTop = combo->rect.top();
+ ret = QRect(qRound(inner.origin.x),
+ comboTop,
+ qRound(inner.origin.x - combo->rect.left() + inner.size.width),
+ editRect.bottom() - comboTop + 2);
+ } else {
+ QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ ret = QRect(combo->rect.x() + 4 - 11,
+ combo->rect.y() + 1,
+ editRect.width() + 10 + 11,
+ 1);
+ }
+ break; }
+ default:
+ break;
+ }
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ bool flat = (groupBox->features & QStyleOptionFrameV2::Flat);
+ bool hasNoText = !checkable && groupBox->text.isEmpty();
+ switch (sc) {
+ case SC_GroupBoxLabel:
+ case SC_GroupBoxCheckBox: {
+ // Cheat and use the smaller font if we need to
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ bool fontIsSet = (widget && widget->testAttribute(Qt::WA_SetFont))
+ || !QApplication::desktopSettingsAware();
+ int tw;
+ int h;
+ int margin = flat || hasNoText ? 0 : 12;
+ ret = groupBox->rect.adjusted(margin, 0, -margin, 0);
+
+ if (!fontIsSet) {
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = kThemeStateActive;
+ tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
+ CGFloat width;
+ CGFloat height;
+ QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
+ HIThemeGetTextDimensions(groupText, 0, &tti, &width, &height, 0);
+ tw = qRound(width);
+ h = qCeil(height);
+ } else {
+ QFontMetricsF fm = QFontMetricsF(groupBox->fontMetrics);
+ h = qCeil(fm.height());
+ tw = qCeil(fm.size(Qt::TextShowMnemonic, groupBox->text).width());
+ }
+ ret.setHeight(h);
+
+ QRect labelRect = alignedRect(groupBox->direction, groupBox->textAlignment,
+ QSize(tw, h), ret);
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
+ bool rtl = groupBox->direction == Qt::RightToLeft;
+ if (sc == SC_GroupBoxLabel) {
+ if (checkable) {
+ int newSum = indicatorWidth + 1;
+ int newLeft = labelRect.left() + (rtl ? -newSum : newSum);
+ labelRect.moveLeft(newLeft);
+ } else if (flat) {
+ int newLeft = labelRect.left() - (rtl ? 3 : -3);
+ labelRect.moveLeft(newLeft);
+ labelRect.moveTop(labelRect.top() + 3);
+ } else {
+ int newLeft = labelRect.left() - (rtl ? 3 : 2);
+ labelRect.moveLeft(newLeft);
+ labelRect.moveTop(labelRect.top() + 5);
+ }
+ ret = labelRect;
+ }
+
+ if (sc == SC_GroupBoxCheckBox) {
+ int left = rtl ? labelRect.right() - indicatorWidth : labelRect.left();
+ ret.setRect(left, ret.top(),
+ indicatorWidth, proxy()->pixelMetric(PM_IndicatorHeight, opt, widget));
+ }
+ break;
+ }
+ case SC_GroupBoxContents:
+ case SC_GroupBoxFrame: {
+ if (flat) {
+ ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
+ break;
+ }
+ QFontMetrics fm = groupBox->fontMetrics;
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ int yOffset = 3;
+ if (!checkable) {
+ if (widget && !widget->testAttribute(Qt::WA_SetFont)
+ && QApplication::desktopSettingsAware())
+ fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
+ yOffset = 5;
+ if (hasNoText)
+ yOffset = -qCeil(QFontMetricsF(fm).height());
+ }
+
+ ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0);
+ if (sc == SC_GroupBoxContents)
+ ret.adjust(3, 3, -3, -4); // guess
+ }
+ break;
+ default:
+ ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
+ break;
+ }
+ }
+ break;
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QAquaWidgetSize aquaSize = d->aquaSizeConstrain(spin, widget);
+ int spinner_w;
+ int spinBoxSep;
+ int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
+ switch (aquaSize) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ spinner_w = 14;
+ spinBoxSep = 2;
+ break;
+ case QAquaSizeSmall:
+ spinner_w = 12;
+ spinBoxSep = 2;
+ break;
+ case QAquaSizeMini:
+ spinner_w = 10;
+ spinBoxSep = 1;
+ break;
+ }
+
+ switch (sc) {
+ case SC_SpinBoxUp:
+ case SC_SpinBoxDown: {
+ if (spin->buttonSymbols == QAbstractSpinBox::NoButtons)
+ break;
+
+ const int y = fw;
+ const int x = spin->rect.width() - spinner_w;
+ ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spin->rect.height() - y * 2);
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.kind = kThemeIncDecButton;
+ int hackTranslateX;
+ switch (aquaSize) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ bdi.kind = kThemeIncDecButton;
+ hackTranslateX = 0;
+ break;
+ case QAquaSizeSmall:
+ bdi.kind = kThemeIncDecButtonSmall;
+ hackTranslateX = -2;
+ break;
+ case QAquaSizeMini:
+ bdi.kind = kThemeIncDecButtonMini;
+ hackTranslateX = -1;
+ break;
+ }
+ bdi.state = kThemeStateActive;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+ HIRect hirect = qt_hirectForQRect(ret);
+
+ HIRect outRect;
+ HIThemeGetButtonBackgroundBounds(&hirect, &bdi, &outRect);
+ ret = qt_qrectForHIRect(outRect);
+ switch (sc) {
+ case SC_SpinBoxUp:
+ ret.setHeight(ret.height() / 2);
+ break;
+ case SC_SpinBoxDown:
+ ret.setY(ret.y() + ret.height() / 2);
+ break;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ ret.translate(hackTranslateX, 0); // hack: position the buttons correctly (weird that we need this)
+ ret = visualRect(spin->direction, spin->rect, ret);
+ break;
+ }
+ case SC_SpinBoxEditField:
+ if (spin->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ ret.setRect(fw, fw,
+ spin->rect.width() - fw * 2,
+ spin->rect.height() - fw * 2);
+ } else {
+ ret.setRect(fw, fw,
+ spin->rect.width() - fw * 2 - spinBoxSep - spinner_w,
+ spin->rect.height() - fw * 2);
+ }
+ ret = visualRect(spin->direction, spin->rect, ret);
+ break;
+ default:
+ ret = QWindowsStyle::subControlRect(cc, spin, sc, widget);
+ break;
+ }
+ }
+ break;
+ case CC_ToolButton:
+ ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
+ if (sc == SC_ToolButtonMenu && widget && !qobject_cast<QToolBar*>(widget->parentWidget())) {
+ ret.adjust(-1, 0, 0, 0);
+ }
+ break;
+ default:
+ ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
+ break;
+ }
+ return ret;
+}
+
+QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *widget) const
+{
+ QSize sz(csz);
+ bool useAquaGuideline = true;
+
+ switch (ct) {
+ case QStyle::CT_SpinBox:
+ // hack to work around horrible sizeHint() code in QAbstractSpinBox
+ sz.setHeight(sz.height() - 3);
+ break;
+ case QStyle::CT_TabWidget:
+ // the size between the pane and the "contentsRect" (+4,+4)
+ // (the "contentsRect" is on the inside of the pane)
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ /**
+ This is supposed to show the relationship between the tabBar and
+ the stack widget of a QTabWidget.
+ Unfortunately ascii is not a good way of representing graphics.....
+ PS: The '=' line is the painted frame.
+
+ top ---+
+ |
+ |
+ |
+ | vvv just outside the painted frame is the "pane"
+ - -|- - - - - - - - - - <-+
+ TAB BAR +=====^============ | +2 pixels
+ - - -|- - -|- - - - - - - <-+
+ | | ^ ^^^ just inside the painted frame is the "contentsRect"
+ | | |
+ | overlap |
+ | | |
+ bottom ------+ <-+ +14 pixels
+ |
+ v
+ ------------------------------ <- top of stack widget
+
+
+ To summarize:
+ * 2 is the distance between the pane and the contentsRect
+ * The 14 and the 1's are the distance from the contentsRect to the stack widget.
+ (same value as used in SE_TabWidgetTabContents)
+ * overlap is how much the pane should overlap the tab bar
+ */
+ // then add the size between the stackwidget and the "contentsRect"
+
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QSize extra(0,0);
+ const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt, widget);
+ const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap;
+
+ if (getTabDirection(twf->shape) == kThemeTabNorth || getTabDirection(twf->shape) == kThemeTabSouth) {
+ extra = QSize(2, gapBetweenTabbarAndStackWidget + 1);
+ } else {
+ extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2);
+ }
+ sz+= extra;
+ }
+
+ break;
+ case QStyle::CT_TabBarTab:
+ if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
+ const QAquaWidgetSize AquaSize = d->aquaSizeConstrain(opt, widget);
+ const bool differentFont = (widget && widget->testAttribute(Qt::WA_SetFont))
+ || !QApplication::desktopSettingsAware();
+ ThemeTabDirection ttd = getTabDirection(tab->shape);
+ bool vertTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
+ if (vertTabs)
+ sz.transpose();
+ int defaultTabHeight;
+ int defaultExtraSpace = proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget); // Remove spurious gcc warning (AFAIK)
+ QFontMetrics fm = opt->fontMetrics;
+ switch (AquaSize) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ if (tab->documentMode)
+ defaultTabHeight = 23;
+ else
+ defaultTabHeight = 21;
+ break;
+ case QAquaSizeSmall:
+ defaultTabHeight = 18;
+ break;
+ case QAquaSizeMini:
+ defaultTabHeight = 16;
+ break;
+ }
+ bool setWidth = false;
+ if (differentFont || !tab->icon.isNull()) {
+ sz.rheight() = qMax(defaultTabHeight, sz.height());
+ } else {
+ QSize textSize = fm.size(Qt::TextShowMnemonic, tab->text);
+ sz.rheight() = qMax(defaultTabHeight, textSize.height());
+ sz.rwidth() = textSize.width() + defaultExtraSpace;
+ setWidth = true;
+ }
+
+ if (vertTabs)
+ sz.transpose();
+
+ int maxWidgetHeight = qMax(tab->leftButtonSize.height(), tab->rightButtonSize.height());
+ int maxWidgetWidth = qMax(tab->leftButtonSize.width(), tab->rightButtonSize.width());
+
+ int widgetWidth = 0;
+ int widgetHeight = 0;
+ int padding = 0;
+ if (tab->leftButtonSize.isValid()) {
+ padding += 8;
+ widgetWidth += tab->leftButtonSize.width();
+ widgetHeight += tab->leftButtonSize.height();
+ }
+ if (tab->rightButtonSize.isValid()) {
+ padding += 8;
+ widgetWidth += tab->rightButtonSize.width();
+ widgetHeight += tab->rightButtonSize.height();
+ }
+
+ if (vertTabs) {
+ sz.setHeight(sz.height() + widgetHeight + padding);
+ sz.setWidth(qMax(sz.width(), maxWidgetWidth));
+ } else {
+ if (setWidth)
+ sz.setWidth(sz.width() + widgetWidth + padding);
+ sz.setHeight(qMax(sz.height(), maxWidgetHeight));
+ }
+ }
+ break;
+ case QStyle::CT_PushButton:
+ // By default, we fit the contents inside a normal rounded push button.
+ // Do this by add enough space around the contents so that rounded
+ // borders (including highlighting when active) will show.
+ sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset + 12;
+ sz.rheight() += QMacStylePrivate::PushButtonTopOffset + QMacStylePrivate::PushButtonBottomOffset;
+ break;
+ case QStyle::CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int maxpmw = mi->maxIconWidth;
+ const QComboBox *comboBox = qobject_cast<const QComboBox *>(widget);
+ int w = sz.width(),
+ h = sz.height();
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ w = 10;
+ SInt16 ash;
+ GetThemeMenuSeparatorHeight(&ash);
+ h = ash;
+ } else {
+ h = mi->fontMetrics.height() + 2;
+ if (!mi->icon.isNull()) {
+ if (comboBox) {
+ const QSize &iconSize = comboBox->iconSize();
+ h = qMax(h, iconSize.height() + 4);
+ maxpmw = qMax(maxpmw, iconSize.width());
+ } else {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
+ }
+ }
+ }
+ if (mi->text.contains(QLatin1Char('\t')))
+ w += 12;
+ if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ w += 20;
+ if (maxpmw)
+ w += maxpmw + 6;
+ // add space for a check. All items have place for a check too.
+ w += 20;
+ if (comboBox && comboBox->isVisible()) {
+ QStyleOptionComboBox cmb;
+ cmb.initFrom(comboBox);
+ cmb.editable = false;
+ cmb.subControls = QStyle::SC_ComboBoxEditField;
+ cmb.activeSubControls = QStyle::SC_None;
+ w = qMax(w, subControlRect(QStyle::CC_ComboBox, &cmb,
+ QStyle::SC_ComboBoxEditField,
+ comboBox).width());
+ } else {
+ w += 12;
+ }
+ sz = QSize(w, h);
+ }
+ break;
+ case CT_ToolButton:
+ if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
+ if (mainWindow->unifiedTitleAndToolBarOnMac()) {
+ sz.rwidth() += 4;
+ if (sz.height() <= 32) {
+ // Workaround strange HIToolBar bug when getting constraints.
+ sz.rheight() += 1;
+ }
+ return sz;
+ }
+ }
+ }
+ sz.rwidth() += 10;
+ sz.rheight() += 10;
+ return sz;
+ case CT_ComboBox:
+ sz.rwidth() += 50;
+ break;
+ case CT_Menu: {
+ QStyleHintReturnMask menuMask;
+ QStyleOption myOption = *opt;
+ myOption.rect.setSize(sz);
+ if (proxy()->styleHint(SH_Menu_Mask, &myOption, widget, &menuMask)) {
+ sz = menuMask.region.boundingRect().size();
+ }
+ break; }
+ case CT_HeaderSection:{
+ const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt);
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ if (header->text.contains(QLatin1Char('\n')))
+ useAquaGuideline = false;
+ break; }
+ case CT_ScrollBar :
+ // Make sure that the scroll bar is large enough to display the thumb indicator.
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ const int minimumSize = scrollButtonsCutoffSize(thumbIndicatorCutoff, widgetSizePolicy(widget));
+ if (slider->orientation == Qt::Horizontal)
+ sz = sz.expandedTo(QSize(minimumSize, sz.height()));
+ else
+ sz = sz.expandedTo(QSize(sz.width(), minimumSize));
+ }
+ break;
+ case CT_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, vopt, csz, widget);
+ sz.setHeight(sz.height() + 2);
+ }
+ break;
+
+ default:
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ }
+
+ if (useAquaGuideline){
+ QSize macsz;
+ if (d->aquaSizeConstrain(opt, widget, ct, sz, &macsz) != QAquaSizeUnknown) {
+ if (macsz.width() != -1)
+ sz.setWidth(macsz.width());
+ if (macsz.height() != -1)
+ sz.setHeight(macsz.height());
+ }
+ }
+
+ // The sizes that Carbon and the guidelines gives us excludes the focus frame.
+ // We compensate for this by adding some extra space here to make room for the frame when drawing:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
+ QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
+ int bkind = 0;
+ switch (widgetSize) {
+ default:
+ case QAquaSizeLarge:
+ bkind = combo->editable ? kThemeComboBox : kThemePopupButton;
+ break;
+ case QAquaSizeSmall:
+ bkind = combo->editable ? int(kThemeComboBoxSmall) : int(kThemePopupButtonSmall);
+ break;
+ case QAquaSizeMini:
+ bkind = combo->editable ? kThemeComboBoxMini : kThemePopupButtonMini;
+ break;
+ }
+ HIRect tmpRect = {{0, 0}, {0, 0}};
+ HIRect diffRect = QMacStylePrivate::comboboxInnerBounds(tmpRect, bkind);
+ sz.rwidth() -= qRound(diffRect.size.width);
+ sz.rheight() -= qRound(diffRect.size.height);
+ } else if (ct == CT_PushButton || ct == CT_ToolButton){
+ ThemeButtonKind bkind;
+ QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
+ switch (ct) {
+ default:
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (btn->features & QStyleOptionButton::CommandLinkButton) {
+ return QWindowsStyle::sizeFromContents(ct, opt, sz, widget);
+ }
+ }
+
+ switch (widgetSize) {
+ default:
+ case QAquaSizeLarge:
+ bkind = kThemePushButton;
+ break;
+ case QAquaSizeSmall:
+ bkind = kThemePushButtonSmall;
+ break;
+ case QAquaSizeMini:
+ bkind = kThemePushButtonMini;
+ break;
+ }
+ break;
+ case CT_ToolButton:
+ switch (widgetSize) {
+ default:
+ case QAquaSizeLarge:
+ bkind = kThemeLargeBevelButton;
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ bkind = kThemeSmallBevelButton;
+ }
+ break;
+ }
+
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeStateActive;
+ bdi.kind = bkind;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+ HIRect macRect, myRect;
+ myRect = CGRectMake(0, 0, sz.width(), sz.height());
+ HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
+ // Mini buttons only return their actual size in HIThemeGetButtonBackgroundBounds, so help them out a bit (guess),
+ if (bkind == kThemePushButtonMini)
+ macRect.size.height += 8.;
+ else if (bkind == kThemePushButtonSmall)
+ macRect.size.height -= 10;
+ sz.setWidth(sz.width() + int(macRect.size.width - myRect.size.width));
+ sz.setHeight(sz.height() + int(macRect.size.height - myRect.size.height));
+ }
+ return sz;
+}
+
+void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
+ bool enabled, const QString &text, QPalette::ColorRole textRole) const
+{
+ if(flags & Qt::TextShowMnemonic)
+ flags |= Qt::TextHideMnemonic;
+ QWindowsStyle::drawItemText(p, r, flags, pal, enabled, text, textRole);
+}
+
+bool QMacStyle::event(QEvent *e)
+{
+ if(e->type() == QEvent::FocusIn) {
+ QWidget *f = 0;
+ QWidget *focusWidget = QApplication::focusWidget();
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
+ QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
+ if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
+ QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
+ if (proxy->widget())
+ focusWidget = proxy->widget()->focusWidget();
+ }
+ }
+#endif
+ if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) {
+ f = focusWidget;
+ QWidget *top = f->parentWidget();
+ while (top && !top->isWindow() && !(top->windowType() == Qt::SubWindow))
+ top = top->parentWidget();
+#ifndef QT_NO_MAINWINDOW
+ if (qobject_cast<QMainWindow *>(top)) {
+ QWidget *central = static_cast<QMainWindow *>(top)->centralWidget();
+ for (const QWidget *par = f; par; par = par->parentWidget()) {
+ if (par == central) {
+ top = central;
+ break;
+ }
+ if (par->isWindow())
+ break;
+ }
+ }
+#endif
+ }
+ if (f) {
+ if(!d->focusWidget)
+ d->focusWidget = new QFocusFrame(f);
+ d->focusWidget->setWidget(f);
+ } else if(d->focusWidget) {
+ d->focusWidget->setWidget(0);
+ }
+ } else if(e->type() == QEvent::FocusOut) {
+ if(d->focusWidget)
+ d->focusWidget->setWidget(0);
+ }
+ return false;
+}
+
+QIcon QMacStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ switch (standardIcon) {
+ default:
+ return QWindowsStyle::standardIconImplementation(standardIcon, opt, widget);
+ case SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton: {
+ QPixmap pixmap(qt_mac_toolbar_ext);
+ if (standardIcon == SP_ToolBarVerticalExtensionButton) {
+ QPixmap pix2(pixmap.height(), pixmap.width());
+ pix2.fill(Qt::transparent);
+ QPainter p(&pix2);
+ p.translate(pix2.width(), 0);
+ p.rotate(90);
+ p.drawPixmap(0, 0, pixmap);
+ return pix2;
+ }
+ return pixmap;
+ }
+ }
+}
+
+int QMacStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton;
+ bool isMetal = (widget && widget->testAttribute(Qt::WA_MacBrushedMetal));
+ int controlSize = getControlSize(option, widget);
+
+ if (control2 == QSizePolicy::ButtonBox) {
+ /*
+ AHIG seems to prefer a 12-pixel margin between group
+ boxes and the row of buttons. The 20 pixel comes from
+ Builder.
+ */
+ if (isMetal // (AHIG, guess, guess)
+ || (control1 & (QSizePolicy::Frame // guess
+ | QSizePolicy::GroupBox // (AHIG, guess, guess)
+ | QSizePolicy::TabWidget // guess
+ | ButtonMask))) { // AHIG
+ return_SIZE(14, 8, 8);
+ } else if (control1 == QSizePolicy::LineEdit) {
+ return_SIZE(8, 8, 8); // Interface Builder
+ } else {
+ return_SIZE(20, 7, 7); // Interface Builder
+ }
+ }
+
+ if ((control1 | control2) & ButtonMask) {
+ if (control1 == QSizePolicy::LineEdit)
+ return_SIZE(8, 8, 8); // Interface Builder
+ else if (control2 == QSizePolicy::LineEdit) {
+ if (orientation == Qt::Vertical)
+ return_SIZE(20, 7, 7); // Interface Builder
+ else
+ return_SIZE(20, 8, 8);
+ }
+ return_SIZE(14, 8, 8); // Interface Builder
+ }
+
+ switch (CT2(control1, control2)) {
+ case CT1(QSizePolicy::Label): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::DefaultType): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::CheckBox): // AHIG
+ case CT2(QSizePolicy::Label, QSizePolicy::ComboBox): // AHIG
+ case CT2(QSizePolicy::Label, QSizePolicy::LineEdit): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::RadioButton): // AHIG
+ case CT2(QSizePolicy::Label, QSizePolicy::Slider): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::SpinBox): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::ToolButton): // guess
+ return_SIZE(8, 6, 5);
+ case CT1(QSizePolicy::ToolButton):
+ return 8; // AHIG
+ case CT1(QSizePolicy::CheckBox):
+ case CT2(QSizePolicy::CheckBox, QSizePolicy::RadioButton):
+ case CT2(QSizePolicy::RadioButton, QSizePolicy::CheckBox):
+ if (orientation == Qt::Vertical)
+ return_SIZE(8, 8, 7); // AHIG and Builder
+ break;
+ case CT1(QSizePolicy::RadioButton):
+ if (orientation == Qt::Vertical)
+ return 5; // (Builder, guess, AHIG)
+ }
+
+ if (orientation == Qt::Horizontal
+ && (control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)))
+ return_SIZE(12, 10, 8); // guess
+
+ if ((control1 | control2) & (QSizePolicy::Frame
+ | QSizePolicy::GroupBox
+ | QSizePolicy::TabWidget)) {
+ /*
+ These values were chosen so that nested container widgets
+ look good side by side. Builder uses 8, which looks way
+ too small, and AHIG doesn't say anything.
+ */
+ return_SIZE(16, 10, 10); // guess
+ }
+
+ if ((control1 | control2) & (QSizePolicy::Line | QSizePolicy::Slider))
+ return_SIZE(12, 10, 8); // AHIG
+
+ if ((control1 | control2) & QSizePolicy::LineEdit)
+ return_SIZE(10, 8, 8); // AHIG
+
+ /*
+ AHIG and Builder differ by up to 4 pixels for stacked editable
+ comboboxes. We use some values that work fairly well in all
+ cases.
+ */
+ if ((control1 | control2) & QSizePolicy::ComboBox)
+ return_SIZE(10, 8, 7); // guess
+
+ /*
+ Builder defaults to 8, 6, 5 in lots of cases, but most of the time the
+ result looks too cramped.
+ */
+ return_SIZE(10, 8, 6); // guess
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h
new file mode 100644
index 0000000000..747779249c
--- /dev/null
+++ b/src/widgets/styles/qmacstyle_mac_p.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMACSTYLE_MAC_P_H
+#define QMACSTYLE_MAC_P_H
+
+#include <qmacstyle_mac.h>
+#include <private/qapplication_p.h>
+#include <private/qcombobox_p.h>
+#include <private/qmacstylepixmaps_mac_p.h>
+#include <private/qpaintengine_mac_p.h>
+#include <private/qpainter_p.h>
+#include <private/qprintengine_mac_p.h>
+#include <private/qstylehelper_p.h>
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qdialogbuttonbox.h>
+#include <qdockwidget.h>
+#include <qevent.h>
+#include <qfocusframe.h>
+#include <qformlayout.h>
+#include <qgroupbox.h>
+#include <qhash.h>
+#include <qheaderview.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlistview.h>
+#include <qmainwindow.h>
+#include <qmap.h>
+#include <qmenubar.h>
+#include <qpaintdevice.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <qpointer.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qrubberband.h>
+#include <qsizegrip.h>
+#include <qspinbox.h>
+#include <qsplitter.h>
+#include <qstyleoption.h>
+#include <qtextedit.h>
+#include <qtextstream.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qtableview.h>
+#include <qwizard.h>
+#include <qdebug.h>
+#include <qlibrary.h>
+#include <qdatetimeedit.h>
+#include <qmath.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
+enum {
+ kThemePushButtonTextured = 31,
+ kThemePushButtonTexturedSmall = 32,
+ kThemePushButtonTexturedMini = 33
+};
+
+/* Search fields */
+enum {
+ kHIThemeFrameTextFieldRound = 1000,
+ kHIThemeFrameTextFieldRoundSmall = 1001,
+ kHIThemeFrameTextFieldRoundMini = 1002
+};
+#endif
+
+/*
+ AHIG:
+ Apple Human Interface Guidelines
+ http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/
+
+ Builder:
+ Apple Interface Builder v. 3.1.1
+*/
+
+// this works as long as we have at most 16 different control types
+#define CT1(c) CT2(c, c)
+#define CT2(c1, c2) ((uint(c1) << 16) | uint(c2))
+
+enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2,
+ QAquaSizeUnknown = -1 };
+
+#define SIZE(large, small, mini) \
+ (controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini))
+
+// same as return SIZE(...) but optimized
+#define return_SIZE(large, small, mini) \
+ do { \
+ static const int sizes[] = { (large), (small), (mini) }; \
+ return sizes[controlSize]; \
+ } while (0)
+
+bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
+
+class QMacStylePrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QMacStylePrivate(QMacStyle *style);
+
+ // Ideally these wouldn't exist, but since they already exist we need some accessors.
+ static const int PushButtonLeftOffset;
+ static const int PushButtonTopOffset;
+ static const int PushButtonRightOffset;
+ static const int PushButtonBottomOffset;
+ static const int MiniButtonH;
+ static const int SmallButtonH;
+ static const int BevelButtonW;
+ static const int BevelButtonH;
+ static const int PushButtonContentPadding;
+
+
+ // Stuff from QAquaAnimate:
+ bool addWidget(QWidget *);
+ void removeWidget(QWidget *);
+
+ enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen };
+ bool animatable(Animates, const QWidget *) const;
+ void stopAnimate(Animates, QWidget *);
+ void startAnimate(Animates, QWidget *);
+ static ThemeDrawState getDrawState(QStyle::State flags);
+ QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
+ QStyle::ContentsType ct = QStyle::CT_CustomBase,
+ QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
+ void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
+ HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe);
+ bool doAnimate(Animates);
+ inline int animateSpeed(Animates) const { return 33; }
+
+ // Utility functions
+ void drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
+ QPainter *p, const QStyleOption *opt) const;
+
+ QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const;
+
+ HIRect pushButtonContentBounds(const QStyleOptionButton *btn,
+ const HIThemeButtonDrawInfo *bdi) const;
+
+ void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
+ const QWidget *widget, const ThemeDrawState &tds);
+
+ static HIRect comboboxInnerBounds(const HIRect &outerBounds, int buttonKind);
+
+ static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi);
+
+ static void drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p);
+ static void drawTableHeader(const HIRect &outerBounds, bool drawTopBorder, bool drawLeftBorder,
+ const HIThemeButtonDrawInfo &bdi, QPainter *p);
+ bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi,
+ ThemeButtonKind buttonKindToCheck) const;
+ void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget,
+ const ThemeDrawState tds,
+ HIThemeButtonDrawInfo *bdi) const;
+ QPixmap generateBackgroundPattern() const;
+protected:
+ bool eventFilter(QObject *, QEvent *);
+ void timerEvent(QTimerEvent *);
+
+private slots:
+ void startAnimationTimer();
+
+public:
+ QPointer<QPushButton> defaultButton; //default push buttons
+ int timerID;
+ QList<QPointer<QWidget> > progressBars; //existing progress bars that need animation
+
+ struct ButtonState {
+ int frame;
+ enum { ButtonDark, ButtonLight } dir;
+ } buttonState;
+ UInt8 progressFrame;
+ QPointer<QFocusFrame> focusWidget;
+ CFAbsoluteTime defaultButtonStart;
+ QMacStyle *q;
+ bool mouseDown;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMACSTYLE_MAC_P_H
diff --git a/src/widgets/styles/qmacstylepixmaps_mac_p.h b/src/widgets/styles/qmacstylepixmaps_mac_p.h
new file mode 100644
index 0000000000..7bd1a2b43e
--- /dev/null
+++ b/src/widgets/styles/qmacstylepixmaps_mac_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACSTYLEPIXMAPS_MAC_P_H
+#define QMACSTYLEPIXMAPS_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+static const char * const qt_mac_toolbar_ext[]={
+ "14 9 4 1",
+ "# c #858585",
+ "b c #d9d9d9",
+ ". c #dbdbdb",
+ "a c None",
+ ".###..###.aaaa",
+ "a.###..###.aaa",
+ "aab###bb###baa",
+ "aaab###bb###ba",
+ "aaaa.###..###.",
+ "aaa.###..###.a",
+ "aab###bb###baa",
+ "ab###bb###baaa",
+ ".###..###.aaaa"};
+
+#endif // QMACSTYLEPIXMAPS_MAC_P_H
diff --git a/src/widgets/styles/qmotifstyle.cpp b/src/widgets/styles/qmotifstyle.cpp
new file mode 100644
index 0000000000..d9be3f3643
--- /dev/null
+++ b/src/widgets/styles/qmotifstyle.cpp
@@ -0,0 +1,2721 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmotifstyle.h"
+#include "qcdestyle.h"
+
+#if !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
+
+#include "qmenu.h"
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include "qpixmap.h"
+#include "qpalette.h"
+#include "qwidget.h"
+#include "qpushbutton.h"
+#include "qscrollbar.h"
+#include "qtabbar.h"
+#include "qtabwidget.h"
+#include "qlistview.h"
+#include "qsplitter.h"
+#include "qslider.h"
+#include "qcombobox.h"
+#include "qlineedit.h"
+#include "qprogressbar.h"
+#include "qimage.h"
+#include "qfocusframe.h"
+#include "qdebug.h"
+#include "qpainterpath.h"
+#include "qmotifstyle_p.h"
+#include "qdialogbuttonbox.h"
+#include "qformlayout.h"
+#include <limits.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtWidgets/qgraphicsview.h>
+
+#ifdef Q_WS_X11
+#include "qx11info_x11.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// old constants that might still be useful...
+static const int motifItemFrame = 2; // menu item frame width
+static const int motifSepHeight = 2; // separator item height
+static const int motifItemHMargin = 3; // menu item hor text margin
+static const int motifItemVMargin = 2; // menu item ver text margin
+static const int motifArrowHMargin = 6; // arrow horizontal margin
+static const int motifTabSpacing = 12; // space between text and tab
+static const int motifCheckMarkHMargin = 2; // horiz. margins of check mark
+static const int motifCheckMarkSpace = 16;
+
+
+/*!
+ \class QMotifStyle
+ \brief The QMotifStyle class provides Motif look and feel.
+
+ \ingroup appearance
+
+ This class implements the Motif look and feel. It closely
+ resembles the original Motif look as defined by the Open Group,
+ but with some minor improvements. The Motif style is Qt's default
+ GUI style on Unix platforms.
+
+ \img qmotifstyle.png
+ \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle
+*/
+
+/*!
+ \variable QMotifStyle::focus
+ \internal
+*/
+
+/*!
+ Constructs a QMotifStyle.
+
+ If \a useHighlightCols is false (the default), the style will
+ polish the application's color palette to emulate the Motif way of
+ highlighting, which is a simple inversion between the base and the
+ text color.
+*/
+QMotifStyle::QMotifStyle(bool useHighlightCols)
+ : QCommonStyle(*new QMotifStylePrivate)
+{
+ focus = 0;
+ highlightCols = useHighlightCols;
+}
+
+
+/*!
+ \internal
+*/
+QMotifStyle::QMotifStyle(QMotifStylePrivate &dd, bool useHighlightColors)
+ : QCommonStyle(dd)
+{
+ focus = 0;
+ highlightCols = useHighlightColors;
+}
+
+
+/*!
+ \overload
+
+ Destroys the style.
+*/
+QMotifStyle::~QMotifStyle()
+{
+ delete focus;
+}
+
+/*!
+ \internal
+ Animate indeterminate progress bars only when visible
+*/
+bool QMotifStyle::eventFilter(QObject *o, QEvent *e)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QMotifStyle);
+ switch(e->type()) {
+ case QEvent::StyleChange:
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
+ d->bars << bar;
+ if (d->bars.size() == 1) {
+ Q_ASSERT(d->animationFps> 0);
+ d->animateTimer = startTimer(1000 / d->animationFps);
+ }
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ // reinterpret_cast because there is no type info when getting
+ // the destroy event. We know that it is a QProgressBar.
+ if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
+ d->bars.removeAll(bar);
+ if (d->bars.isEmpty() && d->animateTimer) {
+ killTimer(d->animateTimer);
+ d->animateTimer = 0;
+ }
+ }
+ default:
+ break;
+ }
+#endif // QT_NO_PROGRESSBAR
+ return QStyle::eventFilter(o, e);
+}
+
+/*!
+ \internal
+*/
+QIcon QMotifStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ return QCommonStyle::standardIconImplementation(standardIcon, opt, widget);
+}
+
+/*!
+ \reimp
+*/
+void QMotifStyle::timerEvent(QTimerEvent *event)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QMotifStyle);
+ if (event->timerId() == d->animateTimer) {
+ Q_ASSERT(d->animationFps > 0);
+ d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
+ foreach (QProgressBar *bar, d->bars) {
+ if ((bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ }
+#endif // QT_NO_PROGRESSBAR
+ event->ignore();
+}
+
+
+QMotifStylePrivate::QMotifStylePrivate()
+#ifndef QT_NO_PROGRESSBAR
+ : animationFps(25), animateTimer(0), animateStep(0)
+#endif
+{
+}
+
+/*!
+ If \a arg is false, the style will polish the application's color
+ palette to emulate the Motif way of highlighting, which is a
+ simple inversion between the base and the text color.
+
+ The effect will show up the next time an application palette is
+ set via QApplication::setPalette(). The current color palette of
+ the application remains unchanged.
+
+ \sa QStyle::polish()
+*/
+void QMotifStyle::setUseHighlightColors(bool arg)
+{
+ highlightCols = arg;
+}
+
+/*!
+ Returns true if the style treats the highlight colors of the
+ palette in a Motif-like manner, which is a simple inversion
+ between the base and the text color; otherwise returns false. The
+ default is false.
+*/
+bool QMotifStyle::useHighlightColors() const
+{
+ return highlightCols;
+}
+
+/*! \reimp */
+
+void QMotifStyle::polish(QPalette& pal)
+{
+ if (pal.brush(QPalette::Active, QPalette::Light) == pal.brush(QPalette::Active, QPalette::Base)) {
+ QColor nlight = pal.color(QPalette::Active, QPalette::Light).darker(108);
+ pal.setColor(QPalette::Active, QPalette::Light, nlight) ;
+ pal.setColor(QPalette::Disabled, QPalette::Light, nlight) ;
+ pal.setColor(QPalette::Inactive, QPalette::Light, nlight) ;
+ }
+
+ if (highlightCols)
+ return;
+
+ // force the ugly motif way of highlighting *sigh*
+ pal.setColor(QPalette::Active, QPalette::Highlight,
+ pal.color(QPalette::Active, QPalette::Text));
+ pal.setColor(QPalette::Active, QPalette::HighlightedText,
+ pal.color(QPalette::Active, QPalette::Base));
+ pal.setColor(QPalette::Disabled, QPalette::Highlight,
+ pal.color(QPalette::Disabled, QPalette::Text));
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
+ pal.color(QPalette::Disabled, QPalette::Base));
+ pal.setColor(QPalette::Inactive, QPalette::Highlight,
+ pal.color(QPalette::Active, QPalette::Text));
+ pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ pal.color(QPalette::Active, QPalette::Base));
+}
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::polish(QWidget* widget)
+{
+ QStyle::polish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+}
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::unpolish(QWidget* widget)
+{
+ QCommonStyle::unpolish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget)) {
+ Q_D(QMotifStyle);
+ widget->removeEventFilter(this);
+ d->bars.removeAll(static_cast<QProgressBar*>(widget));
+ }
+#endif
+}
+
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::polish(QApplication* a)
+{
+ QCommonStyle::polish(a);
+}
+
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::unpolish(QApplication* a)
+{
+ QCommonStyle::unpolish(a);
+}
+
+static void rot(QPolygon& a, int n)
+{
+ QPolygon r(a.size());
+ for (int i = 0; i < (int)a.size(); i++) {
+ switch (n) {
+ case 1: r.setPoint(i,-a[i].y(),a[i].x()); break;
+ case 2: r.setPoint(i,-a[i].x(),-a[i].y()); break;
+ case 3: r.setPoint(i,a[i].y(),-a[i].x()); break;
+ }
+ }
+ a = r;
+}
+
+
+/*!
+ \reimp
+*/
+void QMotifStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ switch(pe) {
+ case PE_Q3CheckListExclusiveIndicator:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (lv->items.isEmpty())
+ return;
+
+ if (lv->state & State_Enabled)
+ p->setPen(QPen(opt->palette.text().color()));
+ else
+ p->setPen(QPen(lv->palette.color(QPalette::Disabled, QPalette::Text)));
+ QPolygon a;
+
+ int cx = opt->rect.width()/2 - 1;
+ int cy = opt->rect.height()/2;
+ int e = opt->rect.width()/2 - 1;
+ for (int i = 0; i < 3; i++) { //penWidth 2 doesn't quite work
+ a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
+ p->drawPolygon(a);
+ e--;
+ }
+ if (opt->state & State_On) {
+ if (lv->state & State_Enabled)
+ p->setPen(QPen(opt->palette.text().color()));
+ else
+ p->setPen(QPen(lv->palette.color(QPalette::Disabled,
+ QPalette::Text)));
+ QBrush saveBrush = p->brush();
+ p->setBrush(opt->palette.text());
+ e = e - 2;
+ a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
+ p->drawPolygon(a);
+ p->setBrush(saveBrush);
+ }
+ }
+ break;
+
+ case PE_FrameTabWidget:
+ case PE_FrameWindow:
+ qDrawShadePanel(p, opt->rect, opt->palette, QStyle::State_None, proxy()->pixelMetric(PM_DefaultFrameWidth));
+ break;
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
+ if ((fropt->state & State_HasFocus) && focus && focus->isVisible()
+ && !(fropt->state & QStyle::State_Item))
+ break;
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle: {
+ p->save();
+ p->translate(opt->rect.x(), opt->rect.y());
+
+ QColor dark(opt->palette.dark().color());
+ QColor light(opt->palette.light().color());
+ int i;
+ if (opt->state & State_Horizontal) {
+ int h = opt->rect.height();
+ if (h > 6) {
+ if (opt->state & State_On)
+ p->fillRect(1, 1, 8, h - 2, opt->palette.highlight());
+ QPolygon a(2 * ((h-6)/3));
+ int y = 3 + (h%3)/2;
+ p->setPen(dark);
+ p->drawLine(8, 1, 8, h-2);
+ for (i=0; 2*i < a.size(); ++i) {
+ a.setPoint(2*i, 5, y+1+3*i);
+ a.setPoint(2*i+1, 2, y+2+3*i);
+ }
+ p->drawPoints(a);
+ p->setPen(light);
+ p->drawLine(9, 1, 9, h-2);
+ for (i=0; 2*i < a.size(); i++) {
+ a.setPoint(2*i, 4, y+3*i);
+ a.setPoint(2*i+1, 1, y+1+3*i);
+ }
+ p->drawPoints(a);
+ // if (drawBorder) {
+ // p->setPen(QPen(Qt::darkGray));
+ // p->drawLine(0, opt->rect.height() - 1,
+ // tbExtent, opt->rect.height() - 1);
+ // }
+ }
+ } else {
+ int w = opt->rect.width();
+ if (w > 6) {
+ if (opt->state & State_On)
+ p->fillRect(1, 1, w - 2, 9, opt->palette.highlight());
+ QPolygon a(2 * ((w-6)/3));
+
+ int x = 3 + (w%3)/2;
+ p->setPen(dark);
+ p->drawLine(1, 8, w-2, 8);
+ for (i=0; 2*i < a.size(); ++i) {
+ a.setPoint(2*i, x+1+3*i, 6);
+ a.setPoint(2*i+1, x+2+3*i, 3);
+ }
+ p->drawPoints(a);
+ p->setPen(light);
+ p->drawLine(1, 9, w-2, 9);
+ for (i=0; 2*i < a.size(); ++i) {
+ a.setPoint(2*i, x+3*i, 5);
+ a.setPoint(2*i+1, x+1+3*i, 2);
+ }
+ p->drawPoints(a);
+ // if (drawBorder) {
+ // p->setPen(QPen(Qt::darkGray));
+ // p->drawLine(opt->rect.width() - 1, 0,
+ // opt->rect.width() - 1, tbExtent);
+ // }
+ }
+ }
+ p->restore();
+ break; }
+
+ case PE_PanelButtonCommand:
+ case PE_PanelButtonBevel:
+ case PE_PanelButtonTool: {
+ QBrush fill;
+ if (opt->state & State_Sunken)
+ fill = opt->palette.brush(QPalette::Mid);
+ else if ((opt->state & State_On) && (opt->state & State_Enabled))
+ fill = QBrush(opt->palette.mid().color(), Qt::Dense4Pattern);
+ else
+ fill = opt->palette.brush(QPalette::Button);
+ if ((opt->state & State_Enabled || opt->state & State_On) || !(opt->state & State_AutoRaise))
+ qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken | State_On)),
+ proxy()->pixelMetric(PM_DefaultFrameWidth), &fill);
+ break; }
+
+ case PE_IndicatorCheckBox: {
+ bool on = opt->state & State_On;
+ bool down = opt->state & State_Sunken;
+ bool showUp = !(down ^ on);
+ QBrush fill = opt->palette.brush((showUp || opt->state & State_NoChange) ?QPalette::Button : QPalette::Mid);
+ if (opt->state & State_NoChange) {
+ qDrawPlainRect(p, opt->rect, opt->palette.text().color(),
+ 1, &fill);
+ p->drawLine(opt->rect.x() + opt->rect.width() - 1, opt->rect.y(),
+ opt->rect.x(), opt->rect.y() + opt->rect.height() - 1);
+ } else {
+ qDrawShadePanel(p, opt->rect, opt->palette, !showUp,
+ proxy()->pixelMetric(PM_DefaultFrameWidth), &fill);
+ }
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ break; }
+
+ case PE_IndicatorRadioButton: {
+#define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
+ int inner_pts[] = { // used for filling diamond
+ 2,opt->rect.height()/2,
+ opt->rect.width()/2,2,
+ opt->rect.width()-3,opt->rect.height()/2,
+ opt->rect.width()/2,opt->rect.height()-3
+ };
+ int top_pts[] = { // top (^) of diamond
+ 0,opt->rect.height()/2,
+ opt->rect.width()/2,0,
+ opt->rect.width()-2,opt->rect.height()/2-1,
+ opt->rect.width()-3,opt->rect.height()/2-1,
+ opt->rect.width()/2,1,
+ 1,opt->rect.height()/2,
+ 2,opt->rect.height()/2,
+ opt->rect.width()/2,2,
+ opt->rect.width()-4,opt->rect.height()/2-1
+ };
+ int bottom_pts[] = { // bottom (v) of diamond
+ 1,opt->rect.height()/2+1,
+ opt->rect.width()/2,opt->rect.height()-1,
+ opt->rect.width()-1,opt->rect.height()/2,
+ opt->rect.width()-2,opt->rect.height()/2,
+ opt->rect.width()/2,opt->rect.height()-2,
+ 2,opt->rect.height()/2+1,
+ 3,opt->rect.height()/2+1,
+ opt->rect.width()/2,opt->rect.height()-3,
+ opt->rect.width()-3,opt->rect.height()/2
+ };
+ bool on = opt->state & State_On;
+ bool down = opt->state & State_Sunken;
+ bool showUp = !(down ^ on);
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ QPolygon a(INTARRLEN(inner_pts), inner_pts);
+ p->setPen(Qt::NoPen);
+ p->setBrush(opt->palette.brush(showUp ? QPalette::Button : QPalette::Mid));
+ a.translate(opt->rect.x(), opt->rect.y());
+ p->drawPolygon(a);
+ p->setPen(showUp ? opt->palette.light().color() : opt->palette.dark().color());
+ p->setBrush(Qt::NoBrush);
+ a.setPoints(INTARRLEN(top_pts), top_pts);
+ a.translate(opt->rect.x(), opt->rect.y());
+ p->drawPolyline(a);
+ p->setPen(showUp ? opt->palette.dark().color() : opt->palette.light().color());
+ a.setPoints(INTARRLEN(bottom_pts), bottom_pts);
+ a.translate(opt->rect.x(), opt->rect.y());
+ p->drawPolyline(a);
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+ break; }
+
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinPlus:
+ case PE_IndicatorSpinDown:
+ case PE_IndicatorSpinMinus:
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft: {
+ QRect rect = opt->rect;
+ QPolygon bFill;
+ QPolygon bTop;
+ QPolygon bBot;
+ QPolygon bLeft;
+ if (pe == PE_IndicatorSpinPlus || pe == PE_IndicatorSpinUp)
+ pe = PE_IndicatorArrowUp;
+ else if (pe == PE_IndicatorSpinMinus || pe == PE_IndicatorSpinDown)
+ pe = PE_IndicatorArrowDown;
+ bool vertical = pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowDown;
+ bool horizontal = !vertical;
+ int dim = rect.width() < rect.height() ? rect.width() : rect.height();
+ int colspec = 0x0000;
+
+ if (!(opt->state & State_Enabled))
+ dim -= 2;
+ if(dim < 2)
+ break;
+
+ // adjust size and center (to fix rotation below)
+ if (rect.width() > dim) {
+ rect.setX(rect.x() + ((rect.width() - dim) / 2));
+ rect.setWidth(dim);
+ }
+ if (rect.height() > dim) {
+ rect.setY(rect.y() + ((rect.height() - dim) / 2));
+ rect.setHeight(dim);
+ }
+
+ if (dim > 3) {
+ if (pixelMetric(PM_DefaultFrameWidth) < 2) { // thin style
+ bFill.resize( dim & 1 ? 3 : 4 );
+ bTop.resize( 2 );
+ bBot.resize( 2 );
+ bLeft.resize( 2 );
+ bLeft.putPoints( 0, 2, 0, 0, 0, dim-1 );
+ bTop.putPoints( 0, 2, 1, 0, dim-1, dim/2 );
+ bBot.putPoints( 0, 2, 1, dim-1, dim-1, dim/2 );
+
+ if ( dim > 6 ) { // dim>6: must fill interior
+ bFill.putPoints( 0, 2, 0, dim-1, 0, 0 );
+ if ( dim & 1 ) // if size is an odd number
+ bFill.setPoint( 2, dim - 1, dim / 2 );
+ else
+ bFill.putPoints( 2, 2, dim-1, dim/2-1, dim-1, dim/2 );
+ }
+ } else {
+ if (dim > 6)
+ bFill.resize(dim & 1 ? 3 : 4);
+ bTop.resize((dim/2)*2);
+ bBot.resize(dim & 1 ? dim + 1 : dim);
+ bLeft.resize(dim > 4 ? 4 : 2);
+ bLeft.putPoints(0, 2, 0,0, 0,dim-1);
+ if (dim > 4)
+ bLeft.putPoints(2, 2, 1,2, 1,dim-3);
+ bTop.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1);
+ bBot.putPoints(0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2);
+
+ for(int i=0; i<dim/2-2 ; i++) {
+ bTop.putPoints(i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i);
+ bBot.putPoints(i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i);
+ }
+ if (dim & 1) // odd number size: extra line
+ bBot.putPoints(dim-1, 2, dim-3,dim/2, dim-1,dim/2);
+ if (dim > 6) { // dim>6: must fill interior
+ bFill.putPoints(0, 2, 1,dim-3, 1,2);
+ if (dim & 1) // if size is an odd number
+ bFill.setPoint(2, dim - 3, dim / 2);
+ else
+ bFill.putPoints(2, 2, dim-4,dim/2-1, dim-4,dim/2);
+ }
+ }
+ } else {
+ if (dim == 3) { // 3x3 arrow pattern
+ bLeft.setPoints(4, 0,0, 0,2, 1,1, 1,1);
+ bTop .setPoints(2, 1,0, 1,0);
+ bBot .setPoints(2, 1,2, 2,1);
+ }
+ else { // 2x2 arrow pattern
+ bLeft.setPoints(2, 0,0, 0,1);
+ bTop .setPoints(2, 1,0, 1,0);
+ bBot .setPoints(2, 1,1, 1,1);
+ }
+ }
+
+ // We use rot() and translate() as it is more efficient that
+ // matrix transformations on the painter, and because it still
+ // works with QT_NO_TRANSFORMATIONS defined.
+
+ if (pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowLeft) {
+ if (vertical) {
+ rot(bFill,3);
+ rot(bLeft,3);
+ rot(bTop,3);
+ rot(bBot,3);
+ bFill.translate(0, rect.height() - 1);
+ bLeft.translate(0, rect.height() - 1);
+ bTop.translate(0, rect.height() - 1);
+ bBot.translate(0, rect.height() - 1);
+ } else {
+ rot(bFill,2);
+ rot(bLeft,2);
+ rot(bTop,2);
+ rot(bBot,2);
+ bFill.translate(rect.width() - 1, rect.height() - 1);
+ bLeft.translate(rect.width() - 1, rect.height() - 1);
+ bTop.translate(rect.width() - 1, rect.height() - 1);
+ bBot.translate(rect.width() - 1, rect.height() - 1);
+ }
+ if (opt->state & State_Sunken)
+ colspec = horizontal ? 0x2334 : 0x2343;
+ else
+ colspec = horizontal ? 0x1443 : 0x1434;
+ } else {
+ if (vertical) {
+ rot(bFill,1);
+ rot(bLeft,1);
+ rot(bTop,1);
+ rot(bBot,1);
+ bFill.translate(rect.width() - 1, 0);
+ bLeft.translate(rect.width() - 1, 0);
+ bTop.translate(rect.width() - 1, 0);
+ bBot.translate(rect.width() - 1, 0);
+ }
+ if (opt->state & State_Sunken)
+ colspec = horizontal ? 0x2443 : 0x2434;
+ else
+ colspec = horizontal ? 0x1334 : 0x1343;
+ }
+ bFill.translate(rect.x(), rect.y());
+ bLeft.translate(rect.x(), rect.y());
+ bTop.translate(rect.x(), rect.y());
+ bBot.translate(rect.x(), rect.y());
+
+ const QColor *cols[5];
+ if (opt->state & State_Enabled) {
+ cols[0] = 0;
+ cols[1] = &opt->palette.button().color();
+ cols[2] = &opt->palette.mid().color();
+ cols[3] = &opt->palette.light().color();
+ cols[4] = &opt->palette.dark().color();
+ } else {
+ cols[0] = 0;
+ cols[1] = &opt->palette.mid().color();
+ cols[2] = &opt->palette.mid().color();
+ cols[3] = &opt->palette.mid().color();
+ cols[4] = &opt->palette.mid().color();
+ }
+
+#define CMID *cols[(colspec>>12) & 0xf]
+#define CLEFT *cols[(colspec>>8) & 0xf]
+#define CTOP *cols[(colspec>>4) & 0xf]
+#define CBOT *cols[colspec & 0xf]
+
+ QPen savePen = p->pen();
+ QBrush saveBrush = p->brush();
+ QPen pen(Qt::NoPen);
+ QBrush brush = opt->palette.brush((opt->state & State_Enabled) ?
+ QPalette::Button : QPalette::Mid);
+ p->setPen(pen);
+ p->setBrush(brush);
+ p->drawPolygon(bFill);
+ p->setBrush(Qt::NoBrush);
+
+ p->setPen(CLEFT);
+ p->drawPolyline(bLeft);
+ p->setPen(CTOP);
+ p->drawPolyline(bTop);
+ p->setPen(CBOT);
+ p->drawPolyline(bBot);
+
+ p->setBrush(saveBrush);
+ p->setPen(savePen);
+#undef CMID
+#undef CLEFT
+#undef CTOP
+#undef CBOT
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ break; }
+
+ case PE_IndicatorDockWidgetResizeHandle: {
+ const int motifOffset = 10;
+ int sw = proxy()->pixelMetric(PM_SplitterWidth);
+ if (opt->state & State_Horizontal) {
+ int yPos = opt->rect.y() + opt->rect.height() / 2;
+ int kPos = opt->rect.right() - motifOffset - sw;
+ int kSize = sw - 2;
+
+ qDrawShadeLine(p, opt->rect.left(), yPos, kPos, yPos, opt->palette);
+ qDrawShadePanel(p, kPos, yPos - sw / 2 + 1, kSize, kSize,
+ opt->palette, false, 1, &opt->palette.brush(QPalette::Button));
+ qDrawShadeLine(p, kPos + kSize - 1, yPos, opt->rect.right(), yPos, opt->palette);
+ } else {
+ int xPos = opt->rect.x() + opt->rect.width() / 2;
+ int kPos = motifOffset;
+ int kSize = sw - 2;
+
+ qDrawShadeLine(p, xPos, opt->rect.top() + kPos + kSize - 1, xPos, opt->rect.bottom(), opt->palette);
+ qDrawShadePanel(p, xPos - sw / 2 + 1, opt->rect.top() + kPos, kSize, kSize, opt->palette,
+ false, 1, &opt->palette.brush(QPalette::Button));
+ qDrawShadeLine(p, xPos, opt->rect.top(), xPos, opt->rect.top() + kPos, opt->palette);
+ }
+ break; }
+
+ case PE_IndicatorMenuCheckMark: {
+ const int markW = 6;
+ const int markH = 6;
+ int posX = opt->rect.x() + (opt->rect.width() - markW) / 2 - 1;
+ int posY = opt->rect.y() + (opt->rect.height() - markH) / 2;
+ int dfw = proxy()->pixelMetric(PM_DefaultFrameWidth);
+
+ if (dfw < 2) {
+ // Could do with some optimizing/caching...
+ QPolygon a(7*2);
+ int i, xx, yy;
+ xx = posX;
+ yy = 3 + posY;
+ for (i=0; i<3; i++) {
+ a.setPoint(2*i, xx, yy);
+ a.setPoint(2*i+1, xx, yy+2);
+ xx++; yy++;
+ }
+ yy -= 2;
+ for (i=3; i<7; i++) {
+ a.setPoint(2*i, xx, yy);
+ a.setPoint(2*i+1, xx, yy+2);
+ xx++; yy--;
+ }
+ if (! (opt->state & State_Enabled) && ! (opt->state & State_On)) {
+ int pnt;
+ p->setPen(opt->palette.highlightedText().color());
+ QPoint offset(1,1);
+ for (pnt = 0; pnt < (int)a.size(); pnt++)
+ a[pnt] += offset;
+ p->drawPolyline(a);
+ for (pnt = 0; pnt < (int)a.size(); pnt++)
+ a[pnt] -= offset;
+ }
+ p->setPen(opt->palette.text().color());
+ p->drawPolyline(a);
+
+ qDrawShadePanel(p, posX-2, posY-2, markW+4, markH+6, opt->palette, true, dfw);
+ } else
+ qDrawShadePanel(p, posX, posY, markW, markH, opt->palette, true, dfw,
+ &opt->palette.brush(QPalette::Mid));
+
+ break; }
+
+ case PE_IndicatorProgressChunk:
+ {
+ bool vertical = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
+ vertical = (pb2->orientation == Qt::Vertical);
+ if (!vertical) {
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(),
+ opt->rect.height(), opt->palette.brush(QPalette::Highlight));
+ } else {
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(),
+ opt->palette.brush(QPalette::Highlight));
+ }
+ }
+ break;
+
+ default:
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void QMotifStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch(element) {
+ case CE_Splitter: {
+ QStyleOption handleOpt = *opt;
+ if (handleOpt.state & State_Horizontal)
+ handleOpt.state &= ~State_Horizontal;
+ else
+ handleOpt.state |= State_Horizontal;
+ proxy()->drawPrimitive(PE_IndicatorDockWidgetResizeHandle, &handleOpt, p, widget);
+ break; }
+
+ case CE_ScrollBarSubLine:
+ case CE_ScrollBarAddLine:{
+ PrimitiveElement pe;
+ if (element == CE_ScrollBarAddLine)
+ pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft) : PE_IndicatorArrowDown;
+ else
+ pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight) : PE_IndicatorArrowUp;
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.state |= State_Enabled;
+ proxy()->drawPrimitive(pe, &arrowOpt, p, widget);
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText)) {
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ p->fillRect(opt->rect.adjusted(fw, fw, -fw, -fw), QBrush(p->background().color(), Qt::Dense5Pattern));
+ }
+ }break;
+
+ case CE_ScrollBarSubPage:
+ case CE_ScrollBarAddPage:
+ p->fillRect(opt->rect, opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
+ break;
+
+ case CE_ScrollBarSlider: {
+ QStyleOption bevelOpt = *opt;
+ bevelOpt.state |= State_Raised;
+ bevelOpt.state &= ~(State_Sunken | State_On);
+ p->save();
+ p->setBrushOrigin(bevelOpt.rect.topLeft());
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
+ p->restore();
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ break; }
+
+ case CE_RadioButton:
+ case CE_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ bool isRadio = (element == CE_RadioButton);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, p, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+ proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
+ if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
+ if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ int diw, x1, y1, x2, y2;
+ p->setPen(opt->palette.foreground().color());
+ p->setBrush(QBrush(opt->palette.button().color(), Qt::NoBrush));
+ diw = proxy()->pixelMetric(PM_ButtonDefaultIndicator);
+ opt->rect.getCoords(&x1, &y1, &x2, &y2);
+ if (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)) {
+ x1 += diw;
+ y1 += diw;
+ x2 -= diw;
+ y2 -= diw;
+ }
+ if (btn->features & QStyleOptionButton::DefaultButton) {
+ if (diw == 0) {
+ QPolygon a;
+ a.setPoints(9,
+ x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
+ x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1);
+ p->setPen(opt->palette.shadow().color());
+ p->drawPolygon(a);
+ x1 += 2;
+ y1 += 2;
+ x2 -= 2;
+ y2 -= 2;
+ } else {
+ qDrawShadePanel(p, opt->rect.adjusted(1, 1, -1, -1), opt->palette, true);
+ }
+ }
+ if (!(btn->features & QStyleOptionButton::Flat) ||
+ (btn->state & (State_Sunken | State_On))) {
+ QStyleOptionButton newOpt = *btn;
+ newOpt.rect = QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ p->setBrushOrigin(p->brushOrigin());
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &newOpt, p, widget);
+ }
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
+ QRect ir = btn->rect;
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QRect(ir.right() - mbi - 3, ir.y() + 4, mbi, ir.height() - 8);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ break;
+ }
+
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ const int default_frame = proxy()->pixelMetric(PM_DefaultFrameWidth, tab, widget);
+ const int frame_offset = (default_frame > 1) ? 1 : 0;
+
+ if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedEast ||
+ tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::RoundedWest) {
+ p->save();
+ QRect tabRect = opt->rect;
+ QColor tabLight = opt->palette.light().color();
+ QColor tabDark = opt->palette.dark().color();
+
+ p->fillRect(opt->rect.adjusted(default_frame, default_frame,
+ -default_frame, -default_frame),
+ tab->palette.background());
+
+ if(tab->shape == QTabBar::RoundedWest) {
+ tabDark = opt->palette.light().color();
+ tabLight = opt->palette.dark().color();
+ tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
+ p->translate(opt->rect.left(), opt->rect.bottom());
+ p->rotate(-90);
+ } else if(tab->shape == QTabBar::RoundedSouth) {
+ tabDark = opt->palette.light().color();
+ tabLight = opt->palette.dark().color();
+ tabRect = QRect(0, 0, tabRect.width(), tabRect.height());
+ p->translate(opt->rect.right(), opt->rect.bottom());
+ p->rotate(180);
+ } else if(tab->shape == QTabBar::RoundedEast) {
+ tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
+ p->translate(opt->rect.right(), opt->rect.top());
+ p->rotate(90);
+ }
+
+ if (default_frame > 1) {
+ p->setPen(tabLight);
+ p->drawLine(tabRect.left(), tabRect.bottom(),
+ tabRect.right(), tabRect.bottom());
+ p->setPen(tabLight);
+ p->drawLine(tabRect.left(), tabRect.bottom()-1,
+ tabRect.right(), tabRect.bottom()-1);
+ if (tabRect.left() == 0)
+ p->drawPoint(tabRect.bottomLeft());
+ } else {
+ p->setPen(tabLight);
+ p->drawLine(tabRect.left(), tabRect.bottom(),
+ tabRect.right(), tabRect.bottom());
+ }
+
+ if (opt->state & State_Selected) {
+ p->fillRect(QRect(tabRect.left()+1, tabRect.bottom()-frame_offset,
+ tabRect.width()-3, 2),
+ tab->palette.brush(QPalette::Active, QPalette::Background));
+ p->setPen(tab->palette.background().color());
+ p->drawLine(tabRect.left()+1, tabRect.bottom(),
+ tabRect.left()+1, tabRect.top()+2);
+ p->setPen(tabLight);
+ } else {
+ p->setPen(tabLight);
+ }
+ p->drawLine(tabRect.left(), tabRect.bottom()-1,
+ tabRect.left(), tabRect.top() + 2);
+ p->drawPoint(tabRect.left()+1, tabRect.top() + 1);
+ p->drawLine(tabRect.left()+2, tabRect.top(),
+ tabRect.right() - 2, tabRect.top());
+ p->drawPoint(tabRect.left(), tabRect.bottom());
+
+ if (default_frame > 1) {
+ p->drawLine(tabRect.left()+1, tabRect.bottom(),
+ tabRect.left()+1, tabRect.top() + 2);
+ p->drawLine(tabRect.left()+2, tabRect.top()+1,
+ tabRect.right() - 2, tabRect.top()+1);
+ }
+
+ p->setPen(tabDark);
+ p->drawLine(tabRect.right() - 1, tabRect.top() + 2,
+ tabRect.right() - 1, tabRect.bottom() - 1 +
+ ((opt->state & State_Selected) ? frame_offset : -frame_offset));
+ if (default_frame > 1) {
+ p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
+ p->drawLine(tabRect.right(), tabRect.top() + 2, tabRect.right(),
+ tabRect.bottom() -
+ ((opt->state & State_Selected) ?
+ ((tab->position == QStyleOptionTab::End) ? 0:1):1+frame_offset));
+ p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
+ }
+ p->restore();
+ } else {
+ QCommonStyle::drawControl(element, opt, p, widget);
+ }
+ break; }
+#endif // QT_NO_TABBAR
+ case CE_ProgressBarGroove:
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 2);
+ break;
+
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QTransform oldMatrix = p->transform();
+ QRect rect = pb->rect;
+ bool vertical = false;
+ bool invert = false;
+ bool bottomToTop = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ invert = pb2->invertedAppearance;
+ bottomToTop = pb2->bottomToTop;
+ }
+ if (vertical) {
+ QTransform m;
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ if (bottomToTop) {
+ m.translate(0.0, rect.width());
+ m.rotate(-90);
+ } else {
+ m.translate(rect.height(), 0.0);
+ m.rotate(90);
+ }
+ p->setTransform(m, true);
+ }
+ const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, widget);
+ int u = rect.width() / unit_width;
+ int p_v = pb->progress - pb->minimum;
+ int t_s = qMax(0, pb->maximum - pb->minimum);
+ if (u > 0 && pb->progress >= INT_MAX / u && t_s >= u) {
+ // scale down to something usable.
+ p_v /= u;
+ t_s /= u;
+ }
+ if (pb->textVisible && t_s) {
+ int nu = (u * p_v + t_s/2) / t_s;
+ int x = unit_width * nu;
+ QRect left(rect.x(), rect.y(), x, rect.height());
+ QRect right(rect.x() + x, rect.y(), rect.width() - x, rect.height());
+ Qt::LayoutDirection dir;
+ dir = vertical ? (bottomToTop ? Qt::LeftToRight : Qt::RightToLeft) : pb->direction;
+ if (invert)
+ dir = (dir == Qt::LeftToRight) ? Qt::RightToLeft : Qt::LeftToRight;
+ const QRect highlighted = visualRect(dir, rect, left);
+ const QRect background = visualRect(dir, rect, right);
+ p->setPen(opt->palette.highlightedText().color());
+ p->setClipRect(highlighted);
+ p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
+
+ if (pb->progress != pb->maximum) {
+ p->setClipRect(background);
+ p->setPen(opt->palette.highlight().color());
+ p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
+ }
+ }
+ p->setTransform(oldMatrix, false);
+ break;
+ }
+
+ case CE_MenuTearoff: {
+ if(opt->state & State_Selected) {
+ if(pixelMetric(PM_MenuPanelWidth, opt, widget) > 1)
+ qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(),
+ opt->rect.height(), opt->palette, false, motifItemFrame,
+ &opt->palette.brush(QPalette::Button));
+ else
+ qDrawShadePanel(p, opt->rect.x()+1, opt->rect.y()+1, opt->rect.width()-2,
+ opt->rect.height()-2, opt->palette, true, 1, &opt->palette.brush(QPalette::Button));
+ } else {
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ }
+ p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
+ p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2-1, opt->rect.x()+opt->rect.width()-4,
+ opt->rect.y()+opt->rect.height()/2-1);
+ p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
+ p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2, opt->rect.x()+opt->rect.width()-4,
+ opt->rect.y()+opt->rect.height()/2);
+ break; }
+
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int maxpmw = menuitem->maxIconWidth;
+ if(menuitem->menuHasCheckableItems)
+ maxpmw = qMax(maxpmw, motifCheckMarkSpace);
+
+ int x, y, w, h;
+ opt->rect.getRect(&x, &y, &w, &h);
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { // draw separator
+ int textWidth = 0;
+ if (!menuitem->text.isEmpty()) {
+ QFont oldFont = p->font();
+ p->setFont(menuitem->font);
+ p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
+ proxy()->drawItemText(p, menuitem->rect.adjusted(10, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
+ menuitem->palette, menuitem->state & State_Enabled, menuitem->text,
+ QPalette::Text);
+ textWidth = menuitem->fontMetrics.width(menuitem->text) + 10;
+ y += menuitem->fontMetrics.height() / 2;
+ p->setFont(oldFont);
+ }
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(x, y, x + 5, y);
+ p->drawLine(x + 5 + textWidth, y, x+w, y);
+ p->setPen(opt->palette.light().color());
+ p->drawLine(x, y + 1, x + 5, y + 1);
+ p->drawLine(x + 5 + textWidth, y + 1, x+w, y + 1);
+ return;
+ }
+
+ int pw = motifItemFrame;
+ if((opt->state & State_Selected) && (opt->state & State_Enabled)) { // active item frame
+ if(pixelMetric(PM_MenuPanelWidth, opt) > 1)
+ qDrawShadePanel(p, x, y, w, h, opt->palette, false, pw,
+ &opt->palette.brush(QPalette::Button));
+ else
+ qDrawShadePanel(p, x+1, y+1, w-2, h-2, opt->palette, true, 1,
+ &opt->palette.brush(QPalette::Button));
+ } else { // incognito frame
+ p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
+ }
+
+ QRect vrect = visualRect(opt->direction, opt->rect,
+ QRect(x+motifItemFrame, y+motifItemFrame, maxpmw,
+ h-2*motifItemFrame));
+ int xvis = vrect.x();
+ if (menuitem->checked) {
+ if(!menuitem->icon.isNull())
+ qDrawShadePanel(p, xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
+ opt->palette, true, 1, &opt->palette.brush(QPalette::Midlight));
+ } else if (!(opt->state & State_Selected)) {
+ p->fillRect(xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
+ opt->palette.brush(QPalette::Button));
+ }
+
+ if(!menuitem->icon.isNull()) { // draw icon
+ QIcon::Mode mode = QIcon::Normal; // no disabled icons in Motif
+ if ((opt->state & State_Selected) && !!(opt->state & State_Enabled))
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable && menuitem->checked)
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode);
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vrect.center());
+ p->setPen(opt->palette.text().color());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+
+ } else if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable) { // just "checking"...
+ int mh = h - 2*motifItemFrame;
+
+ QStyleOptionButton newMenuItem;
+ newMenuItem.state = menuitem->checked ? State_On : State_None;
+ if (opt->state & State_Enabled) {
+ newMenuItem.state |= State_Enabled;
+ if (menuitem->state & State_Sunken)
+ newMenuItem.state |= State_Sunken;
+ }
+ if (menuitem->checkType & QStyleOptionMenuItem::Exclusive) {
+ newMenuItem.rect.setRect(xvis + 2, y + motifItemFrame + mh / 4, 11, 11);
+ proxy()->drawPrimitive(PE_IndicatorRadioButton, &newMenuItem, p, widget);
+ } else {
+ newMenuItem.rect.setRect(xvis + 5, y + motifItemFrame + mh / 4, 9, 9);
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &newMenuItem, p, widget);
+ }
+ }
+
+ p->setPen(opt->palette.buttonText().color());
+
+ QColor discol;
+ if (!(opt->state & State_Enabled)) {
+ discol = opt->palette.text().color();
+ p->setPen(discol);
+ }
+
+ int xm = motifItemFrame + maxpmw + motifItemHMargin;
+
+ vrect = visualRect(opt->direction, opt->rect,
+ QRect(x+xm, y+motifItemVMargin, w-xm-menuitem->tabWidth,
+ h-2*motifItemVMargin));
+ xvis = vrect.x();
+
+ QString s = menuitem->text;
+ if (!s.isNull()) { // draw text
+ int t = s.indexOf(QLatin1Char('\t'));
+ int m = motifItemVMargin;
+ int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ text_flags |= Qt::AlignLeft;
+ QFont oldFont = p->font();
+ p->setFont(menuitem->font);
+ if (t >= 0) { // draw tab text
+ QRect vr = visualRect(opt->direction, opt->rect,
+ QRect(x+w-menuitem->tabWidth-motifItemHMargin-motifItemFrame,
+ y+motifItemVMargin, menuitem->tabWidth,
+ h-2*motifItemVMargin));
+ int xv = vr.x();
+ QRect tr(xv, y+m, menuitem->tabWidth, h-2*m);
+ p->drawText(tr, text_flags, s.mid(t+1));
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
+ s = s.left(t);
+ }
+ QRect tr(xvis, y+m, w - xm - menuitem->tabWidth + 1, h-2*m);
+ p->drawText(tr, text_flags, s.left(t));
+ p->setFont(oldFont);
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { // draw sub menu arrow
+ int dim = (h-2*motifItemFrame) / 2;
+ QStyle::PrimitiveElement arrow = (opt->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight);
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.rect = visualRect(opt->direction, opt->rect,
+ QRect(x+w - motifArrowHMargin - motifItemFrame - dim,
+ y+h/2-dim/2, dim, dim));
+ if ((opt->state & State_Selected))
+ arrowOpt.state = (State_Sunken | ((opt->state & State_Enabled) ? State_Enabled : State_None));
+ else
+ arrowOpt.state = ((opt->state & State_Enabled) ? State_Enabled : State_None);
+ proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
+ }
+ break; }
+
+ case CE_MenuBarItem:
+ if (opt->state & State_Selected) // active item
+ qDrawShadePanel(p, opt->rect, opt->palette, false, motifItemFrame,
+ &opt->palette.brush(QPalette::Button));
+ else // other item
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ QCommonStyle::drawControl(element, opt, p, widget);
+ break;
+
+ case CE_HeaderSection:
+ p->save();
+ p->setBrushOrigin(opt->rect.topLeft());
+ qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken|State_On)),
+ proxy()->pixelMetric(PM_DefaultFrameWidth),
+ &opt->palette.brush((opt->state & State_Sunken) ? QPalette::Mid : QPalette::Button));
+ p->restore();
+ break;
+ case CE_RubberBand: {
+ QPixmap tiledPixmap(16, 16);
+ QPainter pixmapPainter(&tiledPixmap);
+ pixmapPainter.setPen(Qt::NoPen);
+ pixmapPainter.setBrush(Qt::Dense4Pattern);
+ pixmapPainter.setBackground(QBrush(opt->palette.base()));
+ pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
+ pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
+ pixmapPainter.end();
+ // ### workaround for borked XRENDER
+ tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
+
+ p->save();
+ QRect r = opt->rect;
+ QStyleHintReturnMask mask;
+ if (styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
+ p->setClipRegion(mask.region);
+ p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
+ p->restore();
+ }
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QRect rect = pb->rect;
+ bool vertical = false;
+ bool inverted = false;
+
+ // Get extra style options if version 2
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
+ if (pb2) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+
+ QTransform m;
+ if (vertical) {
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+
+ QPalette pal2 = pb->palette;
+ // Correct the highlight color if it is the same as the background
+ if (pal2.highlight() == pal2.background())
+ pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
+ QPalette::Highlight));
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ int w = rect.width();
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ QRect progressBar;
+ Q_D(const QMotifStyle);
+ // draw busy indicator
+ int x = (d->animateStep*8)% (w * 2);
+ if (x > w)
+ x = 2 * w - x;
+ x = reverse ? rect.right() - x : x + rect.x();
+ p->setTransform(m, true);
+ p->setPen(QPen(pal2.highlight().color(), 4));
+ p->drawLine(x, rect.y(), x, rect.height());
+
+ } else
+ QCommonStyle::drawControl(element, opt, p, widget);
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ default:
+ QCommonStyle::drawControl(element, opt, p, widget);
+ break; }
+}
+
+static int get_combo_extra_width(int h, int w, int *return_awh=0)
+{
+ int awh,
+ tmp;
+ if (h < 8) {
+ awh = 6;
+ } else if (h < 14) {
+ awh = h - 2;
+ } else {
+ awh = h/2;
+ }
+ tmp = (awh * 3) / 2;
+ if (tmp > w / 2) {
+ awh = w / 2 - 3;
+ tmp = w / 2 + 3;
+ }
+
+ if (return_awh)
+ *return_awh = awh;
+
+ return tmp;
+}
+
+static void get_combo_parameters(const QRect &r,
+ int &ew, int &awh, int &ax,
+ int &ay, int &sh, int &dh,
+ int &sy)
+{
+ ew = get_combo_extra_width(r.height(), r.width(), &awh);
+
+ sh = (awh+3)/4;
+ if (sh < 3)
+ sh = 3;
+ dh = sh/2 + 1;
+
+ ay = r.y() + (r.height()-awh-sh-dh)/2;
+ if (ay < 0) {
+ //panic mode
+ ay = 0;
+ sy = r.height();
+ } else {
+ sy = ay+awh+dh;
+ }
+ ax = r.x() + r.width() - ew;
+ ax += (ew-awh)/2;
+}
+
+/*!
+ \reimp
+*/
+void QMotifStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch (cc) {
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
+
+ State bflags = toolbutton->state & ~State_Sunken;
+ if (bflags & State_AutoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+ State mflags = bflags;
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ mflags |= State_Sunken;
+ }
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised)) {
+ tool.rect = button;
+ tool.state = bflags;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ }
+ }
+
+ if ((toolbutton->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect = toolbutton->rect.adjusted(3, 3, -3, -3);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if (mflags & (State_Sunken | State_On | State_Raised))
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
+ } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() + 5 - mbi, ir.height() - mbi + 4, mbi - 6, mbi - 6);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ }
+ break;
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox copy = *spinbox;
+ PrimitiveElement pe;
+
+ if (spinbox->frame && (spinbox->subControls & SC_SpinBoxFrame)) {
+ QRect r = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxFrame, widget);
+ qDrawShadePanel(p, r, opt->palette, false, proxy()->pixelMetric(PM_SpinBoxFrameWidth));
+
+ int fw = proxy()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ r = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxEditField, widget).adjusted(-fw,-fw,fw,fw);
+ QStyleOptionFrame lineOpt;
+ lineOpt.QStyleOption::operator=(*opt);
+ lineOpt.rect = r;
+ lineOpt.lineWidth = fw;
+ lineOpt.midLineWidth = 0;
+ lineOpt.state |= QStyle::State_Sunken;
+ proxy()->drawPrimitive(QStyle::PE_FrameLineEdit, &lineOpt, p, widget);
+ }
+
+ if (spinbox->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = spinbox->palette;
+ if (!(spinbox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+
+ copy.palette = pal2;
+
+ if (spinbox->activeSubControls == SC_SpinBoxUp && (spinbox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxUp, widget);
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+
+ if (spinbox->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = spinbox->state;
+ QPalette pal2 = spinbox->palette;
+ if (!(spinbox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+
+ if (spinbox->activeSubControls == SC_SpinBoxDown && (spinbox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxDown, widget);
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QRect groove = proxy()->subControlRect(CC_Slider, opt, SC_SliderGroove, widget),
+ handle = proxy()->subControlRect(CC_Slider, opt, SC_SliderHandle, widget);
+
+ if ((opt->subControls & SC_SliderGroove) && groove.isValid()) {
+ qDrawShadePanel(p, groove, opt->palette, true, proxy()->pixelMetric(PM_DefaultFrameWidth),
+ &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
+ if ((opt->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOption focusOpt = *opt;
+ focusOpt.rect = subElementRect(SE_SliderFocusRect, opt, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focusOpt, p, widget);
+ }
+ }
+
+ if ((opt->subControls & SC_SliderHandle) && handle.isValid()) {
+ QStyleOption bevelOpt = *opt;
+ bevelOpt.state = (opt->state | State_Raised) & ~State_Sunken;
+ bevelOpt.rect = handle;
+ p->save();
+ p->setBrushOrigin(bevelOpt.rect.topLeft());
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
+ p->restore();
+
+ if (slider->orientation == Qt::Horizontal) {
+ int mid = handle.x() + handle.width() / 2;
+ qDrawShadeLine(p, mid, handle.y(), mid, handle.y() + handle.height() - 2,
+ opt->palette, true, 1);
+ } else {
+ int mid = handle.y() + handle.height() / 2;
+ qDrawShadeLine(p, handle.x(), mid, handle.x() + handle.width() - 2, mid, opt->palette,
+ true, 1);
+ }
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(handle, QBrush(p->background().color(), Qt::Dense5Pattern));
+ }
+
+ if (slider->subControls & SC_SliderTickmarks) {
+ QStyleOptionSlider tmpSlider = *slider;
+ tmpSlider.subControls = SC_SliderTickmarks;
+ int frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ tmpSlider.rect.translate(frameWidth - 1, 0);
+ QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ if (opt->subControls & SC_ComboBoxArrow) {
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
+
+ if (cb->frame) {
+ QStyleOptionButton btn;
+ btn.QStyleOption::operator=(*cb);
+ btn.state |= QStyle::State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &btn, p, widget);
+ } else {
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ }
+
+ QRect tr = opt->rect;
+ tr.adjust(fw, fw, -fw, -fw);
+ get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
+
+ QRect ar = QStyle::visualRect(opt->direction, opt->rect, QRect(ax,ay,awh,awh));
+
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.rect = ar;
+ arrowOpt.state |= State_Enabled;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
+
+
+ // draws the shaded line under the arrow
+ p->setPen(opt->palette.light().color());
+ p->drawLine(ar.x(), sy, ar.x()+awh-1, sy);
+ p->drawLine(ar.x(), sy, ar.x(), sy+sh-1);
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(ar.x()+1, sy+sh-1, ar.x()+awh-1, sy+sh-1);
+ p->drawLine(ar.x()+awh-1, sy+1, ar.x()+awh-1, sy+sh-1);
+
+ if ((cb->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect focus;
+ focus.QStyleOption::operator=(*opt);
+ focus.rect = subElementRect(SE_ComboBoxFocusRect, opt, widget);
+ focus.backgroundColor = opt->palette.button().color();
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
+ }
+ }
+
+ if (opt->subControls & SC_ComboBoxEditField) {
+ if (cb->editable) {
+ QRect er = proxy()->subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, widget);
+ er.adjust(-1, -1, 1, 1);
+ qDrawShadePanel(p, er, opt->palette, true, 1,
+ &opt->palette.brush(QPalette::Base));
+ }
+ }
+ p->setPen(opt->palette.buttonText().color());
+ }
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar: {
+ if (opt->subControls & SC_ScrollBarGroove)
+ qDrawShadePanel(p, opt->rect, opt->palette, true,
+ proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget),
+ &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
+
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ if (scrollbar->minimum == scrollbar->maximum)
+ newScrollbar.state |= State_Enabled; // make sure that the slider is drawn.
+ QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
+ }
+ break; }
+#endif
+
+ case CC_Q3ListView:
+ if (opt->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
+ int i;
+ if (opt->subControls & SC_Q3ListView)
+ QCommonStyle::drawComplexControl(cc, opt, p, widget);
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ QStyleOptionQ3ListViewItem item = lv->items.at(0);
+ int y = opt->rect.y();
+ int c;
+ QPolygon dotlines;
+ if ((opt->activeSubControls & SC_All) && (opt->subControls & SC_Q3ListViewExpand)) {
+ c = 2;
+ dotlines.resize(2);
+ dotlines[0] = QPoint(opt->rect.right(), opt->rect.top());
+ dotlines[1] = QPoint(opt->rect.right(), opt->rect.bottom());
+ } else {
+ int linetop = 0, linebot = 0;
+ // each branch needs at most two lines, ie. four end points
+ dotlines.resize(item.childCount * 4);
+ c = 0;
+
+ // skip the stuff above the exposed rectangle
+ for (i = 1; i < lv->items.size(); ++i) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.height + y > 0)
+ break;
+ y += child.totalHeight;
+ }
+
+ int bx = opt->rect.width() / 2;
+
+ // paint stuff in the magical area
+ while (i < lv->items.size() && y < lv->rect.height()) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.features & QStyleOptionQ3ListViewItem::Visible) {
+ int lh;
+ if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
+ lh = child.height;
+ else
+ lh = p->fontMetrics().height() + 2 * lv->itemMargin;
+ lh = qMax(lh, QApplication::globalStrut().height());
+ if (lh % 2 > 0)
+ lh++;
+ linebot = y + lh/2;
+ if ((child.features & QStyleOptionQ3ListViewItem::Expandable || child.childCount > 0) &&
+ child.height > 0) {
+ // needs a box
+ p->setPen(opt->palette.text().color());
+ p->drawRect(bx-4, linebot-4, 9, 9);
+ QPolygon a;
+ if ((child.state & State_Open))
+ a.setPoints(3, bx-2, linebot-2,
+ bx, linebot+2,
+ bx+2, linebot-2); //Qt::RightArrow
+ else
+ a.setPoints(3, bx-2, linebot-2,
+ bx+2, linebot,
+ bx-2, linebot+2); //Qt::DownArrow
+ p->setBrush(opt->palette.text());
+ p->drawPolygon(a);
+ p->setBrush(Qt::NoBrush);
+ // dotlinery
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot - 5);
+ dotlines[c++] = QPoint(bx + 5, linebot);
+ dotlines[c++] = QPoint(opt->rect.width(), linebot);
+ linetop = linebot + 5;
+ } else {
+ // just dotlinery
+ dotlines[c++] = QPoint(bx+1, linebot);
+ dotlines[c++] = QPoint(opt->rect.width(), linebot);
+ }
+ y += child.totalHeight;
+ }
+ ++i;
+ }
+
+ // Expand line height to edge of rectangle if there's any
+ // visible child below
+ while (i < lv->items.size() && lv->items.at(i).height <= 0)
+ ++i;
+ if (i < lv->items.size())
+ linebot = opt->rect.height();
+
+ if (linetop < linebot) {
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot);
+ }
+ }
+
+ int line; // index into dotlines
+ p->setPen(opt->palette.text().color());
+ if (opt->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
+ p->drawLine(dotlines[line].x(), dotlines[line].y(),
+ dotlines[line+1].x(), dotlines[line+1].y());
+ }
+ }
+ break; }
+
+ default:
+ QCommonStyle::drawComplexControl(cc, opt, p, widget);
+ break;
+ }
+}
+
+
+/*! \reimp */
+int QMotifStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ int ret = 0;
+
+ switch(pm) {
+ case PM_ButtonDefaultIndicator:
+ ret = 5;
+ break;
+
+ case PM_CheckBoxLabelSpacing:
+ case PM_RadioButtonLabelSpacing:
+ ret = 10;
+ break;
+
+ case PM_ToolBarFrameWidth:
+ ret = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ break;
+
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+
+ case PM_SplitterWidth:
+ ret = qMax(10, QApplication::globalStrut().width());
+ break;
+
+ case PM_SliderLength:
+ ret = 30;
+ break;
+
+ case PM_SliderThickness:
+ ret = 16 + 4 * proxy()->pixelMetric(PM_DefaultFrameWidth);
+ break;
+#ifndef QT_NO_SLIDER
+ case PM_SliderControlThickness:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
+ int ticks = sl->tickPosition;
+ int n = 0;
+ if (ticks & QSlider::TicksAbove)
+ n++;
+ if (ticks & QSlider::TicksBelow)
+ n++;
+ if (!n) {
+ ret = space;
+ break;
+ }
+
+ int thick = 6; // Magic constant to get 5 + 16 + 5
+
+ space -= thick;
+ //### the two sides may be unequal in size
+ if (space > 0)
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ }
+ break;
+
+ case PM_SliderSpaceAvailable:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ if (sl->orientation == Qt::Horizontal)
+ ret = sl->rect.width() - proxy()->pixelMetric(PM_SliderLength, opt, widget) - 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ else
+ ret = sl->rect.height() - proxy()->pixelMetric(PM_SliderLength, opt, widget) - 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ }
+ break;
+#endif // QT_NO_SLIDER
+ case PM_DockWidgetFrameWidth:
+ ret = 2;
+ break;
+
+ case PM_DockWidgetHandleExtent:
+ ret = 9;
+ break;
+
+ case PM_ProgressBarChunkWidth:
+ ret = 1;
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ ret = 13;
+ break;
+
+ case PM_MenuBarHMargin:
+ ret = 2; // really ugly, but Motif
+ break;
+
+ case PM_MenuButtonIndicator:
+ if (!opt)
+ ret = 12;
+ else
+ ret = qMax(12, (opt->rect.height() - 4) / 3);
+ break;
+ default:
+ ret = QCommonStyle::pixelMetric(pm, opt, widget);
+ break;
+ }
+ return ret;
+}
+
+
+/*!
+ \reimp
+*/
+QRect
+QMotifStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const
+{
+ switch (cc) {
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
+ QSize bs;
+ bs.setHeight(opt->rect.height()/2 - fw);
+ bs.setWidth(qMin(bs.height() * 8 / 5, opt->rect.width() / 4)); // 1.6 -approximate golden mean
+ bs = bs.expandedTo(QApplication::globalStrut());
+ int y = fw + spinbox->rect.y();
+ int x, lx, rx;
+ x = spinbox->rect.x() + opt->rect.width() - fw - bs.width();
+ lx = fw;
+ rx = x - fw * 2;
+ const int margin = spinbox->frame ? 4 : 0;
+ switch (sc) {
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(x, y, bs.width(), bs.height() - 1));
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(x, y + bs.height() + 1, bs.width(), bs.height() - 1));
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(lx + margin, y + margin,
+ spinbox->rect.width() - 2*fw - 2*margin,
+ spinbox->rect.height() - 2*fw - 2*margin));
+
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(lx + margin, y + margin, rx - margin,
+ spinbox->rect.height() - 2*fw - 2 * margin));
+ case SC_SpinBoxFrame:
+ return visualRect(spinbox->direction, spinbox->rect, spinbox->rect);
+ default:
+ break;
+ }
+ break; }
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ if (sc == SC_SliderHandle) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, widget);
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, opt, widget);
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ int len = proxy()->pixelMetric(PM_SliderLength, opt, widget);
+ int motifBorder = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
+ horizontal ? slider->rect.width() - len - 2 * motifBorder
+ : slider->rect.height() - len - 2 * motifBorder,
+ slider->upsideDown);
+ if (horizontal)
+ return visualRect(slider->direction, slider->rect,
+ QRect(sliderPos + motifBorder, tickOffset + motifBorder, len,
+ thickness - 2 * motifBorder));
+ return visualRect(slider->direction, slider->rect,
+ QRect(tickOffset + motifBorder, sliderPos + motifBorder,
+ thickness - 2 * motifBorder, len));
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int dfw = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ QRect rect = visualRect(scrollbar->direction, scrollbar->rect,
+ QCommonStyle::subControlRect(cc, scrollbar, sc, widget));
+ if (sc == SC_ScrollBarSlider) {
+ if (scrollbar->orientation == Qt::Horizontal)
+ rect.adjust(-dfw, dfw, dfw, -dfw);
+ else
+ rect.adjust(dfw, -dfw, -dfw, dfw);
+ } else if (sc != SC_ScrollBarGroove) {
+ if (scrollbar->orientation == Qt::Horizontal)
+ rect.adjust(0, dfw, 0, -dfw);
+ else
+ rect.adjust(dfw, 0, -dfw, 0);
+ }
+ return visualRect(scrollbar->direction, scrollbar->rect, rect);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ switch (sc) {
+ case SC_ComboBoxArrow: {
+ int ew, awh, sh, dh, ax, ay, sy;
+ int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
+ QRect cr = opt->rect;
+ cr.adjust(fw, fw, -fw, -fw);
+ get_combo_parameters(cr, ew, awh, ax, ay, sh, dh, sy);
+ return visualRect(cb->direction, cb->rect, QRect(QPoint(ax, ay), cr.bottomRight()));
+ }
+
+ case SC_ComboBoxEditField: {
+ int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
+ QRect rect = opt->rect;
+ rect.adjust(fw, fw, -fw, -fw);
+ int ew = get_combo_extra_width(rect.height(), rect.width());
+ rect.adjust(1, 1, -1-ew, -1);
+ return visualRect(cb->direction, cb->rect, rect);
+ }
+
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ default:
+ break;
+ }
+ return QCommonStyle::subControlRect(cc, opt, sc, widget);
+}
+
+/*!
+ \reimp
+*/
+QSize
+QMotifStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget) const
+{
+ QSize sz(contentsSize);
+
+ switch(ct) {
+ case CT_RadioButton:
+ case CT_CheckBox:
+ sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
+ sz.rwidth() += motifItemFrame;
+ break;
+
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
+ if (!btn->text.isEmpty() && (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)))
+ sz.setWidth(qMax(75, sz.width()));
+ sz += QSize(0, 1); // magical extra pixel
+ }
+ break;
+
+ case CT_MenuBarItem: {
+ if(!sz.isEmpty())
+ sz += QSize(5*motifItemHMargin+1, 2*motifItemVMargin + motifItemFrame);
+ break; }
+
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, opt, sz, widget);
+ int w = sz.width(), h = sz.height();
+
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ w = 10;
+ h = (mi->text.isEmpty()) ? motifSepHeight : mi->fontMetrics.height();
+ }
+
+ // a little bit of border can never harm
+ w += 2*motifItemHMargin + 2*motifItemFrame;
+
+ if (!mi->text.isNull() && mi->text.indexOf(QLatin1Char('\t')) >= 0)
+ // string contains tab
+ w += motifTabSpacing;
+ else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ // submenu indicator needs some room if we don't have a tab column
+ w += motifArrowHMargin + 4*motifItemFrame;
+
+ int checkColumn = mi->maxIconWidth;
+ if (mi->menuHasCheckableItems)
+ checkColumn = qMax(checkColumn, motifCheckMarkSpace);
+ if (checkColumn > 0)
+ w += checkColumn + motifCheckMarkHMargin;
+
+ sz = QSize(w, h);
+ }
+ break;
+
+
+ default:
+ sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
+ break;
+ }
+
+ return sz;
+}
+
+/*!
+ \reimp
+*/
+QRect
+QMotifStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
+{
+ QRect rect;
+
+ switch (sr) {
+ case SE_SliderFocusRect:
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ rect.adjust(2, 2, -2, -2);
+ break;
+
+ case SE_CheckBoxIndicator:
+ case SE_RadioButtonIndicator:
+ {
+ rect = visualRect(opt->direction, opt->rect,
+ QCommonStyle::subElementRect(sr, opt, widget));
+ rect.adjust(motifItemFrame,0, motifItemFrame,0);
+ rect = visualRect(opt->direction, opt->rect, rect);
+ }
+ break;
+
+ case SE_ComboBoxFocusRect:
+ {
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ QRect tr = opt->rect;
+
+ tr.adjust(fw, fw, -fw, -fw);
+ get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
+ rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4);
+ break;
+ }
+
+ case SE_Q3DockWindowHandleRect:
+ if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
+ if (!dw->docked || !dw->closeEnabled)
+ rect.setRect(0, 0, opt->rect.width(), opt->rect.height());
+ else {
+ if (dw->state == State_Horizontal)
+ rect.setRect(2, 15, opt->rect.width()-2, opt->rect.height() - 15);
+ else
+ rect.setRect(0, 2, opt->rect.width() - 15, opt->rect.height() - 2);
+ }
+ rect = visualRect(dw->direction, dw->rect, rect);
+ }
+ break;
+
+ case SE_ProgressBarLabel:
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ int textw = 0;
+ if (pb->textVisible)
+ textw = pb->fontMetrics.width(QLatin1String("100%")) + 6;
+
+ if (pb->textAlignment == Qt::AlignLeft || pb->textAlignment == Qt::AlignCenter) {
+ rect = opt->rect;
+ } else {
+ if(sr == SE_ProgressBarLabel)
+ rect.setCoords(opt->rect.right() - textw, opt->rect.top(),
+ opt->rect.right(), opt->rect.bottom());
+ else
+ rect.setCoords(opt->rect.left(), opt->rect.top(),
+ opt->rect.right() - textw, opt->rect.bottom());
+ }
+ if (sr == SE_ProgressBarContents)
+ rect.adjust(2, 2, -2, -2);
+ rect = visualRect(pb->direction, pb->rect, rect);
+ }
+ break;
+ case SE_CheckBoxClickRect:
+ case SE_RadioButtonClickRect:
+ rect = visualRect(opt->direction, opt->rect, opt->rect);
+ break;
+
+ default:
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ }
+ return rect;
+}
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+static const char * const qt_menu_xpm[] = {
+"16 16 11 1",
+" c #000000",
+", c #336600",
+". c #99CC00",
+"X c #666600",
+"o c #999933",
+"+ c #333300",
+"@ c #669900",
+"# c #999900",
+"$ c #336633",
+"% c #666633",
+"& c #99CC33",
+"................",
+"................",
+".....#,++X#.....",
+"....X X....",
+"...X Xo#% X&..",
+"..# o..&@o o..",
+".., X..#+ @X X..",
+"..+ o.o+ +o# +..",
+"..+ #o+ +## +..",
+".., %@ ++ +, X..",
+"..# o@oo+ #..",
+"...X X##$ o..",
+"....X X..",
+"....&oX++X#oX...",
+"................",
+"................"};
+
+
+static const char * const qt_close_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " . . ",
+ " ... ... ",
+ " ...... ",
+ " .... ",
+ " .... ",
+ " ...... ",
+ " ... ... ",
+ " . . ",
+ " ",
+ " "};
+
+static const char * const qt_maximize_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " ",
+ " . ",
+ " ... ",
+ " ..... ",
+ " ....... ",
+ " ......... ",
+ " ",
+ " ",
+ " ",
+ " "};
+
+static const char * const qt_minimize_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ......... ",
+ " ....... ",
+ " ..... ",
+ " ... ",
+ " . ",
+ " ",
+ " ",
+ " "};
+
+#if 0 // ### not used???
+static const char * const qt_normalize_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " . ",
+ " .. ",
+ " ... ",
+ " .... ",
+ " ..... ",
+ " ...... ",
+ " ....... ",
+ " ",
+ " ",
+ " "};
+#endif
+
+static const char * const qt_normalizeup_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " ",
+ " ....... ",
+ " ...... ",
+ " ..... ",
+ " .... ",
+ " ... ",
+ " .. ",
+ " . ",
+ " ",
+ " "};
+
+static const char * const qt_shade_xpm[] = {
+ "12 12 2 1", "# c #000000",
+ ". c None",
+ "............",
+ "............",
+ ".#########..",
+ ".#########..",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............"};
+
+
+static const char * const qt_unshade_xpm[] = {
+ "12 12 2 1",
+ "# c #000000",
+ ". c None",
+ "............",
+ "............",
+ ".#########..",
+ ".#########..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#########..",
+ "............",
+ "............"};
+
+
+static const char * dock_window_close_xpm[] = {
+ "8 8 2 1",
+ "# c #000000",
+ ". c None",
+ "##....##",
+ ".##..##.",
+ "..####..",
+ "...##...",
+ "..####..",
+ ".##..##.",
+ "##....##",
+ "........"};
+
+// Message box icons, from page 210 of the Windows style guide.
+
+// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape palette.
+// Thanks to TrueColor displays, it is slightly more efficient to have
+// them duplicated.
+/* XPM */
+static const char * const information_xpm[]={
+ "32 32 5 1",
+ ". c None",
+ "c c #000000",
+ "* c #999999",
+ "a c #ffffff",
+ "b c #0000ff",
+ "...........********.............",
+ "........***aaaaaaaa***..........",
+ "......**aaaaaaaaaaaaaa**........",
+ ".....*aaaaaaaaaaaaaaaaaa*.......",
+ "....*aaaaaaaabbbbaaaaaaaac......",
+ "...*aaaaaaaabbbbbbaaaaaaaac.....",
+ "..*aaaaaaaaabbbbbbaaaaaaaaac....",
+ ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+ ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+ "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+ ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+ "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+ "...caaaaaaabbbbbbbbbaaaaaac****.",
+ "....caaaaaaaaaaaaaaaaaaaac****..",
+ ".....caaaaaaaaaaaaaaaaaac****...",
+ "......ccaaaaaaaaaaaaaacc****....",
+ ".......*cccaaaaaaaaccc*****.....",
+ "........***cccaaaac*******......",
+ "..........****caaac*****........",
+ ".............*caaac**...........",
+ "...............caac**...........",
+ "................cac**...........",
+ ".................cc**...........",
+ "..................***...........",
+ "...................**..........."};
+/* XPM */
+static const char* const warning_xpm[]={
+ "32 32 4 1",
+ ". c None",
+ "a c #ffff00",
+ "* c #000000",
+ "b c #999999",
+ ".............***................",
+ "............*aaa*...............",
+ "...........*aaaaa*b.............",
+ "...........*aaaaa*bb............",
+ "..........*aaaaaaa*bb...........",
+ "..........*aaaaaaa*bb...........",
+ ".........*aaaaaaaaa*bb..........",
+ ".........*aaaaaaaaa*bb..........",
+ "........*aaaaaaaaaaa*bb.........",
+ "........*aaaa***aaaa*bb.........",
+ ".......*aaaa*****aaaa*bb........",
+ ".......*aaaa*****aaaa*bb........",
+ "......*aaaaa*****aaaaa*bb.......",
+ "......*aaaaa*****aaaaa*bb.......",
+ ".....*aaaaaa*****aaaaaa*bb......",
+ ".....*aaaaaa*****aaaaaa*bb......",
+ "....*aaaaaaaa***aaaaaaaa*bb.....",
+ "....*aaaaaaaa***aaaaaaaa*bb.....",
+ "...*aaaaaaaaa***aaaaaaaaa*bb....",
+ "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
+ "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
+ "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
+ ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
+ ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
+ "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
+ "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+ ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
+ "..*************************bbbbb",
+ "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
+ ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
+/* XPM */
+static const char* const critical_xpm[]={
+ "32 32 4 1",
+ ". c None",
+ "a c #999999",
+ "* c #ff0000",
+ "b c #ffffff",
+ "...........********.............",
+ ".........************...........",
+ ".......****************.........",
+ "......******************........",
+ ".....********************a......",
+ "....**********************a.....",
+ "...************************a....",
+ "..*******b**********b*******a...",
+ "..******bbb********bbb******a...",
+ ".******bbbbb******bbbbb******a..",
+ ".*******bbbbb****bbbbb*******a..",
+ "*********bbbbb**bbbbb*********a.",
+ "**********bbbbbbbbbb**********a.",
+ "***********bbbbbbbb***********aa",
+ "************bbbbbb************aa",
+ "************bbbbbb************aa",
+ "***********bbbbbbbb***********aa",
+ "**********bbbbbbbbbb**********aa",
+ "*********bbbbb**bbbbb*********aa",
+ ".*******bbbbb****bbbbb*******aa.",
+ ".******bbbbb******bbbbb******aa.",
+ "..******bbb********bbb******aaa.",
+ "..*******b**********b*******aa..",
+ "...************************aaa..",
+ "....**********************aaa...",
+ "....a********************aaa....",
+ ".....a******************aaa.....",
+ "......a****************aaa......",
+ ".......aa************aaaa.......",
+ ".........aa********aaaaa........",
+ "...........aaaaaaaaaaa..........",
+ ".............aaaaaaa............"};
+/* XPM */
+static const char *const question_xpm[] = {
+ "32 32 5 1",
+ ". c None",
+ "c c #000000",
+ "* c #999999",
+ "a c #ffffff",
+ "b c #0000ff",
+ "...........********.............",
+ "........***aaaaaaaa***..........",
+ "......**aaaaaaaaaaaaaa**........",
+ ".....*aaaaaaaaaaaaaaaaaa*.......",
+ "....*aaaaaaaaaaaaaaaaaaaac......",
+ "...*aaaaaaaabbbbbbaaaaaaaac.....",
+ "..*aaaaaaaabaaabbbbaaaaaaaac....",
+ ".*aaaaaaaabbaaaabbbbaaaaaaaac...",
+ ".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
+ "*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
+ "*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
+ "*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
+ ".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
+ ".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
+ "..*aaaaaaaaaabbbbaaaaaaaaaac***.",
+ "...caaaaaaaaaabbaaaaaaaaaac****.",
+ "....caaaaaaaaaaaaaaaaaaaac****..",
+ ".....caaaaaaaaaaaaaaaaaac****...",
+ "......ccaaaaaaaaaaaaaacc****....",
+ ".......*cccaaaaaaaaccc*****.....",
+ "........***cccaaaac*******......",
+ "..........****caaac*****........",
+ ".............*caaac**...........",
+ "...............caac**...........",
+ "................cac**...........",
+ ".................cc**...........",
+ "..................***...........",
+ "...................**...........",
+};
+#endif
+
+/*!
+ \reimp
+*/
+QPixmap
+QMotifStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ switch (standardPixmap) {
+ case SP_TitleBarMenuButton:
+ return QPixmap(qt_menu_xpm);
+ case SP_TitleBarShadeButton:
+ return QPixmap(qt_shade_xpm);
+ case SP_TitleBarUnshadeButton:
+ return QPixmap(qt_unshade_xpm);
+ case SP_TitleBarNormalButton:
+ return QPixmap(qt_normalizeup_xpm);
+ case SP_TitleBarMinButton:
+ return QPixmap(qt_minimize_xpm);
+ case SP_TitleBarMaxButton:
+ return QPixmap(qt_maximize_xpm);
+ case SP_TitleBarCloseButton:
+ return QPixmap(qt_close_xpm);
+ case SP_DockWidgetCloseButton:
+ return QPixmap(dock_window_close_xpm);
+
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxWarning:
+ case SP_MessageBoxCritical:
+ case SP_MessageBoxQuestion:
+ {
+ const char * const * xpm_data;
+ switch (standardPixmap) {
+ case SP_MessageBoxInformation:
+ xpm_data = information_xpm;
+ break;
+ case SP_MessageBoxWarning:
+ xpm_data = warning_xpm;
+ break;
+ case SP_MessageBoxCritical:
+ xpm_data = critical_xpm;
+ break;
+ case SP_MessageBoxQuestion:
+ xpm_data = question_xpm;
+ break;
+ default:
+ xpm_data = 0;
+ break;
+ }
+ QPixmap pm;
+ if (xpm_data) {
+ QImage image((const char **) xpm_data);
+ // All that color looks ugly in Motif
+ const QPalette &pal = QApplication::palette();
+ switch (standardPixmap) {
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxQuestion:
+ image.setColor(2, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Dark).rgb());
+ image.setColor(3, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Base).rgb());
+ image.setColor(4, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Text).rgb());
+ break;
+ case SP_MessageBoxWarning:
+ image.setColor(1, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Base).rgb());
+ image.setColor(2, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Text).rgb());
+ image.setColor(3, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Dark).rgb());
+ break;
+ case SP_MessageBoxCritical:
+ image.setColor(1, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Dark).rgb());
+ image.setColor(2, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Text).rgb());
+ image.setColor(3, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Base).rgb());
+ break;
+ default:
+ break;
+ }
+ pm = QPixmap::fromImage(image);
+ }
+ return pm;
+ }
+
+ default:
+ break;
+ }
+#endif
+
+ return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+/*! \reimp */
+bool QMotifStyle::event(QEvent *e)
+{
+ if(e->type() == QEvent::FocusIn) {
+ if (QWidget *focusWidget = QApplication::focusWidget()) {
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
+ QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
+ if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
+ QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
+ if (proxy->widget())
+ focusWidget = proxy->widget()->focusWidget();
+ }
+ }
+#endif
+ if(!focus)
+ focus = new QFocusFrame(focusWidget);
+ focus->setWidget(focusWidget);
+ } else {
+ if(focus)
+ focus->setWidget(0);
+ }
+ } else if(e->type() == QEvent::FocusOut) {
+ if(focus)
+ focus->setWidget(0);
+ }
+ return QCommonStyle::event(e);
+}
+
+
+/*! \reimp */
+int
+QMotifStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret;
+
+ switch (hint) {
+#ifdef QT3_SUPPORT
+ case SH_GUIStyle:
+ ret = Qt::MotifStyle;
+ break;
+#endif
+ case SH_DrawMenuBarSeparator:
+ ret = true;
+ break;
+
+ case SH_ScrollBar_MiddleClickAbsolutePosition:
+ case SH_Slider_SloppyKeyEvents:
+ case SH_ProgressDialog_CenterCancelButton:
+ case SH_Menu_SpaceActivatesItem:
+ case SH_ScrollView_FrameOnlyAroundContents:
+ case SH_DitherDisabledText:
+ ret = 1;
+ break;
+
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 96;
+ break;
+
+ case SH_ProgressDialog_TextLabelAlignment:
+ ret = Qt::AlignLeft | Qt::AlignVCenter;
+ break;
+
+ case SH_ItemView_ChangeHighlightOnFocus:
+ ret = 0;
+ break;
+
+ case SH_MessageBox_UseBorderForButtonSpacing:
+ ret = 1;
+ break;
+
+ case SH_Dial_BackgroundRole:
+ ret = QPalette::Mid;
+ break;
+
+ case SH_DialogButtonLayout:
+ ret = QDialogButtonBox::KdeLayout;
+ break;
+ case SH_LineEdit_PasswordCharacter:
+ ret = '*';
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+ ret = 0;
+ break;
+ default:
+ ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
+ break;
+ }
+
+ return ret;
+}
+
+/*! \reimp */
+QPalette QMotifStyle::standardPalette() const
+{
+#ifdef Q_WS_X11
+ QColor background(0xcf, 0xcf, 0xcf);
+ if (QX11Info::appDepth() <= 8)
+ background = QColor(0xc0, 0xc0, 0xc0);
+#else
+ QColor background = QColor(0xcf, 0xcf, 0xcf);
+#endif
+
+ QColor light = background.lighter();
+ QColor mid = QColor(0xa6, 0xa6, 0xa6);
+ QColor dark = QColor(0x79, 0x7d, 0x79);
+ QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, background);
+ return palette;
+}
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
diff --git a/src/widgets/styles/qmotifstyle.h b/src/widgets/styles/qmotifstyle.h
new file mode 100644
index 0000000000..3fe470d1f1
--- /dev/null
+++ b/src/widgets/styles/qmotifstyle.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMOTIFSTYLE_H
+#define QMOTIFSTYLE_H
+
+#include <QtWidgets/qcommonstyle.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_MOTIF)
+
+class QPalette;
+class QFocusFrame;
+
+class QMotifStylePrivate;
+class Q_GUI_EXPORT QMotifStyle : public QCommonStyle
+{
+ Q_OBJECT
+public:
+ explicit QMotifStyle(bool useHighlightCols=false);
+ virtual ~QMotifStyle();
+
+ void setUseHighlightColors(bool);
+ bool useHighlightColors() const;
+
+ void polish(QPalette&);
+ void polish(QWidget*);
+ void unpolish(QWidget*);
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ bool event(QEvent *);
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ QPointer<QFocusFrame> focus;
+ QMotifStyle(QMotifStylePrivate &dd, bool useHighlightCols = false);
+ void timerEvent(QTimerEvent *event);
+ bool eventFilter(QObject *o, QEvent *e);
+
+private:
+ Q_DECLARE_PRIVATE(QMotifStyle)
+ Q_DISABLE_COPY(QMotifStyle)
+
+ bool highlightCols;
+};
+
+#endif // QT_NO_STYLE_MOTIF
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMOTIFSTYLE_H
diff --git a/src/widgets/styles/qmotifstyle_p.h b/src/widgets/styles/qmotifstyle_p.h
new file mode 100644
index 0000000000..90e0c6d530
--- /dev/null
+++ b/src/widgets/styles/qmotifstyle_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMOTIFSTYLE_P_H
+#define QMOTIFSTYLE_P_H
+#include <qlist.h>
+#include <qdatetime.h>
+#include <qprogressbar.h>
+#include "qmotifstyle.h"
+#include "qcommonstyle_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// Private class
+class QMotifStylePrivate : public QCommonStylePrivate
+{
+ Q_DECLARE_PUBLIC(QMotifStyle)
+public:
+ QMotifStylePrivate();
+
+public:
+#ifndef QT_NO_PROGRESSBAR
+ QList<QProgressBar *> bars;
+ int animationFps;
+ int animateTimer;
+ QTime startTime;
+ int animateStep;
+#endif // QT_NO_PROGRESSBAR
+};
+
+QT_END_NAMESPACE
+
+#endif //QMOTIFSTYLE_P_H
diff --git a/src/widgets/styles/qplastiquestyle.cpp b/src/widgets/styles/qplastiquestyle.cpp
new file mode 100644
index 0000000000..a5b0235dbe
--- /dev/null
+++ b/src/widgets/styles/qplastiquestyle.cpp
@@ -0,0 +1,6000 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplastiquestyle.h"
+
+#if !defined(QT_NO_STYLE_PLASTIQUE) || defined(QT_PLUGIN)
+
+static const bool AnimateBusyProgressBar = true;
+static const bool AnimateProgressBar = false;
+// #define QPlastique_MaskButtons
+static const int ProgressBarFps = 25;
+static const int blueFrameWidth = 2; // with of line edit focus frame
+
+#include "qwindowsstyle_p.h"
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qabstractitemview.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qdebug.h>
+#include <qdialogbuttonbox.h>
+#include <qformlayout.h>
+#include <qgroupbox.h>
+#include <qimage.h>
+#include <qlineedit.h>
+#include <qmainwindow.h>
+#include <qmenu.h>
+#include <qmenubar.h>
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <qpainterpath.h>
+#include <qpalette.h>
+#include <qpen.h>
+#include <qpixmap.h>
+#include <qpixmapcache.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qscrollbar.h>
+#include <qspinbox.h>
+#include <qsplitter.h>
+#include <qstyleoption.h>
+#include <qtextedit.h>
+#include <qelapsedtimer.h>
+#include <qtoolbar.h>
+#include <qtoolbox.h>
+#include <qtoolbutton.h>
+#include <qworkspace.h>
+#include <qprocess.h>
+#include <qvarlengtharray.h>
+#include <limits.h>
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// from windows style
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsSepHeight = 2; // separator item height
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 2; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsTabSpacing = 12; // space between text and tab
+static const int windowsRightBorder = 15; // right border on windows
+static const int windowsCheckMarkWidth = 12; // checkmarks width on windows
+
+static const char * const qt_plastique_slider_verticalhandle[] = {
+ "15 11 6 1",
+ " c None",
+ "+ c #979797",
+ "@ c #C9C9C9",
+ "$ c #C1C1C1",
+ "b c None",
+ "d c None",
+ " $++++++++$ ",
+ "$+bbbbbbbb+$ ",
+ "+b $$ +$ ",
+ "+b $@ +$ ",
+ "+b +$",
+ "+b d+",
+ "+b d+$",
+ "+b $$ d+$ ",
+ "+b $@ d+$ ",
+ "$+dddddddd+$ ",
+ " $++++++++$ "};
+
+static const char * const qt_plastique_slider_verticalhandle_left[] = {
+ "15 11 6 1",
+ " c None",
+ "+ c #979797",
+ "@ c #C9C9C9",
+ "$ c #C1C1C1",
+ "b c None",
+ "d c None",
+ " $++++++++$ ",
+ " $+bbbbbbbb+$",
+ " $+b $$ d+",
+ " $+b $@ d+",
+ "$+b d+",
+ "+b d+",
+ "$+ d+",
+ " $+ $$ d+",
+ " $+ $@ d+",
+ " $+dddddddd+$",
+ " $++++++++$ "};
+
+static const char * const qt_plastique_slider_horizontalhandle[] = {
+ "11 15 6 1",
+ " c None",
+ "+ c #979797",
+ "@ c #C9C9C9",
+ "$ c #C1C1C1",
+ "b c None",
+ "d c None",
+ " $+++++++$ ",
+ "$+bbbbbbb+$",
+ "+b d+",
+ "+b$$ $$d+",
+ "+b$@ $@d+",
+ "+b d+",
+ "+b d+",
+ "+b d+",
+ "+b d+",
+ "+b d+",
+ "$+ d+$",
+ " $+ d+$ ",
+ " $+ d+$ ",
+ " $+d+$ ",
+ " $+$ "};
+
+static const char * const qt_plastique_slider_horizontalhandle_up[] = {
+ "11 15 6 1",
+ " c None",
+ "+ c #979797",
+ "@ c #C9C9C9",
+ "$ c #C1C1C1",
+ "b c None",
+ "d c None",
+ " $+$ ",
+ " $+b+$ ",
+ " $+b +$ ",
+ " $+b +$ ",
+ "$+b +$",
+ "+b d+",
+ "+b d+",
+ "+b d+",
+ "+b d+",
+ "+b d+",
+ "+b$$ $$d+",
+ "+b$@ $@d+",
+ "+b d+",
+ "$+ddddddd+$",
+ " $+++++++$ "};
+
+static const char * const qt_scrollbar_button_arrow_left[] = {
+ "4 7 2 1",
+ " c None",
+ "* c #BFBFBF",
+ " *",
+ " **",
+ " ***",
+ "****",
+ " ***",
+ " **",
+ " *"};
+
+static const char * const qt_scrollbar_button_arrow_right[] = {
+ "4 7 2 1",
+ " c None",
+ "* c #BFBFBF",
+ "* ",
+ "** ",
+ "*** ",
+ "****",
+ "*** ",
+ "** ",
+ "* "};
+
+static const char * const qt_scrollbar_button_arrow_up[] = {
+ "7 4 2 1",
+ " c None",
+ "* c #BFBFBF",
+ " * ",
+ " *** ",
+ " ***** ",
+ "*******"};
+
+static const char * const qt_scrollbar_button_arrow_down[] = {
+ "7 4 2 1",
+ " c None",
+ "* c #BFBFBF",
+ "*******",
+ " ***** ",
+ " *** ",
+ " * "};
+
+static const char * const qt_scrollbar_button_left[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ " .+++++++++++++.",
+ ".+#############+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ ".+<<<<<<<<<<<<<+",
+ " .+++++++++++++."};
+
+static const char * const qt_scrollbar_button_right[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ ".+++++++++++++. ",
+ "+#############+.",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+<<<<<<<<<<<<<+.",
+ ".+++++++++++++. "};
+
+static const char * const qt_scrollbar_button_up[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ " .++++++++++++. ",
+ ".+############+.",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+<<<<<<<<<<<<<<+",
+ ".++++++++++++++."};
+
+static const char * const qt_scrollbar_button_down[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ "# c #FAFAFA",
+ "< c #FAFAFA",
+ "* c #FAFAFA",
+ "++++++++++++++++",
+ "+##############+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ "+# <+",
+ ".+<<<<<<<<<<<<+.",
+ " .++++++++++++. "};
+
+static const char * const qt_scrollbar_slider_pattern_vertical[] = {
+ "10 18 3 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ ".. .. ..",
+ ".+ .+ .+",
+ " ",
+ " ",
+ ".. .. ..",
+ ".+ .+ .+",
+ " ",
+ " ",
+ ".. .. ..",
+ ".+ .+ .+",
+ " ",
+ " ",
+ ".. .. ..",
+ ".+ .+ .+",
+ " ",
+ " ",
+ ".. .. ..",
+ ".+ .+ .+"};
+
+static const char * const qt_scrollbar_slider_pattern_horizontal[] = {
+ "18 10 3 1",
+ " c None",
+ ". c #BFBFBF",
+ "+ c #979797",
+ ".. .. .. .. ..",
+ ".+ .+ .+ .+ .+",
+ " ",
+ " ",
+ ".. .. .. .. ..",
+ ".+ .+ .+ .+ .+",
+ " ",
+ " ",
+ ".. .. .. .. ..",
+ ".+ .+ .+ .+ .+"};
+
+static const char * const qt_toolbarhandle[] = {
+ "6 6 4 1",
+ " c None",
+ ". c #C5C5C5",
+ "+ c #EEEEEE",
+ "@ c #FAFAFA",
+ ".. ",
+ ".+@ ",
+ " @@ ",
+ " .. ",
+ " .+@",
+ " @@"};
+
+static const char * const qt_simple_toolbarhandle[] = {
+ "3 3 4 1",
+ " c None",
+ ". c #C5C5C5",
+ "+ c #EEEEEE",
+ "@ c #FAFAFA",
+ ".. ",
+ ".+@",
+ " @@"};
+
+static const char * const qt_titlebar_context_help[] = {
+"27 27 5 1",
+" c None",
+". c #0A0C12",
+"+ c #1B202D",
+"@ c #293144",
+"# c #3C435D",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" +@##@+ ",
+" .@@@.+@@.. ",
+" .##+ +@@+. ",
+" .##@ @#@+. ",
+" .... +@+.. ",
+" .@+@@.. ",
+" +#@@+ ",
+" .##. ",
+" .++. ",
+" .++. ",
+" +##+ ",
+" .@@. ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
+
+static QLinearGradient qMapGradientToRect(const QLinearGradient &gradient, const QRectF &rect)
+{
+ QLinearGradient tmpGrad(rect.center().x(), rect.top(),
+ rect.center().x(), rect.bottom());
+ tmpGrad.setStops(gradient.stops());
+ return tmpGrad;
+}
+
+static QBrush qMapBrushToRect(const QBrush &brush, const QRectF &rect)
+{
+ if (!brush.gradient())
+ return brush;
+
+ // ### Ugly assumption that it's a linear gradient
+ QBrush tmp(qMapGradientToRect(*static_cast<const QLinearGradient *>(brush.gradient()), rect));
+ return tmp;
+}
+
+static void qBrushSetAlphaF(QBrush *brush, qreal alpha)
+{
+ if (const QGradient *gradient = brush->gradient()) {
+ // Use the gradient. Call QColor::setAlphaF() on all color stops.
+ QGradientStops stops = gradient->stops();
+ QMutableVectorIterator<QGradientStop> it(stops);
+ QColor tmpColor;
+ while (it.hasNext()) {
+ it.next();
+ tmpColor = it.value().second;
+ tmpColor.setAlphaF(alpha * tmpColor.alphaF());
+ it.setValue(QPair<qreal, QColor>(it.value().first, tmpColor));
+ }
+
+ switch (gradient->type()) {
+ case QGradient::RadialGradient: {
+ QRadialGradient grad = *static_cast<const QRadialGradient *>(gradient);
+ grad.setStops(stops);
+ *brush = QBrush(grad);
+ break;
+ }
+ case QGradient::ConicalGradient: {
+ QConicalGradient grad = *static_cast<const QConicalGradient *>(gradient);
+ grad.setStops(stops);
+ *brush = QBrush(grad);
+ break;
+ }
+ default:
+ qWarning("QPlastiqueStyle::qBrushLight() - unknown gradient type"
+ " - falling back to QLinearGradient");
+ case QGradient::LinearGradient: {
+ QLinearGradient grad = *static_cast<const QLinearGradient *>(gradient);
+ grad.setStops(stops);
+ *brush = QBrush(grad);
+ break;
+ }
+ }
+ } else if (!brush->texture().isNull()) {
+ // Modify the texture - ridiculously expensive.
+ QPixmap texture = brush->texture();
+ QPixmap pixmap;
+ QString name = QLatin1Literal("qbrushtexture-alpha")
+ % HexString<qreal>(alpha)
+ % HexString<qint64>(texture.cacheKey());
+ if (!QPixmapCache::find(name, pixmap)) {
+ QImage image = texture.toImage();
+ QRgb *rgb = reinterpret_cast<QRgb *>(image.bits());
+ int pixels = image.width() * image.height();
+ QColor tmpColor;
+ while (pixels--) {
+ tmpColor.setRgb(*rgb);
+ tmpColor.setAlphaF(alpha * tmpColor.alphaF());
+ *rgb++ = tmpColor.rgba();
+ }
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(name, pixmap);
+ }
+ brush->setTexture(pixmap);
+ } else {
+ // Use the color
+ QColor tmpColor = brush->color();
+ tmpColor.setAlphaF(alpha * tmpColor.alphaF());
+ brush->setColor(tmpColor);
+ }
+}
+
+static QBrush qBrushLight(QBrush brush, int light)
+{
+ if (const QGradient *gradient = brush.gradient()) {
+ // Use the gradient. Call QColor::lighter() on all color stops.
+ QGradientStops stops = gradient->stops();
+ QMutableVectorIterator<QGradientStop> it(stops);
+ while (it.hasNext()) {
+ it.next();
+ it.setValue(QPair<qreal, QColor>(it.value().first, it.value().second.lighter(light)));
+ }
+
+ switch (gradient->type()) {
+ case QGradient::RadialGradient: {
+ QRadialGradient grad = *static_cast<const QRadialGradient *>(gradient);
+ grad.setStops(stops);
+ brush = QBrush(grad);
+ break;
+ }
+ case QGradient::ConicalGradient: {
+ QConicalGradient grad = *static_cast<const QConicalGradient *>(gradient);
+ grad.setStops(stops);
+ brush = QBrush(grad);
+ break;
+ }
+ default:
+ qWarning("QPlastiqueStyle::qBrushLight() - unknown gradient type"
+ " - falling back to QLinearGradient");
+ case QGradient::LinearGradient: {
+ QLinearGradient grad = *static_cast<const QLinearGradient *>(gradient);
+ grad.setStops(stops);
+ brush = QBrush(grad);
+ break;
+ }
+ }
+ } else if (!brush.texture().isNull()) {
+ // Modify the texture - ridiculously expensive.
+ QPixmap texture = brush.texture();
+ QPixmap pixmap;
+ QString name = QLatin1Literal("qbrushtexture-light")
+ % HexString<int>(light)
+ % HexString<qint64>(texture.cacheKey());
+
+ if (!QPixmapCache::find(name, pixmap)) {
+ QImage image = texture.toImage();
+ QRgb *rgb = reinterpret_cast<QRgb *>(image.bits());
+ int pixels = image.width() * image.height();
+ QColor tmpColor;
+ while (pixels--) {
+ tmpColor.setRgb(*rgb);
+ *rgb++ = tmpColor.lighter(light).rgba();
+ }
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(name, pixmap);
+ }
+ brush.setTexture(pixmap);
+ } else {
+ // Use the color
+ brush.setColor(brush.color().lighter(light));
+ }
+ return brush;
+}
+
+static QBrush qBrushDark(QBrush brush, int dark)
+{
+ if (const QGradient *gradient = brush.gradient()) {
+ // Use the gradient. Call QColor::darker() on all color stops.
+ QGradientStops stops = gradient->stops();
+ QMutableVectorIterator<QGradientStop> it(stops);
+ while (it.hasNext()) {
+ it.next();
+ it.setValue(QPair<qreal, QColor>(it.value().first, it.value().second.darker(dark)));
+ }
+
+ switch (gradient->type()) {
+ case QGradient::RadialGradient: {
+ QRadialGradient grad = *static_cast<const QRadialGradient *>(gradient);
+ grad.setStops(stops);
+ brush = QBrush(grad);
+ break;
+ }
+ case QGradient::ConicalGradient: {
+ QConicalGradient grad = *static_cast<const QConicalGradient *>(gradient);
+ grad.setStops(stops);
+ brush = QBrush(grad);
+ break;
+ }
+ default:
+ qWarning("QPlastiqueStyle::qBrushDark() - unknown gradient type"
+ " - falling back to QLinearGradient");
+ case QGradient::LinearGradient: {
+ QLinearGradient grad = *static_cast<const QLinearGradient *>(gradient);
+ grad.setStops(stops);
+ brush = QBrush(grad);
+ break;
+ }
+ }
+ } else if (!brush.texture().isNull()) {
+ // Modify the texture - ridiculously expensive.
+ QPixmap texture = brush.texture();
+ QPixmap pixmap;
+ QString name = QLatin1Literal("qbrushtexture-dark")
+ % HexString<int>(dark)
+ % HexString<qint64>(texture.cacheKey());
+
+ if (!QPixmapCache::find(name, pixmap)) {
+ QImage image = texture.toImage();
+ QRgb *rgb = reinterpret_cast<QRgb *>(image.bits());
+ int pixels = image.width() * image.height();
+ QColor tmpColor;
+ while (pixels--) {
+ tmpColor.setRgb(*rgb);
+ *rgb++ = tmpColor.darker(dark).rgba();
+ }
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(name, pixmap);
+ }
+ brush.setTexture(pixmap);
+ } else {
+ // Use the color
+ brush.setColor(brush.color().darker(dark));
+ }
+ return brush;
+}
+
+/*
+ Draws a rounded frame using the provided brush for 1, and adds 0.5 alpha
+ for 0.
+
+ 0111111110
+ 01 10
+ 1 1
+ 1 1
+ 1 1
+ 01 10
+ 0111111110
+*/
+static void qt_plastique_draw_frame(QPainter *painter, const QRect &rect, const QStyleOption *option,
+ QFrame::Shadow shadow = QFrame::Plain)
+{
+ QPen oldPen = painter->pen();
+ QBrush border;
+ QBrush corner;
+ QBrush innerTopLeft;
+ QBrush innerBottomRight;
+
+ if (shadow != QFrame::Plain && (option->state & QStyle::State_HasFocus)) {
+ border = option->palette.highlight();
+ qBrushSetAlphaF(&border, qreal(0.8));
+ corner = option->palette.highlight();
+ qBrushSetAlphaF(&corner, 0.5);
+ innerTopLeft = qBrushDark(option->palette.highlight(), 125);
+ innerBottomRight = option->palette.highlight();
+ qBrushSetAlphaF(&innerBottomRight, qreal(0.65));
+ } else {
+ border = option->palette.shadow();
+ qBrushSetAlphaF(&border, qreal(0.4));
+ corner = option->palette.shadow();
+ qBrushSetAlphaF(&corner, 0.25);
+ innerTopLeft = option->palette.shadow();
+ innerBottomRight = option->palette.shadow();
+ if (shadow == QFrame::Sunken) {
+ qBrushSetAlphaF(&innerTopLeft, qreal(0.23));
+ qBrushSetAlphaF(&innerBottomRight, qreal(0.075));
+ } else {
+ qBrushSetAlphaF(&innerTopLeft, qreal(0.075));
+ qBrushSetAlphaF(&innerBottomRight, qreal(0.23));
+ }
+ }
+
+ QLine lines[4];
+ QPoint points[8];
+
+ // Opaque corner lines
+ painter->setPen(QPen(border, 0));
+ lines[0] = QLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
+ lines[1] = QLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
+ lines[2] = QLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
+ lines[3] = QLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
+ painter->drawLines(lines, 4);
+
+ // Opaque corner dots
+ points[0] = QPoint(rect.left() + 1, rect.top() + 1);
+ points[1] = QPoint(rect.left() + 1, rect.bottom() - 1);
+ points[2] = QPoint(rect.right() - 1, rect.top() + 1);
+ points[3] = QPoint(rect.right() - 1, rect.bottom() - 1);
+ painter->drawPoints(points, 4);
+
+ // Shaded corner dots
+ painter->setPen(QPen(corner, 0));
+ points[0] = QPoint(rect.left(), rect.top() + 1);
+ points[1] = QPoint(rect.left(), rect.bottom() - 1);
+ points[2] = QPoint(rect.left() + 1, rect.top());
+ points[3] = QPoint(rect.left() + 1, rect.bottom());
+ points[4] = QPoint(rect.right(), rect.top() + 1);
+ points[5] = QPoint(rect.right(), rect.bottom() - 1);
+ points[6] = QPoint(rect.right() - 1, rect.top());
+ points[7] = QPoint(rect.right() - 1, rect.bottom());
+ painter->drawPoints(points, 8);
+
+ // Shadows
+ if (shadow != QFrame::Plain) {
+ painter->setPen(QPen(innerTopLeft, 0));
+ lines[0] = QLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, rect.top() + 1);
+ lines[1] = QLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
+ painter->drawLines(lines, 2);
+ painter->setPen(QPen(innerBottomRight, 0));
+ lines[0] = QLine(rect.left() + 2, rect.bottom() - 1, rect.right() - 2, rect.bottom() - 1);
+ lines[1] = QLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
+ painter->drawLines(lines, 2);
+ }
+
+ painter->setPen(oldPen);
+}
+
+static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
+{
+ const int maxFactor = 100;
+ QColor tmp = colorA;
+ tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
+ tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
+ tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
+ return tmp;
+}
+
+static void qt_plastique_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart,
+ const QColor &gradientStop)
+{
+ QString gradientName = QLatin1Literal("qplastique-g")
+ % HexString<int>(rect.width())
+ % HexString<int>(rect.height())
+ % HexString<QRgb>(gradientStart.rgba())
+ % HexString<QRgb>(gradientStop.rgba());
+
+ QPixmap cache;
+ QPainter *p = painter;
+ QRect r = rect;
+
+ bool doPixmapCache = painter->deviceTransform().isIdentity()
+ && painter->worldMatrix().isIdentity();
+ if (doPixmapCache && QPixmapCache::find(gradientName, cache)) {
+ painter->drawPixmap(rect, cache);
+ } else {
+ if (doPixmapCache) {
+ cache = QPixmap(rect.size());
+ cache.fill(Qt::transparent);
+ p = new QPainter(&cache);
+ r = QRect(0, 0, rect.width(), rect.height());
+ }
+
+ int x = r.center().x();
+ QLinearGradient gradient(x, r.top(), x, r.bottom());
+ gradient.setColorAt(0, gradientStart);
+ gradient.setColorAt(1, gradientStop);
+ p->fillRect(r, gradient);
+
+ if (doPixmapCache) {
+ p->end();
+ delete p;
+ painter->drawPixmap(rect, cache);
+ QPixmapCache::insert(gradientName, cache);
+ }
+ }
+}
+
+static void qt_plastique_drawFrame(QPainter *painter, const QStyleOption *option, const QWidget *widget)
+{
+ QRect rect = option->rect;
+ QPen oldPen = painter->pen();
+
+ QColor borderColor = option->palette.background().color().darker(178);
+ QColor gradientStartColor = option->palette.button().color().lighter(104);
+ QColor gradientStopColor = option->palette.button().color().darker(105);
+ QColor alphaCornerColor;
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
+ }
+
+ QLine lines[4];
+ QPoint points[8];
+
+ // outline / border
+ painter->setPen(borderColor);
+ lines[0] = QLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
+ lines[1] = QLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
+ lines[2] = QLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
+ lines[3] = QLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
+ painter->drawLines(lines, 4);
+
+ points[0] = QPoint(rect.left() + 1, rect.top() + 1);
+ points[1] = QPoint(rect.right() - 1, rect.top() + 1);
+ points[2] = QPoint(rect.left() + 1, rect.bottom() - 1);
+ points[3] = QPoint(rect.right() - 1, rect.bottom() - 1);
+ painter->drawPoints(points, 4);
+
+ painter->setPen(alphaCornerColor);
+
+ points[0] = QPoint(rect.left() + 1, rect.top());
+ points[1] = QPoint(rect.right() - 1, rect.top());
+ points[2] = QPoint(rect.left() + 1, rect.bottom());
+ points[3] = QPoint(rect.right() - 1, rect.bottom());
+ points[4] = QPoint(rect.left(), rect.top() + 1);
+ points[5] = QPoint(rect.right(), rect.top() + 1);
+ points[6] = QPoint(rect.left(), rect.bottom() - 1);
+ points[7] = QPoint(rect.right(), rect.bottom() - 1);
+ painter->drawPoints(points, 8);
+
+ // inner border
+ if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
+ painter->setPen(option->palette.button().color().darker(118));
+ else
+ painter->setPen(gradientStartColor);
+
+ lines[0] = QLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, option->rect.top() + 1);
+ lines[1] = QLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, option->rect.bottom() - 2);
+ painter->drawLines(lines, 2);
+
+ if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
+ painter->setPen(option->palette.button().color().darker(110));
+ else
+ painter->setPen(gradientStopColor.darker(102));
+
+ lines[0] = QLine(rect.left() + 2, rect.bottom() - 1, rect.right() - 2, rect.bottom() - 1);
+ lines[1] = QLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
+ painter->drawLines(lines, 2);
+
+ painter->setPen(oldPen);
+}
+
+static void qt_plastique_drawShadedPanel(QPainter *painter, const QStyleOption *option, bool base,
+ const QWidget *widget)
+{
+ QRect rect = option->rect;
+ QPen oldPen = painter->pen();
+
+ QColor gradientStartColor = option->palette.button().color().lighter(104);
+ QColor gradientStopColor = option->palette.button().color().darker(105);
+
+ // gradient fill
+ if ((option->state & QStyle::State_Enabled) || !(option->state & QStyle::State_AutoRaise)) {
+ if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On)) {
+ qt_plastique_draw_gradient(painter, rect.adjusted(1, 1, -1, -1),
+ option->palette.button().color().darker(114),
+ option->palette.button().color().darker(106));
+ } else {
+ qt_plastique_draw_gradient(painter, rect.adjusted(1, 1, -1, -1),
+ base ? option->palette.background().color().lighter(105) : gradientStartColor,
+ base ? option->palette.background().color().darker(102) : gradientStopColor);
+ }
+ }
+
+ qt_plastique_drawFrame(painter, option, widget);
+
+ painter->setPen(oldPen);
+}
+
+static void qt_plastique_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
+{
+ if (tmp.isNull())
+ return;
+ bool active = (option->titleBarState & QStyle::State_Active);
+
+ // ### use palette colors instead
+ QColor mdiButtonGradientStartColor;
+ QColor mdiButtonGradientStopColor;
+ if (active) {
+ mdiButtonGradientStartColor = QColor((hover || sunken) ? 0x7d8bb1 : 0x55689a);
+ mdiButtonGradientStopColor = QColor((hover || sunken) ? 0x939ebe : 0x7381ab);
+ } else {
+ mdiButtonGradientStartColor = QColor((hover || sunken) ? 0x9e9e9e : 0x818181);
+ mdiButtonGradientStopColor = QColor((hover || sunken) ? 0xababab : 0x929292);
+ }
+
+ qt_plastique_draw_gradient(painter, tmp.adjusted(1, 1, -1, -1),
+ mdiButtonGradientStartColor, mdiButtonGradientStopColor);
+
+ QColor mdiButtonBorderColor;
+ if (active) {
+ mdiButtonBorderColor = (hover || sunken) ? QColor(0x627097) : QColor(0x324577);
+ } else {
+ mdiButtonBorderColor = (hover || sunken) ? QColor(0x838383) : QColor(0x5e5e5e);
+ }
+ painter->setPen(QPen(mdiButtonBorderColor, 1));
+
+ const QLine lines[4] = {
+ QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()),
+ QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()),
+ QLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2),
+ QLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2) };
+ painter->drawLines(lines, 4);
+
+ const QPoint points[4] = {
+ QPoint(tmp.left() + 1, tmp.top() + 1),
+ QPoint(tmp.right() - 1, tmp.top() + 1),
+ QPoint(tmp.left() + 1, tmp.bottom() - 1),
+ QPoint(tmp.right() - 1, tmp.bottom() - 1) };
+ painter->drawPoints(points, 4);
+}
+
+#ifndef QT_NO_DOCKWIDGET
+static QString elliditide(const QString &text, const QFontMetrics &fontMetrics, const QRect &rect, int *textWidth = 0)
+{
+ // Chop and insert ellide into title if text is too wide
+ QString title = text;
+ int width = textWidth ? *textWidth : fontMetrics.width(text);
+ QString ellipsis = QLatin1String("...");
+ if (width > rect.width()) {
+ QString leftHalf = title.left(title.size() / 2);
+ QString rightHalf = title.mid(leftHalf.size() + 1);
+ while (!leftHalf.isEmpty() && !rightHalf.isEmpty()) {
+ leftHalf.chop(1);
+ int width = fontMetrics.width(leftHalf + ellipsis + rightHalf);
+ if (width < rect.width()) {
+ title = leftHalf + ellipsis + rightHalf;
+ width = width;
+ break;
+ }
+ rightHalf.remove(0, 1);
+ width = fontMetrics.width(leftHalf + ellipsis + rightHalf);
+ if (width < rect.width()) {
+ title = leftHalf + ellipsis + rightHalf;
+ width = width;
+ break;
+ }
+ }
+ }
+ if (textWidth)
+ *textWidth = width;
+ return title;
+}
+#endif
+
+#if !defined(QT_NO_DOCKWIDGET) || !defined(QT_NO_SPLITTER)
+static void qt_plastique_draw_handle(QPainter *painter, const QStyleOption *option,
+ const QRect &rect, Qt::Orientation orientation,
+ const QWidget *widget)
+{
+ QColor borderColor = option->palette.background().color().darker(178);
+ QColor alphaCornerColor;
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
+ }
+ QImage handle(qt_simple_toolbarhandle);
+ alphaCornerColor.setAlpha(170);
+ handle.setColor(1, alphaCornerColor.rgba());
+ handle.setColor(2, mergedColors(alphaCornerColor, option->palette.light().color()).rgba());
+ handle.setColor(3, option->palette.light().color().rgba());
+
+ const int spacing = 2;
+
+ if (orientation == Qt::Vertical) {
+ int nchunks = rect.width() / (handle.width() + spacing);
+ for (int i = 0; i < nchunks; ++i)
+ painter->drawImage(QPoint(rect.left() + i * (handle.width() + spacing), rect.top()), handle);
+ } else {
+ int nchunks = rect.height() / (handle.height() + spacing);
+ for (int i = 0; i < nchunks; ++i)
+ painter->drawImage(QPoint(rect.left(), rect.top() + i * (handle.height() + spacing)), handle);
+ }
+}
+#endif
+
+class QPlastiqueStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QPlastiqueStyle)
+public:
+ QPlastiqueStylePrivate();
+ virtual ~QPlastiqueStylePrivate();
+ void drawPartialFrame(QPainter *painter, const QStyleOptionComplex *option,
+ const QRect &rect, const QWidget *widget) const;
+
+#ifndef QT_NO_PROGRESSBAR
+ QList<QProgressBar *> bars;
+ int progressBarAnimateTimer;
+ QElapsedTimer timer;
+#endif
+};
+
+/*!
+ \internal
+ */
+QPlastiqueStylePrivate::QPlastiqueStylePrivate() :
+ QWindowsStylePrivate()
+#ifndef QT_NO_PROGRESSBAR
+ , progressBarAnimateTimer(0)
+#endif
+{
+}
+
+/*!
+ \internal
+ */
+QPlastiqueStylePrivate::~QPlastiqueStylePrivate()
+{
+}
+
+/*!
+ \class QPlastiqueStyle
+ \brief The QPlastiqueStyle class provides a widget style similar to the
+ Plastik style available in KDE.
+
+ The Plastique style provides a default look and feel for widgets on X11
+ that closely resembles the Plastik style, introduced by Sandro Giessl in
+ KDE 3.2.
+
+ \img qplastiquestyle.png
+ \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QCDEStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QPlastiqueStyle object.
+*/
+QPlastiqueStyle::QPlastiqueStyle()
+ : QWindowsStyle(*new QPlastiqueStylePrivate)
+{
+ setObjectName(QLatin1String("Plastique"));
+}
+
+/*!
+ Destructs the QPlastiqueStyle object.
+*/
+QPlastiqueStyle::~QPlastiqueStyle()
+{
+}
+
+/*
+ Used by spin- and combo box.
+ Draws a rounded frame around rect but omits the right hand edge
+*/
+void QPlastiqueStylePrivate::drawPartialFrame(QPainter *painter, const QStyleOptionComplex *option,
+ const QRect &rect, const QWidget *widget) const
+{
+ Q_Q(const QPlastiqueStyle);
+ bool reverse = option->direction == Qt::RightToLeft;
+ QStyleOptionFrame frameOpt;
+#ifndef QT_NO_LINEEDIT
+ if (QLineEdit *lineedit = widget->findChild<QLineEdit *>())
+ frameOpt.initFrom(lineedit);
+#else
+ Q_UNUSED(widget)
+#endif // QT_NO_LINEEDIT
+
+ frameOpt.rect = rect;
+ painter->save();
+ frameOpt.rect.adjust(-blueFrameWidth + (reverse ? 1 : 0), -blueFrameWidth,
+ blueFrameWidth + (reverse ? 0 : -1), blueFrameWidth);
+ painter->setClipRect(frameOpt.rect);
+ frameOpt.rect.adjust(reverse ? -2 : 0, 0, reverse ? 0 : 2, 0);
+ frameOpt.lineWidth = q->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ frameOpt.midLineWidth = 0;
+ frameOpt.state = option->state | QStyle::State_Sunken;
+ frameOpt.palette = option->palette;
+ q->drawPrimitive(QStyle::PE_PanelLineEdit, &frameOpt, painter, widget);
+ painter->restore();
+
+ // Draw a two pixel highlight on the flat edge
+ if (option->state & QStyle::State_HasFocus) {
+ painter->setPen(QPen(option->palette.highlight(), 0));
+ QBrush focusBorder = option->palette.highlight();
+ qBrushSetAlphaF(&focusBorder, qreal(0.65));
+ if (!reverse) {
+ painter->drawLine(rect.topRight() + QPoint(1, -1),
+ rect.bottomRight() + QPoint(1, 1));
+ painter->setPen(QPen(focusBorder, 0));
+ painter->drawLine(rect.topRight(),
+ rect.bottomRight());
+ }
+ else {
+ painter->drawLine(rect.topLeft() + QPoint(-1, -1),
+ rect.bottomLeft() + QPoint(-1, 1));
+ painter->setPen(QPen(focusBorder, 0));
+ painter->drawLine(rect.topLeft(),
+ rect.bottomLeft());
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ Q_ASSERT(option);
+
+ QColor borderColor = option->palette.background().color().darker(178);
+ QColor alphaCornerColor;
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
+ }
+ QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color());
+
+ switch (element) {
+ case PE_IndicatorButtonDropDown:
+ proxy()->drawPrimitive(PE_PanelButtonTool, option, painter, widget);
+ break;
+ case PE_FrameDefaultButton: {
+ if (!(option->state & QStyle::State_Enabled))
+ break;
+ painter->setPen(QPen(QColor(0, 0, 0, 127), 0));
+ const QLine lines[4] = {
+ QLine(option->rect.left() + 2, option->rect.top(),
+ option->rect.right() - 2, option->rect.top()),
+ QLine(option->rect.left() + 2, option->rect.bottom(),
+ option->rect.right() - 2, option->rect.bottom()),
+ QLine(option->rect.left(), option->rect.top() + 2,
+ option->rect.left(), option->rect.bottom() - 2),
+ QLine(option->rect.right(), option->rect.top() + 2,
+ option->rect.right(), option->rect.bottom() - 2) };
+ painter->drawLines(lines, 4);
+
+ QPoint points[8];
+ points[0] = QPoint(option->rect.left() + 1, option->rect.top() + 1);
+ points[1] = QPoint(option->rect.right() - 1, option->rect.top() + 1);
+ points[2] = QPoint(option->rect.left() + 1, option->rect.bottom() - 1);
+ points[3] = QPoint(option->rect.right() - 1, option->rect.bottom() - 1);
+ painter->drawPoints(points, 4);
+
+ painter->setPen(QPen(QColor(0, 0, 0, 63), 0));
+ points[0] = QPoint(option->rect.left() + 1, option->rect.top());
+ points[1] = QPoint(option->rect.right() - 1, option->rect.top());
+ points[2] = QPoint(option->rect.left(), option->rect.top() + 1);
+ points[3] = QPoint(option->rect.right(), option->rect.top() + 1);
+ points[4] = QPoint(option->rect.left() + 1, option->rect.bottom());
+ points[5] = QPoint(option->rect.right() - 1, option->rect.bottom());
+ points[6] = QPoint(option->rect.left(), option->rect.bottom() - 1);
+ points[7] = QPoint(option->rect.right(), option->rect.bottom() - 1);
+ painter->drawPoints(points, 8);
+
+ break;
+ }
+#ifndef QT_NO_TABWIDGET
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
+ if (twf->shape != QTabBar::RoundedNorth && twf->shape != QTabBar::RoundedWest &&
+ twf->shape != QTabBar::RoundedSouth && twf->shape != QTabBar::RoundedEast) {
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+
+ int borderThickness = proxy()->pixelMetric(PM_TabBarBaseOverlap, twf, widget);
+ bool reverse = (twf->direction == Qt::RightToLeft);
+
+ painter->save();
+
+ // Start by filling the contents of the tab widget frame (which is
+ // actually a panel).
+ painter->fillRect(option->rect.adjusted(1, 1, -1, -1), option->palette.window());
+
+ QRect tabBarRect;
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ if (reverse)
+ tabBarRect = QRect(twf->rect.right() - twf->leftCornerWidgetSize.width() - twf->tabBarSize.width() + 1, twf->rect.top(), twf->tabBarSize.width(), borderThickness);
+ else
+ tabBarRect = QRect(twf->rect.left() + twf->leftCornerWidgetSize.width(), twf->rect.top(), twf->tabBarSize.width(), borderThickness);
+ break ;
+ case QTabBar::RoundedWest:
+ tabBarRect = QRect(twf->rect.left(), twf->rect.top() + twf->leftCornerWidgetSize.height(), borderThickness, twf->tabBarSize.height());
+ break ;
+ case QTabBar::RoundedEast:
+ tabBarRect = QRect(twf->rect.right() - borderThickness + 1, twf->rect.top() + twf->leftCornerWidgetSize.height(),
+ borderThickness, twf->tabBarSize.height());
+ break ;
+ case QTabBar::RoundedSouth:
+ if (reverse)
+ tabBarRect = QRect(twf->rect.right() - twf->leftCornerWidgetSize.width() - twf->tabBarSize.width() + 1,
+ twf->rect.bottom() - borderThickness + 1, twf->tabBarSize.width(), borderThickness);
+ else
+ tabBarRect = QRect(twf->rect.left() + twf->leftCornerWidgetSize.width(),
+ twf->rect.bottom() - borderThickness + 1, twf->tabBarSize.width(), borderThickness);
+ break ;
+ default:
+ break;
+ }
+
+ QRegion region(twf->rect);
+ region -= tabBarRect;
+ painter->setClipRegion(region);
+
+ // Outer border
+ QLine leftLine = QLine(twf->rect.topLeft() + QPoint(0, 2), twf->rect.bottomLeft() - QPoint(0, 2));
+ QLine rightLine = QLine(twf->rect.topRight() + QPoint(0, 2), twf->rect.bottomRight() - QPoint(0, 2));
+ QLine bottomLine = QLine(twf->rect.bottomLeft() + QPoint(2, 0), twf->rect.bottomRight() - QPoint(2, 0));
+ QLine topLine = QLine(twf->rect.topLeft() + QPoint(2, 0), twf->rect.topRight() - QPoint(2, 0));
+
+ QBrush border = option->palette.shadow();
+ qBrushSetAlphaF(&border, qreal(0.4));
+ painter->setPen(QPen(border, 0));
+
+ QVarLengthArray<QLine, 4> lines;
+ QVarLengthArray<QPoint, 8> points;
+
+ lines.append(topLine);
+
+ // Inner border
+ QLine innerLeftLine = QLine(leftLine.p1() + QPoint(1, 0), leftLine.p2() + QPoint(1, 0));
+ QLine innerRightLine = QLine(rightLine.p1() - QPoint(1, 0), rightLine.p2() - QPoint(1, 0));
+ QLine innerBottomLine = QLine(bottomLine.p1() - QPoint(0, 1), bottomLine.p2() - QPoint(0, 1));
+ QLine innerTopLine = QLine(topLine.p1() + QPoint(0, 1), topLine.p2() + QPoint(0, 1));
+
+ // Rounded Corner
+ QPoint leftBottomOuterCorner = QPoint(innerLeftLine.p2() + QPoint(0, 1));
+ QPoint leftBottomInnerCorner1 = QPoint(leftLine.p2() + QPoint(0, 1));
+ QPoint leftBottomInnerCorner2 = QPoint(bottomLine.p1() - QPoint(1, 0));
+ QPoint rightBottomOuterCorner = QPoint(innerRightLine.p2() + QPoint(0, 1));
+ QPoint rightBottomInnerCorner1 = QPoint(rightLine.p2() + QPoint(0, 1));
+ QPoint rightBottomInnerCorner2 = QPoint(bottomLine.p2() + QPoint(1, 0));
+ QPoint rightTopOuterCorner = QPoint(innerRightLine.p1() - QPoint(0, 1));
+ QPoint rightTopInnerCorner1 = QPoint(rightLine.p1() - QPoint(0, 1));
+ QPoint rightTopInnerCorner2 = QPoint(topLine.p2() + QPoint(1, 0));
+ QPoint leftTopOuterCorner = QPoint(innerLeftLine.p1() - QPoint(0, 1));
+ QPoint leftTopInnerCorner1 = QPoint(leftLine.p1() - QPoint(0, 1));
+ QPoint leftTopInnerCorner2 = QPoint(topLine.p1() - QPoint(1, 0));
+
+ lines.append(leftLine);
+ lines.append(rightLine);
+ lines.append(bottomLine);
+
+ painter->drawLines(lines.constData(), lines.size());
+ lines.clear();
+
+ points.append(leftBottomOuterCorner);
+ points.append(rightBottomOuterCorner);
+ points.append(rightTopOuterCorner);
+ points.append(leftTopOuterCorner);
+
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+
+ QBrush innerTopLeft = option->palette.shadow();
+ qBrushSetAlphaF(&innerTopLeft, qreal(0.075));
+ painter->setPen(QPen(innerTopLeft, 0));
+
+ lines.append(innerLeftLine);
+ lines.append(innerTopLine);
+ painter->drawLines(lines.constData(), lines.size());
+ lines.clear();
+
+ QBrush innerBottomRight = option->palette.shadow();
+ qBrushSetAlphaF(&innerBottomRight, qreal(0.23));
+ painter->setPen(QPen(innerBottomRight, 0));
+ lines.append(innerRightLine);
+ lines.append(innerBottomLine);
+ painter->drawLines(lines.constData(), lines.size());
+ lines.clear();
+
+ QBrush corner = option->palette.shadow();
+ qBrushSetAlphaF(&corner, 0.25);
+ painter->setPen(QPen(corner, 0));
+ points.append(leftBottomInnerCorner1);
+ points.append(leftBottomInnerCorner2);
+ points.append(rightBottomInnerCorner1);
+ points.append(rightBottomInnerCorner2);
+ points.append(rightTopInnerCorner1);
+ points.append(rightTopInnerCorner2);
+ points.append(leftTopInnerCorner1);
+ points.append(leftTopInnerCorner2);
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+
+ painter->restore();
+ }
+ break ;
+#endif // QT_NO_TABWIDGET
+#ifndef QT_NO_TABBAR
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+ if (tbb->shape != QTabBar::RoundedNorth && tbb->shape != QTabBar::RoundedWest &&
+ tbb->shape != QTabBar::RoundedSouth && tbb->shape != QTabBar::RoundedEast) {
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+
+ painter->save();
+
+ QRegion region(tbb->rect);
+ region -= tbb->tabBarRect;
+ painter->setClipRegion(region);
+
+ QLine topLine = QLine(tbb->rect.bottomLeft() - QPoint(0, 1), tbb->rect.bottomRight() - QPoint(0, 1));
+ QLine bottomLine = QLine(tbb->rect.bottomLeft(), tbb->rect.bottomRight());
+
+ QBrush border = option->palette.shadow();
+ qBrushSetAlphaF(&border, qreal(0.4));
+ QBrush innerTopLeft = option->palette.shadow();
+ qBrushSetAlphaF(&innerTopLeft, qreal(0.075));
+ QBrush innerBottomRight = option->palette.shadow();
+ qBrushSetAlphaF(&innerBottomRight, qreal(0.23));
+ QBrush corner = option->palette.shadow();
+ qBrushSetAlphaF(&corner, 0.25);
+
+ if (tbb->shape == QTabBar::RoundedSouth)
+ painter->setPen(QPen(corner, 0));
+ else
+ painter->setPen(QPen(border, 0));
+ painter->drawLine(topLine);
+
+ if (tbb->shape != QTabBar::RoundedSouth)
+ painter->setPen(QPen(innerTopLeft, 0));
+ else
+ painter->setPen(QPen(border, 0));
+ painter->drawLine(bottomLine);
+
+ painter->restore();
+ }
+ break ;
+#endif // QT_NO_TABBAR
+#ifndef QT_NO_GROUPBOX
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ QStyleOptionFrameV2 frameV2(*frame);
+ if (frameV2.features & QStyleOptionFrameV2::Flat) {
+ QPen oldPen = painter->pen();
+ painter->setPen(borderColor);
+ painter->drawLine(frameV2.rect.topLeft(), frameV2.rect.topRight());
+ painter->setPen(oldPen);
+ } else {
+ frameV2.state &= ~(State_Sunken | State_HasFocus);
+ proxy()->drawPrimitive(PE_Frame, &frameV2, painter, widget);
+ }
+ }
+ break;
+#endif // QT_NO_GROUPBOX
+ case PE_Frame: {
+ QFrame::Shadow shadow = QFrame::Plain;
+ if (option->state & State_Sunken)
+ shadow = QFrame::Sunken;
+ else if (option->state & State_Raised)
+ shadow = QFrame::Raised;
+ qt_plastique_draw_frame(painter, option->rect, option, shadow);
+ break;
+ }
+#ifndef QT_NO_LINEEDIT
+ case PE_FrameLineEdit:
+ qt_plastique_draw_frame(painter, option->rect, option, QFrame::Sunken);
+ break;
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ // Panel of a line edit inside combo box or spin box is drawn in CC_ComboBox and CC_SpinBox
+ if (widget) {
+#ifndef QT_NO_SPINBOX
+ // Spinbox doesn't need a separate palette for the lineedit
+ if (qobject_cast<const QAbstractSpinBox *>(widget->parentWidget()))
+ break;
+#endif
+ }
+
+ painter->save();
+
+ // Fill the line edit insides
+ QRect filledRect = lineEdit->rect.adjusted(1, 1, -1, -1);
+ QBrush baseBrush = qMapBrushToRect(lineEdit->palette.base(), filledRect);
+ painter->setBrushOrigin(filledRect.topLeft());
+ painter->fillRect(filledRect.adjusted(1, 1, -1, -1), baseBrush);
+
+ painter->setPen(QPen(baseBrush, 0));
+ const QLine lines[4] = {
+ QLine(filledRect.left(), filledRect.top() + 1,
+ filledRect.left(), filledRect.bottom() - 1),
+ QLine(filledRect.right(), filledRect.top() + 1,
+ filledRect.right(), filledRect.bottom() - 1),
+ QLine(filledRect.left() + 1, filledRect.top(),
+ filledRect.right() - 1, filledRect.top()),
+ QLine(filledRect.left() + 1, filledRect.bottom(),
+ filledRect.right() - 1, filledRect.bottom()) };
+ painter->drawLines(lines, 4);
+
+ if (lineEdit->lineWidth != 0)
+ qt_plastique_draw_frame(painter, option->rect, option, QFrame::Sunken);
+
+ painter->restore();
+ break;
+ }
+#endif // QT_NO_LINEEDIT
+ case PE_FrameDockWidget:
+ case PE_FrameMenu:
+ case PE_FrameStatusBarItem: {
+ // Draws the frame around a popup menu.
+ QPen oldPen = painter->pen();
+ painter->setPen(borderColor);
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ painter->setPen(alphaCornerColor);
+ const QPoint points[4] = {
+ QPoint(option->rect.topLeft()),
+ QPoint(option->rect.topRight()),
+ QPoint(option->rect.bottomLeft()),
+ QPoint(option->rect.bottomRight()) };
+ painter->drawPoints(points, 4);
+ painter->setPen(oldPen);
+ break;
+ }
+#ifdef QT3_SUPPORT
+ case PE_Q3DockWindowSeparator: {
+ QPen oldPen = painter->pen();
+ painter->setPen(alphaCornerColor);
+ QRect rect = option->rect;
+ if (option->state & State_Horizontal) {
+ painter->drawLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 1);
+ } else {
+ painter->drawLine(rect.left() + 2, rect.bottom(), rect.right() - 1, rect.bottom());
+ }
+ painter->setPen(oldPen);
+ break;
+ }
+ case PE_Q3Separator: {
+ QPen oldPen = painter->pen();
+ painter->setPen(alphaCornerColor);
+ if ((option->state & State_Horizontal) == 0)
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ else
+ painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
+ painter->setPen(option->palette.background().color().lighter(104));
+ if ((option->state & State_Horizontal) == 0)
+ painter->drawLine(option->rect.topLeft(), option->rect.topRight());
+ else
+ painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
+ painter->setPen(oldPen);
+ break;
+ }
+#endif // QT3_SUPPORT
+#ifndef QT_NO_MAINWINDOW
+ case PE_PanelMenuBar:
+ if ((widget && qobject_cast<const QMainWindow *>(widget->parentWidget()))
+#ifdef QT3_SUPPORT
+ || (widget && widget->parentWidget() && widget->parentWidget()->inherits("Q3MainWindow"))
+#endif
+ ) {
+ // Draws the light line above and the dark line below menu bars and
+ // tool bars.
+ QPen oldPen = painter->pen();
+ if (element == PE_PanelMenuBar || (option->state & State_Horizontal)) {
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.left(), option->rect.bottom(),
+ option->rect.right(), option->rect.bottom());
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.left(), option->rect.top(),
+ option->rect.right(), option->rect.top());
+ } else {
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.left(), option->rect.top(),
+ option->rect.left(), option->rect.bottom());
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.right(), option->rect.top(),
+ option->rect.right(), option->rect.bottom());
+ }
+ painter->setPen(oldPen);
+ }
+ break;
+#endif // QT_NO_MAINWINDOW
+ case PE_IndicatorHeaderArrow: {
+ bool usedAntialiasing = painter->renderHints() & QPainter::Antialiasing;
+ if (!usedAntialiasing)
+ painter->setRenderHint(QPainter::Antialiasing);
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ if (!usedAntialiasing)
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ break;
+ }
+ case PE_PanelButtonTool:
+ // Draws a tool button (f.ex., in QToolBar and QTabBar)
+ if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise))
+ qt_plastique_drawShadedPanel(painter, option, true, widget);
+ break;
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarHandle: {
+ QPixmap cache;
+ QRect rect = option->rect;
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowHandle") && widget->parentWidget()->inherits("Q3DockWindow")) {
+ if (!(option->state & State_Horizontal))
+ rect.adjust(2, 0, -2, 0);
+ }
+#endif
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("toolbarhandle"), option, rect.size());
+ if (!QPixmapCache::find(pixmapName, cache)) {
+ cache = QPixmap(rect.size());
+ cache.fill(Qt::transparent);
+ QPainter cachePainter(&cache);
+ QRect cacheRect(QPoint(0, 0), rect.size());
+ if (widget)
+ cachePainter.fillRect(cacheRect, option->palette.brush(widget->backgroundRole()));
+ else
+ cachePainter.fillRect(cacheRect, option->palette.background());
+
+ QImage handle(qt_toolbarhandle);
+ alphaCornerColor.setAlpha(170);
+ handle.setColor(1, alphaCornerColor.rgba());
+ handle.setColor(2, mergedColors(alphaCornerColor, option->palette.light().color()).rgba());
+ handle.setColor(3, option->palette.light().color().rgba());
+
+ if (option->state & State_Horizontal) {
+ int nchunks = cacheRect.height() / handle.height();
+ int indent = (cacheRect.height() - (nchunks * handle.height())) / 2;
+ for (int i = 0; i < nchunks; ++i)
+ cachePainter.drawImage(QPoint(cacheRect.left() + 3, cacheRect.top() + indent + i * handle.height()),
+ handle);
+ } else {
+ int nchunks = cacheRect.width() / handle.width();
+ int indent = (cacheRect.width() - (nchunks * handle.width())) / 2;
+ for (int i = 0; i < nchunks; ++i)
+ cachePainter.drawImage(QPoint(cacheRect.left() + indent + i * handle.width(), cacheRect.top() + 3),
+ handle);
+ }
+ cachePainter.end();
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ painter->drawPixmap(rect.topLeft(), cache);
+ break;
+ }
+ case PE_IndicatorToolBarSeparator: {
+ QPen oldPen = painter->pen();
+ painter->setPen(alphaCornerColor);
+ if (option->state & State_Horizontal) {
+ painter->drawLine(option->rect.left(), option->rect.top() + 1, option->rect.left(), option->rect.bottom() - 2);
+ painter->setPen(option->palette.base().color());
+ painter->drawLine(option->rect.right(), option->rect.top() + 1, option->rect.right(), option->rect.bottom() - 2);
+ } else {
+ painter->drawLine(option->rect.left() + 1, option->rect.top(), option->rect.right() - 2, option->rect.top());
+ painter->setPen(option->palette.base().color());
+ painter->drawLine(option->rect.left() + 1, option->rect.bottom(), option->rect.right() - 2, option->rect.bottom());
+ }
+ painter->setPen(oldPen);
+ break;
+ }
+#endif // QT_NO_TOOLBAR
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool sunken = (button->state & State_Sunken) || (button->state & State_On);
+ if ((button->features & QStyleOptionButton::Flat) && !sunken)
+ break;
+
+ bool defaultButton = (button->features & (QStyleOptionButton::DefaultButton
+ | QStyleOptionButton::AutoDefaultButton));
+
+ BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("pushbutton-%1").arg(defaultButton))
+
+ QPen oldPen = p->pen();
+ bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
+
+ // Give the painter a different brush origin for sunken buttons
+ if (sunken) {
+ // ### No such function
+ // p->setPenOrigin(rect.left() + 1, rect.top() + 1);
+ p->setBrushOrigin(rect.left() + 1, rect.top() + 1);
+ }
+
+ // Draw border
+ qt_plastique_draw_frame(p, rect, option);
+
+ // Fill the panel
+ QRectF fillRect = rect.adjusted(2, 2, -2, -2);
+
+ // Button colors
+ QBrush alphaCornerBrush = qMapBrushToRect(qBrushDark(option->palette.button(), 165), rect);
+ qBrushSetAlphaF(&alphaCornerBrush, 0.5);
+ QBrush buttonGradientBrush;
+ QBrush leftLineGradientBrush;
+ QBrush rightLineGradientBrush;
+ QBrush sunkenButtonGradientBrush;
+ QBrush sunkenLeftLineGradientBrush;
+ QBrush sunkenRightLineGradientBrush;
+ QBrush buttonBrush = qMapBrushToRect(option->palette.button(), rect);
+ if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
+ buttonGradientBrush = buttonBrush;
+ sunkenButtonGradientBrush = qBrushDark(buttonBrush, 108);
+ leftLineGradientBrush = qBrushLight(buttonBrush, 105);
+ rightLineGradientBrush = qBrushDark(buttonBrush, 105);
+ sunkenLeftLineGradientBrush = qBrushDark(buttonBrush, 110);
+ sunkenRightLineGradientBrush = qBrushDark(buttonBrush, 106);
+ } else {
+ // Generate gradients
+ QLinearGradient buttonGradient(rect.topLeft(), rect.bottomLeft());
+ if (hover) {
+ buttonGradient.setColorAt(0.0, mergedColors(option->palette.highlight().color(),
+ buttonBrush.color().lighter(104), 6));
+ buttonGradient.setColorAt(1.0, mergedColors(option->palette.highlight().color(),
+ buttonBrush.color().darker(110), 6));
+ } else {
+ buttonGradient.setColorAt(0.0, buttonBrush.color().lighter(104));
+ buttonGradient.setColorAt(1.0, buttonBrush.color().darker(110));
+ }
+ buttonGradientBrush = QBrush(buttonGradient);
+
+ QLinearGradient buttonGradient2(rect.topLeft(), rect.bottomLeft());
+ buttonGradient2.setColorAt(0.0, buttonBrush.color().darker(113));
+ buttonGradient2.setColorAt(1.0, buttonBrush.color().darker(103));
+ sunkenButtonGradientBrush = QBrush(buttonGradient2);
+
+ QLinearGradient buttonGradient3(rect.topLeft(), rect.bottomLeft());
+ buttonGradient3.setColorAt(0.0, buttonBrush.color().lighter(105));
+ buttonGradient3.setColorAt(1.0, buttonBrush.color());
+ leftLineGradientBrush = QBrush(buttonGradient3);
+
+ QLinearGradient buttonGradient4(rect.topLeft(), rect.bottomLeft());
+ buttonGradient4.setColorAt(0.0, buttonBrush.color());
+ buttonGradient4.setColorAt(1.0, buttonBrush.color().darker(110));
+ rightLineGradientBrush = QBrush(buttonGradient4);
+
+ QLinearGradient buttonGradient5(rect.topLeft(), rect.bottomLeft());
+ buttonGradient5.setColorAt(0.0, buttonBrush.color().darker(113));
+ buttonGradient5.setColorAt(1.0, buttonBrush.color().darker(107));
+ sunkenLeftLineGradientBrush = QBrush(buttonGradient5);
+
+ QLinearGradient buttonGradient6(rect.topLeft(), rect.bottomLeft());
+ buttonGradient6.setColorAt(0.0, buttonBrush.color().darker(108));
+ buttonGradient6.setColorAt(1.0, buttonBrush.color().darker(103));
+ sunkenRightLineGradientBrush = QBrush(buttonGradient6);
+ }
+
+ // Main fill
+ p->fillRect(fillRect,
+ qMapBrushToRect(sunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, rect));
+
+ // Top line
+ p->setPen(QPen(qBrushLight(qMapBrushToRect(sunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, rect), 105), 0));
+ p->drawLine(QPointF(rect.left() + 2, rect.top() + 1),
+ QPointF(rect.right() - 2, rect.top() + 1));
+
+ // Bottom line
+ p->setPen(QPen(qBrushDark(qMapBrushToRect(sunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, rect), 105), 0));
+ p->drawLine(QPointF(rect.left() + 2, rect.bottom() - 1),
+ QPointF(rect.right() - 2, rect.bottom() - 1));
+
+ // Left line
+ p->setPen(QPen(qMapBrushToRect(sunken ? sunkenLeftLineGradientBrush
+ : leftLineGradientBrush, rect), 1));
+ p->drawLine(QPointF(rect.left() + 1, rect.top() + 2),
+ QPointF(rect.left() + 1, rect.bottom() - 2));
+
+ // Right line
+ p->setPen(QPen(qMapBrushToRect(sunken ? sunkenRightLineGradientBrush
+ : rightLineGradientBrush, rect), 1));
+ p->drawLine(QPointF(rect.right() - 1, rect.top() + 2),
+ QPointF(rect.right() - 1, rect.bottom() - 2));
+
+ // Hovering
+ if (hover && !sunken) {
+ QBrush hover = qMapBrushToRect(option->palette.highlight(), rect);
+ QBrush hoverOuter = hover;
+ qBrushSetAlphaF(&hoverOuter, qreal(0.7));
+
+ QLine lines[2];
+
+ p->setPen(QPen(hoverOuter, 0));
+ lines[0] = QLine(rect.left() + 1, rect.top() + 1, rect.right() - 1, rect.top() + 1);
+ lines[1] = QLine(rect.left() + 1, rect.bottom() - 1, rect.right() - 1, rect.bottom() - 1);
+ p->drawLines(lines, 2);
+
+ QBrush hoverInner = hover;
+ qBrushSetAlphaF(&hoverInner, qreal(0.45));
+ p->setPen(QPen(hoverInner, 0));
+ lines[0] = QLine(rect.left() + 1, rect.top() + 2, rect.right() - 1, rect.top() + 2);
+ lines[1] = QLine(rect.left() + 1, rect.bottom() - 2, rect.right() - 1, rect.bottom() - 2);
+ p->drawLines(lines, 2);
+
+ QBrush hoverSide = hover;
+ qBrushSetAlphaF(&hoverSide, qreal(0.075));
+ p->setPen(QPen(hoverSide, 0));
+ lines[0] = QLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
+ lines[1] = QLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
+ p->drawLines(lines, 2);
+ }
+
+ p->setPen(oldPen);
+
+ END_STYLE_PIXMAPCACHE
+ }
+ break;
+ case PE_IndicatorCheckBox:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ BEGIN_STYLE_PIXMAPCACHE(QLatin1String("checkbox"))
+
+ p->save();
+
+ // Outline
+ QBrush border = option->palette.shadow();
+ qBrushSetAlphaF(&border, qreal(0.4));
+ p->setPen(QPen(border, 0));
+ const QLine lines[4] = {
+ QLine(rect.left() + 1, rect.top(), rect.right() - 1, rect.top()),
+ QLine(rect.left() + 1, rect.bottom(), rect.right() - 1, rect.bottom()),
+ QLine(rect.left(), rect.top() + 1, rect.left(), rect.bottom() - 1),
+ QLine(rect.right(), rect.top() + 1, rect.right(), rect.bottom() - 1) };
+ p->drawLines(lines, 4);
+
+ QBrush corner = option->palette.shadow();
+ qBrushSetAlphaF(&corner, qreal(0.2));
+ p->setPen(QPen(corner, 0));
+ const QPoint points[4] = {
+ rect.topLeft(), rect.topRight(),
+ rect.bottomLeft(), rect.bottomRight() };
+ p->drawPoints(points, 4);
+
+ // Fill
+ QBrush baseBrush = qMapBrushToRect(button->palette.base(), rect);
+ if (!baseBrush.gradient() && baseBrush.texture().isNull()) {
+ QLinearGradient gradient(rect.center().x(), rect.top(), rect.center().x(), rect.bottom());
+ gradient.setColorAt(0, baseBrush.color());
+ gradient.setColorAt(1, baseBrush.color().darker(105));
+ baseBrush = gradient;
+ }
+ p->fillRect(rect.adjusted(1, 1, -1, -1), baseBrush);
+
+ // Hover
+ if ((button->state & State_Enabled) && (button->state & State_MouseOver)) {
+ QBrush pen = qMapBrushToRect(button->palette.highlight(), rect);
+ qBrushSetAlphaF(&pen, qreal(0.8));
+ p->setPen(QPen(pen, 0));
+ p->drawRect(rect.adjusted(1, 1, -2, -2));
+ qBrushSetAlphaF(&pen, 0.5);
+ p->setPen(QPen(pen, 0));
+ p->drawRect(rect.adjusted(2, 2, -3, -3));
+
+ qBrushSetAlphaF(&pen, qreal(0.2));
+ p->setBrush(pen);
+ p->drawRect(rect.adjusted(2, 2, -3, -3));
+ }
+
+ // Indicator
+ bool on = button->state & State_On;
+ bool sunken = button->state & State_Sunken;
+ bool unchanged = button->state & State_NoChange;
+ bool enabled = button->state & State_Enabled;
+ if (on || (enabled && sunken) || unchanged) {
+ p->setRenderHint(QPainter::Antialiasing);
+ QBrush pointBrush = qMapBrushToRect(button->palette.text(), rect);
+ if (sunken)
+ qBrushSetAlphaF(&pointBrush, qreal(0.5));
+ else if (unchanged)
+ qBrushSetAlphaF(&pointBrush, qreal(0.3));
+ p->setPen(QPen(pointBrush, 3));
+ const QLine lines[2] = {
+ QLine(rect.left() + 4, rect.top() + 4, rect.right() - 3, rect.bottom() - 3),
+ QLine(rect.right() - 3, rect.top() + 4, rect.left() + 4, rect.bottom() - 3) };
+ p->drawLines(lines, 2);
+ }
+
+ p->restore();
+ END_STYLE_PIXMAPCACHE
+ }
+ break;
+ case PE_IndicatorRadioButton:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ BEGIN_STYLE_PIXMAPCACHE(QLatin1String("radiobutton"))
+
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+
+ // The the filled ellipse
+ QBrush border = qMapBrushToRect(option->palette.shadow(), rect);
+ qBrushSetAlphaF(&border, qreal(0.51));
+ p->setPen(QPen(border, 0));
+
+ QBrush baseBrush = qMapBrushToRect(button->palette.base(), rect);
+ if (!baseBrush.gradient() && baseBrush.texture().isNull()) {
+ QLinearGradient gradient(rect.center().x(), rect.top(), rect.center().x(), rect.bottom());
+ gradient.setColorAt(0, baseBrush.color());
+ gradient.setColorAt(1, baseBrush.color().darker(105));
+ baseBrush = gradient;
+ }
+ p->setBrush(baseBrush);
+ p->drawEllipse(QRectF(rect).adjusted(1, 1, -1, -1));
+
+ // Hover
+ if ((button->state & State_Enabled) && (button->state & State_MouseOver)) {
+ QBrush pen = qMapBrushToRect(button->palette.highlight(), rect);
+ qBrushSetAlphaF(&pen, qreal(0.8));
+ p->setPen(QPen(pen, 0));
+ qBrushSetAlphaF(&pen, qreal(0.2));
+ p->setBrush(pen);
+ p->drawEllipse(QRectF(rect).adjusted(2, 2, -2, -2));
+ }
+
+ // Indicator
+ bool on = button->state & State_On;
+ bool sunken = button->state & State_Sunken;
+ bool enabled = button->state & State_Enabled;
+ if (on || (enabled && sunken)) {
+ p->setPen(Qt::NoPen);
+ QBrush pointBrush = qMapBrushToRect(button->palette.text(), rect);
+ if (sunken)
+ qBrushSetAlphaF(&pointBrush, 0.5);
+ p->setBrush(pointBrush);
+ p->drawEllipse(QRectF(rect).adjusted(3, 3, -3, -3));
+ }
+
+ p->restore();
+ END_STYLE_PIXMAPCACHE
+ }
+ break;
+#ifndef QT_NO_DOCKWIDGET
+ case PE_IndicatorDockWidgetResizeHandle:
+ if ((option->state & State_Enabled) && (option->state & State_MouseOver))
+ painter->fillRect(option->rect, QColor(255, 255, 255, 128));
+ if (option->state & State_Horizontal) {
+ int width = option->rect.width() / 3;
+ QRect rect(option->rect.center().x() - width / 2,
+ option->rect.top() + (option->rect.height() / 2) - 1, width, 3);
+ qt_plastique_draw_handle(painter, option, rect, Qt::Vertical, widget);
+ } else {
+ int height = option->rect.height() / 3;
+ QRect rect(option->rect.left() + (option->rect.width() / 2 - 1),
+ option->rect.center().y() - height / 2, 3, height);
+ qt_plastique_draw_handle(painter, option, rect, Qt::Horizontal, widget);
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+ case PE_IndicatorViewItemCheck: {
+ QStyleOptionButton button;
+ button.QStyleOption::operator=(*option);
+ button.state &= ~State_MouseOver;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
+ break;
+ }
+ case PE_FrameWindow: {
+ painter->save();
+ bool active = (option->state & State_Active);
+ int titleBarStop = option->rect.top() + proxy()->pixelMetric(PM_TitleBarHeight, option, widget);
+
+ QPalette palette = option->palette;
+ if (!active)
+ palette.setCurrentColorGroup(QPalette::Disabled);
+
+ // Frame and rounded corners
+ painter->setPen(mergedColors(palette.highlight().color(), Qt::black, 50));
+
+ QLine lines[3];
+ QPoint points[4];
+
+ // bottom border line
+ lines[0] = QLine(option->rect.left() + 1, option->rect.bottom(), option->rect.right() - 1, option->rect.bottom());
+
+ // bottom left and right side border lines
+ lines[1] = QLine(option->rect.left(), titleBarStop, option->rect.left(), option->rect.bottom() - 1);
+ lines[2] = QLine(option->rect.right(), titleBarStop, option->rect.right(), option->rect.bottom() - 1);
+ painter->drawLines(lines, 3);
+ points[0] = QPoint(option->rect.left() + 1, option->rect.bottom() - 1);
+ points[1] = QPoint(option->rect.right() - 1, option->rect.bottom() - 1);
+ painter->drawPoints(points, 2);
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindow")) {
+ // also draw the frame on the title bar
+ lines[0] = QLine(option->rect.left() + 1, option->rect.top(),
+ option->rect.right() - 1, option->rect.top());
+ lines[1] = QLine(option->rect.left(), option->rect.top() + 1,
+ option->rect.left(), titleBarStop);
+ lines[2] = QLine(option->rect.right(), option->rect.top() + 1,
+ option->rect.right(), titleBarStop);
+ painter->drawLines(lines, 3);
+ }
+#endif
+
+ // alpha corners
+ painter->setPen(mergedColors(palette.highlight().color(), palette.background().color(), 55));
+ points[0] = QPoint(option->rect.left() + 2, option->rect.bottom() - 1);
+ points[1] = QPoint(option->rect.left() + 1, option->rect.bottom() - 2);
+ points[2] = QPoint(option->rect.right() - 2, option->rect.bottom() - 1);
+ points[3] = QPoint(option->rect.right() - 1, option->rect.bottom() - 2);
+ painter->drawPoints(points, 4);
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindow")) {
+ // also draw the frame on the title bar
+ points[0] = option->rect.topLeft();
+ points[1] = option->rect.topRight();
+ painter->drawPoints(points, 2);
+ }
+#endif
+
+ // upper and lower left inner
+ painter->setPen(active ? mergedColors(palette.highlight().color(), palette.background().color()) : palette.background().color().darker(120));
+ painter->drawLine(option->rect.left() + 1, titleBarStop, option->rect.left() + 1, option->rect.bottom() - 2);
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindow")) {
+ // also draw the frame on the title bar
+ lines[0] = QLine(option->rect.left() + 1, option->rect.top() + 1,
+ option->rect.left() + 1, titleBarStop);
+ lines[1] = QLine(option->rect.right() - 1, option->rect.top() + 1,
+ option->rect.right() - 1, titleBarStop);
+ lines[2] = QLine(option->rect.left() + 1, option->rect.top() + 1,
+ option->rect.right() - 1, option->rect.top() + 1);
+ painter->drawLines(lines, 3);
+ }
+#endif
+
+ painter->setPen(active ? mergedColors(palette.highlight().color(), palette.background().color(), 57) : palette.background().color().darker(130));
+ lines[0] = QLine(option->rect.right() - 1, titleBarStop, option->rect.right() - 1, option->rect.bottom() - 2);
+ lines[1] = QLine(option->rect.left() + 1, option->rect.bottom() - 1, option->rect.right() - 1, option->rect.bottom() - 1);
+ painter->drawLines(lines, 2);
+
+ painter->restore();
+ }
+ break;
+ case PE_IndicatorBranch: {
+ int mid_h = option->rect.x() + option->rect.width() / 2;
+ int mid_v = option->rect.y() + option->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+ if (option->state & State_Item) {
+ if (option->direction == Qt::RightToLeft)
+ painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+ else
+ painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (option->state & State_Sibling)
+ painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+ if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
+ painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+
+ if (option->state & State_Children) {
+ painter->save();
+ QPoint center = option->rect.center();
+ // border
+ QRect fullRect(center.x() - 4, center.y() - 4, 9, 9);
+ painter->setPen(borderColor);
+
+ const QLine lines[4] = {
+ QLine(fullRect.left() + 1, fullRect.top(),
+ fullRect.right() - 1, fullRect.top()),
+ QLine(fullRect.left() + 1, fullRect.bottom(),
+ fullRect.right() - 1, fullRect.bottom()),
+ QLine(fullRect.left(), fullRect.top() + 1,
+ fullRect.left(), fullRect.bottom() - 1),
+ QLine(fullRect.right(), fullRect.top() + 1,
+ fullRect.right(), fullRect.bottom() - 1) };
+ painter->drawLines(lines, 4);
+
+ // "antialiased" corners
+ painter->setPen(alphaCornerColor);
+ const QPoint points[4] = {
+ fullRect.topLeft(),
+ fullRect.topRight(),
+ fullRect.bottomLeft(),
+ fullRect.bottomRight() };
+ painter->drawPoints(points, 4);
+
+ // fill
+ QRect adjustedRect = fullRect;
+ QRect gradientRect(adjustedRect.left() + 1, adjustedRect.top() + 1,
+ adjustedRect.right() - adjustedRect.left() - 1,
+ adjustedRect.bottom() - adjustedRect.top() - 1);
+ if (option->palette.base().style() == Qt::SolidPattern) {
+ QColor baseGradientStartColor = option->palette.base().color().darker(101);
+ QColor baseGradientStopColor = option->palette.base().color().darker(106);
+ qt_plastique_draw_gradient(painter, gradientRect, baseGradientStartColor, baseGradientStopColor);
+ } else {
+ painter->fillRect(gradientRect, option->palette.base());
+ }
+ // draw "+" or "-"
+ painter->setPen(alphaTextColor);
+ painter->drawLine(center.x() - 2, center.y(), center.x() + 2, center.y());
+ if (!(option->state & State_Open))
+ painter->drawLine(center.x(), center.y() - 2, center.x(), center.y() + 2);
+ painter->restore();
+ }
+ }
+ break;
+ default:
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QColor borderColor = option->palette.background().color().darker(178);
+ QColor alphaCornerColor;
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
+ }
+
+ QColor gradientStartColor = option->palette.button().color().lighter(104);
+ QColor gradientStopColor = option->palette.button().color().darker(105);
+
+ QColor highlightedGradientStartColor = option->palette.button().color().lighter(101);
+ QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85);
+
+ QColor lightShadowGradientStartColor = highlightedGradientStartColor.lighter(105);
+ QColor lightShadowGradientStopColor = highlightedGradientStopColor.lighter(105);
+
+ QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35);
+ QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58);
+
+ QColor alphaInnerColor = mergedColors(highlightedDarkInnerBorderColor, option->palette.base().color());
+
+ switch (element) {
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+
+ if (tab->shape != QTabBar::RoundedNorth && tab->shape != QTabBar::RoundedWest &&
+ tab->shape != QTabBar::RoundedSouth && tab->shape != QTabBar::RoundedEast) {
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+
+ painter->save();
+
+ // Set up some convenience variables
+ bool disabled = !(tab->state & State_Enabled);
+ bool onlyTab = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool selected = tab->state & State_Selected;
+ bool mouseOver = (tab->state & State_MouseOver) && !selected && !disabled;
+ bool previousSelected = tab->selectedPosition == QStyleOptionTab::PreviousIsSelected;
+ bool nextSelected = tab->selectedPosition == QStyleOptionTab::NextIsSelected;
+ bool leftCornerWidget = (tab->cornerWidgets & QStyleOptionTab::LeftCornerWidget);
+ bool reverse = (tab->direction == Qt::RightToLeft);
+
+ int lowerTop = selected ? 0 : 3; // to make the selected tab bigger than the rest
+ bool atEnd = (tab->position == QStyleOptionTab::End) || onlyTab;
+ bool atBeginning = ((tab->position == QStyleOptionTab::Beginning) || onlyTab)
+ && !leftCornerWidget;
+ bool reverseShadow = false;
+
+ int borderThickness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
+ int marginLeft = 0;
+ if ((atBeginning && !selected) || (selected && leftCornerWidget && ((tab->position == QStyleOptionTab::Beginning) || onlyTab))) {
+ marginLeft = 1;
+ }
+
+ // I've set the names based on the natural coordinate system. Vectors are used to rotate everything
+ // if the orientation of the tab bare is different than north.
+ {
+ // Coordinates of corners of rectangle for transformation
+ QPoint topLeft;
+ QPoint topRight;
+ QPoint bottomLeft;
+ QPoint bottomRight;
+
+ // Fill with normalized vectors in the direction of the coordinate system
+ // (down and right should be complement of up and left, or it will look odd)
+ QPoint vectorUp;
+ QPoint vectorDown;
+ QPoint vectorLeft;
+ QPoint vectorRight;
+
+ QBrush border = option->palette.shadow();
+ qBrushSetAlphaF(&border, qreal(0.4));
+ QBrush innerTopLeft = option->palette.shadow();
+ qBrushSetAlphaF(&innerTopLeft, qreal(0.075));
+ QBrush innerBottomRight = option->palette.shadow();
+ qBrushSetAlphaF(&innerBottomRight, qreal(0.23));
+ QBrush corner = option->palette.shadow();
+ qBrushSetAlphaF(&corner, qreal(0.25));
+
+ QBrush baseColor1;
+ QBrush baseColor2;
+
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ vectorUp = QPoint(0, -1);
+ vectorDown = QPoint(0, 1);
+
+ if (reverse) {
+ vectorLeft = QPoint(1, 0);
+ vectorRight = QPoint(-1, 0);
+ reverseShadow = true;
+ } else {
+ vectorLeft = QPoint(-1, 0);
+ vectorRight = QPoint(1, 0);
+ }
+
+ if (reverse) {
+ topLeft = tab->rect.topRight();
+ topRight = tab->rect.topLeft();
+ bottomLeft = tab->rect.bottomRight();
+ bottomRight = tab->rect.bottomLeft();
+ } else {
+ topLeft = tab->rect.topLeft();
+ topRight = tab->rect.topRight();
+ bottomLeft = tab->rect.bottomLeft();
+ bottomRight = tab->rect.bottomRight();
+ }
+
+
+ baseColor1 = border;
+ baseColor2 = innerTopLeft;
+ break ;
+ case QTabBar::RoundedWest:
+ vectorUp = QPoint(-1, 0);
+ vectorDown = QPoint(1, 0);
+ vectorLeft = QPoint(0, -1);
+ vectorRight = QPoint(0, 1);
+
+ topLeft = tab->rect.topLeft();
+ topRight = tab->rect.bottomLeft();
+ bottomLeft = tab->rect.topRight();
+ bottomRight = tab->rect.bottomRight();
+
+ baseColor1 = border;
+ baseColor2 = innerTopLeft;
+ break ;
+ case QTabBar::RoundedEast:
+ vectorUp = QPoint(1, 0);
+ vectorDown = QPoint(-1, 0);
+ vectorLeft = QPoint(0, -1);
+ vectorRight = QPoint(0, 1);
+
+ topLeft = tab->rect.topRight();
+ topRight = tab->rect.bottomRight();
+ bottomLeft = tab->rect.topLeft();
+ bottomRight = tab->rect.bottomLeft();
+
+ baseColor1 = border;
+ baseColor2 = innerBottomRight;
+ break ;
+ case QTabBar::RoundedSouth:
+ vectorUp = QPoint(0, 1);
+ vectorDown = QPoint(0, -1);
+
+ if (reverse) {
+ vectorLeft = QPoint(1, 0);
+ vectorRight = QPoint(-1, 0);
+ reverseShadow = true;
+
+ topLeft = tab->rect.bottomRight();
+ topRight = tab->rect.bottomLeft();
+ bottomLeft = tab->rect.topRight();
+ bottomRight = tab->rect.topLeft();
+ } else {
+ vectorLeft = QPoint(-1, 0);
+ vectorRight = QPoint(1, 0);
+
+ topLeft = tab->rect.bottomLeft();
+ topRight = tab->rect.bottomRight();
+ bottomLeft = tab->rect.topLeft();
+ bottomRight = tab->rect.topRight();
+ }
+
+ baseColor1 = border;
+ baseColor2 = innerBottomRight;
+ break ;
+ default:
+ break;
+ }
+
+ // Make the tab smaller when it's at the end, so that we are able to draw the corner
+ if (atEnd) {
+ topRight += vectorLeft;
+ bottomRight += vectorLeft;
+ }
+
+ {
+ // Outer border
+ QLine topLine;
+ {
+ QPoint adjustTopLineLeft = (vectorRight * (marginLeft + (previousSelected ? 0 : 1))) +
+ (vectorDown * lowerTop);
+ QPoint adjustTopLineRight = (vectorDown * lowerTop);
+ if (atBeginning || selected)
+ adjustTopLineLeft += vectorRight;
+ if (atEnd || selected)
+ adjustTopLineRight += 2 * vectorLeft;
+
+ topLine = QLine(topLeft + adjustTopLineLeft, topRight + adjustTopLineRight);
+ }
+
+ QLine leftLine;
+ {
+ QPoint adjustLeftLineTop = (vectorRight * marginLeft) + (vectorDown * (lowerTop + 1));
+ QPoint adjustLeftLineBottom = (vectorRight * marginLeft) + (vectorUp * borderThickness);
+ if (atBeginning || selected)
+ adjustLeftLineTop += vectorDown; // Make place for rounded corner
+ if (atBeginning && selected)
+ adjustLeftLineBottom += borderThickness * vectorDown;
+ else if (selected)
+ adjustLeftLineBottom += vectorUp;
+
+ leftLine = QLine(topLeft + adjustLeftLineTop, bottomLeft + adjustLeftLineBottom);
+ }
+
+ QLine rightLine;
+ {
+ QPoint adjustRightLineTop = vectorDown * (2 + lowerTop);
+ QPoint adjustRightLineBottom = vectorUp * borderThickness;
+ if (selected)
+ adjustRightLineBottom += vectorUp;
+
+ rightLine = QLine(topRight + adjustRightLineTop, bottomRight + adjustRightLineBottom);
+ }
+
+ // Background
+ QPoint startPoint = topLine.p1() + vectorDown + vectorLeft;
+ if (mouseOver)
+ startPoint += vectorDown;
+ QPoint endPoint = rightLine.p2();
+
+ if (tab->state & State_Enabled) {
+ QRect fillRect = QRect(startPoint, endPoint).normalized();
+ if (fillRect.isValid()) {
+ if (selected) {
+ fillRect = QRect(startPoint, endPoint + vectorLeft + vectorDown * 3).normalized();
+ painter->fillRect(fillRect, option->palette.window());
+
+ // Connect to the base
+ painter->setPen(QPen(option->palette.window(), 0));
+ QVarLengthArray<QPoint, 6> points;
+ points.append(rightLine.p2() + vectorDown);
+ points.append(rightLine.p2() + vectorDown + vectorDown);
+ points.append(rightLine.p2() + vectorDown + vectorDown + vectorRight);
+ if (tab->position != QStyleOptionTab::Beginning) {
+ points.append(leftLine.p2() + vectorDown);
+ points.append(leftLine.p2() + vectorDown + vectorDown);
+ points.append(leftLine.p2() + vectorDown + vectorDown + vectorLeft);
+ }
+ painter->drawPoints(points.constData(), points.size());
+ } else {
+ QBrush buttonGradientBrush;
+ QBrush buttonBrush = qMapBrushToRect(option->palette.button(), fillRect);
+ if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
+ buttonGradientBrush = buttonBrush;
+ } else {
+ // Generate gradients
+ QLinearGradient buttonGradient(fillRect.topLeft(), fillRect.bottomLeft());
+ buttonGradient.setColorAt(0.0, buttonBrush.color().lighter(104));
+ buttonGradient.setColorAt(1.0, buttonBrush.color().darker(110));
+ buttonGradientBrush = QBrush(buttonGradient);
+ }
+
+ painter->fillRect(fillRect, buttonGradientBrush);
+ }
+ }
+ }
+
+ QPoint rightCornerDot = topRight + vectorLeft + (lowerTop + 1)*vectorDown;
+ QPoint leftCornerDot = topLeft + (marginLeft + 1)*vectorRight + (lowerTop + 1)*vectorDown;
+ QPoint bottomRightConnectToBase = rightLine.p2() + vectorRight + vectorDown;
+ QPoint bottomLeftConnectToBase = leftLine.p2() + vectorLeft + vectorDown;
+
+ painter->setPen(QPen(border, 0));
+
+ QVarLengthArray<QLine, 3> lines;
+ QVarLengthArray<QPoint, 7> points;
+
+ lines.append(topLine);
+
+ if (mouseOver) {
+ painter->drawLines(lines.constData(), lines.count());
+ lines.clear();
+
+ QLine secondHoverLine = QLine(topLine.p1() + vectorDown * 2 + vectorLeft, topLine.p2() + vectorDown * 2 + vectorRight);
+ painter->setPen(highlightedLightInnerBorderColor);
+ painter->drawLine(secondHoverLine);
+ }
+
+ if (mouseOver)
+ painter->setPen(QPen(border, 0));
+
+ if (!previousSelected)
+ lines.append(leftLine);
+ if (atEnd || selected) {
+ lines.append(rightLine);
+ points.append(rightCornerDot);
+ }
+ if (atBeginning || selected)
+ points.append(leftCornerDot);
+ if (selected) {
+ points.append(bottomRightConnectToBase);
+ points.append(bottomLeftConnectToBase);
+ }
+ if (lines.size() > 0) {
+ painter->drawLines(lines.constData(), lines.size());
+ lines.clear();
+ }
+ if (points.size() > 0) {
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+ }
+
+ // Antialiasing
+ painter->setPen(QPen(corner, 0));
+ if (atBeginning || selected)
+ points.append(topLine.p1() + vectorLeft);
+ if (!previousSelected)
+ points.append(leftLine.p1() + vectorUp);
+ if (atEnd || selected) {
+ points.append(topLine.p2() + vectorRight);
+ points.append(rightLine.p1() + vectorUp);
+ }
+
+ if (selected) {
+ points.append(bottomRightConnectToBase + vectorLeft);
+ if (!atBeginning) {
+ points.append(bottomLeftConnectToBase + vectorRight);
+
+ if (((tab->position == QStyleOptionTab::Beginning) || onlyTab) && leftCornerWidget) {
+ // A special case: When the first tab is selected and
+ // has a left corner widget, it needs to do more work
+ // to connect to the base
+ QPoint p1 = bottomLeftConnectToBase + vectorDown;
+
+ points.append(p1);
+ }
+ }
+ }
+ if (points.size() > 0) {
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+ }
+
+ // Inner border
+ QLine innerTopLine = QLine(topLine.p1() + vectorDown, topLine.p2() + vectorDown);
+ if (!selected) {
+ QLinearGradient topLineGradient(innerTopLine.p1(),innerTopLine.p2());
+ topLineGradient.setColorAt(0, lightShadowGradientStartColor);
+ topLineGradient.setColorAt(1, lightShadowGradientStopColor);
+ painter->setPen(QPen(mouseOver ? QBrush(highlightedDarkInnerBorderColor) : QBrush(topLineGradient), 1));
+ } else {
+ painter->setPen(QPen(innerTopLeft, 0));
+ }
+ painter->drawLine(innerTopLine);
+
+ QLine innerLeftLine = QLine(leftLine.p1() + vectorRight + vectorDown, leftLine.p2() + vectorRight);
+ QLine innerRightLine = QLine(rightLine.p1() + vectorLeft + vectorDown, rightLine.p2() + vectorLeft);
+
+ if (selected) {
+ innerRightLine = QLine(innerRightLine.p1() + vectorUp, innerRightLine.p2());
+ innerLeftLine = QLine(innerLeftLine.p1() + vectorUp, innerLeftLine.p2());
+ }
+
+ if (selected || atBeginning) {
+ QBrush leftLineGradientBrush;
+ QRect rect = QRect(innerLeftLine.p1(), innerLeftLine.p2()).normalized();
+ QBrush buttonBrush = qMapBrushToRect(option->palette.button(), rect);
+ if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
+ leftLineGradientBrush = qBrushLight(buttonBrush, 105);
+ } else {
+ QLinearGradient buttonGradient3(rect.topLeft(), rect.bottomLeft());
+ buttonGradient3.setColorAt(0.0, buttonBrush.color().lighter(105));
+ buttonGradient3.setColorAt(1.0, buttonBrush.color());
+ leftLineGradientBrush = QBrush(buttonGradient3);
+ }
+
+ if (!selected)
+ painter->setPen(QPen(leftLineGradientBrush, 0));
+
+ // Assume the sun is on the same side in Right-To-Left layouts and draw the
+ // light shadow on the left side always (the right line is on the left side in
+ // reverse layouts for north and south)
+ if (reverseShadow)
+ painter->drawLine(innerRightLine);
+ else
+ painter->drawLine(innerLeftLine);
+ }
+
+ if (atEnd || selected) {
+ if (!selected) {
+ QBrush rightLineGradientBrush;
+ QRect rect = QRect(innerRightLine.p1(), innerRightLine.p2()).normalized();
+ QBrush buttonBrush = qMapBrushToRect(option->palette.button(), rect);
+ if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
+ rightLineGradientBrush = qBrushDark(buttonBrush, 105);
+ } else {
+ QLinearGradient buttonGradient4(rect.topLeft(), rect.bottomLeft());
+ buttonGradient4.setColorAt(0.0, buttonBrush.color());
+ buttonGradient4.setColorAt(1.0, buttonBrush.color().darker(110));
+ rightLineGradientBrush = QBrush(buttonGradient4);
+ }
+
+ painter->setPen(QPen(rightLineGradientBrush, 0));
+ } else {
+ painter->setPen(QPen(innerBottomRight, 0));
+ }
+
+ if (reverseShadow)
+ painter->drawLine(innerLeftLine);
+ else
+ painter->drawLine(innerRightLine);
+ }
+
+
+ // Base
+ QLine baseLine = QLine(bottomLeft + marginLeft * 2 * vectorRight, bottomRight);
+ {
+
+ QPoint adjustedLeft;
+ QPoint adjustedRight;
+
+ if (atEnd && !selected) {
+ baseLine = QLine(baseLine.p1(), baseLine.p2() + vectorRight);
+ }
+
+ if (nextSelected) {
+ adjustedRight += vectorLeft;
+ baseLine = QLine(baseLine.p1(), baseLine.p2() + vectorLeft);
+ }
+ if (previousSelected) {
+ adjustedLeft += vectorRight;
+ baseLine = QLine(baseLine.p1() + vectorRight, baseLine.p2());
+ }
+ if (atBeginning)
+ adjustedLeft += vectorRight;
+
+ painter->setPen(QPen(baseColor2, 0));
+ if (!selected)
+ painter->drawLine(baseLine);
+
+ if (atEnd && !selected)
+ painter->drawPoint(baseLine.p2() + vectorRight);
+
+ if (atBeginning && !selected)
+ adjustedLeft = vectorRight;
+ else
+ adjustedLeft = QPoint(0, 0);
+ painter->setPen(QPen(baseColor1, 0));
+ if (!selected)
+ painter->drawLine(bottomLeft + vectorUp + adjustedLeft, baseLine.p2() + vectorUp);
+
+ QPoint endPoint = bottomRight + vectorUp;
+ if (atEnd && !selected)
+ painter->drawPoint(endPoint);
+
+ // For drawing a lower left "fake" corner on the base when the first tab is unselected
+ if (atBeginning && !selected) {
+ painter->drawPoint(baseLine.p1() + vectorLeft);
+ }
+
+ painter->setPen(QPen(corner, 0));
+ if (nextSelected)
+ painter->drawPoint(endPoint);
+ else if (selected)
+ painter->drawPoint(endPoint + vectorRight);
+
+ // For drawing a lower left "fake" corner on the base when the first tab is unselected
+ if (atBeginning && !selected) {
+ painter->drawPoint(baseLine.p1() + 2 * vectorLeft);
+ }
+ }
+ }
+ }
+
+ // Yay we're done
+
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_TABBAR
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarGroove:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ QRect rect = bar->rect;
+ QPen oldPen = painter->pen();
+
+ QLine lines[4];
+
+ // outline
+ painter->setPen(borderColor);
+ lines[0] = QLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
+ lines[1] = QLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
+ lines[2] = QLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
+ lines[3] = QLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
+ painter->drawLines(lines, 4);
+
+ QPoint points[8];
+ points[0] = QPoint(rect.left() + 1, rect.top() + 1);
+ points[1] = QPoint(rect.right() - 1, rect.top() + 1);
+ points[2] = QPoint(rect.left() + 1, rect.bottom() - 1);
+ points[3] = QPoint(rect.right() - 1, rect.bottom() - 1);
+ painter->drawPoints(points, 4);
+
+ // alpha corners
+ painter->setPen(alphaCornerColor);
+ points[0] = QPoint(rect.left(), rect.top() + 1);
+ points[1] = QPoint(rect.left() + 1, rect.top());
+ points[2] = QPoint(rect.right(), rect.top() + 1);
+ points[3] = QPoint(rect.right() - 1, rect.top());
+ points[4] = QPoint(rect.left(), rect.bottom() - 1);
+ points[5] = QPoint(rect.left() + 1, rect.bottom());
+ points[6] = QPoint(rect.right(), rect.bottom() - 1);
+ points[7] = QPoint(rect.right() - 1, rect.bottom());
+ painter->drawPoints(points, 8);
+
+ // inner outline, north-west
+ painter->setPen(gradientStartColor.darker(105));
+ lines[0] = QLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, rect.top() + 1);
+ lines[1] = QLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
+ painter->drawLines(lines, 2);
+
+ // base of the groove
+ painter->setPen(QPen());
+ painter->fillRect(rect.adjusted(2, 2, -2, -1), QBrush(bar->palette.base().color()));
+ painter->setPen(bar->palette.base().color());
+ painter->drawLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
+
+ painter->setPen(oldPen);
+ }
+ break;
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ // The busy indicator doesn't draw a label
+ if (bar->minimum == 0 && bar->maximum == 0)
+ return;
+
+ painter->save();
+
+ QRect rect = bar->rect;
+ QRect leftRect;
+
+ QFont font;
+ font.setBold(true);
+ painter->setFont(font);
+ painter->setPen(bar->palette.text().color());
+
+ bool vertical = false;
+ bool inverted = false;
+ bool bottomToTop = false;
+ // Get extra style options if version 2
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ bottomToTop = bar2->bottomToTop;
+ }
+
+ if (vertical) {
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ QTransform m;
+ if (bottomToTop) {
+ m.translate(0.0, rect.width());
+ m.rotate(-90);
+ } else {
+ m.translate(rect.height(), 0.0);
+ m.rotate(90);
+ }
+ painter->setTransform(m, true);
+ }
+
+ int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) / qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum) * rect.width();
+
+ bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted)
+ || ((bar->direction == Qt::LeftToRight) && inverted))) || (vertical && ((!inverted && !bottomToTop) || (inverted && bottomToTop)));
+ if (flip) {
+ int indicatorPos = rect.width() - progressIndicatorPos;
+ if (indicatorPos >= 0 && indicatorPos <= rect.width()) {
+ painter->setPen(bar->palette.base().color());
+ leftRect = QRect(rect.left(), rect.top(), indicatorPos, rect.height());
+ } else if (indicatorPos > rect.width()) {
+ painter->setPen(bar->palette.text().color());
+ } else {
+ painter->setPen(bar->palette.base().color());
+ }
+ } else {
+ if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) {
+ leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
+ } else if (progressIndicatorPos > rect.width()) {
+ painter->setPen(bar->palette.base().color());
+ } else {
+ painter->setPen(bar->palette.text().color());
+ }
+ }
+
+ QRegion rightRect = rect;
+ rightRect = rightRect.subtracted(leftRect);
+ painter->setClipRegion(rightRect);
+ painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
+ if (!leftRect.isNull()) {
+ painter->setPen(flip ? bar->palette.text().color() : bar->palette.base().color());
+ painter->setClipRect(leftRect);
+ painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
+ }
+
+ painter->restore();
+ }
+ break;
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ Q_D(const QPlastiqueStyle);
+ QRect rect = bar->rect;
+ bool vertical = false;
+ bool inverted = false;
+ bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
+ if (!indeterminate && bar->progress == -1)
+ break;
+
+ painter->save();
+
+ // Get extra style options if version 2
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ }
+
+ // If the orientation is vertical, we use a transform to rotate
+ // the progress bar 90 degrees clockwise. This way we can use the
+ // same rendering code for both orientations.
+ if (vertical) {
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ QTransform m = QTransform::fromTranslate(rect.height()-1, 0);
+ m.rotate(90.0);
+ painter->setTransform(m, true);
+ }
+
+ int maxWidth = rect.width() - 4;
+ int minWidth = 4;
+ qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth);
+ int width = indeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth);
+ bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
+ if (inverted)
+ reverse = !reverse;
+
+ QRect progressBar;
+ if (!indeterminate) {
+ if (!reverse) {
+ progressBar.setRect(rect.left() + 2, rect.top() + 2, width, rect.height() - 4);
+ } else {
+ progressBar.setRect(rect.right() - 1 - width, rect.top() + 2, width, rect.height() - 4);
+ }
+ } else {
+ int slideWidth = ((rect.width() - 4) * 2) / 3;
+ int step = ((d->animateStep * slideWidth) / ProgressBarFps) % slideWidth;
+ if ((((d->animateStep * slideWidth) / ProgressBarFps) % (2 * slideWidth)) >= slideWidth)
+ step = slideWidth - step;
+ progressBar.setRect(rect.left() + 2 + step, rect.top() + 2,
+ slideWidth / 2, rect.height() - 4);
+ }
+
+ // outline
+ painter->setPen(highlightedDarkInnerBorderColor);
+
+ QVarLengthArray<QLine, 4> lines;
+ QVarLengthArray<QPoint, 8> points;
+ if (!reverse) {
+ if (width == minWidth) {
+ points.append(QPoint(progressBar.left() + 1, progressBar.top()));
+ points.append(QPoint(progressBar.left() + 1, progressBar.bottom()));
+ } else {
+ if (indeterminate) {
+ lines.append(QLine(progressBar.left() + 2, progressBar.top(),
+ progressBar.right() - 2, progressBar.top()));
+ lines.append(QLine(progressBar.left() + 2, progressBar.bottom(),
+ progressBar.right() - 2, progressBar.bottom()));
+ } else {
+ lines.append(QLine(progressBar.left() + 1, progressBar.top(),
+ progressBar.right() - 2, progressBar.top()));
+ lines.append(QLine(progressBar.left() + 1, progressBar.bottom(),
+ progressBar.right() - 2, progressBar.bottom()));
+ }
+ }
+
+ if (indeterminate) {
+ lines.append(QLine(progressBar.left(), progressBar.top() + 2,
+ progressBar.left(), progressBar.bottom() - 2));
+ } else {
+ lines.append(QLine(progressBar.left(), progressBar.top() + 1,
+ progressBar.left(), progressBar.bottom() - 1));
+ }
+ lines.append(QLine(progressBar.right(), progressBar.top() + 2,
+ progressBar.right(), progressBar.bottom() - 2));
+ } else {
+ if (width == minWidth) {
+ points.append(QPoint(progressBar.right() - 1, progressBar.top()));
+ points.append(QPoint(progressBar.right() - 1, progressBar.bottom()));
+ } else {
+ if (indeterminate) {
+ lines.append(QLine(progressBar.right() - 2, progressBar.top(),
+ progressBar.left() + 2, progressBar.top()));
+ lines.append(QLine(progressBar.right() - 2, progressBar.bottom(),
+ progressBar.left() + 2, progressBar.bottom()));
+ } else {
+ lines.append(QLine(progressBar.right() - 1, progressBar.top(),
+ progressBar.left() + 2, progressBar.top()));
+ lines.append(QLine(progressBar.right() - 1, progressBar.bottom(),
+ progressBar.left() + 2, progressBar.bottom()));
+ }
+ }
+ if (indeterminate) {
+ lines.append(QLine(progressBar.right(), progressBar.top() + 2,
+ progressBar.right(), progressBar.bottom() - 2));
+ } else {
+ lines.append(QLine(progressBar.right(), progressBar.top() + 1,
+ progressBar.right(), progressBar.bottom() - 1));
+ }
+ lines.append(QLine(progressBar.left(), progressBar.top() + 2,
+ progressBar.left(), progressBar.bottom() - 2));
+ }
+
+ if (points.size() > 0) {
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+ }
+ painter->drawLines(lines.constData(), lines.size());
+ lines.clear();
+
+ // alpha corners
+ painter->setPen(alphaInnerColor);
+ if (!reverse) {
+ if (indeterminate) {
+ points.append(QPoint(progressBar.left() + 1, progressBar.top()));
+ points.append(QPoint(progressBar.left(), progressBar.top() + 1));
+ points.append(QPoint(progressBar.left() + 1, progressBar.bottom()));
+ points.append(QPoint(progressBar.left(), progressBar.bottom() - 1));
+ } else {
+ points.append(QPoint(progressBar.left(), progressBar.top()));
+ points.append(QPoint(progressBar.left(), progressBar.bottom()));
+ }
+ points.append(QPoint(progressBar.right() - 1, progressBar.top()));
+ points.append(QPoint(progressBar.right(), progressBar.top() + 1));
+ points.append(QPoint(progressBar.right() - 1, progressBar.bottom()));
+ points.append(QPoint(progressBar.right(), progressBar.bottom() - 1));
+ } else {
+ if (indeterminate) {
+ points.append(QPoint(progressBar.right() - 1, progressBar.top()));
+ points.append(QPoint(progressBar.right(), progressBar.top() + 1));
+ points.append(QPoint(progressBar.right() - 1, progressBar.bottom()));
+ points.append(QPoint(progressBar.right(), progressBar.bottom() - 1));
+ } else {
+ points.append(QPoint(progressBar.right(), progressBar.top()));
+ points.append(QPoint(progressBar.right(), progressBar.bottom()));
+ }
+ points.append(QPoint(progressBar.left() + 1, progressBar.top()));
+ points.append(QPoint(progressBar.left(), progressBar.top() + 1));
+ points.append(QPoint(progressBar.left() + 1, progressBar.bottom()));
+ points.append(QPoint(progressBar.left(), progressBar.bottom() - 1));
+ }
+
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+
+ // contents
+ painter->setPen(QPen());
+
+ QString progressBarName = QStyleHelper::uniqueName(QLatin1String("progressBarContents"),
+ option, rect.size());
+ QPixmap cache;
+ if (!QPixmapCache::find(progressBarName, cache) && rect.height() > 7) {
+ QSize size = rect.size();
+ cache = QPixmap(QSize(size.width() - 6 + 30, size.height() - 6));
+ cache.fill(Qt::white);
+ QPainter cachePainter(&cache);
+ QRect pixmapRect(0, 0, cache.width(), cache.height());
+
+ int leftEdge = 0;
+ bool flip = false;
+ while (leftEdge < cache.width() + 1) {
+ QColor rectColor = option->palette.highlight().color();
+ QColor lineColor = option->palette.highlight().color();
+ if (flip) {
+ flip = false;
+ rectColor = rectColor.lighter(105);
+ lineColor = lineColor.lighter(105);
+ } else {
+ flip = true;
+ }
+
+ cachePainter.setPen(lineColor);
+ const QLine cacheLines[2] = {
+ QLine(pixmapRect.left() + leftEdge - 1, pixmapRect.top(),
+ pixmapRect.left() + leftEdge + 9, pixmapRect.top()),
+ QLine(pixmapRect.left() + leftEdge - 1, pixmapRect.bottom(),
+ pixmapRect.left() + leftEdge + 9, pixmapRect.bottom()) };
+ cachePainter.drawLines(cacheLines, 2);
+ cachePainter.fillRect(QRect(pixmapRect.left() + leftEdge, pixmapRect.top(),
+ 10, pixmapRect.height()), rectColor);
+
+ leftEdge += 10;
+ }
+
+ QPixmapCache::insert(progressBarName, cache);
+ }
+ painter->setClipRect(progressBar.adjusted(1, 0, -1, -1));
+
+ if (!vertical)
+ progressBar.adjust(0, 1, 0, 1);
+ if (!indeterminate) {
+ int step = (AnimateProgressBar || (indeterminate && AnimateBusyProgressBar)) ? (d->animateStep % 20) : 0;
+ if (reverse)
+ painter->drawPixmap(progressBar.left() - 25 + step, progressBar.top(), cache);
+ else
+ painter->drawPixmap(progressBar.left() - 25 - step + width % 20, progressBar.top(), cache);
+ } else {
+ painter->drawPixmap(progressBar.left(), progressBar.top(), cache);
+ }
+
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ case CE_HeaderSection:
+ // Draws the header in tables.
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ QPixmap cache;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("headersection"), option, option->rect.size());
+ pixmapName += QString::number(- int(header->position));
+ pixmapName += QString::number(- int(header->orientation));
+
+ if (!QPixmapCache::find(pixmapName, cache)) {
+ cache = QPixmap(option->rect.size());
+ cache.fill(Qt::white);
+ QRect pixmapRect(0, 0, option->rect.width(), option->rect.height());
+ QPainter cachePainter(&cache);
+
+ bool sunken = (header->state & State_Enabled) && (header->state & State_Sunken);
+
+ QColor headerGradientStart = sunken ? option->palette.background().color().darker(114) : gradientStartColor;
+ QColor headerGradientStop = sunken ? option->palette.background().color().darker(106) : gradientStopColor;
+
+ QColor lightLine = sunken ? option->palette.background().color().darker(118) : gradientStartColor;
+ QColor darkLine = sunken ? option->palette.background().color().darker(110) : gradientStopColor.darker(105);
+
+ qt_plastique_draw_gradient(&cachePainter, pixmapRect,
+ headerGradientStart, headerGradientStop);
+
+ cachePainter.setPen(borderColor);
+ cachePainter.drawRect(pixmapRect.adjusted(0, 0, -1, -1));
+ cachePainter.setPen(alphaCornerColor);
+
+ const QPoint points[4] = {
+ pixmapRect.topLeft(), pixmapRect.topRight(),
+ pixmapRect.bottomLeft(), pixmapRect.bottomRight() };
+ cachePainter.drawPoints(points, 4);
+
+ QLine lines[2];
+
+ // inner lines
+ cachePainter.setPen(lightLine);
+ lines[0] = QLine(pixmapRect.left() + 2, pixmapRect.top() + 1,
+ pixmapRect.right() - 2, pixmapRect.top() + 1);
+ lines[1] = QLine(pixmapRect.left() + 1, pixmapRect.top() + 2,
+ pixmapRect.left() + 1, pixmapRect.bottom() - 2);
+ cachePainter.drawLines(lines, 2);
+
+ cachePainter.setPen(darkLine);
+ lines[0] = QLine(pixmapRect.left() + 2, pixmapRect.bottom() - 1,
+ pixmapRect.right() - 2, pixmapRect.bottom() - 1);
+ lines[1] = QLine(pixmapRect.right() - 1, pixmapRect.bottom() - 2,
+ pixmapRect.right() - 1, pixmapRect.top() + 2);
+ cachePainter.drawLines(lines, 2);
+
+ cachePainter.end();
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ painter->drawPixmap(option->rect.topLeft(), cache);
+
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ // Draws one item in a popup menu.
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ painter->save();
+ QBrush textBrush;
+ if (option->palette.resolve() & (1 << QPalette::ButtonText))
+ textBrush = option->palette.buttonText();
+ else
+ textBrush = option->palette.windowText(); // KDE uses windowText rather than buttonText for menus
+
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ painter->fillRect(menuItem->rect, option->palette.background().color().lighter(103));
+
+ int w = 0;
+ if (!menuItem->text.isEmpty()) {
+ painter->setFont(menuItem->font);
+ proxy()->drawItemText(painter, menuItem->rect.adjusted(5, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
+ menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
+ QPalette::Text);
+ w = menuItem->fontMetrics.width(menuItem->text) + 5;
+ }
+
+ painter->setPen(alphaCornerColor);
+ bool reverse = menuItem->direction == Qt::RightToLeft;
+ painter->drawLine(menuItem->rect.left() + 5 + (reverse ? 0 : w), menuItem->rect.center().y(),
+ menuItem->rect.right() - 5 - (reverse ? w : 0), menuItem->rect.center().y());
+
+ painter->restore();
+ break;
+ }
+
+ bool selected = menuItem->state & State_Selected;
+ bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
+ bool checked = menuItem->checked;
+
+ if (selected) {
+ qt_plastique_draw_gradient(painter, menuItem->rect,
+ option->palette.highlight().color().lighter(105),
+ option->palette.highlight().color().darker(110));
+
+ painter->setPen(option->palette.highlight().color().lighter(110));
+ painter->drawLine(option->rect.topLeft(), option->rect.topRight());
+ painter->setPen(option->palette.highlight().color().darker(115));
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ } else {
+ painter->fillRect(option->rect, option->palette.background().color().lighter(103));
+ }
+
+ // Check
+ QRect checkRect(option->rect.left() + 7, option->rect.center().y() - 6, 13, 13);
+ checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
+ if (checkable) {
+ if ((menuItem->checkType & QStyleOptionMenuItem::Exclusive) && menuItem->icon.isNull()) {
+ QStyleOptionButton button;
+ button.rect = checkRect;
+ button.state = menuItem->state;
+ if (checked)
+ button.state |= State_On;
+ button.palette = menuItem->palette;
+ proxy()->drawPrimitive(PE_IndicatorRadioButton, &button, painter, widget);
+ } else {
+ if (menuItem->icon.isNull()) {
+ QStyleOptionButton button;
+ button.rect = checkRect;
+ button.state = menuItem->state;
+ if (checked)
+ button.state |= State_On;
+ button.palette = menuItem->palette;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
+ } else if (checked) {
+ int iconSize = qMax(menuItem->maxIconWidth, 20);
+ QRect sunkenRect(option->rect.left() + 1,
+ option->rect.top() + (option->rect.height() - iconSize) / 2 + 1,
+ iconSize, iconSize);
+ sunkenRect = visualRect(menuItem->direction, menuItem->rect, sunkenRect);
+
+ QStyleOption opt = *option;
+ opt.state |= State_Sunken;
+ opt.rect = sunkenRect;
+ qt_plastique_drawShadedPanel(painter, &opt, false, widget);
+ }
+ }
+ }
+
+ // Text and icon, ripped from windows style
+ bool dis = !(menuItem->state & State_Enabled);
+ bool act = menuItem->state & State_Selected;
+ const QStyleOption *opt = option;
+ const QStyleOptionMenuItem *menuitem = menuItem;
+ int checkcol = qMax(menuitem->maxIconWidth, 20);
+ QPainter *p = painter;
+ QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
+ QRect(menuitem->rect.x(), menuitem->rect.y(),
+ checkcol, menuitem->rect.height()));
+ if (!menuItem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
+ else
+ pixmap = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(textBrush.color());
+ if (checkable && checked)
+ painter->drawPixmap(QPoint(pmr.left() + 1, pmr.top() + 1), pixmap);
+ else
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ }
+
+ if (selected) {
+ painter->setPen(menuItem->palette.highlightedText().color());
+ } else {
+ painter->setPen(textBrush.color());
+ }
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ QColor discol;
+ if (dis) {
+ discol = textBrush.color();
+ p->setPen(discol);
+ }
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act && styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+ p->setPen(discol);
+ }
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+ if (dis && !act && styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+ p->setPen(discol);
+ }
+ p->drawText(vTextRect, text_flags, s.left(t));
+ p->restore();
+ }
+
+ // Arrow
+ if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (menuItem->rect.height() - 4) / 2;
+ PrimitiveElement arrow;
+ arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ int xpos = menuItem->rect.left() + menuItem->rect.width() - 6 - 2 - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
+ QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuItem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = option->state & State_Enabled;
+ if (selected)
+ newMI.palette.setColor(QPalette::ButtonText,
+ newMI.palette.highlightedText().color());
+ else
+ newMI.palette.setColor(QPalette::ButtonText, textBrush.color());
+ proxy()->drawPrimitive(arrow, &newMI, painter, widget);
+ }
+
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_MENUBAR
+ case CE_MenuBarItem:
+ // Draws a menu bar item; File, Edit, Help etc..
+ if ((option->state & State_Selected)) {
+ QPixmap cache;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("menubaritem"), option, option->rect.size());
+ if (!QPixmapCache::find(pixmapName, cache)) {
+ cache = QPixmap(option->rect.size());
+ cache.fill(Qt::white);
+ QRect pixmapRect(0, 0, option->rect.width(), option->rect.height());
+ QPainter cachePainter(&cache);
+
+ QRect rect = pixmapRect;
+
+ // gradient fill
+ if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On)) {
+ qt_plastique_draw_gradient(&cachePainter, rect.adjusted(1, 1, -1, -1),
+ option->palette.button().color().darker(114),
+ option->palette.button().color().darker(106));
+ } else {
+ qt_plastique_draw_gradient(&cachePainter, rect.adjusted(1, 1, -1, -1),
+ option->palette.background().color().lighter(105),
+ option->palette.background().color().darker(102));
+ }
+
+ // outer border and corners
+ cachePainter.setPen(borderColor);
+ cachePainter.drawRect(rect.adjusted(0, 0, -1, -1));
+ cachePainter.setPen(alphaCornerColor);
+
+ const QPoint points[4] = {
+ rect.topLeft(),
+ rect.topRight(),
+ rect.bottomLeft(),
+ rect.bottomRight() };
+ cachePainter.drawPoints(points, 4);
+
+ // inner border
+ if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
+ cachePainter.setPen(option->palette.button().color().darker(118));
+ else
+ cachePainter.setPen(gradientStartColor);
+
+ QLine lines[2];
+ lines[0] = QLine(rect.left() + 1, rect.top() + 1, rect.right() - 1, rect.top() + 1);
+ lines[1] = QLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
+ cachePainter.drawLines(lines, 2);
+
+ if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
+ cachePainter.setPen(option->palette.button().color().darker(114));
+ else
+ cachePainter.setPen(gradientStopColor.darker(102));
+ lines[0] = QLine(rect.left() + 1, rect.bottom() - 1, rect.right() - 1, rect.bottom() - 1);
+ lines[1] = QLine(rect.right() - 1, rect.top() + 1, rect.right() - 1, rect.bottom() - 2);
+ cachePainter.drawLines(lines, 2);
+ cachePainter.end();
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ painter->drawPixmap(option->rect.topLeft(), cache);
+ } else {
+ painter->fillRect(option->rect, option->palette.background());
+ }
+
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ QStyleOptionMenuItem newMI = *mbi;
+ if (!(option->palette.resolve() & (1 << QPalette::ButtonText))) //KDE uses windowText rather than buttonText for menus
+ newMI.palette.setColor(QPalette::ButtonText, newMI.palette.windowText().color());
+ QCommonStyle::drawControl(element, &newMI, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_MAINWINDOW
+ case CE_MenuBarEmptyArea:
+ if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
+ painter->fillRect(option->rect, option->palette.window());
+ QPen oldPen = painter->pen();
+ painter->setPen(QPen(option->palette.dark().color()));
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ painter->setPen(oldPen);
+ }
+ break;
+#endif // QT_NO_MAINWINDOW
+
+#endif // QT_NO_MENUBAR
+
+#ifndef QT_NO_TOOLBOX
+ case CE_ToolBoxTabShape:
+ if (const QStyleOptionToolBox *toolBox = qstyleoption_cast<const QStyleOptionToolBox *>(option)) {
+ painter->save();
+
+ int width = toolBox->rect.width();
+ int diag = toolBox->rect.height() - 2;
+
+ // The essential points
+ QPoint rightMost;
+ QPoint rightEdge;
+ QPoint leftEdge;
+ QPoint leftMost;
+ QPoint leftOne;
+ QPoint rightOne;
+ QPoint upOne(0, -1);
+ QPoint downOne(0, 1);
+
+ if (toolBox->direction != Qt::RightToLeft) {
+ rightMost = QPoint(toolBox->rect.right(), toolBox->rect.bottom() - 2);
+ rightEdge = QPoint(toolBox->rect.right() - width / 10, toolBox->rect.bottom() - 2);
+ leftEdge = QPoint(toolBox->rect.right() - width / 10 - diag, toolBox->rect.top());
+ leftMost = QPoint(toolBox->rect.left(), toolBox->rect.top());
+ leftOne = QPoint(-1, 0);
+ rightOne = QPoint(1, 0);
+ } else {
+ rightMost = QPoint(toolBox->rect.left(), toolBox->rect.bottom() - 2);
+ rightEdge = QPoint(toolBox->rect.left() + width / 10, toolBox->rect.bottom() - 2);
+ leftEdge = QPoint(toolBox->rect.left() + width / 10 + diag, toolBox->rect.top());
+ leftMost = QPoint(toolBox->rect.right(), toolBox->rect.top());
+ leftOne = QPoint(1, 0);
+ rightOne = QPoint(-1, 0);
+ }
+
+ QLine lines[3];
+
+ // Draw the outline
+ painter->setPen(borderColor);
+ lines[0] = QLine(rightMost, rightEdge);
+ lines[1] = QLine(rightEdge + leftOne, leftEdge);
+ lines[2] = QLine(leftEdge + leftOne, leftMost);
+ painter->drawLines(lines, 3);
+ painter->setPen(toolBox->palette.base().color());
+ lines[0] = QLine(rightMost + downOne, rightEdge + downOne);
+ lines[1] = QLine(rightEdge + leftOne + downOne, leftEdge + downOne);
+ lines[2] = QLine(leftEdge + leftOne + downOne, leftMost + downOne);
+ painter->drawLines(lines, 3);
+
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_TOOLBOX
+#ifndef QT_NO_SPLITTER
+ case CE_Splitter:
+ if ((option->state & State_Enabled) && (option->state & State_MouseOver))
+ painter->fillRect(option->rect, QColor(255, 255, 255, 128));
+ if (option->state & State_Horizontal) {
+ int height = option->rect.height() / 3;
+ QRect rect(option->rect.left() + (option->rect.width() / 2 - 1),
+ option->rect.center().y() - height / 2, 3, height);
+ qt_plastique_draw_handle(painter, option, rect, Qt::Horizontal, widget);
+ } else {
+ int width = option->rect.width() / 3;
+ QRect rect(option->rect.center().x() - width / 2,
+ option->rect.top() + (option->rect.height() / 2) - 1, width, 3);
+ qt_plastique_draw_handle(painter, option, rect, Qt::Vertical, widget);
+ }
+ break;
+#endif // QT_NO_SPLITTER
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidget *dockWidget = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ painter->save();
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dockWidget);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ // Find text width and title rect
+ int textWidth = option->fontMetrics.width(dockWidget->title);
+ int margin = 4;
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget);
+ QRect rect = dockWidget->rect;
+
+ if (verticalTitleBar) {
+ QRect r = rect;
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+
+ painter->translate(r.left(), r.top() + r.width());
+ painter->rotate(-90);
+ painter->translate(-r.left(), -r.top());
+
+ rect = r;
+ }
+
+ // Chop and insert ellide into title if text is too wide
+ QString title = elliditide(dockWidget->title, dockWidget->fontMetrics, titleRect, &textWidth);
+
+ // Draw the toolbar handle pattern to the left and right of the text
+ QImage handle(qt_toolbarhandle);
+ alphaCornerColor.setAlpha(170);
+ handle.setColor(1, alphaCornerColor.rgba());
+ handle.setColor(2, mergedColors(alphaCornerColor, option->palette.light().color()).rgba());
+ handle.setColor(3, option->palette.light().color().rgba());
+
+ if (title.isEmpty()) {
+ // Joint handle if there's no title
+ QRect r;
+#ifdef QT3_SUPPORT
+ // Q3DockWindow doesn't need space for buttons
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ r = rect;
+ } else
+#endif
+ r.setRect(titleRect.left(), titleRect.top(), titleRect.width(), titleRect.bottom());
+ int nchunks = (r.width() / handle.width()) - 1;
+ int indent = (r.width() - (nchunks * handle.width())) / 2;
+ for (int i = 0; i < nchunks; ++i) {
+ painter->drawImage(QPoint(r.left() + indent + i * handle.width(),
+ r.center().y() - handle.height() / 2),
+ handle);
+ }
+ } else {
+ // Handle pattern to the left of the title
+ QRect leftSide(titleRect.left(), titleRect.top(),
+ titleRect.width() / 2 - textWidth / 2 - margin, titleRect.bottom());
+ int nchunks = leftSide.width() / handle.width();
+ int indent = (leftSide.width() - (nchunks * handle.width())) / 2;
+ for (int i = 0; i < nchunks; ++i) {
+ painter->drawImage(QPoint(leftSide.left() + indent
+ + i * handle.width(),
+ leftSide.center().y()
+ - handle.height() / 2),
+ handle);
+ }
+
+ // Handle pattern to the right of the title
+ QRect rightSide = titleRect.adjusted(titleRect.width() / 2 + textWidth / 2 + margin, 0, 0, 0);
+ nchunks = rightSide.width() / handle.width();
+ indent = (rightSide.width() - (nchunks * handle.width())) / 2;
+ for (int j = 0; j < nchunks; ++j) {
+ painter->drawImage(QPoint(rightSide.left() + indent + j * handle.width(),
+ rightSide.center().y() - handle.height() / 2),
+ handle);
+ }
+ }
+
+ // Draw the text centered
+ QFont font = painter->font();
+ font.setPointSize(QFontInfo(font).pointSize() - 1);
+ painter->setFont(font);
+ painter->setPen(dockWidget->palette.windowText().color());
+ painter->drawText(titleRect,
+ int(Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextShowMnemonic),
+ title);
+
+ painter->restore();
+ }
+
+ break;
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ // Draws the light line above and the dark line below menu bars and
+ // tool bars.
+ QPen oldPen = painter->pen();
+ if (toolBar->toolBarArea == Qt::TopToolBarArea) {
+ if (toolBar->positionOfLine == QStyleOptionToolBar::End
+ || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
+ // The end and onlyone top toolbar lines draw a double
+ // line at the bottom to blend with the central
+ // widget.
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
+ option->rect.right(), option->rect.bottom() - 1);
+ } else {
+ // All others draw a single dark line at the bottom.
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ }
+ // All top toolbar lines draw a light line at the top.
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.topLeft(), option->rect.topRight());
+ } else if (toolBar->toolBarArea == Qt::BottomToolBarArea) {
+ if (toolBar->positionOfLine == QStyleOptionToolBar::End
+ || toolBar->positionOfLine == QStyleOptionToolBar::Middle) {
+ // The end and middle bottom tool bar lines draw a dark
+ // line at the bottom.
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ }
+ if (toolBar->positionOfLine == QStyleOptionToolBar::Beginning
+ || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
+ // The beginning and only one tool bar lines draw a
+ // double line at the bottom to blend with the
+ // status bar.
+ // ### The styleoption could contain whether the
+ // main window has a menu bar and a status bar, and
+ // possibly dock widgets.
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
+ option->rect.right(), option->rect.bottom() - 1);
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ }
+ if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.topLeft(), option->rect.topRight());
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.left(), option->rect.top() + 1,
+ option->rect.right(), option->rect.top() + 1);
+
+ } else {
+ // All other bottom toolbars draw a light line at the top.
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.topLeft(), option->rect.topRight());
+ }
+ }
+ if (toolBar->toolBarArea == Qt::LeftToolBarArea) {
+ if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
+ || toolBar->positionOfLine == QStyleOptionToolBar::End) {
+ // The middle and left end toolbar lines draw a light
+ // line to the left.
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
+ }
+ if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
+ // All other left toolbar lines draw a dark line to the right
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.right() - 1, option->rect.top(),
+ option->rect.right() - 1, option->rect.bottom());
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
+ } else {
+ // All other left toolbar lines draw a dark line to the right
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
+ }
+ } else if (toolBar->toolBarArea == Qt::RightToolBarArea) {
+ if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
+ || toolBar->positionOfLine == QStyleOptionToolBar::End) {
+ // Right middle and end toolbar lines draw the dark right line
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
+ }
+ if (toolBar->positionOfLine == QStyleOptionToolBar::End
+ || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
+ // The right end and single toolbar draws the dark
+ // line on its left edge
+ painter->setPen(alphaCornerColor);
+ painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
+ // And a light line next to it
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.left() + 1, option->rect.top(),
+ option->rect.left() + 1, option->rect.bottom());
+ } else {
+ // Other right toolbars draw a light line on its left edge
+ painter->setPen(option->palette.background().color().lighter(104));
+ painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
+ }
+ }
+ painter->setPen(oldPen);
+ }
+ break;
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_SCROLLBAR
+ case CE_ScrollBarAddLine:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+ bool reverse = scrollBar->direction == Qt::RightToLeft;
+ bool sunken = scrollBar->state & State_Sunken;
+
+ QString addLinePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_addline"), option, option->rect.size());
+ QPixmap cache;
+ if (!QPixmapCache::find(addLinePixmapName, cache)) {
+ cache = QPixmap(option->rect.size());
+ cache.fill(Qt::white);
+ QRect pixmapRect(0, 0, cache.width(), cache.height());
+ QPainter addLinePainter(&cache);
+ addLinePainter.fillRect(pixmapRect, option->palette.background());
+
+ if (option->state & State_Enabled) {
+ // Gradient
+ QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top() + 2,
+ pixmapRect.center().x(), pixmapRect.bottom() - 2);
+ if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken) {
+ gradient.setColorAt(0, gradientStopColor);
+ gradient.setColorAt(1, gradientStopColor);
+ } else {
+ gradient.setColorAt(0, gradientStartColor.lighter(105));
+ gradient.setColorAt(1, gradientStopColor);
+ }
+ addLinePainter.fillRect(pixmapRect.left() + 2, pixmapRect.top() + 2,
+ pixmapRect.right() - 3, pixmapRect.bottom() - 3,
+ gradient);
+ }
+
+ // Details
+ QImage addButton;
+ if (horizontal) {
+ addButton = QImage(reverse ? qt_scrollbar_button_left : qt_scrollbar_button_right);
+ } else {
+ addButton = QImage(qt_scrollbar_button_down);
+ }
+ addButton.setColor(1, alphaCornerColor.rgba());
+ addButton.setColor(2, borderColor.rgba());
+ if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken) {
+ addButton.setColor(3, gradientStopColor.rgba());
+ addButton.setColor(4, gradientStopColor.rgba());
+ } else {
+ addButton.setColor(3, gradientStartColor.lighter(105).rgba());
+ addButton.setColor(4, gradientStopColor.rgba());
+ }
+ addButton.setColor(5, scrollBar->palette.text().color().rgba());
+ addLinePainter.drawImage(pixmapRect, addButton);
+
+ // Arrow
+ if (horizontal) {
+ QImage arrow(reverse ? qt_scrollbar_button_arrow_left : qt_scrollbar_button_arrow_right);
+ arrow.setColor(1, scrollBar->palette.foreground().color().rgba());
+
+ if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
+ addLinePainter.translate(1, 1);
+ addLinePainter.drawImage(QPoint(pixmapRect.center().x() - 2, pixmapRect.center().y() - 3), arrow);
+ } else {
+ QImage arrow(qt_scrollbar_button_arrow_down);
+ arrow.setColor(1, scrollBar->palette.foreground().color().rgba());
+
+ if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
+ addLinePainter.translate(1, 1);
+ addLinePainter.drawImage(QPoint(pixmapRect.center().x() - 3, pixmapRect.center().y() - 2), arrow);
+ }
+ addLinePainter.end();
+ QPixmapCache::insert(addLinePixmapName, cache);
+ }
+ painter->drawPixmap(option->rect.topLeft(), cache);
+ }
+ break;
+ case CE_ScrollBarSubPage:
+ case CE_ScrollBarAddPage:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ bool sunken = scrollBar->state & State_Sunken;
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+
+ QString groovePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_groove"), option, option->rect.size());
+ if (sunken)
+ groovePixmapName += QLatin1String("-sunken");
+ if (element == CE_ScrollBarAddPage)
+ groovePixmapName += QLatin1String("-addpage");
+
+ QPixmap cache;
+ if (!QPixmapCache::find(groovePixmapName, cache)) {
+ cache = QPixmap(option->rect.size());
+ cache.fill(option->palette.background().color());
+ QPainter groovePainter(&cache);
+ QRect pixmapRect = QRect(0, 0, option->rect.width(), option->rect.height());
+ QColor color = scrollBar->palette.base().color().darker(sunken ? 125 : 100);
+ groovePainter.setBrushOrigin((element == CE_ScrollBarAddPage) ? pixmapRect.width() : 0,
+ (element == CE_ScrollBarAddPage) ? pixmapRect.height() : 0);
+ groovePainter.fillRect(pixmapRect, QBrush(color, Qt::Dense4Pattern));
+
+ QColor edgeColor = scrollBar->palette.base().color().darker(125);
+ if (horizontal) {
+ groovePainter.setBrushOrigin((element == CE_ScrollBarAddPage) ? pixmapRect.width() : 1, 0);
+ groovePainter.fillRect(QRect(pixmapRect.topLeft(), QSize(pixmapRect.width(), 1)),
+ QBrush(edgeColor, Qt::Dense4Pattern));
+ groovePainter.fillRect(QRect(pixmapRect.bottomLeft(), QSize(pixmapRect.width(), 1)),
+ QBrush(edgeColor, Qt::Dense4Pattern));
+ } else {
+ groovePainter.setBrushOrigin(0, (element == CE_ScrollBarAddPage) ? pixmapRect.height() : 1);
+ groovePainter.fillRect(QRect(pixmapRect.topLeft(), QSize(1, pixmapRect.height())),
+ QBrush(edgeColor, Qt::Dense4Pattern));
+ groovePainter.fillRect(QRect(pixmapRect.topRight(), QSize(1, pixmapRect.height())),
+ QBrush(edgeColor, Qt::Dense4Pattern));
+ }
+
+ groovePainter.end();
+ QPixmapCache::insert(groovePixmapName, cache);
+ }
+ painter->drawPixmap(option->rect.topLeft(), cache);
+ }
+ break;
+ case CE_ScrollBarSubLine:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect scrollBarSubLine = scrollBar->rect;
+
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+ bool isEnabled = scrollBar->state & State_Enabled;
+ bool reverse = scrollBar->direction == Qt::RightToLeft;
+ bool sunken = scrollBar->state & State_Sunken;
+
+ // The SubLine (up/left) buttons
+ QRect button1;
+ QRect button2;
+ int scrollBarExtent = proxy()->pixelMetric(PM_ScrollBarExtent, option, widget);
+ if (horizontal) {
+ button1.setRect(scrollBarSubLine.left(), scrollBarSubLine.top(), scrollBarExtent, scrollBarSubLine.height());
+ button2.setRect(scrollBarSubLine.right() - (scrollBarExtent - 1), scrollBarSubLine.top(), scrollBarExtent, scrollBarSubLine.height());
+ } else {
+ button1.setRect(scrollBarSubLine.left(), scrollBarSubLine.top(), scrollBarSubLine.width(), scrollBarExtent);
+ button2.setRect(scrollBarSubLine.left(), scrollBarSubLine.bottom() - (scrollBarExtent - 1), scrollBarSubLine.width(), scrollBarExtent);
+ }
+
+ QString subLinePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_subline"), option, button1.size());
+ QPixmap cache;
+ if (!QPixmapCache::find(subLinePixmapName, cache)) {
+ cache = QPixmap(button1.size());
+ cache.fill(Qt::white);
+ QRect pixmapRect(0, 0, cache.width(), cache.height());
+ QPainter subLinePainter(&cache);
+ subLinePainter.fillRect(pixmapRect, option->palette.background());
+
+ if (isEnabled) {
+ // Gradients
+ if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken) {
+ qt_plastique_draw_gradient(&subLinePainter,
+ QRect(pixmapRect.left() + 2, pixmapRect.top() + 2,
+ pixmapRect.right() - 3, pixmapRect.bottom() - 3),
+ gradientStopColor,
+ gradientStopColor);
+ } else {
+ qt_plastique_draw_gradient(&subLinePainter,
+ QRect(pixmapRect.left() + 2, pixmapRect.top() + 2,
+ pixmapRect.right() - 3, pixmapRect.bottom() - 3),
+ gradientStartColor.lighter(105),
+ gradientStopColor);
+ }
+ }
+
+ // Details
+ QImage subButton;
+ if (horizontal) {
+ subButton = QImage(reverse ? qt_scrollbar_button_right : qt_scrollbar_button_left);
+ } else {
+ subButton = QImage(qt_scrollbar_button_up);
+ }
+ subButton.setColor(1, alphaCornerColor.rgba());
+ subButton.setColor(2, borderColor.rgba());
+ if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken) {
+ subButton.setColor(3, gradientStopColor.rgba());
+ subButton.setColor(4, gradientStopColor.rgba());
+ } else {
+ subButton.setColor(3, gradientStartColor.lighter(105).rgba());
+ subButton.setColor(4, gradientStopColor.rgba());
+ }
+ subButton.setColor(5, scrollBar->palette.text().color().rgba());
+ subLinePainter.drawImage(pixmapRect, subButton);
+
+ // Arrows
+ if (horizontal) {
+ QImage arrow(reverse ? qt_scrollbar_button_arrow_right : qt_scrollbar_button_arrow_left);
+ arrow.setColor(1, scrollBar->palette.foreground().color().rgba());
+
+ if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
+ subLinePainter.translate(1, 1);
+ subLinePainter.drawImage(QPoint(pixmapRect.center().x() - 2, pixmapRect.center().y() - 3), arrow);
+ } else {
+ QImage arrow(qt_scrollbar_button_arrow_up);
+ arrow.setColor(1, scrollBar->palette.foreground().color().rgba());
+
+ if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
+ subLinePainter.translate(1, 1);
+ subLinePainter.drawImage(QPoint(pixmapRect.center().x() - 3, pixmapRect.center().y() - 2), arrow);
+ }
+ subLinePainter.end();
+ QPixmapCache::insert(subLinePixmapName, cache);
+ }
+ painter->drawPixmap(button1.topLeft(), cache);
+ painter->drawPixmap(button2.topLeft(), cache);
+ }
+ break;
+ case CE_ScrollBarSlider:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+ bool isEnabled = scrollBar->state & State_Enabled;
+
+ // The slider
+ if (option->rect.isValid()) {
+ QString sliderPixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_slider"), option, option->rect.size());
+ if (horizontal)
+ sliderPixmapName += QLatin1String("-horizontal");
+
+ QPixmap cache;
+ if (!QPixmapCache::find(sliderPixmapName, cache)) {
+ cache = QPixmap(option->rect.size());
+ cache.fill(Qt::white);
+ QRect pixmapRect(0, 0, cache.width(), cache.height());
+ QPainter sliderPainter(&cache);
+ bool sunken = (scrollBar->state & State_Sunken);
+
+ if (isEnabled) {
+ QLinearGradient gradient(pixmapRect.left(), pixmapRect.center().y(),
+ pixmapRect.right(), pixmapRect.center().y());
+ if (horizontal)
+ gradient = QLinearGradient(pixmapRect.center().x(), pixmapRect.top(),
+ pixmapRect.center().x(), pixmapRect.bottom());
+
+ if (sunken) {
+ gradient.setColorAt(0, gradientStartColor.lighter(110));
+ gradient.setColorAt(1, gradientStopColor.lighter(105));
+ } else {
+ gradient.setColorAt(0, gradientStartColor.lighter(105));
+ gradient.setColorAt(1, gradientStopColor);
+ }
+ sliderPainter.fillRect(pixmapRect.adjusted(2, 2, -2, -2), gradient);
+ } else {
+ sliderPainter.fillRect(pixmapRect.adjusted(2, 2, -2, -2), option->palette.background());
+ }
+
+ sliderPainter.setPen(borderColor);
+ sliderPainter.drawRect(pixmapRect.adjusted(0, 0, -1, -1));
+ sliderPainter.setPen(alphaCornerColor);
+ QPoint points[4] = {
+ QPoint(pixmapRect.left(), pixmapRect.top()),
+ QPoint(pixmapRect.left(), pixmapRect.bottom()),
+ QPoint(pixmapRect.right(), pixmapRect.top()),
+ QPoint(pixmapRect.right(), pixmapRect.bottom()) };
+ sliderPainter.drawPoints(points, 4);
+
+ QLine lines[2];
+ sliderPainter.setPen(sunken ? gradientStartColor.lighter(110) : gradientStartColor.lighter(105));
+ lines[0] = QLine(pixmapRect.left() + 1, pixmapRect.top() + 1,
+ pixmapRect.right() - 1, pixmapRect.top() + 1);
+ lines[1] = QLine(pixmapRect.left() + 1, pixmapRect.top() + 2,
+ pixmapRect.left() + 1, pixmapRect.bottom() - 2);
+ sliderPainter.drawLines(lines, 2);
+
+ sliderPainter.setPen(sunken ? gradientStopColor.lighter(105) : gradientStopColor);
+ lines[0] = QLine(pixmapRect.left() + 1, pixmapRect.bottom() - 1,
+ pixmapRect.right() - 1, pixmapRect.bottom() - 1);
+ lines[1] = QLine(pixmapRect.right() - 1, pixmapRect.top() + 2,
+ pixmapRect.right() - 1, pixmapRect.bottom() - 1);
+ sliderPainter.drawLines(lines, 2);
+
+ int sliderMinLength = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollBar, widget);
+ if ((horizontal && scrollBar->rect.width() > sliderMinLength)
+ || (!horizontal && scrollBar->rect.height() > sliderMinLength)) {
+ QImage pattern(horizontal ? qt_scrollbar_slider_pattern_horizontal
+ : qt_scrollbar_slider_pattern_vertical);
+ pattern.setColor(1, alphaCornerColor.rgba());
+ pattern.setColor(2, (sunken ? gradientStartColor.lighter(110) : gradientStartColor.lighter(105)).rgba());
+
+ if (horizontal) {
+ sliderPainter.drawImage(pixmapRect.center().x() - pattern.width() / 2 + 1,
+ pixmapRect.center().y() - 4,
+ pattern);
+ } else {
+ sliderPainter.drawImage(pixmapRect.center().x() - 4,
+ pixmapRect.center().y() - pattern.height() / 2 + 1,
+ pattern);
+ }
+ }
+ sliderPainter.end();
+ // insert the slider into the cache
+ QPixmapCache::insert(sliderPixmapName, cache);
+ }
+ painter->drawPixmap(option->rect.topLeft(), cache);
+ }
+ }
+ break;
+#endif
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ painter->save();
+ if (!comboBox->editable) {
+ // Plastique's non-editable combo box is drawn as a button, so
+ // we need the label to be drawn using ButtonText where it
+ // would usually use Text.
+ painter->setPen(QPen(comboBox->palette.buttonText(), 0));
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ } else if (!comboBox->currentIcon.isNull()) {
+ {
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget);
+ if (comboBox->direction == Qt::RightToLeft)
+ editRect.adjust(0, 2, -2, -2);
+ else
+ editRect.adjust(2, 2, 0, -2);
+ painter->save();
+ painter->setClipRect(editRect);
+ if (!comboBox->currentIcon.isNull()) {
+ QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(comboBox->iconSize.width() + 5);
+ iconRect = alignedRect(comboBox->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ painter->fillRect(iconRect, option->palette.brush(QPalette::Base));
+ proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
+ }
+ painter->restore();
+ }
+ } else {
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ }
+
+ painter->restore();
+ }
+ break;
+#endif
+ default:
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QColor borderColor = option->palette.background().color().darker(178);
+ QColor alphaCornerColor;
+ if (widget) {
+ // ### backgroundrole/foregroundrole should be part of the style option
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
+ } else {
+ alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
+ }
+ QColor gradientStartColor = option->palette.button().color().lighter(104);
+ QColor gradientStopColor = option->palette.button().color().darker(105);
+
+ switch (control) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect grooveRegion = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
+ bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
+
+ QRect groove;
+ //The clickable region is 5 px wider than the visible groove for improved usability
+ if (grooveRegion.isValid())
+ groove = horizontal ? grooveRegion.adjusted(0, 5, 0, -5) : grooveRegion.adjusted(5, 0, -5, 0);
+
+
+ QPixmap cache;
+
+ if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
+ BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("slider_groove-%0-%1").arg(ticksAbove).arg(ticksBelow))
+ p->fillRect(groove, option->palette.background());
+
+ // draw groove
+ if (horizontal) {
+ p->setPen(borderColor);
+ const QLine lines[4] = {
+ QLine(groove.left() + 1, groove.top(),
+ groove.right() - 1, groove.top()),
+ QLine(groove.left() + 1, groove.bottom(),
+ groove.right() - 1, groove.bottom()),
+ QLine(groove.left(), groove.top() + 1,
+ groove.left(), groove.bottom() - 1),
+ QLine(groove.right(), groove.top() + 1,
+ groove.right(), groove.bottom() - 1) };
+ p->drawLines(lines, 4);
+
+ p->setPen(alphaCornerColor);
+ const QPoint points[4] = {
+ QPoint(groove.left(), groove.top()),
+ QPoint(groove.left(), groove.bottom()),
+ QPoint(groove.right(), groove.top()),
+ QPoint(groove.right(), groove.bottom()) };
+ p->drawPoints(points, 4);
+ } else {
+ p->setPen(borderColor);
+ const QLine lines[4] = {
+ QLine(groove.left() + 1, groove.top(),
+ groove.right() - 1, groove.top()),
+ QLine(groove.left() + 1, groove.bottom(),
+ groove.right() - 1, groove.bottom()),
+ QLine(groove.left(), groove.top() + 1,
+ groove.left(), groove.bottom() - 1),
+ QLine(groove.right(), groove.top() + 1,
+ groove.right(), groove.bottom() - 1) };
+ p->drawLines(lines, 4);
+
+ p->setPen(alphaCornerColor);
+ const QPoint points[4] = {
+ QPoint(groove.left(), groove.top()),
+ QPoint(groove.right(), groove.top()),
+ QPoint(groove.left(), groove.bottom()),
+ QPoint(groove.right(), groove.bottom()) };
+ p->drawPoints(points, 4);
+ }
+ END_STYLE_PIXMAPCACHE
+ }
+
+ if ((option->subControls & SC_SliderHandle) && handle.isValid()) {
+ QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_handle"), option, handle.size());
+ if (ticksAbove && !ticksBelow)
+ handlePixmapName += QLatin1String("-flipped");
+ if ((option->activeSubControls & SC_SliderHandle) && (option->state & State_Sunken))
+ handlePixmapName += QLatin1String("-sunken");
+
+ if (!QPixmapCache::find(handlePixmapName, cache)) {
+ cache = QPixmap(handle.size());
+ cache.fill(Qt::white);
+ QRect pixmapRect(0, 0, handle.width(), handle.height());
+ QPainter handlePainter(&cache);
+ handlePainter.fillRect(pixmapRect, option->palette.background());
+
+ // draw handle
+ if (horizontal) {
+ QPainterPath path;
+ if (ticksAbove && !ticksBelow) {
+ path.moveTo(QPoint(pixmapRect.right(), pixmapRect.bottom()));
+ path.lineTo(QPoint(pixmapRect.right(), pixmapRect.bottom() - 10));
+ path.lineTo(QPoint(pixmapRect.right() - 5, pixmapRect.bottom() - 14));
+ path.lineTo(QPoint(pixmapRect.left() + 1, pixmapRect.bottom() - 10));
+ path.lineTo(QPoint(pixmapRect.left() + 1, pixmapRect.bottom()));
+ path.lineTo(QPoint(pixmapRect.right(), pixmapRect.bottom()));
+ } else {
+ path.moveTo(QPoint(pixmapRect.right(), pixmapRect.top() + 1));
+ path.lineTo(QPoint(pixmapRect.right(), pixmapRect.top() + 10));
+ path.lineTo(QPoint(pixmapRect.right() - 5, pixmapRect.top() + 14));
+ path.lineTo(QPoint(pixmapRect.left() + 1, pixmapRect.top() + 10));
+ path.lineTo(QPoint(pixmapRect.left() + 1, pixmapRect.top() + 1));
+ path.lineTo(QPoint(pixmapRect.right(), pixmapRect.top() + 1));
+ }
+ if (slider->state & State_Enabled) {
+ QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
+ pixmapRect.center().x(), pixmapRect.bottom());
+ if ((option->activeSubControls & SC_SliderHandle) && (option->state & State_Sunken)) {
+ gradient.setColorAt(0, gradientStartColor.lighter(110));
+ gradient.setColorAt(1, gradientStopColor.lighter(110));
+ } else {
+ gradient.setColorAt(0, gradientStartColor);
+ gradient.setColorAt(1, gradientStopColor);
+ }
+ handlePainter.fillPath(path, gradient);
+ } else {
+ handlePainter.fillPath(path, slider->palette.background());
+ }
+ } else {
+ QPainterPath path;
+ if (ticksAbove && !ticksBelow) {
+ path.moveTo(QPoint(pixmapRect.right(), pixmapRect.top() + 1));
+ path.lineTo(QPoint(pixmapRect.right() - 10, pixmapRect.top() + 1));
+ path.lineTo(QPoint(pixmapRect.right() - 14, pixmapRect.top() + 5));
+ path.lineTo(QPoint(pixmapRect.right() - 10, pixmapRect.bottom()));
+ path.lineTo(QPoint(pixmapRect.right(), pixmapRect.bottom()));
+ path.lineTo(QPoint(pixmapRect.right(), pixmapRect.top() + 1));
+ } else {
+ path.moveTo(QPoint(pixmapRect.left() + 1, pixmapRect.top() + 1));
+ path.lineTo(QPoint(pixmapRect.left() + 10, pixmapRect.top() + 1));
+ path.lineTo(QPoint(pixmapRect.left() + 14, pixmapRect.top() + 5));
+ path.lineTo(QPoint(pixmapRect.left() + 10, pixmapRect.bottom()));
+ path.lineTo(QPoint(pixmapRect.left() + 1, pixmapRect.bottom()));
+ path.lineTo(QPoint(pixmapRect.left() + 1, pixmapRect.top() + 1));
+ }
+ if (slider->state & State_Enabled) {
+ QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
+ pixmapRect.center().x(), pixmapRect.bottom());
+ gradient.setColorAt(0, gradientStartColor);
+ gradient.setColorAt(1, gradientStopColor);
+ handlePainter.fillPath(path, gradient);
+ } else {
+ handlePainter.fillPath(path, slider->palette.background());
+ }
+ }
+
+ QImage image;
+ if (horizontal) {
+ image = QImage((ticksAbove && !ticksBelow) ? qt_plastique_slider_horizontalhandle_up : qt_plastique_slider_horizontalhandle);
+ } else {
+ image = QImage((ticksAbove && !ticksBelow) ? qt_plastique_slider_verticalhandle_left : qt_plastique_slider_verticalhandle);
+ }
+
+ image.setColor(1, borderColor.rgba());
+ image.setColor(2, gradientStartColor.rgba());
+ image.setColor(3, alphaCornerColor.rgba());
+ if (option->state & State_Enabled) {
+ image.setColor(4, 0x80ffffff);
+ image.setColor(5, 0x25000000);
+ }
+ handlePainter.drawImage(pixmapRect, image);
+ handlePainter.end();
+ QPixmapCache::insert(handlePixmapName, cache);
+ }
+
+ painter->drawPixmap(handle.topLeft(), cache);
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+
+ if (option->subControls & SC_SliderTickmarks) {
+ QPen oldPen = painter->pen();
+ painter->setPen(borderColor);
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+ if (interval <= 0) {
+ interval = slider->singleStep;
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+ if (interval <= 0)
+ interval = 1;
+
+ int v = slider->minimum;
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ QVarLengthArray<QLine, 32> lines;
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, (horizontal
+ ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown) + len / 2;
+
+ int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
+
+ if (horizontal) {
+ if (ticksAbove) {
+ lines.append(QLine(pos, slider->rect.top() + extra,
+ pos, slider->rect.top() + tickSize));
+ }
+ if (ticksBelow) {
+ lines.append(QLine(pos, slider->rect.bottom() - extra,
+ pos, slider->rect.bottom() - tickSize));
+ }
+ } else {
+ if (ticksAbove) {
+ lines.append(QLine(slider->rect.left() + extra, pos,
+ slider->rect.left() + tickSize, pos));
+ }
+ if (ticksBelow) {
+ lines.append(QLine(slider->rect.right() - extra, pos,
+ slider->rect.right() - tickSize, pos));
+ }
+ }
+
+ // in the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ painter->drawLines(lines.constData(), lines.size());
+ painter->setPen(oldPen);
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ painter->save();
+ bool upSunken = (spinBox->activeSubControls & SC_SpinBoxUp) && (spinBox->state & (State_Sunken | State_On));
+ bool downSunken = (spinBox->activeSubControls & SC_SpinBoxDown) && (spinBox->state & (State_Sunken | State_On));
+ bool reverse = (spinBox->direction == Qt::RightToLeft);
+
+ // Rects
+ QRect upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
+ QRect downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+ QRect buttonRect = upRect | downRect;
+
+ // Brushes
+ QBrush corner = qMapBrushToRect(option->palette.shadow(), buttonRect);
+ qBrushSetAlphaF(&corner, qreal(0.25));
+ QBrush border = qMapBrushToRect(option->palette.shadow(), buttonRect);
+ qBrushSetAlphaF(&border, qreal(0.4));
+
+ QVarLengthArray<QPoint, 4> points;
+
+ Q_D(const QPlastiqueStyle);
+ if (spinBox->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ QRect filledRect = option->rect.adjusted(1, 1, -1, -1);
+ QBrush baseBrush = qMapBrushToRect(option->palette.base(), filledRect);
+ painter->setBrushOrigin(filledRect.topLeft());
+ painter->fillRect(filledRect.adjusted(1, 1, -1, -1), baseBrush);
+ qt_plastique_draw_frame(painter, option->rect, option, QFrame::Sunken);
+ } else {
+ d->drawPartialFrame(painter,
+ option,
+ proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxEditField, widget),
+ widget);
+ }
+ // Paint buttons
+ if (spinBox->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ painter->restore();
+ break;
+ }
+ // Button outlines
+ painter->setPen(QPen(border, 0));
+ if (!reverse)
+ painter->drawLine(buttonRect.topLeft() + QPoint(0, 1), buttonRect.bottomLeft() + QPoint(0, -1));
+ else
+ painter->drawLine(buttonRect.topRight() + QPoint(0, -1), buttonRect.bottomRight() + QPoint(0, 1));
+
+ if (!reverse) {
+ const QLine lines[4] = {
+ QLine(upRect.left(), upRect.top(), upRect.right() - 2, upRect.top()),
+ QLine(upRect.left() + 1, upRect.bottom(), upRect.right() - 1, upRect.bottom()),
+ QLine(downRect.left(), downRect.bottom(), downRect.right() - 2, downRect.bottom()),
+ QLine(buttonRect.right(), buttonRect.top() + 2, buttonRect.right(), buttonRect.bottom() - 2) };
+ painter->drawLines(lines, 4);
+
+ points.append(QPoint(upRect.right() - 1, upRect.top() + 1));
+ points.append(QPoint(downRect.right() - 1, downRect.bottom() - 1));
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+ painter->setPen(QPen(corner, 0));
+ points.append(QPoint(upRect.right() - 1, upRect.top()));
+ points.append(QPoint(upRect.right(), upRect.top() + 1));
+ points.append(QPoint(upRect.right(), downRect.bottom() - 1));
+ points.append(QPoint(upRect.right() - 1, downRect.bottom()));
+ } else {
+ const QLine lines[4] = {
+ QLine(upRect.right(), upRect.top(), upRect.left() + 2, upRect.top()),
+ QLine(upRect.right() - 1, upRect.bottom(), upRect.left() + 1, upRect.bottom()),
+ QLine(downRect.right(), downRect.bottom(), downRect.left() + 2, downRect.bottom()),
+ QLine(buttonRect.left(), buttonRect.top() + 2, buttonRect.left(), buttonRect.bottom() - 2) };
+ painter->drawLines(lines, 4);
+
+ points.append(QPoint(upRect.left() + 1, upRect.top() + 1));
+ points.append(QPoint(downRect.left() + 1, downRect.bottom() - 1));
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+ painter->setPen(QPen(corner, 0));
+ points.append(QPoint(upRect.left() + 1, upRect.top()));
+ points.append(QPoint(upRect.left(), upRect.top() + 1));
+ points.append(QPoint(upRect.left(), downRect.bottom() - 1));
+ points.append(QPoint(upRect.left() + 1, downRect.bottom()));
+ }
+ painter->drawPoints(points.constData(), points.size());
+ points.clear();
+
+ // Button colors
+ QBrush buttonGradientBrush;
+ QBrush leftLineGradientBrush;
+ QBrush rightLineGradientBrush;
+ QBrush sunkenButtonGradientBrush;
+ QBrush sunkenLeftLineGradientBrush;
+ QBrush sunkenRightLineGradientBrush;
+ QBrush buttonBrush = qMapBrushToRect(option->palette.button(), buttonRect);
+ if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
+ buttonGradientBrush = buttonBrush;
+ sunkenButtonGradientBrush = qBrushDark(buttonBrush, 108);
+ leftLineGradientBrush = qBrushLight(buttonBrush, 105);
+ rightLineGradientBrush = qBrushDark(buttonBrush, 105);
+ sunkenLeftLineGradientBrush = qBrushDark(buttonBrush, 110);
+ sunkenRightLineGradientBrush = qBrushDark(buttonBrush, 106);
+ } else {
+ // Generate gradients
+ QLinearGradient buttonGradient(buttonRect.topLeft(), buttonRect.bottomLeft());
+ buttonGradient.setColorAt(0.0, buttonBrush.color().lighter(104));
+ buttonGradient.setColorAt(1.0, buttonBrush.color().darker(110));
+ buttonGradientBrush = QBrush(buttonGradient);
+
+ QLinearGradient buttonGradient2(buttonRect.topLeft(), buttonRect.bottomLeft());
+ buttonGradient2.setColorAt(0.0, buttonBrush.color().darker(113));
+ buttonGradient2.setColorAt(1.0, buttonBrush.color().darker(103));
+ sunkenButtonGradientBrush = QBrush(buttonGradient2);
+
+ QLinearGradient buttonGradient3(buttonRect.topLeft(), buttonRect.bottomLeft());
+ buttonGradient3.setColorAt(0.0, buttonBrush.color().lighter(105));
+ buttonGradient3.setColorAt(1.0, buttonBrush.color());
+ leftLineGradientBrush = QBrush(buttonGradient3);
+
+ QLinearGradient buttonGradient4(buttonRect.topLeft(), buttonRect.bottomLeft());
+ buttonGradient4.setColorAt(0.0, buttonBrush.color());
+ buttonGradient4.setColorAt(1.0, buttonBrush.color().darker(110));
+ rightLineGradientBrush = QBrush(buttonGradient4);
+
+ QLinearGradient buttonGradient5(buttonRect.topLeft(), buttonRect.bottomLeft());
+ buttonGradient5.setColorAt(0.0, buttonBrush.color().darker(113));
+ buttonGradient5.setColorAt(1.0, buttonBrush.color().darker(107));
+ sunkenLeftLineGradientBrush = QBrush(buttonGradient5);
+
+ QLinearGradient buttonGradient6(buttonRect.topLeft(), buttonRect.bottomLeft());
+ buttonGradient6.setColorAt(0.0, buttonBrush.color().darker(108));
+ buttonGradient6.setColorAt(1.0, buttonBrush.color().darker(103));
+ sunkenRightLineGradientBrush = QBrush(buttonGradient6);
+ }
+
+ // Main fill
+ painter->fillRect(upRect.adjusted(2, 2, -2, -2),
+ qMapBrushToRect(upSunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, upRect));
+ painter->fillRect(downRect.adjusted(2, 2, -2, -2),
+ qMapBrushToRect(downSunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, downRect));
+
+ // Top line
+ painter->setPen(QPen(qBrushLight(qMapBrushToRect(upSunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, upRect), 105), 0));
+ if (!reverse) {
+ painter->drawLine(upRect.left() + 1, upRect.top() + 1,
+ upRect.right() - 2, upRect.top() + 1);
+ } else {
+ painter->drawLine(upRect.right() - 1, upRect.top() + 1,
+ upRect.left() + 2, upRect.top() + 1);
+ }
+ painter->setPen(QPen(qBrushLight(qMapBrushToRect(downSunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, downRect), 105), 0));
+ if (!reverse) {
+ painter->drawLine(downRect.left() + 1, downRect.top() + 1,
+ downRect.right() - 1, downRect.top() + 1);
+ } else {
+ painter->drawLine(downRect.right() - 1, downRect.top() + 1,
+ downRect.left() + 1, downRect.top() + 1);
+ }
+
+ // Left line
+ painter->setPen(QPen(qMapBrushToRect(upSunken ? sunkenLeftLineGradientBrush
+ : leftLineGradientBrush, upRect), 1));
+ if (!reverse) {
+ painter->drawLine(upRect.left() + 1, upRect.top() + 2,
+ upRect.left() + 1, upRect.bottom() - 1);
+ } else {
+ painter->drawLine(upRect.left() + 1, upRect.top() + 2,
+ upRect.left() + 1, upRect.bottom() - 1);
+ }
+ painter->setPen(QPen(qMapBrushToRect(downSunken ? sunkenLeftLineGradientBrush
+ : leftLineGradientBrush, downRect), 1));
+ if (!reverse) {
+ painter->drawLine(downRect.left() + 1, downRect.top() + 2,
+ downRect.left() + 1, downRect.bottom() - 1);
+ } else {
+ painter->drawLine(downRect.left() + 1, downRect.top() + 1,
+ downRect.left() + 1, downRect.bottom() - 2);
+ }
+
+ // Bottom line
+ painter->setPen(QPen(qBrushDark(qMapBrushToRect(upSunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, upRect), 105), 0));
+ if (!reverse) {
+ painter->drawLine(upRect.left() + 2, upRect.bottom() - 1,
+ upRect.right() - 1, upRect.bottom() - 1);
+ } else {
+ painter->drawLine(upRect.right() - 2, upRect.bottom() - 1,
+ upRect.left() + 1, upRect.bottom() - 1);
+ }
+ painter->setPen(QPen(qBrushDark(qMapBrushToRect(downSunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, downRect), 105), 0));
+ if (!reverse) {
+ painter->drawLine(downRect.left() + 2, downRect.bottom() - 1,
+ downRect.right() - 2, downRect.bottom() - 1);
+ } else {
+ painter->drawLine(downRect.right() - 2, downRect.bottom() - 1,
+ downRect.left() + 2, downRect.bottom() - 1);
+ }
+
+ // Right line
+ painter->setPen(QPen(qMapBrushToRect(upSunken ? sunkenRightLineGradientBrush
+ : rightLineGradientBrush, upRect), 1));
+ if (!reverse) {
+ painter->drawLine(upRect.right() - 1, upRect.top() + 2,
+ upRect.right() - 1, upRect.bottom() - 1);
+ } else {
+ painter->drawLine(upRect.right() - 1, upRect.top() + 2,
+ upRect.right() - 1, upRect.bottom() - 1);
+ }
+ painter->setPen(QPen(qMapBrushToRect(downSunken ? sunkenRightLineGradientBrush
+ : rightLineGradientBrush, downRect), 1));
+ if (!reverse) {
+ painter->drawLine(downRect.right() - 1, downRect.top() + 1,
+ downRect.right() - 1, downRect.bottom() - 2);
+ } else {
+ painter->drawLine(downRect.right() - 1, downRect.top() + 2,
+ downRect.right() - 1, downRect.bottom() - 1);
+ }
+
+ QBrush indicatorBrush = qMapBrushToRect(option->palette.buttonText(), buttonRect);
+ painter->setPen(QPen(indicatorBrush, 0));
+ if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
+ QPoint center;
+ if (spinBox->subControls & SC_SpinBoxUp) {
+ // .......
+ // ...X...
+ // ...X...
+ // .XXXXX.
+ // ...X...
+ // ...X...
+ // .......
+ center = upRect.center();
+ if (upSunken) {
+ ++center.rx();
+ ++center.ry();
+ }
+ painter->drawLine(center.x(), center.y() - 2, center.x(), center.y() + 2);
+ painter->drawLine(center.x() - 2, center.y(), center.x() + 2, center.y());
+ }
+ if (spinBox->subControls & SC_SpinBoxDown) {
+ // .......
+ // .......
+ // .......
+ // .XXXXX.
+ // .......
+ // .......
+ // .......
+ center = downRect.center();
+ if (downSunken) {
+ ++center.rx();
+ ++center.ry();
+ }
+ painter->drawLine(center.x() - 2, center.y(), center.x() + 2, center.y());
+ }
+ } else {
+ int offset;
+ int centerX;
+ if (spinBox->subControls & SC_SpinBoxUp) {
+ // ...........
+ // .....X.....
+ // ....XXX....
+ // ...XXXXX...
+ // ..XXXXXXX..
+ // ...........
+ offset = upSunken ? 1 : 0;
+ QRect upArrowRect(upRect.center().x() - 3 + offset, upRect.center().y() - 2 + offset, 7, 4);
+ centerX = upArrowRect.center().x();
+ painter->drawPoint(centerX, upArrowRect.top());
+ const QLine lines[3] = {
+ QLine(centerX - 1, upArrowRect.top() + 1, centerX + 1, upArrowRect.top() + 1),
+ QLine(centerX - 2, upArrowRect.top() + 2, centerX + 2, upArrowRect.top() + 2),
+ QLine(centerX - 3, upArrowRect.top() + 3, centerX + 3, upArrowRect.top() + 3) };
+ painter->drawLines(lines, 3);
+ }
+ if (spinBox->subControls & SC_SpinBoxDown) {
+ // ...........
+ // ..XXXXXXX..
+ // ...XXXXX...
+ // ....XXX....
+ // .....X.....
+ // ...........
+ offset = downSunken ? 1 : 0;
+ QRect downArrowRect(downRect.center().x() - 3 + offset, downRect.center().y() - 2 + offset + 1, 7, 4);
+ centerX = downArrowRect.center().x();
+ const QLine lines[3] = {
+ QLine(centerX - 3, downArrowRect.top(), centerX + 3, downArrowRect.top()),
+ QLine(centerX - 2, downArrowRect.top() + 1, centerX + 2, downArrowRect.top() + 1),
+ QLine(centerX - 1, downArrowRect.top() + 2, centerX + 1, downArrowRect.top() + 2) };
+ painter->drawLines(lines, 3);
+ painter->drawPoint(centerX, downArrowRect.top() + 3);
+ }
+ }
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ bool sunken = comboBox->state & State_On; // play dead if combobox has no items
+ bool reverse = comboBox->direction == Qt::RightToLeft;
+ int menuButtonWidth = 16;
+ int xoffset = sunken ? (reverse ? -1 : 1) : 0;
+ int yoffset = sunken ? 1 : 0;
+ QRect rect = comboBox->rect;
+ QPen oldPen = painter->pen();
+
+ // Fill
+ if (comboBox->editable) {
+ // Button colors
+ QBrush alphaCornerBrush = qBrushDark(option->palette.button(), 165);
+ qBrushSetAlphaF(&alphaCornerBrush, 0.5);
+ QBrush buttonGradientBrush;
+ QBrush leftLineGradientBrush;
+ QBrush rightLineGradientBrush;
+ QBrush sunkenButtonGradientBrush;
+ QBrush sunkenLeftLineGradientBrush;
+ QBrush sunkenRightLineGradientBrush;
+ QBrush button = option->palette.button();
+ if (button.gradient() || !button.texture().isNull()) {
+ buttonGradientBrush = button;
+ sunkenButtonGradientBrush = qBrushDark(button, 108);
+ leftLineGradientBrush = qBrushLight(button, 105);
+ rightLineGradientBrush = qBrushDark(button, 105);
+ sunkenLeftLineGradientBrush = qBrushDark(button, 110);
+ sunkenRightLineGradientBrush = qBrushDark(button, 106);
+ } else {
+ // Generate gradients
+ QLinearGradient buttonGradient(option->rect.topLeft(), option->rect.bottomLeft());
+ buttonGradient.setColorAt(0.0, button.color().lighter(104));
+ buttonGradient.setColorAt(1.0, button.color().darker(110));
+ buttonGradientBrush = QBrush(buttonGradient);
+
+ QLinearGradient buttonGradient2(option->rect.topLeft(), option->rect.bottomLeft());
+ buttonGradient2.setColorAt(0.0, button.color().darker(113));
+ buttonGradient2.setColorAt(1.0, button.color().darker(103));
+ sunkenButtonGradientBrush = QBrush(buttonGradient2);
+
+ QLinearGradient buttonGradient3(option->rect.topLeft(), option->rect.bottomLeft());
+ buttonGradient3.setColorAt(0.0, button.color().lighter(105));
+ buttonGradient3.setColorAt(1.0, button.color());
+ leftLineGradientBrush = QBrush(buttonGradient3);
+
+ QLinearGradient buttonGradient4(option->rect.topLeft(), option->rect.bottomLeft());
+ buttonGradient4.setColorAt(0.0, button.color());
+ buttonGradient4.setColorAt(1.0, button.color().darker(110));
+ rightLineGradientBrush = QBrush(buttonGradient4);
+
+ QLinearGradient buttonGradient5(option->rect.topLeft(), option->rect.bottomLeft());
+ buttonGradient5.setColorAt(0.0, button.color().darker(113));
+ buttonGradient5.setColorAt(1.0, button.color().darker(107));
+ sunkenLeftLineGradientBrush = QBrush(buttonGradient5);
+
+ QLinearGradient buttonGradient6(option->rect.topLeft(), option->rect.bottomLeft());
+ buttonGradient6.setColorAt(0.0, button.color().darker(108));
+ buttonGradient6.setColorAt(1.0, button.color().darker(103));
+ sunkenRightLineGradientBrush = QBrush(buttonGradient6);
+ }
+
+ // ComboBox starts with a lineedit in place already.
+ QRect buttonRect;
+ if (!reverse) {
+ buttonRect.setRect(rect.right() - menuButtonWidth, rect.top(), menuButtonWidth + 1, rect.height());
+ } else {
+ buttonRect.setRect(rect.left(), rect.top(), menuButtonWidth + 1, rect.height());
+ }
+
+ Q_D(const QPlastiqueStyle);
+ d->drawPartialFrame(painter,
+ option,
+ proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget),
+ widget);
+
+ QBrush border = qMapBrushToRect(option->palette.shadow(), buttonRect);
+ qBrushSetAlphaF(&border, qreal(0.4));
+ painter->setPen(QPen(border, 0));
+ if (!reverse)
+ painter->drawLine(buttonRect.topLeft() + QPoint(0, 1), buttonRect.bottomLeft() + QPoint(0, -1));
+ else
+ painter->drawLine(buttonRect.topRight() + QPoint(0, -1), buttonRect.bottomRight() + QPoint(0, 1));
+
+ // Outline the button border
+ if (!reverse) {
+ const QLine lines[3] = {
+ QLine(buttonRect.left(), buttonRect.top(),
+ buttonRect.right() - 2, buttonRect.top()),
+ QLine(buttonRect.right(), buttonRect.top() + 2,
+ buttonRect.right(), buttonRect.bottom() - 2),
+ QLine(buttonRect.left(), buttonRect.bottom(),
+ buttonRect.right() - 2, buttonRect.bottom()) };
+ painter->drawLines(lines, 3);
+ {
+ const QPoint points[2] = {
+ QPoint(buttonRect.right() - 1, buttonRect.top() + 1),
+ QPoint(buttonRect.right() - 1, buttonRect.bottom() - 1) };
+ painter->drawPoints(points, 2);
+ }
+
+ QBrush corner = qMapBrushToRect(option->palette.shadow(), buttonRect);
+ qBrushSetAlphaF(&corner, qreal(0.16));
+ painter->setPen(QPen(corner, 0));
+ {
+ const QPoint points[4] = {
+ QPoint(buttonRect.right() - 1, buttonRect.top()),
+ QPoint(buttonRect.right() - 1, buttonRect.bottom()),
+ QPoint(buttonRect.right(), buttonRect.top() + 1),
+ QPoint(buttonRect.right(), buttonRect.bottom() - 1) };
+ painter->drawPoints(points, 4);
+ }
+ } else {
+ const QLine lines[3] = {
+ QLine(buttonRect.right(), buttonRect.top(),
+ buttonRect.left() + 2, buttonRect.top()),
+ QLine(buttonRect.left(), buttonRect.top() + 2,
+ buttonRect.left(), buttonRect.bottom() - 2),
+ QLine(buttonRect.right(), buttonRect.bottom(),
+ buttonRect.left() + 2, buttonRect.bottom()) };
+ painter->drawLines(lines, 3);
+ {
+ const QPoint points[2] = {
+ QPoint(buttonRect.left() + 1, buttonRect.top() + 1),
+ QPoint(buttonRect.left() + 1, buttonRect.bottom() - 1) };
+ painter->drawPoints(points, 2);
+ }
+
+ QBrush corner = qMapBrushToRect(option->palette.shadow(), buttonRect);
+ qBrushSetAlphaF(&corner, qreal(0.16));
+ painter->setPen(QPen(corner, 0));
+ {
+ const QPoint points[4] = {
+ QPoint(buttonRect.left() + 1, buttonRect.top()),
+ QPoint(buttonRect.left() + 1, buttonRect.bottom()),
+ QPoint(buttonRect.left(), buttonRect.top() + 1),
+ QPoint(buttonRect.left(), buttonRect.bottom() - 1) };
+ painter->drawPoints(points, 4);
+ }
+ }
+
+ QRect fillRect = buttonRect.adjusted(2, 2, -2, -2);
+ // Main fill
+ painter->fillRect(fillRect,
+ qMapBrushToRect(sunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, option->rect));
+
+ // Top line
+ painter->setPen(QPen(qBrushLight(qMapBrushToRect(sunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, option->rect), 105), 0));
+ if (!reverse) {
+ painter->drawLine(QPointF(buttonRect.left() + 1, buttonRect.top() + 1),
+ QPointF(buttonRect.right() - 2, buttonRect.top() + 1));
+ } else {
+ painter->drawLine(QPointF(buttonRect.right() - 1, buttonRect.top() + 1),
+ QPointF(buttonRect.left() + 2, buttonRect.top() + 1));
+ }
+
+ // Bottom line
+ painter->setPen(QPen(qBrushDark(qMapBrushToRect(sunken ? sunkenButtonGradientBrush
+ : buttonGradientBrush, option->rect), 105), 0));
+ if (!reverse) {
+ painter->drawLine(QPointF(buttonRect.left() + 1, buttonRect.bottom() - 1),
+ QPointF(buttonRect.right() - 2, buttonRect.bottom() - 1));
+ } else {
+ painter->drawLine(QPointF(buttonRect.right() - 1, buttonRect.bottom() - 1),
+ QPointF(buttonRect.left() + 2, buttonRect.bottom() - 1));
+ }
+
+ // Left line
+ painter->setPen(QPen(qMapBrushToRect(sunken ? sunkenLeftLineGradientBrush
+ : leftLineGradientBrush, option->rect), 1));
+ if (!reverse) {
+ painter->drawLine(QPointF(buttonRect.left() + 1, buttonRect.top() + 2),
+ QPointF(buttonRect.left() + 1, buttonRect.bottom() - 2));
+ } else {
+ painter->drawLine(QPointF(buttonRect.left() + 1, buttonRect.top() + 2),
+ QPointF(buttonRect.left() + 1, buttonRect.bottom() - 2));
+ }
+
+ // Right line
+ painter->setPen(QPen(qMapBrushToRect(sunken ? sunkenRightLineGradientBrush
+ : rightLineGradientBrush, option->rect), 1));
+ if (!reverse) {
+ painter->drawLine(QPointF(buttonRect.right() - 1, buttonRect.top() + 2),
+ QPointF(buttonRect.right() - 1, buttonRect.bottom() - 2));
+ } else {
+ painter->drawLine(QPointF(buttonRect.right() - 1, buttonRect.top() + 2),
+ QPointF(buttonRect.right() - 1, buttonRect.bottom() - 2));
+ }
+ } else {
+ // Start with a standard panel button fill
+ QStyleOptionButton buttonOption;
+ buttonOption.QStyleOption::operator=(*comboBox);
+ if (!sunken) {
+ buttonOption.state &= ~State_Sunken;
+ }
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget);
+
+ // Draw the menu button separator line
+ QBrush border = qMapBrushToRect(option->palette.shadow(), rect);
+ qBrushSetAlphaF(&border, qreal(0.35));
+ painter->setPen(QPen(border, 0));
+ if (!reverse) {
+ painter->drawLine(rect.right() - menuButtonWidth + xoffset, rect.top() + 1,
+ rect.right() - menuButtonWidth + xoffset, rect.bottom() - 1);
+ } else {
+ painter->drawLine(rect.left() + menuButtonWidth + xoffset, rect.top() + 1,
+ rect.left() + menuButtonWidth + xoffset, rect.bottom() - 1);
+ }
+ }
+
+ // Draw the little arrow
+ if (comboBox->subControls & SC_ComboBoxArrow) {
+ int left = !reverse ? rect.right() - menuButtonWidth : rect.left();
+ int right = !reverse ? rect.right() : rect.left() + menuButtonWidth;
+ QRect arrowRect((left + right) / 2 - 3 + xoffset,
+ rect.center().y() - 1 + yoffset, 7, 4);
+ painter->setPen(QPen(qMapBrushToRect(option->palette.buttonText(), rect), 0));
+ const QLine lines[3] = {
+ QLine(arrowRect.topLeft(), arrowRect.topRight()),
+ QLine(arrowRect.left() + 1, arrowRect.top() + 1,
+ arrowRect.right() - 1, arrowRect.top() + 1),
+ QLine(arrowRect.left() + 2, arrowRect.top() + 2,
+ arrowRect.right() - 2, arrowRect.top() + 2) };
+ painter->drawLines(lines, 3);
+ painter->drawPoint(arrowRect.center().x(), arrowRect.bottom());
+ }
+
+ // Draw the focus rect
+ if ((option->state & State_HasFocus) && !comboBox->editable
+ && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget))) {
+ QStyleOptionFocusRect focus;
+ focus.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget)
+ .adjusted(-2, 0, 2, 0);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, painter, widget);
+ }
+
+ painter->setPen(oldPen);
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ painter->save();
+ bool active = (titleBar->titleBarState & State_Active);
+ QRect fullRect = titleBar->rect;
+
+ // ### use palette colors instead
+ QColor titleBarGradientStart(active ? 0x3b508a : 0x6e6e6e);
+ QColor titleBarGradientStop(active ? 0x5d6e9e : 0x818181);
+ QColor titleBarFrameBorder(0x393939);
+ QColor titleBarAlphaCorner(active ? 0x4b5e7f : 0x6a6a6a);
+ QColor titleBarInnerTopLine(active ? 0x8e98ba : 0xa4a4a4);
+ QColor titleBarInnerInnerTopLine(active ? 0x57699b : 0x808080);
+ QColor leftCorner(active ? 0x6f7ea8 : 0x8e8e8e);
+ QColor rightCorner(active ? 0x44537d : 0x676767);
+ QColor textColor(active ? 0x282e40 : 0x282e40);
+ QColor textAlphaColor(active ? 0x3f4862 : 0x3f4862);
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ QStyleOptionDockWidgetV2 dockwidget;
+ dockwidget.QStyleOption::operator=(*option);
+ dockwidget.title = titleBar->text;
+ proxy()->drawControl(CE_DockWidgetTitle, &dockwidget, painter, widget);
+ } else
+#endif // QT3_SUPPORT
+
+ {
+ // Fill title bar gradient
+ qt_plastique_draw_gradient(painter, option->rect.adjusted(1, 1, -1, 0),
+ titleBarGradientStart,
+ titleBarGradientStop);
+
+ // Frame and rounded corners
+ painter->setPen(titleBarFrameBorder);
+
+ // top border line
+ {
+ const QLine lines[3] = {
+ QLine(fullRect.left() + 2, fullRect.top(), fullRect.right() - 2, fullRect.top()),
+ QLine(fullRect.left(), fullRect.top() + 2, fullRect.left(), fullRect.bottom()),
+ QLine(fullRect.right(), fullRect.top() + 2, fullRect.right(), fullRect.bottom()) };
+ painter->drawLines(lines, 3);
+ const QPoint points[2] = {
+ QPoint(fullRect.left() + 1, fullRect.top() + 1),
+ QPoint(fullRect.right() - 1, fullRect.top() + 1) };
+ painter->drawPoints(points, 2);
+ }
+
+ // alpha corners
+ painter->setPen(titleBarAlphaCorner);
+ {
+ const QPoint points[4] = {
+ QPoint(fullRect.left() + 2, fullRect.top() + 1),
+ QPoint(fullRect.left() + 1, fullRect.top() + 2),
+ QPoint(fullRect.right() - 2, fullRect.top() + 1),
+ QPoint(fullRect.right() - 1, fullRect.top() + 2) };
+ painter->drawPoints(points, 4);
+ }
+
+ // inner top line
+ painter->setPen(titleBarInnerTopLine);
+ painter->drawLine(fullRect.left() + 3, fullRect.top() + 1, fullRect.right() - 3, fullRect.top() + 1);
+
+ // inner inner top line
+ painter->setPen(titleBarInnerInnerTopLine);
+ painter->drawLine(fullRect.left() + 2, fullRect.top() + 2, fullRect.right() - 2, fullRect.top() + 2);
+
+ // left and right inner
+ painter->setPen(leftCorner);
+ painter->drawLine(fullRect.left() + 1, fullRect.top() + 3, fullRect.left() + 1, fullRect.bottom());
+ painter->setPen(rightCorner);
+ painter->drawLine(fullRect.right() - 1, fullRect.top() + 3, fullRect.right() - 1, fullRect.bottom());
+
+ if (titleBar->titleBarState & Qt::WindowMinimized) {
+ painter->setPen(titleBarFrameBorder);
+ painter->drawLine(fullRect.left() + 2, fullRect.bottom(), fullRect.right() - 2, fullRect.bottom());
+ {
+ const QPoint points[2] = {
+ QPoint(fullRect.left() + 1, fullRect.bottom() - 1),
+ QPoint(fullRect.right() - 1, fullRect.bottom() - 1) };
+ painter->drawPoints(points, 2);
+ }
+ painter->setPen(rightCorner);
+ painter->drawLine(fullRect.left() + 2, fullRect.bottom() - 1, fullRect.right() - 2, fullRect.bottom() - 1);
+ painter->setPen(titleBarAlphaCorner);
+ {
+ const QPoint points[4] = {
+ QPoint(fullRect.left() + 1, fullRect.bottom() - 2),
+ QPoint(fullRect.left() + 2, fullRect.bottom() - 1),
+ QPoint(fullRect.right() - 1, fullRect.bottom() - 2),
+ QPoint(fullRect.right() - 2, fullRect.bottom() - 1) };
+ painter->drawPoints(points, 4);
+ }
+ }
+ // draw title
+ QRect textRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget);
+
+ QFont font = painter->font();
+ font.setBold(true);
+ painter->setFont(font);
+ painter->setPen(titleBar->palette.text().color());
+
+ // Attempt to align left if there is not enough room for the title
+ // text. Otherwise, align center. QWorkspace does elliding for us,
+ // and it doesn't know about the bold title, so we need to work
+ // around some of the width mismatches.
+ bool tooWide = (QFontMetrics(font).width(titleBar->text) > textRect.width());
+ QTextOption option((tooWide ? Qt::AlignLeft : Qt::AlignHCenter) | Qt::AlignVCenter);
+ option.setWrapMode(QTextOption::NoWrap);
+
+ painter->drawText(textRect.adjusted(1, 1, 1, 1), titleBar->text, option);
+ painter->setPen(titleBar->palette.highlightedText().color());
+ painter->drawText(textRect, titleBar->text, option);
+ }
+
+ // min button
+ if ((titleBar->subControls & SC_TitleBarMinButton)
+ && (titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ && !(titleBar->titleBarState & Qt::WindowMinimized)) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_Sunken);
+
+ QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMinButton, widget);
+ qt_plastique_draw_mdibutton(painter, titleBar, minButtonRect, hover, sunken);
+
+ int xoffset = minButtonRect.width() / 3;
+ int yoffset = minButtonRect.height() / 3;
+
+ QRect minButtonIconRect(minButtonRect.left() + xoffset, minButtonRect.top() + yoffset,
+ minButtonRect.width() - xoffset * 2, minButtonRect.height() - yoffset * 2);
+
+ painter->setPen(textColor);
+ {
+ const QLine lines[2] = {
+ QLine(minButtonIconRect.center().x() - 2,
+ minButtonIconRect.center().y() + 3,
+ minButtonIconRect.center().x() + 3,
+ minButtonIconRect.center().y() + 3),
+ QLine(minButtonIconRect.center().x() - 2,
+ minButtonIconRect.center().y() + 4,
+ minButtonIconRect.center().x() + 3,
+ minButtonIconRect.center().y() + 4) };
+ painter->drawLines(lines, 2);
+ }
+ painter->setPen(textAlphaColor);
+ {
+ const QLine lines[2] = {
+ QLine(minButtonIconRect.center().x() - 3,
+ minButtonIconRect.center().y() + 3,
+ minButtonIconRect.center().x() - 3,
+ minButtonIconRect.center().y() + 4),
+ QLine(minButtonIconRect.center().x() + 4,
+ minButtonIconRect.center().y() + 3,
+ minButtonIconRect.center().x() + 4,
+ minButtonIconRect.center().y() + 4) };
+ painter->drawLines(lines, 2);
+ }
+ }
+
+ // max button
+ if ((titleBar->subControls & SC_TitleBarMaxButton)
+ && (titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ && !(titleBar->titleBarState & Qt::WindowMaximized)) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_Sunken);
+
+ QRect maxButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMaxButton, widget);
+ qt_plastique_draw_mdibutton(painter, titleBar, maxButtonRect, hover, sunken);
+
+ int xoffset = maxButtonRect.width() / 3;
+ int yoffset = maxButtonRect.height() / 3;
+
+ QRect maxButtonIconRect(maxButtonRect.left() + xoffset, maxButtonRect.top() + yoffset,
+ maxButtonRect.width() - xoffset * 2, maxButtonRect.height() - yoffset * 2);
+
+ painter->setPen(textColor);
+ painter->drawRect(maxButtonIconRect.adjusted(0, 0, -1, -1));
+ painter->drawLine(maxButtonIconRect.left() + 1, maxButtonIconRect.top() + 1,
+ maxButtonIconRect.right() - 1, maxButtonIconRect.top() + 1);
+ painter->setPen(textAlphaColor);
+ const QPoint points[4] = {
+ maxButtonIconRect.topLeft(), maxButtonIconRect.topRight(),
+ maxButtonIconRect.bottomLeft(), maxButtonIconRect.bottomRight() };
+ painter->drawPoints(points, 4);
+ }
+
+ // close button
+ if (titleBar->subControls & SC_TitleBarCloseButton && titleBar->titleBarFlags & Qt::WindowSystemMenuHint) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_Sunken);
+
+ QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarCloseButton, widget);
+ qt_plastique_draw_mdibutton(painter, titleBar, closeButtonRect, hover, sunken);
+
+ int xoffset = closeButtonRect.width() / 3;
+ int yoffset = closeButtonRect.height() / 3;
+
+ QRect closeIconRect(closeButtonRect.left() + xoffset, closeButtonRect.top() + yoffset,
+ closeButtonRect.width() - xoffset * 2, closeButtonRect.height() - yoffset * 2);
+
+ painter->setPen(textAlphaColor);
+ {
+ const QLine lines[4] = {
+ QLine(closeIconRect.left() + 1, closeIconRect.top(),
+ closeIconRect.right(), closeIconRect.bottom() - 1),
+ QLine(closeIconRect.left(), closeIconRect.top() + 1,
+ closeIconRect.right() - 1, closeIconRect.bottom()),
+ QLine(closeIconRect.right() - 1, closeIconRect.top(),
+ closeIconRect.left(), closeIconRect.bottom() - 1),
+ QLine(closeIconRect.right(), closeIconRect.top() + 1,
+ closeIconRect.left() + 1, closeIconRect.bottom()) };
+ painter->drawLines(lines, 4);
+ const QPoint points[4] = {
+ closeIconRect.topLeft(), closeIconRect.topRight(),
+ closeIconRect.bottomLeft(), closeIconRect.bottomRight() };
+ painter->drawPoints(points, 4);
+ }
+ painter->setPen(textColor);
+ {
+ const QLine lines[2] = {
+ QLine(closeIconRect.left() + 1, closeIconRect.top() + 1,
+ closeIconRect.right() - 1, closeIconRect.bottom() - 1),
+ QLine(closeIconRect.left() + 1, closeIconRect.bottom() - 1,
+ closeIconRect.right() - 1, closeIconRect.top() + 1) };
+ painter->drawLines(lines, 2);
+ }
+ }
+
+ // normalize button
+ if ((titleBar->subControls & SC_TitleBarNormalButton) &&
+ (((titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
+ (titleBar->titleBarState & Qt::WindowMinimized)) ||
+ ((titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
+ (titleBar->titleBarState & Qt::WindowMaximized)))) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_Sunken);
+
+ QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarNormalButton, widget);
+ qt_plastique_draw_mdibutton(painter, titleBar, normalButtonRect, hover, sunken);
+ int xoffset = int(normalButtonRect.width() / 3.5);
+ int yoffset = int(normalButtonRect.height() / 3.5);
+
+ QRect normalButtonIconRect(normalButtonRect.left() + xoffset, normalButtonRect.top() + yoffset,
+ normalButtonRect.width() - xoffset * 2, normalButtonRect.height() - yoffset * 2);
+
+ QRect frontWindowRect = normalButtonIconRect.adjusted(0, 3, -3, 0);
+ painter->setPen(textColor);
+ painter->drawRect(frontWindowRect.adjusted(0, 0, -1, -1));
+ painter->drawLine(frontWindowRect.left() + 1, frontWindowRect.top() + 1,
+ frontWindowRect.right() - 1, frontWindowRect.top() + 1);
+ painter->setPen(textAlphaColor);
+ {
+ const QPoint points[4] = {
+ frontWindowRect.topLeft(), frontWindowRect.topRight(),
+ frontWindowRect.bottomLeft(), frontWindowRect.bottomRight() };
+ painter->drawPoints(points, 4);
+ }
+
+ QRect backWindowRect = normalButtonIconRect.adjusted(3, 0, 0, -3);
+ QRegion clipRegion = backWindowRect;
+ clipRegion -= frontWindowRect;
+ painter->save();
+ painter->setClipRegion(clipRegion);
+ painter->setPen(textColor);
+ painter->drawRect(backWindowRect.adjusted(0, 0, -1, -1));
+ painter->drawLine(backWindowRect.left() + 1, backWindowRect.top() + 1,
+ backWindowRect.right() - 1, backWindowRect.top() + 1);
+ painter->setPen(textAlphaColor);
+ {
+ const QPoint points[4] = {
+ backWindowRect.topLeft(), backWindowRect.topRight(),
+ backWindowRect.bottomLeft(), backWindowRect.bottomRight() };
+ painter->drawPoints(points, 4);
+ }
+ painter->restore();
+ }
+
+ // context help button
+ if (titleBar->subControls & SC_TitleBarContextHelpButton
+ && (titleBar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken);
+
+ QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarContextHelpButton, widget);
+
+ qt_plastique_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken);
+
+ QColor blend;
+ // ### Use palette colors
+ if (active) {
+ blend = mergedColors(QColor(hover ? 0x7d8bb1 : 0x55689a),
+ QColor(hover ? 0x939ebe : 0x7381ab));
+ } else {
+ blend = mergedColors(QColor(hover ? 0x9e9e9e : 0x818181),
+ QColor(hover ? 0xababab : 0x929292));
+ }
+ QImage image(qt_titlebar_context_help);
+ image.setColor(4, textColor.rgba());
+ image.setColor(3, mergedColors(blend, textColor, 30).rgba());
+ image.setColor(2, mergedColors(blend, textColor, 70).rgba());
+ image.setColor(1, mergedColors(blend, textColor, 90).rgba());
+
+ painter->drawImage(contextHelpButtonRect, image);
+ }
+
+ // shade button
+ if (titleBar->subControls & SC_TitleBarShadeButton) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
+
+ QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarShadeButton, widget);
+ qt_plastique_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
+
+ int xoffset = shadeButtonRect.width() / 3;
+ int yoffset = shadeButtonRect.height() / 3;
+
+ QRect shadeButtonIconRect(shadeButtonRect.left() + xoffset, shadeButtonRect.top() + yoffset,
+ shadeButtonRect.width() - xoffset * 2, shadeButtonRect.height() - yoffset * 2);
+
+ QPainterPath path(shadeButtonIconRect.bottomLeft());
+ path.lineTo(shadeButtonIconRect.center().x(), shadeButtonIconRect.bottom() - shadeButtonIconRect.height() / 2);
+ path.lineTo(shadeButtonIconRect.bottomRight());
+ path.lineTo(shadeButtonIconRect.bottomLeft());
+
+ painter->setPen(textAlphaColor);
+ painter->setBrush(textColor);
+ painter->drawPath(path);
+ }
+
+ // unshade button
+ if (titleBar->subControls & SC_TitleBarUnshadeButton) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
+
+ QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarUnshadeButton, widget);
+ qt_plastique_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
+
+ int xoffset = unshadeButtonRect.width() / 3;
+ int yoffset = unshadeButtonRect.height() / 3;
+
+ QRect unshadeButtonIconRect(unshadeButtonRect.left() + xoffset, unshadeButtonRect.top() + yoffset,
+ unshadeButtonRect.width() - xoffset * 2, unshadeButtonRect.height() - yoffset * 2);
+
+ int midY = unshadeButtonIconRect.bottom() - unshadeButtonIconRect.height() / 2;
+ QPainterPath path(QPoint(unshadeButtonIconRect.left(), midY));
+ path.lineTo(unshadeButtonIconRect.right(), midY);
+ path.lineTo(unshadeButtonIconRect.center().x(), unshadeButtonIconRect.bottom());
+ path.lineTo(unshadeButtonIconRect.left(), midY);
+
+ painter->setPen(textAlphaColor);
+ painter->setBrush(textColor);
+ painter->drawPath(path);
+ }
+
+ // from qwindowsstyle.cpp
+ if ((titleBar->subControls & SC_TitleBarSysMenu) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
+ bool hover = (titleBar->activeSubControls & SC_TitleBarSysMenu) && (titleBar->state & State_MouseOver);
+ bool sunken = (titleBar->activeSubControls & SC_TitleBarSysMenu) && (titleBar->state & State_Sunken);
+
+ QRect iconRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget);
+ if (hover)
+ qt_plastique_draw_mdibutton(painter, titleBar, iconRect, hover, sunken);
+
+ if (!titleBar->icon.isNull()) {
+ titleBar->icon.paint(painter, iconRect);
+ } else {
+ QStyleOption tool(0);
+ tool.palette = titleBar->palette;
+ QPixmap pm = standardPixmap(SP_TitleBarMenuButton, &tool, widget);
+ tool.rect = iconRect;
+ painter->save();
+ proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
+ painter->restore();
+ }
+ }
+ painter->restore();
+ }
+ break;
+#ifndef QT_NO_DIAL
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ QStyleHelper::drawDial(dial, painter);
+ break;
+#endif // QT_NO_DIAL
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+QSize QPlastiqueStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+
+ switch (type) {
+ case CT_RadioButton:
+ ++newSize.rheight();
+ ++newSize.rwidth();
+ break;
+#ifndef QT_NO_SLIDER
+ case CT_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+ if (slider->tickPosition & QSlider::TicksBelow) {
+ if (slider->orientation == Qt::Horizontal)
+ newSize.rheight() += tickSize;
+ else
+ newSize.rwidth() += tickSize;
+ }
+ if (slider->tickPosition & QSlider::TicksAbove) {
+ if (slider->orientation == Qt::Horizontal)
+ newSize.rheight() += tickSize;
+ else
+ newSize.rwidth() += tickSize;
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CT_ScrollBar:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int scrollBarExtent = proxy()->pixelMetric(PM_ScrollBarExtent, option, widget);
+ int scrollBarSliderMinimum = proxy()->pixelMetric(PM_ScrollBarSliderMin, option, widget);
+ if (scrollBar->orientation == Qt::Horizontal) {
+ newSize = QSize(scrollBarExtent * 3 + scrollBarSliderMinimum, scrollBarExtent);
+ } else {
+ newSize = QSize(scrollBarExtent, scrollBarExtent * 3 + scrollBarSliderMinimum);
+ }
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_SPINBOX
+ case CT_SpinBox:
+ // Make sure the size is odd
+ newSize.setHeight(sizeFromContents(CT_LineEdit, option, size, widget).height());
+ newSize.rheight() -= ((1 - newSize.rheight()) & 1);
+ break;
+#endif
+#ifndef QT_NO_TOOLBUTTON
+ case CT_ToolButton:
+ newSize.rheight() += 3;
+ newSize.rwidth() += 3;
+ break;
+#endif
+#ifndef QT_NO_COMBOBOX
+ case CT_ComboBox:
+ newSize = sizeFromContents(CT_PushButton, option, size, widget);
+ newSize.rwidth() += 30; // Make room for drop-down indicator
+ newSize.rheight() += 4;
+ break;
+#endif
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator)
+ newSize.setHeight(menuItem->text.isEmpty() ? 2 : menuItem->fontMetrics.height());
+ }
+ break;
+ case CT_MenuBarItem:
+ newSize.setHeight(newSize.height());
+ break;
+ default:
+ break;
+ }
+
+ return newSize;
+}
+
+/*!
+ \reimp
+*/
+QRect QPlastiqueStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ QRect rect;
+ switch (element) {
+ case SE_RadioButtonIndicator:
+ rect = visualRect(option->direction, option->rect,
+ QWindowsStyle::subElementRect(element, option, widget)).adjusted(0, 0, 1, 1);
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case SE_ProgressBarLabel:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarGroove:
+ return option->rect;
+#endif // QT_NO_PROGRESSBAR
+ default:
+ return QWindowsStyle::subElementRect(element, option, widget);
+ }
+
+ return visualRect(option->direction, option->rect, rect);
+}
+
+/*!
+ \reimp
+*/
+QRect QPlastiqueStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+
+ switch (control) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+
+ switch (subControl) {
+ case SC_SliderHandle:
+ if (slider->orientation == Qt::Horizontal) {
+ rect.setWidth(11);
+ rect.setHeight(15);
+ int centerY = slider->rect.center().y() - rect.height() / 2;
+ if (slider->tickPosition & QSlider::TicksAbove)
+ centerY += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ centerY -= tickSize;
+ rect.moveTop(centerY);
+ } else {
+ rect.setWidth(15);
+ rect.setHeight(11);
+ int centerX = slider->rect.center().x() - rect.width() / 2;
+ if (slider->tickPosition & QSlider::TicksAbove)
+ centerX += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ centerX -= tickSize;
+ rect.moveLeft(centerX);
+ }
+ break;
+ case SC_SliderGroove: {
+ QPoint grooveCenter = slider->rect.center();
+ if (slider->orientation == Qt::Horizontal) {
+ rect.setHeight(14);
+ --grooveCenter.ry();
+ if (slider->tickPosition & QSlider::TicksAbove)
+ grooveCenter.ry() += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ grooveCenter.ry() -= tickSize;
+ } else {
+ rect.setWidth(14);
+ --grooveCenter.rx();
+ if (slider->tickPosition & QSlider::TicksAbove)
+ grooveCenter.rx() += tickSize;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ grooveCenter.rx() -= tickSize;
+ }
+ rect.moveCenter(grooveCenter);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int scrollBarExtent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollBar, widget);
+ int sliderMaxLength = ((scrollBar->orientation == Qt::Horizontal) ?
+ scrollBar->rect.width() : scrollBar->rect.height()) - (scrollBarExtent * 3);
+ int sliderMinLength = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollBar, widget);
+ int sliderLength;
+
+ // calculate slider length
+ if (scrollBar->maximum != scrollBar->minimum) {
+ uint valueRange = scrollBar->maximum - scrollBar->minimum;
+ sliderLength = (scrollBar->pageStep * sliderMaxLength) / (valueRange + scrollBar->pageStep);
+
+ if (sliderLength < sliderMinLength || valueRange > INT_MAX / 2)
+ sliderLength = sliderMinLength;
+ if (sliderLength > sliderMaxLength)
+ sliderLength = sliderMaxLength;
+ } else {
+ sliderLength = sliderMaxLength;
+ }
+
+ int sliderStart = scrollBarExtent + sliderPositionFromValue(scrollBar->minimum,
+ scrollBar->maximum,
+ scrollBar->sliderPosition,
+ sliderMaxLength - sliderLength,
+ scrollBar->upsideDown);
+
+ QRect scrollBarRect = scrollBar->rect;
+
+ switch (subControl) {
+ case SC_ScrollBarSubLine: // top/left button
+ if (scrollBar->orientation == Qt::Horizontal) {
+ rect.setRect(scrollBarRect.left(), scrollBarRect.top(), scrollBarRect.width() - scrollBarExtent, scrollBarRect.height());
+ } else {
+ rect.setRect(scrollBarRect.left(), scrollBarRect.top(), scrollBarRect.width(), scrollBarRect.height() - scrollBarExtent);
+ }
+ break;
+ case SC_ScrollBarAddLine: // bottom/right button
+ if (scrollBar->orientation == Qt::Horizontal) {
+ rect.setRect(scrollBarRect.right() - (scrollBarExtent - 1), scrollBarRect.top(), scrollBarExtent, scrollBarRect.height());
+ } else {
+ rect.setRect(scrollBarRect.left(), scrollBarRect.bottom() - (scrollBarExtent - 1), scrollBarRect.width(), scrollBarExtent);
+ }
+ break;
+ case SC_ScrollBarSubPage:
+ if (scrollBar->orientation == Qt::Horizontal) {
+ rect.setRect(scrollBarRect.left() + scrollBarExtent, scrollBarRect.top(),
+ sliderStart - (scrollBarRect.left() + scrollBarExtent), scrollBarRect.height());
+ } else {
+ rect.setRect(scrollBarRect.left(), scrollBarRect.top() + scrollBarExtent,
+ scrollBarRect.width(), sliderStart - (scrollBarRect.left() + scrollBarExtent));
+ }
+ break;
+ case SC_ScrollBarAddPage:
+ if (scrollBar->orientation == Qt::Horizontal)
+ rect.setRect(sliderStart + sliderLength, 0,
+ sliderMaxLength - sliderStart - sliderLength + scrollBarExtent, scrollBarRect.height());
+ else
+ rect.setRect(0, sliderStart + sliderLength,
+ scrollBarRect.width(), sliderMaxLength - sliderStart - sliderLength + scrollBarExtent);
+ break;
+ case SC_ScrollBarGroove:
+ if (scrollBar->orientation == Qt::Horizontal) {
+ rect = scrollBarRect.adjusted(scrollBarExtent, 0, -2 * scrollBarExtent, 0);
+ } else {
+ rect = scrollBarRect.adjusted(0, scrollBarExtent, 0, -2 * scrollBarExtent);
+ }
+ break;
+ case SC_ScrollBarSlider:
+ if (scrollBar->orientation == Qt::Horizontal) {
+ rect.setRect(sliderStart, 0, sliderLength, scrollBarRect.height());
+ } else {
+ rect.setRect(0, sliderStart, scrollBarRect.width(), sliderLength);
+ }
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(scrollBar->direction, scrollBarRect, rect);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ int center = spinBox->rect.height() / 2;
+ switch (subControl) {
+ case SC_SpinBoxUp:
+ if (spinBox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = visualRect(spinBox->direction, spinBox->rect, rect);
+ rect.setRect(spinBox->rect.right() - 16, spinBox->rect.top(), 17, center + 1);
+ rect = visualRect(spinBox->direction, spinBox->rect, rect);
+ break;
+ case SC_SpinBoxDown:
+ if (spinBox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = visualRect(spinBox->direction, spinBox->rect, rect);
+ rect.setRect(spinBox->rect.right() - 16, spinBox->rect.top() + center, 17, spinBox->rect.height() - center);
+ rect = visualRect(spinBox->direction, spinBox->rect, rect);
+ break;
+ case SC_SpinBoxEditField:
+ if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
+ rect = spinBox->rect.adjusted(0, 0, -16, 0);
+ } else {
+ rect = spinBox->rect;
+ }
+ rect.adjust(blueFrameWidth, blueFrameWidth, -blueFrameWidth, -blueFrameWidth);
+ rect = visualRect(spinBox->direction, spinBox->rect, rect);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ switch (subControl) {
+ case SC_ComboBoxArrow:
+ rect = visualRect(option->direction, option->rect, rect);
+ rect.setRect(rect.right() - 17, rect.top() - 2,
+ 19, rect.height() + 4);
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ case SC_ComboBoxEditField: {
+ if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ rect = visualRect(option->direction, option->rect, rect);
+
+ if (box->editable) {
+ rect = box->rect.adjusted(blueFrameWidth, blueFrameWidth, -blueFrameWidth, -blueFrameWidth);
+ rect.setRight(rect.right() - 16); // Overlaps the combobox button by 2 pixels
+ } else {
+ rect.setRect(option->rect.left() + frameWidth, option->rect.top() + frameWidth,
+ option->rect.width() - 16 - 2 * frameWidth,
+ option->rect.height() - 2 * frameWidth);
+ rect.setLeft(rect.left() + 2);
+ rect.setRight(rect.right() - 2);
+ if (box->state & (State_Sunken | State_On))
+ rect.translate(1, 1);
+ }
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ SubControl sc = subControl;
+ QRect &ret = rect;
+ const int indent = 3;
+ const int controlTopMargin = 4;
+ const int controlBottomMargin = 3;
+ const int controlWidthMargin = 1;
+ const int controlHeight = tb->rect.height() - controlTopMargin - controlBottomMargin;
+ const int delta = controlHeight + controlWidthMargin;
+ int offset = 0;
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+
+ switch (sc) {
+ case SC_TitleBarLabel:
+ if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
+ ret = tb->rect;
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ ret.adjust(delta, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ ret.adjust(0, 0, -delta, 0);
+ ret.adjusted(indent, 0, -indent, 0);
+ }
+ break;
+ case SC_TitleBarContextHelpButton:
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ offset += delta;
+ case SC_TitleBarMinButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarMinButton)
+ break;
+ case SC_TitleBarNormalButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarNormalButton)
+ break;
+ case SC_TitleBarMaxButton:
+ if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarMaxButton)
+ break;
+ case SC_TitleBarShadeButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarShadeButton)
+ break;
+ case SC_TitleBarUnshadeButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (sc == SC_TitleBarUnshadeButton)
+ break;
+ case SC_TitleBarCloseButton:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ offset += delta;
+ else if (sc == SC_TitleBarCloseButton)
+ break;
+ ret.setRect(tb->rect.right() - indent - offset, tb->rect.top() + controlTopMargin,
+ controlHeight, controlHeight);
+ break;
+ case SC_TitleBarSysMenu:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ ret.setRect(tb->rect.left() + controlWidthMargin + indent, tb->rect.top() + controlTopMargin,
+ controlHeight, controlHeight);
+ }
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(tb->direction, tb->rect, ret);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return rect;
+}
+
+/*!
+ \reimp
+*/
+int QPlastiqueStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = 0;
+ switch (hint) {
+ case SH_WindowFrame_Mask:
+ ret = 1;
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData)) {
+ mask->region = option->rect;
+ mask->region -= QRect(option->rect.left(), option->rect.top(), 2, 1);
+ mask->region -= QRect(option->rect.right() - 1, option->rect.top(), 2, 1);
+ mask->region -= QRect(option->rect.left(), option->rect.top() + 1, 1, 1);
+ mask->region -= QRect(option->rect.right(), option->rect.top() + 1, 1, 1);
+
+ const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
+ if (titleBar && (titleBar->titleBarState & Qt::WindowMinimized)) {
+ mask->region -= QRect(option->rect.left(), option->rect.bottom(), 2, 1);
+ mask->region -= QRect(option->rect.right() - 1, option->rect.bottom(), 2, 1);
+ mask->region -= QRect(option->rect.left(), option->rect.bottom() - 1, 1, 1);
+ mask->region -= QRect(option->rect.right(), option->rect.bottom() - 1, 1, 1);
+ } else {
+ mask->region -= QRect(option->rect.bottomLeft(), QSize(1, 1));
+ mask->region -= QRect(option->rect.bottomRight(), QSize(1, 1));
+ }
+ }
+ break;
+ case SH_TitleBar_NoBorder:
+ ret = 1;
+ break;
+ case SH_TitleBar_AutoRaise:
+ ret = 1;
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+ ret = true;
+ break;
+ case SH_ToolBox_SelectedPageTitleBold:
+ case SH_ScrollBar_MiddleClickAbsolutePosition:
+ ret = true;
+ break;
+ case SH_MainWindow_SpaceBelowMenuBar:
+ ret = 0;
+ break;
+ case SH_FormLayoutWrapPolicy:
+ ret = QFormLayout::DontWrapRows;
+ break;
+ case SH_FormLayoutFieldGrowthPolicy:
+ ret = QFormLayout::ExpandingFieldsGrow;
+ break;
+ case SH_FormLayoutFormAlignment:
+ ret = Qt::AlignLeft | Qt::AlignTop;
+ break;
+ case SH_FormLayoutLabelAlignment:
+ ret = Qt::AlignRight;
+ break;
+ case SH_MessageBox_TextInteractionFlags:
+ ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
+ break;
+ case SH_LineEdit_PasswordCharacter:
+ ret = QCommonStyle::styleHint(hint, option, widget, returnData);
+ break;
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = true;
+ break;
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 96; // from Plastik
+ break;
+#ifdef Q_WS_X11
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+ ret = true;
+ break;
+#endif
+#ifndef Q_OS_WIN
+ case SH_Menu_AllowActiveAndDisabled:
+ ret = false;
+ break;
+#endif
+ default:
+ ret = QWindowsStyle::styleHint(hint, option, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+QStyle::SubControl QPlastiqueStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const
+{
+ SubControl ret = SC_None;
+ switch (control) {
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect slider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
+ if (slider.contains(pos)) {
+ ret = SC_ScrollBarSlider;
+ break;
+ }
+
+ QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
+ if (scrollBarAddLine.contains(pos)) {
+ ret = SC_ScrollBarAddLine;
+ break;
+ }
+
+ QRect scrollBarSubPage = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubPage, widget);
+ if (scrollBarSubPage.contains(pos)) {
+ ret = SC_ScrollBarSubPage;
+ break;
+ }
+
+ QRect scrollBarAddPage = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddPage, widget);
+ if (scrollBarAddPage.contains(pos)) {
+ ret = SC_ScrollBarAddPage;
+ break;
+ }
+
+ QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
+ if (scrollBarSubLine.contains(pos)) {
+ ret = SC_ScrollBarSubLine;
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ default:
+ break;
+ }
+
+ return ret != SC_None ? ret : QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+/*!
+ \reimp
+*/
+int QPlastiqueStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ int ret = -1;
+ switch (metric) {
+ case PM_MenuVMargin:
+ case PM_MenuHMargin:
+ ret = 0;
+ break;
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 1;
+ break;
+ case PM_ButtonDefaultIndicator:
+ ret = 0;
+ break;
+#ifndef QT_NO_SLIDER
+ case PM_SliderThickness:
+ ret = 15;
+ break;
+ case PM_SliderLength:
+ case PM_SliderControlThickness:
+ ret = 11;
+ break;
+ case PM_SliderTickmarkOffset:
+ ret = 5;
+ break;
+ case PM_SliderSpaceAvailable:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int size = 15;
+ if (slider->tickPosition & QSlider::TicksBelow)
+ ++size;
+ if (slider->tickPosition & QSlider::TicksAbove)
+ ++size;
+ ret = size;
+ break;
+ }
+#endif // QT_NO_SLIDER
+ case PM_ScrollBarExtent:
+ ret = 16;
+ break;
+ case PM_ScrollBarSliderMin:
+ ret = 26;
+ break;
+ case PM_ProgressBarChunkWidth:
+ ret = 1;
+ break;
+ case PM_MenuBarItemSpacing:
+ ret = 3;
+ break;
+ case PM_MenuBarVMargin:
+ ret = 2;
+ break;
+ case PM_MenuBarHMargin:
+ ret = 0;
+ break;
+ case PM_MenuBarPanelWidth:
+ ret = 1;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = 9;
+ break;
+ case PM_ToolBarSeparatorExtent:
+ ret = 2;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 1;
+ break;
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+ case PM_ToolBarFrameWidth:
+ ret = 2;
+ break;
+ case PM_SplitterWidth:
+ ret = 6;
+ break;
+ case PM_DockWidgetSeparatorExtent:
+ ret = 6;
+ break;
+ case PM_DockWidgetHandleExtent:
+ ret = 20;
+ break;
+ case PM_DefaultFrameWidth:
+#ifndef QT_NO_MENU
+ if (qobject_cast<const QMenu *>(widget)) {
+ ret = 1;
+ break;
+ }
+#endif
+ ret = 2;
+ break;
+ case PM_MdiSubWindowFrameWidth:
+ ret = 4;
+ break;
+ case PM_TitleBarHeight:
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ // Q3DockWindow has smaller title bars than QDockWidget
+ ret = qMax(widget->fontMetrics().height(), 20);
+ } else
+#endif
+ ret = qMax(widget ? widget->fontMetrics().height() :
+ (option ? option->fontMetrics.height() : 0), 30);
+ break;
+ case PM_MaximumDragDistance:
+ return -1;
+ case PM_DockWidgetTitleMargin:
+ return 2;
+ case PM_LayoutHorizontalSpacing:
+ case PM_LayoutVerticalSpacing:
+ return -1; // rely on layoutHorizontalSpacing()
+ case PM_LayoutLeftMargin:
+ case PM_LayoutTopMargin:
+ case PM_LayoutRightMargin:
+ case PM_LayoutBottomMargin:
+ {
+ bool isWindow = false;
+ if (option) {
+ isWindow = (option->state & State_Window);
+ } else if (widget) {
+ isWindow = widget->isWindow();
+ }
+
+ if (isWindow) {
+ ret = 11;
+ } else {
+ ret = 9;
+ }
+ }
+ default:
+ break;
+ }
+
+ return ret != -1 ? ret : QWindowsStyle::pixelMetric(metric, option, widget);
+}
+
+/*!
+ \reimp
+*/
+QPalette QPlastiqueStyle::standardPalette() const
+{
+ QPalette palette;
+
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, QColor(QRgb(0xff808080)));
+ palette.setBrush(QPalette::Disabled, QPalette::Button, QColor(QRgb(0xffdddfe4)));
+ palette.setBrush(QPalette::Disabled, QPalette::Light, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Disabled, QPalette::Midlight, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Disabled, QPalette::Dark, QColor(QRgb(0xff555555)));
+ palette.setBrush(QPalette::Disabled, QPalette::Mid, QColor(QRgb(0xffc7c7c7)));
+ palette.setBrush(QPalette::Disabled, QPalette::Text, QColor(QRgb(0xffc7c7c7)));
+ palette.setBrush(QPalette::Disabled, QPalette::BrightText, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, QColor(QRgb(0xff808080)));
+ palette.setBrush(QPalette::Disabled, QPalette::Base, QColor(QRgb(0xffefefef)));
+ palette.setBrush(QPalette::Disabled, QPalette::AlternateBase, palette.color(QPalette::Disabled, QPalette::Base).darker(110));
+ palette.setBrush(QPalette::Disabled, QPalette::Window, QColor(QRgb(0xffefefef)));
+ palette.setBrush(QPalette::Disabled, QPalette::Shadow, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(QRgb(0xff567594)));
+ palette.setBrush(QPalette::Disabled, QPalette::HighlightedText, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Disabled, QPalette::Link, QColor(QRgb(0xff0000ee)));
+ palette.setBrush(QPalette::Disabled, QPalette::LinkVisited, QColor(QRgb(0xff52188b)));
+ palette.setBrush(QPalette::Active, QPalette::WindowText, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Active, QPalette::Button, QColor(QRgb(0xffdddfe4)));
+ palette.setBrush(QPalette::Active, QPalette::Light, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Active, QPalette::Midlight, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Active, QPalette::Dark, QColor(QRgb(0xff555555)));
+ palette.setBrush(QPalette::Active, QPalette::Mid, QColor(QRgb(0xffc7c7c7)));
+ palette.setBrush(QPalette::Active, QPalette::Text, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Active, QPalette::BrightText, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Active, QPalette::ButtonText, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Active, QPalette::Base, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Active, QPalette::AlternateBase, palette.color(QPalette::Active, QPalette::Base).darker(110));
+ palette.setBrush(QPalette::Active, QPalette::Window, QColor(QRgb(0xffefefef)));
+ palette.setBrush(QPalette::Active, QPalette::Shadow, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Active, QPalette::Highlight, QColor(QRgb(0xff678db2)));
+ palette.setBrush(QPalette::Active, QPalette::HighlightedText, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Active, QPalette::Link, QColor(QRgb(0xff0000ee)));
+ palette.setBrush(QPalette::Active, QPalette::LinkVisited, QColor(QRgb(0xff52188b)));
+ palette.setBrush(QPalette::Inactive, QPalette::WindowText, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Inactive, QPalette::Button, QColor(QRgb(0xffdddfe4)));
+ palette.setBrush(QPalette::Inactive, QPalette::Light, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Inactive, QPalette::Midlight, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Inactive, QPalette::Dark, QColor(QRgb(0xff555555)));
+ palette.setBrush(QPalette::Inactive, QPalette::Mid, QColor(QRgb(0xffc7c7c7)));
+ palette.setBrush(QPalette::Inactive, QPalette::Text, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Inactive, QPalette::BrightText, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Inactive, QPalette::ButtonText, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Inactive, QPalette::Base, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Inactive, QPalette::AlternateBase, palette.color(QPalette::Inactive, QPalette::Base).darker(110));
+ palette.setBrush(QPalette::Inactive, QPalette::Window, QColor(QRgb(0xffefefef)));
+ palette.setBrush(QPalette::Inactive, QPalette::Shadow, QColor(QRgb(0xff000000)));
+ palette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(QRgb(0xff678db2)));
+ palette.setBrush(QPalette::Inactive, QPalette::HighlightedText, QColor(QRgb(0xffffffff)));
+ palette.setBrush(QPalette::Inactive, QPalette::Link, QColor(QRgb(0xff0000ee)));
+ palette.setBrush(QPalette::Inactive, QPalette::LinkVisited, QColor(QRgb(0xff52188b)));
+ return palette;
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::polish(QWidget *widget)
+{
+ if (qobject_cast<QPushButton *>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox *>(widget)
+#endif
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox *>(widget)
+#endif
+ || qobject_cast<QCheckBox *>(widget)
+#ifndef QT_NO_GROUPBOX
+ || qobject_cast<QGroupBox *>(widget)
+#endif
+ || qobject_cast<QRadioButton *>(widget)
+#ifndef QT_NO_SPLITTER
+ || qobject_cast<QSplitterHandle *>(widget)
+#endif
+#ifndef QT_NO_TABBAR
+ || qobject_cast<QTabBar *>(widget)
+#endif
+ ) {
+ widget->setAttribute(Qt::WA_Hover);
+ }
+
+ if (widget->inherits("QWorkspaceTitleBar")
+ || widget->inherits("QDockSeparator")
+ || widget->inherits("QDockWidgetSeparator")
+ || widget->inherits("Q3DockWindowResizeHandle")) {
+ widget->setAttribute(Qt::WA_Hover);
+ }
+
+ if (false // to simplify the #ifdefs
+#ifndef QT_NO_MENUBAR
+ || qobject_cast<QMenuBar *>(widget)
+#endif
+#ifdef QT3_SUPPORT
+ || widget->inherits("Q3ToolBar")
+#endif
+#ifndef QT_NO_TOOLBAR
+ || qobject_cast<QToolBar *>(widget)
+ || (widget && qobject_cast<QToolBar *>(widget->parent()))
+#endif
+ ) {
+ widget->setBackgroundRole(QPalette::Window);
+ }
+
+#ifndef QT_NO_PROGRESSBAR
+ if (AnimateBusyProgressBar && qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+
+#if defined QPlastique_MaskButtons
+ if (qobject_cast<QPushButton *>(widget) || qobject_cast<QToolButton *>(widget))
+ widget->installEventFilter(this);
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::unpolish(QWidget *widget)
+{
+ if (qobject_cast<QPushButton *>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox *>(widget)
+#endif
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox *>(widget)
+#endif
+ || qobject_cast<QCheckBox *>(widget)
+#ifndef QT_NO_GROUPBOX
+ || qobject_cast<QGroupBox *>(widget)
+#endif
+#ifndef QT_NO_SPLITTER
+ || qobject_cast<QSplitterHandle *>(widget)
+#endif
+#ifndef QT_NO_TABBAR
+ || qobject_cast<QTabBar *>(widget)
+#endif
+ || qobject_cast<QRadioButton *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+
+ if (widget->inherits("QWorkspaceTitleBar")
+ || widget->inherits("QDockSeparator")
+ || widget->inherits("QDockWidgetSeparator")
+ || widget->inherits("Q3DockWindowResizeHandle")) {
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+
+ if (false // to simplify the #ifdefs
+#ifndef QT_NO_MENUBAR
+ || qobject_cast<QMenuBar *>(widget)
+#endif
+#ifndef QT_NO_TOOLBOX
+ || qobject_cast<QToolBox *>(widget)
+#endif
+#ifdef QT3_SUPPORT
+ || widget->inherits("Q3ToolBar")
+#endif
+#ifndef QT_NO_TOOLBAR
+ || qobject_cast<QToolBar *>(widget)
+ || (widget && qobject_cast<QToolBar *>(widget->parent()))
+#endif
+ ) {
+ widget->setBackgroundRole(QPalette::Button);
+ }
+
+#ifndef QT_NO_PROGRESSBAR
+ if (AnimateBusyProgressBar && qobject_cast<QProgressBar *>(widget)) {
+ Q_D(QPlastiqueStyle);
+ widget->removeEventFilter(this);
+ d->bars.removeAll(static_cast<QProgressBar*>(widget));
+ }
+#endif
+
+#if defined QPlastique_MaskButtons
+ if (qobject_cast<QPushButton *>(widget) || qobject_cast<QToolButton *>(widget))
+ widget->removeEventFilter(this);
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::polish(QApplication *app)
+{
+ QWindowsStyle::polish(app);
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::polish(QPalette &pal)
+{
+ QWindowsStyle::polish(pal);
+#ifdef Q_WS_MAC
+ pal.setBrush(QPalette::Shadow, Qt::black);
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::unpolish(QApplication *app)
+{
+ QWindowsStyle::unpolish(app);
+}
+
+/*!
+ \internal
+*/
+QIcon QPlastiqueStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+/*!
+ \reimp
+*/
+QPixmap QPlastiqueStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+// this works as long as we have at most 16 different control types
+#define CT1(c) CT2(c, c)
+#define CT2(c1, c2) (((uint)c1 << 16) | (uint)c2)
+
+/*!
+ \internal
+*/
+int QPlastiqueStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption * /* option */,
+ const QWidget * /* widget */) const
+{
+ const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton;
+
+ if (control2 == QSizePolicy::ButtonBox)
+ return 11;
+
+ if ((control1 | control2) & ButtonMask)
+ return (orientation == Qt::Horizontal) ? 10 : 9;
+
+ switch (CT2(control1, control2)) {
+ case CT1(QSizePolicy::Label):
+ case CT2(QSizePolicy::Label, QSizePolicy::DefaultType):
+ case CT2(QSizePolicy::Label, QSizePolicy::CheckBox):
+ case CT2(QSizePolicy::Label, QSizePolicy::ComboBox):
+ case CT2(QSizePolicy::Label, QSizePolicy::LineEdit):
+ case CT2(QSizePolicy::Label, QSizePolicy::RadioButton):
+ case CT2(QSizePolicy::Label, QSizePolicy::Slider):
+ case CT2(QSizePolicy::Label, QSizePolicy::SpinBox):
+ case CT2(QSizePolicy::Label, QSizePolicy::ToolButton):
+ return 5;
+ case CT2(QSizePolicy::CheckBox, QSizePolicy::RadioButton):
+ case CT2(QSizePolicy::RadioButton, QSizePolicy::CheckBox):
+ case CT1(QSizePolicy::CheckBox):
+ if (orientation == Qt::Vertical)
+ return 2;
+ case CT1(QSizePolicy::RadioButton):
+ if (orientation == Qt::Vertical)
+ return 1;
+ }
+
+ if (orientation == Qt::Horizontal
+ && (control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)))
+ return 8;
+
+ if ((control1 | control2) & (QSizePolicy::Frame
+ | QSizePolicy::GroupBox
+ | QSizePolicy::TabWidget)) {
+ return 11;
+ }
+
+ if ((control1 | control2) & (QSizePolicy::Line | QSizePolicy::Slider
+ | QSizePolicy::LineEdit | QSizePolicy::ComboBox
+ | QSizePolicy::SpinBox))
+ return 7;
+
+ return 6;
+}
+
+/*!
+ \reimp
+*/
+bool QPlastiqueStyle::eventFilter(QObject *watched, QEvent *event)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QPlastiqueStyle);
+
+ switch (event->type()) {
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(watched)) {
+ d->bars.append(bar);
+ if (d->bars.size() == 1) {
+ Q_ASSERT(ProgressBarFps > 0);
+ d->timer.start();
+ d->progressBarAnimateTimer = startTimer(1000 / ProgressBarFps);
+ }
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ if(!d->bars.isEmpty()) {
+ d->bars.removeAll(reinterpret_cast<QProgressBar*>(watched));
+ if (d->bars.isEmpty()) {
+ killTimer(d->progressBarAnimateTimer);
+ d->progressBarAnimateTimer = 0;
+ }
+ }
+ break;
+#if defined QPlastique_MaskButtons
+ case QEvent::Resize:
+ if (qobject_cast<QPushButton *>(watched) || qobject_cast<QToolButton *>(watched)) {
+ QWidget *widget = qobject_cast<QWidget *>(watched);
+ QRect rect = widget->rect();
+ QRegion region(rect);
+ region -= QRect(rect.left(), rect.top(), 2, 1);
+ region -= QRect(rect.left(), rect.top() + 1, 1, 1);
+ region -= QRect(rect.left(), rect.bottom(), 2, 1);
+ region -= QRect(rect.left(), rect.bottom() - 1, 1, 1);
+ region -= QRect(rect.right() - 1, rect.top(), 2, 1);
+ region -= QRect(rect.right(), rect.top() + 1, 1, 1);
+ region -= QRect(rect.right() - 1, rect.bottom(), 2, 1);
+ region -= QRect(rect.right(), rect.bottom() - 1, 1, 1);
+ widget->setMask(region);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+#endif // QT_NO_PROGRESSBAR
+
+ return QWindowsStyle::eventFilter(watched, event);
+}
+
+/*!
+ \reimp
+*/
+void QPlastiqueStyle::timerEvent(QTimerEvent *event)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QPlastiqueStyle);
+
+ if (event->timerId() == d->progressBarAnimateTimer) {
+ Q_ASSERT(ProgressBarFps > 0);
+ d->animateStep = d->timer.elapsed() / (1000 / ProgressBarFps);
+ foreach (QProgressBar *bar, d->bars) {
+ if (AnimateProgressBar || (bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ }
+#endif // QT_NO_PROGRESSBAR
+ event->ignore();
+}
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_STYLE_PLASTIQUE) || defined(QT_PLUGIN)
diff --git a/src/widgets/styles/qplastiquestyle.h b/src/widgets/styles/qplastiquestyle.h
new file mode 100644
index 0000000000..51a0139b21
--- /dev/null
+++ b/src/widgets/styles/qplastiquestyle.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLASTIQUESTYLE_H
+#define QPLASTIQUESTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_PLASTIQUE)
+
+class QPlastiqueStylePrivate;
+class Q_GUI_EXPORT QPlastiqueStyle : public QWindowsStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlastiqueStyle)
+public:
+ QPlastiqueStyle();
+ ~QPlastiqueStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &pal);
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event);
+ void timerEvent(QTimerEvent *event);
+
+private:
+ Q_DISABLE_COPY(QPlastiqueStyle)
+ void *reserved;
+};
+
+#endif // QT_NO_STYLE_PLASTIQUE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLASTIQUESTYLE_H
diff --git a/src/widgets/styles/qproxystyle.cpp b/src/widgets/styles/qproxystyle.cpp
new file mode 100644
index 0000000000..476a758992
--- /dev/null
+++ b/src/widgets/styles/qproxystyle.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qstyle.h>
+#include <private/qproxystyle_p.h>
+#include <private/qapplication_p.h>
+#include "qproxystyle.h"
+#include "qstylefactory.h"
+#include <private/qstyle_p.h>
+
+#if !defined(QT_NO_STYLE_PROXY) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QProxyStyle
+
+ \brief The QProxyStyle class is a convenience class that simplifies
+ dynamically overriding QStyle elements.
+
+ \since 4.6
+
+ A QProxyStyle wraps a QStyle (usually the default system style) for the
+ purpose of dynamically overriding painting or other specific style behavior.
+
+ The following example shows how to override the shortcut underline
+ behavior on any platform:
+
+ \snippet doc/src/snippets/code/src_gui_qproxystyle.cpp 1
+
+ Warning: The \l {QCommonStyle} {common styles} provided by Qt will
+ respect this hint, because they call QStyle::proxy(), but there is
+ no guarantee that QStyle::proxy() will be called for user defined
+ or system controlled styles. It would not work on a Mac, for
+ example, where menus are handled by the operating system.
+
+ \sa QStyle
+*/
+
+void QProxyStylePrivate::ensureBaseStyle() const
+{
+ Q_Q(const QProxyStyle);
+
+ if (baseStyle)
+ return;
+
+ if (!baseStyle && !QApplicationPrivate::styleOverride.isEmpty()) {
+ baseStyle = QStyleFactory::create(QApplicationPrivate::styleOverride);
+ if (baseStyle) {
+ // If baseStyle is an instance of the same proxyStyle
+ // we destroy it and fall back to the desktop style
+ if (qstrcmp(baseStyle->metaObject()->className(),
+ q->metaObject()->className()) == 0) {
+ delete baseStyle;
+ baseStyle = 0;
+ }
+ }
+ }
+
+ if (!baseStyle) // Use application desktop style
+ baseStyle = QStyleFactory::create(QApplicationPrivate::desktopStyleKey());
+
+ if (!baseStyle) // Fallback to windows style
+ baseStyle = QStyleFactory::create(QLatin1String("windows"));
+
+ baseStyle->setProxy(const_cast<QProxyStyle*>(q));
+ baseStyle->setParent(const_cast<QProxyStyle*>(q)); // Take ownership
+}
+
+/*!
+ Constructs a QProxyStyle object for overriding behavior in \a style
+ or in the current application \l{QStyle}{style} if \a style is 0
+ (default). Normally \a style is 0, because you want to override
+ behavior in the system style.
+
+ Ownership of \a style is transferred to QProxyStyle.
+*/
+QProxyStyle::QProxyStyle(QStyle *style) :
+ QCommonStyle(*new QProxyStylePrivate())
+{
+ Q_D(QProxyStyle);
+ if (style) {
+ style->setProxy(this);
+ style->setParent(this); // Take ownership
+ d->baseStyle = style;
+ }
+}
+
+/*!
+ Destroys the QProxyStyle object.
+*/
+QProxyStyle::~QProxyStyle()
+{
+}
+
+/*!
+ Returns the proxy base style object. If no base style
+ is set on the proxy style, QProxyStyle will create
+ an instance of the application style instead.
+
+ \sa setBaseStyle(), QStyle
+*/
+QStyle *QProxyStyle::baseStyle() const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle;
+}
+
+/*!
+ Sets the base style that should be proxied.
+
+ Ownership of \a style is transferred to QProxyStyle.
+
+ If style is zero, a desktop-dependant style will be
+ assigned automatically.
+*/
+void QProxyStyle::setBaseStyle(QStyle *style)
+{
+ Q_D (QProxyStyle);
+
+ if (d->baseStyle && d->baseStyle->parent() == this)
+ d->baseStyle->deleteLater();
+
+ d->baseStyle = style;
+
+ if (d->baseStyle) {
+ d->baseStyle->setProxy(this);
+ d->baseStyle->setParent(this);
+ }
+}
+
+/*! \reimp
+ */
+void QProxyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->drawPrimitive(element, option, painter, widget);
+}
+
+/*!
+ \reimp
+ */
+void QProxyStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->drawControl(element, option, painter, widget);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->drawComplexControl(control, option, painter, widget);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->drawItemText(painter, rect, flags, pal, enabled, text, textRole);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->drawItemPixmap(painter, rect, alignment, pixmap);
+}
+
+/*! \reimp
+ */
+QSize QProxyStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->sizeFromContents(type, option, size, widget);
+}
+
+/*! \reimp
+ */
+QRect QProxyStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->subElementRect(element, option, widget);
+}
+
+/*! \reimp
+ */
+QRect QProxyStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->subControlRect(cc, option, sc, widget);
+}
+
+/*! \reimp
+ */
+QRect QProxyStyle::itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->itemTextRect(fm, r, flags, enabled, text);
+}
+
+/*! \reimp
+ */
+QRect QProxyStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->itemPixmapRect(r, flags, pixmap);
+}
+
+/*! \reimp
+ */
+QStyle::SubControl QProxyStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->hitTestComplexControl(control, option, pos, widget);
+}
+
+/*! \reimp
+ */
+int QProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->styleHint(hint, option, widget, returnData);
+}
+
+/*! \reimp
+ */
+int QProxyStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->pixelMetric(metric, option, widget);
+}
+
+/*! \reimp
+ */
+QPixmap QProxyStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->standardPixmap(standardPixmap, opt, widget);
+}
+
+/*! \reimp
+ */
+QPixmap QProxyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+/*! \reimp
+ */
+QPalette QProxyStyle::standardPalette() const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->standardPalette();
+}
+
+/*! \reimp
+ */
+void QProxyStyle::polish(QWidget *widget)
+{
+ Q_D (QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->polish(widget);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::polish(QPalette &pal)
+{
+ Q_D (QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->polish(pal);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::polish(QApplication *app)
+{
+ Q_D (QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->polish(app);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::unpolish(QWidget *widget)
+{
+ Q_D (QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->unpolish(widget);
+}
+
+/*! \reimp
+ */
+void QProxyStyle::unpolish(QApplication *app)
+{
+ Q_D (QProxyStyle);
+ d->ensureBaseStyle();
+ d->baseStyle->unpolish(app);
+}
+
+/*! \reimp
+ */
+bool QProxyStyle::event(QEvent *e)
+{
+ Q_D (QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->event(e);
+}
+
+/*!
+ Returns an icon for the given \a standardIcon.
+
+ Reimplement this slot to provide your own icons in a QStyle
+ subclass. The \a option argument can be used to pass extra
+ information required to find the appropriate icon. The \a widget
+ argument is optional and can also be used to help find the icon.
+
+ \note Because of binary compatibility constraints, standardIcon()
+ introduced in Qt 4.1 is not virtual. Therefore it must dynamically
+ detect and call \e this slot. This default implementation simply
+ calls standardIcon() with the given parameters.
+
+ \sa standardIcon()
+ */
+QIcon QProxyStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->standardIcon(standardIcon, option, widget);
+}
+
+/*!
+ This slot is called by layoutSpacing() to determine the spacing that
+ should be used between \a control1 and \a control2 in a layout. \a
+ orientation specifies whether the controls are laid out side by side
+ or stacked vertically. The \a option parameter can be used to pass
+ extra information about the parent widget. The \a widget parameter
+ is optional and can also be used if \a option is 0.
+
+ The default implementation returns -1.
+
+ \sa layoutSpacing(), combinedLayoutSpacing()
+ */
+int QProxyStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D (const QProxyStyle);
+ d->ensureBaseStyle();
+ return d->baseStyle->layoutSpacing(control1, control2, orientation, option, widget);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_PROXY
diff --git a/src/widgets/styles/qproxystyle.h b/src/widgets/styles/qproxystyle.h
new file mode 100644
index 0000000000..14b96ba0e4
--- /dev/null
+++ b/src/widgets/styles/qproxystyle.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROXYSTYLE_H
+#define QPROXYSTYLE_H
+
+#include <QtWidgets/QCommonStyle>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_PROXY)
+
+class QProxyStylePrivate;
+class Q_GUI_EXPORT QProxyStyle : public QCommonStyle
+{
+ Q_OBJECT
+
+public:
+ QProxyStyle(QStyle *baseStyle = 0);
+ ~QProxyStyle();
+
+ QStyle *baseStyle() const;
+ void setBaseStyle(QStyle *style);
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+ virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
+ QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const;
+ QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
+ QPalette standardPalette() const;
+
+ void polish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+protected:
+ bool event(QEvent *e);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+private:
+ Q_DISABLE_COPY(QProxyStyle)
+ Q_DECLARE_PRIVATE(QProxyStyle)
+};
+
+#endif // QT_NO_STYLE_PROXY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPROXYSTYLE_H
diff --git a/src/widgets/styles/qproxystyle_p.h b/src/widgets/styles/qproxystyle_p.h
new file mode 100644
index 0000000000..9ccd382cd3
--- /dev/null
+++ b/src/widgets/styles/qproxystyle_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROXYSTYLE_P_H
+#define QPROXYSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qcommonstyle.h"
+#include "qcommonstyle_p.h"
+#include "qproxystyle.h"
+
+#ifndef QT_NO_STYLE_PROXY
+
+QT_BEGIN_NAMESPACE
+
+class QProxyStylePrivate : public QCommonStylePrivate
+{
+ Q_DECLARE_PUBLIC(QProxyStyle)
+public:
+ void ensureBaseStyle() const;
+private:
+ QProxyStylePrivate() :
+ QCommonStylePrivate(), baseStyle(0) {}
+ mutable QPointer <QStyle> baseStyle;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_PROXY
+
+#endif //QPROXYSTYLE_P_H
diff --git a/src/widgets/styles/qs60style.cpp b/src/widgets/styles/qs60style.cpp
new file mode 100644
index 0000000000..634cf00536
--- /dev/null
+++ b/src/widgets/styles/qs60style.cpp
@@ -0,0 +1,3618 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qs60style_p.h"
+
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qstyleoption.h"
+#include "qevent.h"
+#include "qpixmapcache.h"
+
+#include "qcalendarwidget.h"
+#include "qdial.h"
+#include "qdialog.h"
+#include "qmessagebox.h"
+#include "qgroupbox.h"
+#include "qheaderview.h"
+#include "qlist.h"
+#include "qlistwidget.h"
+#include "qlistview.h"
+#include "qmenu.h"
+#include "qmenubar.h"
+#include "qpushbutton.h"
+#include "qscrollarea.h"
+#include "qscrollbar.h"
+#include "qtabbar.h"
+#include "qtableview.h"
+#include "qtextedit.h"
+#include "qtoolbar.h"
+#include "qtoolbutton.h"
+#include "qfocusframe.h"
+#include "qformlayout.h"
+#include "qradiobutton.h"
+#include "qcheckbox.h"
+#include "qdesktopwidget.h"
+#include "qprogressbar.h"
+#include "qlabel.h"
+
+#include "private/qtoolbarextension_p.h"
+#include "private/qcombobox_p.h"
+#include "private/qwidget_p.h"
+#include "private/qapplication_p.h"
+#include "private/qfont_p.h"
+
+#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+const QS60StylePrivate::SkinElementFlags QS60StylePrivate::KDefaultSkinElementFlags =
+ SkinElementFlags(SF_PointNorth | SF_StateEnabled);
+
+static const qreal goldenRatio = 1.618;
+
+const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
+// *** generated layout data ***
+{240,320,1,19,"QVGA Landscape"},
+{320,240,1,19,"QVGA Portrait"},
+{360,640,1,19,"NHD Landscape"},
+{640,360,1,19,"NHD Portrait"},
+{352,800,1,12,"E90 Landscape"},
+{480,640,1,19,"VGA Landscape"}
+// *** End of generated data ***
+};
+const int QS60StylePrivate::m_numberOfLayouts =
+ (int)sizeof(QS60StylePrivate::m_layoutHeaders)/sizeof(QS60StylePrivate::m_layoutHeaders[0]);
+
+const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
+// *** generated pixel metrics ***
+{5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106},
+{5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106},
+{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,11,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
+{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,13,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
+{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106},
+{9,0,-909,0,0,2,0,5,-1,34,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,19,19,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184}
+// *** End of generated data ***
+};
+
+const short *QS60StylePrivate::m_pmPointer = QS60StylePrivate::data[0];
+
+// theme background texture
+QPixmap *QS60StylePrivate::m_background = 0;
+QPixmap *QS60StylePrivate::m_placeHolderTexture = 0;
+
+// theme palette
+QPalette *QS60StylePrivate::m_themePalette = 0;
+
+qint64 QS60StylePrivate::m_webPaletteKey = 0;
+
+QPointer<QWidget> QS60StylePrivate::m_pressedWidget = 0;
+
+const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = {
+ {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter},
+ {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed},
+ {SE_FrameLineEdit, QS60StyleEnums::SP_QsnFrInputCenter},
+ {SE_ListHighlight, QS60StyleEnums::SP_QsnFrListCenter},
+ {SE_PopupBackground, QS60StyleEnums::SP_QsnFrPopupCenter},
+ {SE_SettingsList, QS60StyleEnums::SP_QsnFrSetOptCenter},
+ {SE_TableItem, QS60StyleEnums::SP_QsnFrCaleCenter},
+ {SE_TableHeaderItem, QS60StyleEnums::SP_QsnFrCaleHeadingCenter},
+ {SE_ToolTip, QS60StyleEnums::SP_QsnFrPopupPreviewCenter},
+ {SE_ToolBar, QS60StyleEnums::SP_QsnFrPopupSubCenter},
+ {SE_ToolBarButton, QS60StyleEnums::SP_QgnFrSctrlButtonCenter},
+ {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QgnFrSctrlButtonCenterPressed},
+ {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter},
+ {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive},
+ {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter},
+ {SE_TableItemPressed, QS60StyleEnums::SP_QsnFrGridCenterPressed},
+ {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListCenterPressed},
+};
+
+static const int frameElementsCount =
+ int(sizeof(QS60StylePrivate::m_frameElementsData)/sizeof(QS60StylePrivate::m_frameElementsData[0]));
+
+const int KNotFound = -909;
+const double KTabFontMul = 0.72;
+
+QS60StylePrivate::~QS60StylePrivate()
+{
+ clearCaches(); //deletes also background image
+ if (m_placeHolderTexture) {
+ delete m_placeHolderTexture;
+ m_placeHolderTexture = 0;
+ }
+ deleteThemePalette();
+#ifdef Q_WS_S60
+ removeAnimations();
+#endif
+}
+
+void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
+ const QRect &rect, SkinElementFlags flags)
+{
+ switch (element) {
+ case SE_ButtonNormal:
+ drawFrame(SF_ButtonNormal, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ButtonPressed:
+ drawFrame(SF_ButtonPressed, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_FrameLineEdit:
+ drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ProgressBarGrooveHorizontal:
+ drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter,
+ QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ProgressBarGrooveVertical:
+ drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter,
+ QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Vertical, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_ProgressBarIndicatorHorizontal:
+ drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ProgressBarIndicatorVertical:
+ drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointWest);
+ break;
+ case SE_ScrollBarGrooveHorizontal:
+ drawRow(QS60StyleEnums::SP_QsnCpScrollBgBottom, QS60StyleEnums::SP_QsnCpScrollBgMiddle,
+ QS60StyleEnums::SP_QsnCpScrollBgTop, Qt::Horizontal, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_ScrollBarGrooveVertical:
+ drawRow(QS60StyleEnums::SP_QsnCpScrollBgTop, QS60StyleEnums::SP_QsnCpScrollBgMiddle,
+ QS60StyleEnums::SP_QsnCpScrollBgBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ScrollBarHandleHorizontal:
+ drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottom, QS60StyleEnums::SP_QsnCpScrollHandleMiddle,
+ QS60StyleEnums::SP_QsnCpScrollHandleTop, Qt::Horizontal, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_ScrollBarHandleVertical:
+ drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTop, QS60StyleEnums::SP_QsnCpScrollHandleMiddle,
+ QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_SliderHandleHorizontal:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_SliderHandleVertical:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderHandleSelectedHorizontal:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_SliderHandleSelectedVertical:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderGrooveVertical:
+ drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle,
+ QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Vertical, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderGrooveHorizontal:
+ drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle,
+ QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_TabBarTabEastActive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM,
+ QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Vertical, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_TabBarTabEastInactive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM,
+ QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Vertical, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_TabBarTabNorthActive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM,
+ QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_TabBarTabNorthInactive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM,
+ QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_TabBarTabSouthActive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM,
+ QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth);
+ break;
+ case SE_TabBarTabSouthInactive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM,
+ QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth);
+ break;
+ case SE_TabBarTabWestActive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM,
+ QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Vertical, painter, rect, flags | SF_PointWest);
+ break;
+ case SE_TabBarTabWestInactive:
+ drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM,
+ QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Vertical, painter, rect, flags | SF_PointWest);
+ break;
+ case SE_ListHighlight:
+ drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_PopupBackground:
+ drawFrame(SF_PopupBackground, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_SettingsList:
+ drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_TableItem:
+ drawFrame(SF_TableItem, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_TableHeaderItem:
+ drawFrame(SF_TableHeaderItem, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ToolTip:
+ drawFrame(SF_ToolTip, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ToolBar:
+ drawFrame(SF_ToolBar, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ToolBarButton:
+ drawFrame(SF_ToolBarButton, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ToolBarButtonPressed:
+ drawFrame(SF_ToolBarButtonPressed, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_PanelBackground:
+ drawFrame(SF_PanelBackground, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ScrollBarHandlePressedHorizontal:
+ drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed,
+ QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, Qt::Horizontal, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_ScrollBarHandlePressedVertical:
+ drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed,
+ QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, Qt::Vertical, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ButtonInactive:
+ drawFrame(SF_ButtonInactive, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_Editor:
+ drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_DropArea:
+ drawPart(QS60StyleEnums::SP_QgnGrafOrgBgGrid, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_TableItemPressed:
+ drawFrame(SF_TableItemPressed, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_ListItemPressed:
+ drawFrame(SF_ListItemPressed, painter, rect, flags | SF_PointNorth);
+ break;
+ default:
+ break;
+ }
+}
+
+void QS60StylePrivate::drawSkinPart(QS60StyleEnums::SkinParts part,
+ QPainter *painter, const QRect &rect, SkinElementFlags flags)
+{
+ drawPart(part, painter, rect, flags);
+}
+
+short QS60StylePrivate::pixelMetric(int metric)
+{
+ //If it is a custom value, need to strip away the base to map to internal
+ //pixel metric value table
+ if (metric & QStyle::PM_CustomBase) {
+ metric -= QStyle::PM_CustomBase;
+ metric += MAX_NON_CUSTOM_PIXELMETRICS - 1;
+ }
+
+ Q_ASSERT(metric < MAX_PIXELMETRICS);
+ const short returnValue = m_pmPointer[metric];
+ return returnValue;
+}
+
+QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *option)
+{
+ QColor retColor (color);
+ if (option && !(option->state & QStyle::State_Enabled)) {
+ QColor hsvColor = retColor.toHsv();
+ int colorSat = hsvColor.saturation();
+ int colorVal = hsvColor.value();
+ colorSat = (colorSat != 0) ? (colorSat >> 1) : 128;
+ colorVal = (colorVal != 0) ? (colorVal >> 1) : 128;
+ hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal);
+ retColor = hsvColor.toRgb();
+ }
+ return retColor;
+}
+
+QColor QS60StylePrivate::lighterColor(const QColor &baseColor)
+{
+ QColor result(baseColor);
+ bool modifyColor = false;
+ if (result.saturation() == 0) {
+ result.setHsv(result.hue(), 128, result.value());
+ modifyColor = true;
+ }
+ if (result.value() == 0) {
+ result.setHsv(result.hue(), result.saturation(), 128);
+ modifyColor = true;
+ }
+ if (modifyColor)
+ result = result.lighter(175);
+ else
+ result = result.lighter(225);
+ return result;
+}
+
+bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget)
+{
+ return (widget ? (widget->windowType() == Qt::Dialog) : false);
+}
+
+QFont QS60StylePrivate::s60Font(
+ QS60StyleEnums::FontCategories fontCategory,
+ int pointSize, bool resolveFontSize) const
+{
+ QFont result;
+ int actualPointSize = pointSize;
+ if (actualPointSize <= 0) {
+ const QFont appFont = QApplication::font();
+ actualPointSize = appFont.pointSize();
+ if (actualPointSize <= 0)
+ actualPointSize = appFont.pixelSize() * 72 / qt_defaultDpiY();
+ }
+ Q_ASSERT(actualPointSize > 0);
+ const QPair<QS60StyleEnums::FontCategories, int> key(fontCategory, actualPointSize);
+ if (!m_mappedFontsCache.contains(key)) {
+ result = s60Font_specific(fontCategory, actualPointSize, resolveFontSize);
+ m_mappedFontsCache.insert(key, result);
+ } else {
+ result = m_mappedFontsCache.value(key);
+ if (result.pointSize() != actualPointSize)
+ result.setPointSize(actualPointSize);
+ }
+ return result;
+}
+
+void QS60StylePrivate::clearCaches(CacheClearReason reason)
+{
+ switch(reason){
+ case CC_LayoutChange:
+ // when layout changes, the colors remain in cache, but graphics and fonts can change
+ m_mappedFontsCache.clear();
+ QPixmapCache::clear();
+ break;
+ case CC_ThemeChange:
+ QPixmapCache::clear();
+#ifdef Q_WS_S60
+ deleteStoredSettings();
+#endif
+ deleteBackground();
+ break;
+ case CC_UndefinedChange:
+ default:
+ m_mappedFontsCache.clear();
+ QPixmapCache::clear();
+ deleteBackground();
+ break;
+ }
+}
+
+QColor QS60StylePrivate::calculatedColor(SkinFrameElements frame) const
+{
+ const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth);
+ const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight);
+ Q_ASSERT(2 * frameCornerWidth < 32);
+ Q_ASSERT(2 * frameCornerHeight < 32);
+
+ const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage();
+ Q_ASSERT(frameImage.bytesPerLine() > 0);
+ if (frameImage.isNull())
+ return Qt::black;
+
+ const QRgb *pixelRgb = (const QRgb*)frameImage.constBits();
+ const int pixels = frameImage.byteCount() / sizeof(QRgb);
+
+ int estimatedRed = 0;
+ int estimatedGreen = 0;
+ int estimatedBlue = 0;
+
+ int skips = 0;
+ int estimations = 0;
+
+ const int topBorderLastPixel = frameCornerHeight * frameImage.width() - 1;
+ const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - topBorderLastPixel;
+ const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth;
+ const int leftBorderLastPixel = frameCornerWidth;
+
+ while ((skips + estimations) < pixels) {
+ if ((skips + estimations) > topBorderLastPixel &&
+ (skips + estimations) < bottomBorderFirstPixel) {
+ for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) {
+ if (rowIndex > leftBorderLastPixel &&
+ rowIndex < rightBorderFirstPixel) {
+ estimatedRed += qRed(*pixelRgb);
+ estimatedGreen += qGreen(*pixelRgb);
+ estimatedBlue += qBlue(*pixelRgb);
+ }
+ pixelRgb++;
+ estimations++;
+ }
+ } else {
+ pixelRgb++;
+ skips++;
+ }
+ }
+ QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations);
+ return !estimations ? Qt::black : frameColor;
+}
+
+void QS60StylePrivate::setThemePalette(QApplication *app) const
+{
+ Q_UNUSED(app)
+ QPalette widgetPalette = QPalette(Qt::white);
+ setThemePalette(&widgetPalette);
+}
+
+QPalette* QS60StylePrivate::themePalette()
+{
+ return m_themePalette;
+}
+
+bool QS60StylePrivate::equalToThemePalette(QColor color, QPalette::ColorRole role)
+{
+ if (!m_themePalette)
+ return false;
+ if (color == m_themePalette->color(role))
+ return true;
+ return false;
+}
+
+bool QS60StylePrivate::equalToThemePalette(qint64 cacheKey, QPalette::ColorRole role)
+{
+ if (!m_themePalette)
+ return false;
+ if (cacheKey == m_themePalette->brush(role).texture().cacheKey())
+ return true;
+ return false;
+}
+
+void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
+{
+ Q_UNUSED(app)
+ QPalette applicationPalette = QApplication::palette();
+ // The initial QPalette::Window is just a placeHolder QPixmap to save RAM
+ // if the actual texture is not needed. The real texture is created just before
+ // painting it in qt_s60_fill_background().
+ applicationPalette.setBrush(QPalette::Window, placeHolderTexture());
+ setThemePalette(&applicationPalette);
+}
+
+void QS60StylePrivate::deleteBackground()
+{
+ if (m_background) {
+ delete m_background;
+ m_background = 0;
+ }
+}
+
+void QS60StylePrivate::setCurrentLayout(int index)
+{
+ m_pmPointer = data[index];
+}
+
+void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart,
+ QPainter *painter, const QRect &rect, SkinElementFlags flags)
+{
+ static const bool doCache =
+#if defined(Q_WS_S60)
+ // Freezes on 3.1. Anyways, caching is only really needed on touch UI
+ !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
+#else
+ true;
+#endif
+
+ const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), painter, flags));
+ if (!skinPartPixMap.isNull())
+ painter->drawPixmap(rect.topLeft(), skinPartPixMap);
+}
+
+void QS60StylePrivate::drawFrame(SkinFrameElements frameElement, QPainter *painter, const QRect &rect, SkinElementFlags flags)
+{
+ static const bool doCache =
+#if defined(Q_WS_S60)
+ // Freezes on 3.1. Anyways, caching is only really needed on touch UI
+ !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
+#else
+ true;
+#endif
+ const QPixmap frameElementPixMap((doCache ? cachedFrame : frame)(frameElement, rect.size(), flags));
+ if (!frameElementPixMap.isNull())
+ painter->drawPixmap(rect.topLeft(), frameElementPixMap);
+}
+
+void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start,
+ QS60StyleEnums::SkinParts middle, QS60StyleEnums::SkinParts end,
+ Qt::Orientation orientation, QPainter *painter, const QRect &rect,
+ SkinElementFlags flags)
+{
+ QSize startEndSize(partSize(start, flags));
+ startEndSize.scale(rect.size(), Qt::KeepAspectRatio);
+
+ QRect startRect = QRect(rect.topLeft(), startEndSize);
+ QRect middleRect = rect;
+ QRect endRect;
+
+ if (orientation == Qt::Horizontal) {
+ startRect.setHeight(rect.height());
+ startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width()));
+ endRect = startRect.translated(rect.width() - startRect.width(), 0);
+ middleRect.adjust(startRect.width(), 0, -startRect.width(), 0);
+ if (startRect.bottomRight().x() > endRect.topLeft().x()) {
+ const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x()) >> 1;
+ startRect.setWidth(startRect.width() - overlap);
+ endRect.adjust(overlap, 0, 0, 0);
+ }
+ } else {
+ startRect.setWidth(rect.width());
+ startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height()));
+ endRect = startRect.translated(0, rect.height() - startRect.height());
+ middleRect.adjust(0, startRect.height(), 0, -startRect.height());
+ if (startRect.topRight().y() > endRect.bottomLeft().y()) {
+ const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y()) >> 1;
+ startRect.setHeight(startRect.height() - overlap);
+ endRect.adjust(0, overlap, 0, 0);
+ }
+ }
+
+#if 0
+ painter->save();
+ painter->setOpacity(.3);
+ painter->fillRect(startRect, Qt::red);
+ painter->fillRect(middleRect, Qt::green);
+ painter->fillRect(endRect, Qt::blue);
+ painter->restore();
+#else
+ drawPart(start, painter, startRect, flags);
+ if (middleRect.isValid())
+ drawPart(middle, painter, middleRect, flags);
+ drawPart(end, painter, endRect, flags);
+#endif
+}
+
+QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part,
+ const QSize &size, QPainter *painter, SkinElementFlags flags)
+{
+ QPixmap result;
+ const int animationFrame = (flags & SF_Animation) ? currentAnimationFrame(part) : 0;
+
+ const QString cacheKey =
+ QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4 AnimationFrame=%5")
+ .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags).arg(animationFrame);
+ if (!QPixmapCache::find(cacheKey, result)) {
+ result = QS60StylePrivate::part(part, size, painter, flags);
+ QPixmapCache::insert(cacheKey, result);
+ }
+ return result;
+}
+
+QPixmap QS60StylePrivate::cachedFrame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags)
+{
+ QPixmap result;
+ const QString cacheKey =
+ QString::fromLatin1("S60Style: SkinFrameElements=%1 QSize=%2|%3 SkinElementFlags=%4")
+ .arg((int)frame).arg(size.width()).arg(size.height()).arg((int)flags);
+ if (!QPixmapCache::find(cacheKey, result)) {
+ result = QS60StylePrivate::frame(frame, size, flags);
+ QPixmapCache::insert(cacheKey, result);
+ }
+ return result;
+}
+
+void QS60StylePrivate::setFont(QWidget *widget) const
+{
+ QS60StyleEnums::FontCategories fontCategory = QS60StyleEnums::FC_Undefined;
+ if (!widget)
+ return;
+ if (qobject_cast<QPushButton *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Primary;
+ } else if (qobject_cast<QToolButton *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Primary;
+ } else if (qobject_cast<QHeaderView *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Secondary;
+ } else if (qobject_cast<QGroupBox *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Title;
+ } else if (qobject_cast<QMessageBox *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Primary;
+ } else if (qobject_cast<QMenu *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Primary;
+ } else if (qobject_cast<QCalendarWidget *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Secondary;
+ }
+ if (fontCategory != QS60StyleEnums::FC_Undefined) {
+ const bool resolveFontSize = widget->testAttribute(Qt::WA_SetFont)
+ && (widget->font().resolve() & QFont::SizeResolved);
+ const QFont suggestedFont =
+ s60Font(fontCategory, widget->font().pointSizeF(), resolveFontSize);
+ widget->setFont(suggestedFont);
+ }
+}
+
+void QS60StylePrivate::setThemePalette(QWidget *widget)
+{
+ if(!widget)
+ return;
+
+ //header view and its viewport need to be set 100% transparent button color, since drawing code will
+ //draw transparent theme graphics to table column and row headers.
+ if (qobject_cast<QHeaderView *>(widget)){
+ QPalette widgetPalette = QApplication::palette(widget);
+ widgetPalette.setColor(QPalette::Active, QPalette::ButtonText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0));
+ QHeaderView* header = qobject_cast<QHeaderView *>(widget);
+ widgetPalette.setColor(QPalette::Button, Qt::transparent );
+ if (header->viewport())
+ header->viewport()->setPalette(widgetPalette);
+ QApplication::setPalette(widgetPalette, "QHeaderView");
+ } else if (qobject_cast<QLabel *>(widget)) {
+ if (widget->window() && widget->window()->windowType() == Qt::Dialog) {
+ QPalette widgetPalette = widget->palette();
+ widgetPalette.setColor(QPalette::WindowText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 19, 0));
+ widget->setPalette(widgetPalette);
+ }
+ }
+}
+
+void QS60StylePrivate::setThemePalette(QPalette *palette) const
+{
+ if (!palette)
+ return;
+
+ // basic colors
+ palette->setColor(QPalette::WindowText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
+ palette->setColor(QPalette::ButtonText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 20, 0));
+ palette->setColor(QPalette::Text,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
+ palette->setColor(QPalette::ToolTipText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 55, 0));
+ palette->setColor(QPalette::BrightText, palette->color(QPalette::WindowText).lighter());
+ palette->setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
+ palette->setColor(QPalette::Link,
+ s60Color(QS60StyleEnums::CL_QsnHighlightColors, 3, 0));
+ palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker());
+ palette->setColor(QPalette::Highlight,
+ s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0));
+ // The initial QPalette::Window is just a placeHolder QPixmap to save RAM
+ // if the actual texture is not needed. The real texture is created just before
+ // painting it in qt_s60_fill_background().
+ palette->setBrush(QPalette::Window, placeHolderTexture());
+ // set as transparent so that styled full screen theme background is visible
+ palette->setBrush(QPalette::Base, Qt::transparent);
+ // set button color based on pixel colors
+#ifndef Q_WS_S60
+ //For emulated style, just calculate the color every time
+ const QColor buttonColor = calculatedColor(SF_ButtonNormal);
+#else
+ const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal);
+#endif
+ palette->setColor(QPalette::Button, buttonColor);
+ palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter());
+ palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker());
+ palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125));
+ palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150));
+ palette->setColor(QPalette::Shadow, Qt::black);
+ QColor alternateBase = palette->light().color();
+ alternateBase.setAlphaF(0.8);
+ palette->setColor(QPalette::AlternateBase, alternateBase);
+
+ QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash
+ setThemePaletteHash(palette);
+ storeThemePalette(palette);
+}
+
+void QS60StylePrivate::deleteThemePalette()
+{
+ if (m_themePalette) {
+ delete m_themePalette;
+ m_themePalette = 0;
+ }
+}
+
+void QS60StylePrivate::storeThemePalette(QPalette *palette)
+{
+ deleteThemePalette();
+ //store specified palette for latter use.
+ m_themePalette = new QPalette(*palette);
+}
+
+// set widget specific palettes
+void QS60StylePrivate::setThemePaletteHash(QPalette *palette)
+{
+ if (!palette)
+ return;
+
+ //store the original palette
+ QPalette widgetPalette = *palette;
+ const QColor mainAreaTextColor =
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0);
+
+ widgetPalette.setColor(QPalette::WindowText,
+ s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0));
+ QApplication::setPalette(widgetPalette, "QSlider");
+ // return to original palette after each widget
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor);
+ widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor);
+ const QStyleOption opt;
+ widgetPalette.setColor(QPalette::Disabled, QPalette::ButtonText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 6, &opt));
+ QApplication::setPalette(widgetPalette, "QPushButton");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor);
+ widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor);
+ QApplication::setPalette(widgetPalette, "QToolButton");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::Active, QPalette::ButtonText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0));
+ QApplication::setPalette(widgetPalette, "QHeaderView");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::ButtonText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0));
+ QApplication::setPalette(widgetPalette, "QMenuBar");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::Text,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
+ widgetPalette.setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
+ QApplication::setPalette(widgetPalette, "QMenu");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::WindowText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0));
+ widgetPalette.setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 3, 0));
+ QApplication::setPalette(widgetPalette, "QTabBar");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0));
+ QApplication::setPalette(widgetPalette, "QListView");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::Text,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
+ widgetPalette.setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
+ QApplication::setPalette(widgetPalette, "QTableView");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::Text,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 27, 0));
+ widgetPalette.setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
+ QApplication::setPalette(widgetPalette, "QLineEdit");
+ QApplication::setPalette(widgetPalette, "QTextEdit");
+ QApplication::setPalette(widgetPalette, "QComboBox");
+ QApplication::setPalette(widgetPalette, "QSpinBox");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0));
+ widgetPalette.setColor(QPalette::HighlightedText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
+ QApplication::setPalette(widgetPalette, "QRadioButton");
+ QApplication::setPalette(widgetPalette, "QCheckBox");
+ widgetPalette = *palette;
+
+ widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor);
+ widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button));
+ widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker());
+ widgetPalette.setColor(QPalette::Light, mainAreaTextColor.lighter());
+ QApplication::setPalette(widgetPalette, "QDial");
+ widgetPalette = *palette;
+
+ widgetPalette.setBrush(QPalette::Window, QBrush());
+ QApplication::setPalette(widgetPalette, "QScrollArea");
+ widgetPalette = *palette;
+
+ //Webpages should not use S60 theme colors as they are designed to work
+ //with themeBackground and do not generally mesh well with web page backgrounds.
+ QPalette webPalette = *palette;
+ webPalette.setColor(QPalette::WindowText, Qt::black);
+ webPalette.setColor(QPalette::Text, Qt::black);
+ webPalette.setBrush(QPalette::Base, Qt::white);
+
+ QApplication::setPalette(webPalette, "QWebView");
+ QApplication::setPalette(webPalette, "QGraphicsWebView");
+
+ m_webPaletteKey = webPalette.cacheKey();
+}
+
+QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags)
+{
+ QSize result(20, 20);
+ switch (part)
+ {
+ case QS60StyleEnums::SP_QgnGrafBarProgress:
+ result.setWidth(pixelMetric(QStyle::PM_ProgressBarChunkWidth));
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveM:
+ case QS60StyleEnums::SP_QgnGrafTabPassiveM:
+ case QS60StyleEnums::SP_QgnGrafTabActiveR:
+ case QS60StyleEnums::SP_QgnGrafTabPassiveR:
+ case QS60StyleEnums::SP_QgnGrafTabPassiveL:
+ case QS60StyleEnums::SP_QgnGrafTabActiveL:
+ //Returned QSize for tabs must not be square, but narrow rectangle with width:height
+ //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones).
+ result.setWidth(result.height() >> 1);
+ break;
+
+ case QS60StyleEnums::SP_QgnGrafNsliderEndLeft:
+ case QS60StyleEnums::SP_QgnGrafNsliderEndRight:
+ case QS60StyleEnums::SP_QgnGrafNsliderMiddle:
+ break;
+
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
+ result.scale(pixelMetric(QStyle::PM_SliderLength),
+ pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio);
+ break;
+
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
+ result.setWidth(pixelMetric(PM_FrameCornerWidth));
+ break;
+
+ case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
+ case QS60StyleEnums::SP_QsnCpScrollBgBottom:
+ case QS60StyleEnums::SP_QsnCpScrollBgTop:
+ case QS60StyleEnums::SP_QsnCpScrollHandleBottom:
+ case QS60StyleEnums::SP_QsnCpScrollHandleTop:
+ case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
+ result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent));
+ result.setWidth(pixelMetric(QStyle::PM_ScrollBarExtent));
+ break;
+ case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
+ case QS60StyleEnums::SP_QsnCpScrollBgMiddle:
+ case QS60StyleEnums::SP_QsnCpScrollHandleMiddle:
+ result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent));
+ result.setWidth(pixelMetric(QStyle::PM_ScrollBarSliderMin));
+ break;
+ default:
+ // Generic frame part size gathering.
+ for (int i = 0; i < frameElementsCount; ++i)
+ {
+ switch (m_frameElementsData[i].center - part) {
+ case 8: /* CornerTl */
+ case 7: /* CornerTr */
+ case 6: /* CornerBl */
+ case 5: /* CornerBr */
+ result.setWidth(pixelMetric(PM_FrameCornerWidth));
+ // Falltrough intended...
+ case 4: /* SideT */
+ case 3: /* SideB */
+ result.setHeight(pixelMetric(PM_FrameCornerHeight));
+ break;
+ case 2: /* SideL */
+ case 1: /* SideR */
+ result.setWidth(pixelMetric(PM_FrameCornerWidth));
+ break;
+ case 0: /* center */
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ if (flags & (SF_PointEast | SF_PointWest)) {
+ const int temp = result.width();
+ result.setWidth(result.height());
+ result.setHeight(temp);
+ }
+ return result;
+}
+
+bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget)
+{
+ // Always return true for web pages.
+ if (widget && m_webPaletteKey == QApplication::palette(widget).cacheKey())
+ return true;
+ //If brush is not changed from style's default values, draw theme graphics.
+ return (backgroundBrush.color() == Qt::transparent ||
+ backgroundBrush.style() == Qt::NoBrush) ? true : false;
+}
+
+bool QS60StylePrivate::isWidgetPressed(const QWidget *widget)
+{
+ return (widget && widget == m_pressedWidget);
+}
+
+// Generates 1*1 white pixmap as a placeholder for real texture.
+// The actual theme texture is drawn in qt_s60_fill_background().
+QPixmap QS60StylePrivate::placeHolderTexture()
+{
+ if (!m_placeHolderTexture) {
+ m_placeHolderTexture = new QPixmap(1,1);
+ m_placeHolderTexture->fill(Qt::green);
+ }
+ return *m_placeHolderTexture;
+}
+
+/*!
+ \class QS60Style
+ \brief The QS60Style class provides a look and feel suitable for applications on S60.
+ \since 4.6
+ \ingroup appearance
+
+ \sa QMacStyle, QWindowsStyle, QWindowsXPStyle, QWindowsVistaStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
+*/
+
+
+/*!
+ Destroys the style.
+*/
+QS60Style::~QS60Style()
+{
+}
+
+/*!
+ \reimp
+*/
+void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
+{
+ const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
+ SubControls sub = option->subControls;
+
+ switch (control) {
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ const bool horizontal = optionSlider->orientation == Qt::Horizontal;
+
+ const QRect scrollBarSlider = subControlRect(control, optionSlider, SC_ScrollBarSlider, widget);
+ const QRect grooveRect = subControlRect(control, optionSlider, SC_ScrollBarGroove, widget);
+
+ const QS60StylePrivate::SkinElements grooveElement =
+ horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical;
+ QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags);
+
+ const SubControls subControls = optionSlider->subControls;
+
+ // select correct slider (horizontal/vertical/pressed)
+ const bool sliderPressed = ((optionSlider->state & State_Sunken) && (subControls & SC_ScrollBarSlider));
+ const QS60StylePrivate::SkinElements handleElement =
+ horizontal ?
+ ( sliderPressed ?
+ QS60StylePrivate::SE_ScrollBarHandlePressedHorizontal :
+ QS60StylePrivate::SE_ScrollBarHandleHorizontal ) :
+ ( sliderPressed ?
+ QS60StylePrivate::SE_ScrollBarHandlePressedVertical :
+ QS60StylePrivate::SE_ScrollBarHandleVertical);
+ QS60StylePrivate::drawSkinElement(handleElement, painter, scrollBarSlider, flags);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+
+ const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
+ const bool horizontal = optionSlider->orientation == Qt::Horizontal;
+
+ //Highlight
+/* if (optionSlider->state & State_HasFocus)
+ drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/
+
+ //Groove graphics
+ if (QS60StylePrivate::hasSliderGrooveGraphic()) {
+ const QS60StylePrivate::SkinElements grooveElement = horizontal ?
+ QS60StylePrivate::SE_SliderGrooveHorizontal :
+ QS60StylePrivate::SE_SliderGrooveVertical;
+ QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
+ } else {
+ const QPoint sliderGrooveCenter = sliderGroove.center();
+ const bool horizontal = optionSlider->orientation == Qt::Horizontal;
+ painter->save();
+ if (widget)
+ painter->setPen(widget->palette().windowText().color());
+ if (horizontal)
+ painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
+ else
+ painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
+ painter->restore();
+ }
+
+ //Handle graphics
+ const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget);
+ QS60StylePrivate::SkinElements handleElement;
+ if (optionSlider->state & State_Sunken)
+ handleElement =
+ horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical;
+ else
+ handleElement =
+ horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
+ QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags);
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ const QRect cmbxEditField = subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
+ const QRect cmbxFrame = subControlRect(CC_ComboBox, option, SC_ComboBoxFrame, widget);
+ const bool direction = cmb->direction == Qt::LeftToRight;
+
+ // Button frame
+ QStyleOptionFrame buttonOption;
+ buttonOption.QStyleOption::operator=(*cmb);
+ const int maxButtonSide = cmbxFrame.width() - cmbxEditField.width();
+ const int newTop = cmbxEditField.center().y() - maxButtonSide / 2;
+ const int topLeftPoint = direction ?
+ (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxButtonSide);
+ const QRect buttonRect(topLeftPoint, newTop, maxButtonSide, maxButtonSide);
+ buttonOption.rect = buttonRect;
+ buttonOption.state = cmb->state;
+ drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget);
+
+ // draw label background - label itself is drawn separately
+ const QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_FrameLineEdit;
+ QS60StylePrivate::drawSkinElement(skinElement, painter, cmbxEditField, flags);
+
+ // Draw the combobox arrow
+ if (sub & SC_ComboBoxArrow) {
+ // Make rect slightly smaller
+ buttonOption.rect.adjust(1, 1, -1, -1);
+ painter->save();
+ painter->setPen(option->palette.buttonText().color());
+ drawPrimitive(PE_IndicatorSpinDown, &buttonOption, painter, widget);
+ painter->restore();
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ State bflags = toolBtn->state & ~State_Sunken;
+
+ if (bflags & State_AutoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+ State mflags = bflags;
+ if (toolBtn->state & State_Sunken) {
+ bflags |= State_Sunken;
+ mflags |= State_Sunken;
+ }
+
+ const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget));
+ QRect menuRect = QRect();
+ if (toolBtn->subControls & SC_ToolButtonMenu)
+ menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget);
+
+ if (toolBtn->subControls & SC_ToolButton) {
+ QStyleOption tool(0);
+ tool.palette = toolBtn->palette;
+
+ if (bflags & (State_Sunken | State_On | State_Raised | State_Enabled)) {
+ tool.rect = button.unite(menuRect);
+ tool.state = bflags;
+ drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+ if (toolBtn->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuRect;
+ tool.state = mflags;
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ }
+ }
+ QStyleOptionToolButton toolButton = *toolBtn;
+ if (toolBtn->features & QStyleOptionToolButton::Arrow) {
+ PrimitiveElement pe;
+ switch (toolBtn->arrowType) {
+ case Qt::LeftArrow:
+ pe = PE_IndicatorArrowLeft;
+ break;
+ case Qt::RightArrow:
+ pe = PE_IndicatorArrowRight;
+ break;
+ case Qt::UpArrow:
+ pe = PE_IndicatorArrowUp;
+ break;
+ case Qt::DownArrow:
+ pe = PE_IndicatorArrowDown;
+ break;
+ default:
+ break; }
+ toolButton.rect = button;
+ drawPrimitive(pe, &toolButton, painter, widget);
+ }
+
+ if (toolBtn->text.length() > 0 ||
+ !toolBtn->icon.isNull()) {
+ const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ toolButton.rect = button.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth);
+ drawControl(CE_ToolButtonLabel, &toolButton, painter, widget);
+ }
+ }
+ break;
+#endif //QT_NO_TOOLBUTTON
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QStyleOptionSpinBox copy = *spinBox;
+ PrimitiveElement pe;
+
+ if (spinBox->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette spinBoxPal = spinBox->palette;
+ if (!(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ spinBoxPal.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ copy.palette = spinBoxPal;
+ }
+
+ if (spinBox->activeSubControls == SC_SpinBoxUp && (spinBox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ?
+ PE_IndicatorSpinPlus :
+ PE_IndicatorSpinUp;
+
+ copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget);
+ drawPrimitive(PE_PanelButtonBevel, &copy, painter, widget);
+ copy.rect.adjust(1, 1, -1, -1);
+ drawPrimitive(pe, &copy, painter, widget);
+ }
+
+ if (spinBox->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = spinBox->state;
+ QPalette spinBoxPal = spinBox->palette;
+ if (!(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ spinBoxPal.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ copy.palette = spinBoxPal;
+ }
+
+ if (spinBox->activeSubControls == SC_SpinBoxDown && (spinBox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ?
+ PE_IndicatorSpinMinus :
+ PE_IndicatorSpinDown;
+
+ copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget);
+ drawPrimitive(PE_PanelButtonBevel, &copy, painter, widget);
+ copy.rect.adjust(1, 1, -1, -1);
+ drawPrimitive(pe, &copy, painter, widget);
+ }
+ }
+ break;
+#endif //QT_NO_SPINBOX
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ // Draw frame
+ const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
+ const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
+ if (groupBox->subControls & SC_GroupBoxFrame) {
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*groupBox);
+ frame.features = groupBox->features;
+ frame.lineWidth = groupBox->lineWidth;
+ frame.midLineWidth = groupBox->midLineWidth;
+ frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
+ drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
+ }
+
+ // Draw title
+ if ((groupBox->subControls & SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ const QColor textColor = groupBox->textColor;
+ painter->save();
+
+ if (textColor.isValid())
+ painter->setPen(textColor);
+ int alignment = int(groupBox->textAlignment);
+ if (!styleHint(SH_UnderlineShortcut, option, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment,
+ groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
+ textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
+ painter->restore();
+ }
+
+ // Draw checkbox
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
+ }
+ }
+ break;
+#endif //QT_NO_GROUPBOX
+ default:
+ QCommonStyle::drawComplexControl(control, option, painter, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+{
+ Q_D(const QS60Style);
+ const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
+ switch (element) {
+ case CE_CheckBox:
+ case CE_RadioButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (element == CE_RadioButton);
+ QStyleOptionButton subopt = *btn;
+
+ // Highlight needs to be drawn first, as it goes "underneath" the text and indicator.
+ if (btn->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+
+ subopt.palette.setColor(QPalette::Active, QPalette::WindowText,
+ subopt.palette.highlightedText().color());
+ }
+
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, painter, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+
+ drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
+ }
+ break;
+
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+
+ drawControl(CE_PushButtonBevel, btn, painter, widget);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
+
+ drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ const bool isDisabled = !(option->state & State_Enabled);
+ const bool isFlat = button->features & QStyleOptionButton::Flat;
+ QS60StyleEnums::SkinParts skinPart;
+ QS60StylePrivate::SkinElements skinElement;
+ if (!isDisabled) {
+ const bool isPressed = (option->state & State_Sunken) ||
+ (option->state & State_On);
+ if (isFlat) {
+ skinPart =
+ isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter;
+ } else {
+ skinElement =
+ isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
+ }
+ } else {
+ if (isFlat)
+ skinPart =QS60StyleEnums::SP_QsnFrButtonCenterInactive;
+ else
+ skinElement = QS60StylePrivate::SE_ButtonInactive;
+ }
+ if (isFlat)
+ QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
+ else
+ QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ }
+ break;
+#ifndef QT_NO_TOOLBUTTON
+ case CE_ToolButtonLabel:
+ if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QStyleOptionToolButton optionToolButton = *toolBtn;
+
+ if (!optionToolButton.icon.isNull() && (optionToolButton.state & State_Sunken)
+ && (optionToolButton.state & State_Enabled)) {
+
+ const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off;
+ const QPixmap pm(optionToolButton.icon.pixmap(optionToolButton.rect.size().boundedTo(optionToolButton.iconSize),
+ QIcon::Normal, state));
+ optionToolButton.icon = generatedIconPixmap(QIcon::Selected, pm, &optionToolButton);
+ }
+
+ QCommonStyle::drawControl(element, &optionToolButton, painter, widget);
+ }
+ break;
+#endif //QT_NO_TOOLBUTTON
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QStyleOption optionComboBox = *comboBox;
+ optionComboBox.palette.setColor(QPalette::Active, QPalette::WindowText,
+ optionComboBox.palette.text().color() );
+ optionComboBox.palette.setColor(QPalette::Inactive, QPalette::WindowText,
+ optionComboBox.palette.text().color() );
+ QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget);
+ const int frameW = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+
+ if (!comboBox->currentIcon.isNull()) {
+ const QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ const QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(comboBox->iconSize.width() + frameW);
+ iconRect = alignedRect(comboBox->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ if (comboBox->editable)
+ painter->fillRect(iconRect, optionComboBox.palette.brush(QPalette::Base));
+ drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
+
+ if (comboBox->direction == Qt::RightToLeft)
+ editRect.setRight(editRect.right() - frameW - comboBox->iconSize.width());
+ else
+ editRect.setLeft(comboBox->iconSize.width() + frameW);
+ }
+ if (!comboBox->currentText.isEmpty() && !comboBox->editable) {
+ const Qt::TextElideMode elideMode = (comboBox->direction == Qt::LeftToRight) ? Qt::ElideRight : Qt::ElideLeft;
+ const QString text = comboBox->fontMetrics.elidedText(comboBox->currentText, elideMode, editRect.width());
+
+ QCommonStyle::drawItemText(painter,
+ editRect.adjusted(QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 0, -1, 0),
+ visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ comboBox->palette, comboBox->state & State_Enabled, text);
+ }
+ }
+ break;
+#endif //QT_NO_COMBOBOX
+#ifndef QT_NO_ITEMVIEWS
+ case CE_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ QStyleOptionViewItemV4 voptAdj = *vopt;
+ painter->save();
+
+ painter->setClipRect(voptAdj.rect);
+ const bool isSelected = (vopt->state & State_Selected);
+ const bool hasFocus = (vopt->state & State_HasFocus);
+
+ bool isScrollBarVisible = false;
+ int scrollBarWidth = 0;
+ QList<QScrollBar *> scrollBars = widget->findChildren<QScrollBar *>();
+ for (int i = 0; i < scrollBars.size(); ++i) {
+ QScrollBar *scrollBar = scrollBars.at(i);
+ if (scrollBar && scrollBar->orientation() == Qt::Vertical) {
+ isScrollBarVisible = scrollBar->isVisible();
+ scrollBarWidth = scrollBar->size().width();
+ break;
+ }
+ }
+
+ int rightValue = widget ? widget->contentsRect().right() : voptAdj.rect.right();
+
+ if (isScrollBarVisible)
+ rightValue -= scrollBarWidth;
+
+ if (voptAdj.rect.right() > rightValue)
+ voptAdj.rect.setRight(rightValue);
+
+ const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget);
+ QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget);
+ const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget);
+
+ const bool singleSelection = itemView &&
+ ((itemView->selectionMode() == QAbstractItemView::SingleSelection ||
+ itemView->selectionMode() == QAbstractItemView::NoSelection));
+ const bool selectItems = itemView && (itemView->selectionBehavior() == QAbstractItemView::SelectItems);
+
+ // draw themed background for itemview unless background brush has been defined.
+ if (vopt->backgroundBrush == Qt::NoBrush) {
+ if (itemView) {
+ //With single item selection, use highlight focus as selection indicator.
+ if (singleSelection && isSelected){
+ voptAdj.state = voptAdj.state | State_HasFocus;
+ if (!hasFocus && selectItems) {
+ painter->save();
+ painter->setOpacity(0.5);
+ }
+ }
+ drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);
+ if (singleSelection && isSelected && !hasFocus && selectItems)
+ painter->restore();
+ }
+ } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);}
+
+ // draw the icon
+ const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled;
+ const QIcon::State state = (voptAdj.state & State_Open) ? QIcon::On : QIcon::Off;
+ voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state);
+
+ // Draw selection check mark or checkbox
+ if (itemView && (!singleSelection || (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator))) {
+ const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget);
+
+ QStyleOptionViewItemV4 checkMarkOption(voptAdj);
+ if (selectionRect.isValid())
+ checkMarkOption.rect = selectionRect;
+ // Draw selection mark.
+ if (isSelected && selectItems) {
+ proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
+ // @todo: this should happen in the rect retrievel i.e. subElementRect()
+ if (textRect.right() > selectionRect.left())
+ textRect.setRight(selectionRect.left());
+ } else if (voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) {
+ checkMarkOption.state = checkMarkOption.state & ~State_HasFocus;
+
+ switch (vopt->checkState) {
+ case Qt::Unchecked:
+ checkMarkOption.state |= State_Off;
+ break;
+ case Qt::PartiallyChecked:
+ checkMarkOption.state |= State_NoChange;
+ break;
+ case Qt::Checked:
+ checkMarkOption.state |= State_On;
+ break;
+ }
+ drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
+ }
+ }
+
+ // draw the text
+ if (!voptAdj.text.isEmpty()) {
+ if (hasFocus)
+ painter->setPen(voptAdj.palette.highlightedText().color());
+ else
+ painter->setPen(voptAdj.palette.text().color());
+ d->viewItemDrawText(painter, &voptAdj, textRect);
+ }
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_ITEMVIEWS
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) {
+ QStyleOptionTabV3 optionTabAdj = *optionTab;
+ const bool isSelected = optionTab->state & State_Selected;
+ const bool directionMirrored = (optionTab->direction == Qt::RightToLeft);
+ QS60StylePrivate::SkinElements skinElement;
+ switch (optionTab->shape) {
+ case QTabBar::TriangularEast:
+ case QTabBar::RoundedEast:
+ skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabEastActive:
+ QS60StylePrivate::SE_TabBarTabEastInactive;
+ break;
+ case QTabBar::TriangularSouth:
+ case QTabBar::RoundedSouth:
+ skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabSouthActive:
+ QS60StylePrivate::SE_TabBarTabSouthInactive;
+ break;
+ case QTabBar::TriangularWest:
+ case QTabBar::RoundedWest:
+ skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabWestActive:
+ QS60StylePrivate::SE_TabBarTabWestInactive;
+ break;
+ case QTabBar::TriangularNorth:
+ case QTabBar::RoundedNorth:
+ default:
+ skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabNorthActive:
+ QS60StylePrivate::SE_TabBarTabNorthInactive;
+ break;
+ }
+ if (skinElement == QS60StylePrivate::SE_TabBarTabEastInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabNorthInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabSouthInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabWestInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabEastActive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabNorthActive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabSouthActive ||
+ skinElement==QS60StylePrivate::SE_TabBarTabWestActive) {
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
+
+ const bool usesScrollButtons =
+ (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
+ const int roomForScrollButton =
+ usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+
+ // adjust for overlapping tabs and scrollbuttons, if necessary
+ if (skinElement == QS60StylePrivate::SE_TabBarTabEastInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabEastActive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabWestInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabWestActive){
+ if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+ optionTabAdj.rect.adjust(0, roomForScrollButton, 0, tabOverlap);
+ else if (optionTabAdj.position == QStyleOptionTabV3::End)
+ optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
+ else
+ optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
+ } else {
+ if (directionMirrored) {
+ if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+ optionTabAdj.rect.adjust(-tabOverlap, 0, -roomForScrollButton, 0);
+ else
+ optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0);
+ } else {
+ if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+ optionTabAdj.rect.adjust(roomForScrollButton, 0, tabOverlap, 0);
+ else
+ optionTabAdj.rect.adjust(0, 0, tabOverlap, 0);
+ }
+ }
+ }
+ QS60StylePrivate::drawSkinElement(skinElement, painter, optionTabAdj.rect, flags);
+ }
+ break;
+ case CE_TabBarTabLabel:
+ if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) {
+ QStyleOptionTabV3 optionTab = *tab;
+ QRect tr = optionTab.rect;
+ const bool directionMirrored = (optionTab.direction == Qt::RightToLeft);
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
+ const bool usesScrollButtons =
+ (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
+ const int roomForScrollButton =
+ usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+
+ switch (tab->shape) {
+ case QTabBar::TriangularWest:
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularEast:
+ case QTabBar::RoundedEast:
+ tr.adjust(0, 0, 0, tabOverlap);
+ break;
+ case QTabBar::TriangularSouth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::RoundedNorth:
+ default:
+ if (directionMirrored)
+ tr.adjust(-tabOverlap, 0, 0, 0);
+ else
+ tr.adjust(0, 0, tabOverlap, 0);
+ break;
+ }
+ painter->save();
+ QFont f = painter->font();
+ f.setPointSizeF(f.pointSizeF() * KTabFontMul);
+ painter->setFont(f);
+
+ const bool selected = optionTab.state & State_Selected;
+ if (selected)
+ optionTab.palette.setColor(QPalette::Active, QPalette::WindowText,
+ optionTab.palette.highlightedText().color());
+
+ const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast
+ || optionTab.shape == QTabBar::RoundedWest
+ || optionTab.shape == QTabBar::TriangularEast
+ || optionTab.shape == QTabBar::TriangularWest;
+
+ //make room for scrollbuttons
+ if (!verticalTabs) {
+ if ((tab->position == QStyleOptionTabV3::Beginning && !directionMirrored))
+ tr.adjust(roomForScrollButton, 0, 0, 0);
+ else if ((tab->position == QStyleOptionTabV3::Beginning && directionMirrored))
+ tr.adjust(0, 0, -roomForScrollButton, 0);
+ } else {
+ if (tab->position == QStyleOptionTabV3::Beginning)
+ tr.adjust(0, roomForScrollButton, 0, 0);
+ }
+
+ if (verticalTabs) {
+ painter->save();
+ int newX, newY, newRotation;
+ if (optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::TriangularEast) {
+ newX = tr.width();
+ newY = tr.y();
+ newRotation = 90;
+ } else {
+ newX = 0;
+ newY = tr.y() + tr.height();
+ newRotation = -90;
+ }
+ tr.setRect(0, 0, tr.height(), tr.width());
+ QTransform m;
+ m.translate(newX, newY);
+ m.rotate(newRotation);
+ painter->setTransform(m, true);
+ }
+ tr.adjust(0, 0, pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget),
+ pixelMetric(PM_TabBarTabShiftVertical, tab, widget));
+
+ if (selected) {
+ tr.setBottom(tr.bottom() - pixelMetric(PM_TabBarTabShiftVertical, tab, widget));
+ tr.setRight(tr.right() - pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget));
+ }
+
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
+ if (!styleHint(SH_UnderlineShortcut, &optionTab, widget))
+ alignment |= Qt::TextHideMnemonic;
+ if (!optionTab.icon.isNull()) {
+ QSize iconSize = optionTab.iconSize;
+ if (!iconSize.isValid()) {
+ const int iconExtent = pixelMetric(PM_TabBarIconSize);
+ iconSize = QSize(iconExtent, iconExtent);
+ }
+ QPixmap tabIcon = optionTab.icon.pixmap(iconSize,
+ (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
+ if (tab->text.isEmpty())
+ painter->drawPixmap(tr.center().x() - (tabIcon.height() >> 1),
+ tr.center().y() - (tabIcon.height() >> 1),
+ tabIcon);
+ else
+ painter->drawPixmap(tr.left() + tabOverlap,
+ tr.center().y() - (tabIcon.height() >> 1),
+ tabIcon);
+ tr.setLeft(tr.left() + iconSize.width() + 4); //todo: magic four
+ }
+
+ QCommonStyle::drawItemText(painter, tr, alignment, optionTab.palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
+ if (verticalTabs)
+ painter->restore();
+
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_TABBAR
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ QRect progressRect = optionProgressBar->rect;
+
+ if (optionProgressBar->minimum == optionProgressBar->maximum && optionProgressBar->minimum == 0) {
+ // busy indicator
+ const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ?
+ QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest;
+
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWaitAnim,
+ painter, progressRect, flags | orientationFlag | QS60StylePrivate::SF_Animation );
+ } else {
+ const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0
+ : (qreal)optionProgressBar->progress / optionProgressBar->maximum;
+ const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ if (optionProgressBar->orientation == Qt::Horizontal) {
+ progressRect.setWidth(int(progressRect.width() * progressFactor));
+ if(optionProgressBar->direction == Qt::RightToLeft)
+ progressRect.translate(optionProgressBar->rect.width() - progressRect.width(), 0);
+ progressRect.adjust(frameWidth, 0, -frameWidth, 0);
+ } else {
+ progressRect.adjust(0, frameWidth, 0, -frameWidth);
+ progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor));
+ }
+
+ const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ?
+ QS60StylePrivate::SE_ProgressBarIndicatorHorizontal : QS60StylePrivate::SE_ProgressBarIndicatorVertical;
+ QS60StylePrivate::drawSkinElement(skinElement, painter, progressRect, flags);
+ }
+ }
+ break;
+ case CE_ProgressBarGroove:
+ if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ?
+ QS60StylePrivate::SE_ProgressBarGrooveHorizontal : QS60StylePrivate::SE_ProgressBarGrooveVertical;
+ QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ }
+ break;
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBarV2 *progressbar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ QStyleOptionProgressBarV2 optionProgressBar = *progressbar;
+ QCommonStyle::drawItemText(painter, progressbar->rect, flags | Qt::AlignCenter | Qt::TextSingleLine, optionProgressBar.palette,
+ progressbar->state & State_Enabled, progressbar->text, QPalette::WindowText);
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ QStyleOptionMenuItem optionMenuItem = *menuItem;
+
+ bool drawSubMenuIndicator = false;
+ bool drawSeparator = false;
+ switch(menuItem->menuItemType) {
+ case QStyleOptionMenuItem::Separator:
+ drawSeparator = true;
+ break;
+ case QStyleOptionMenuItem::Scroller:
+ return; // no scrollers in S60 menus
+ case QStyleOptionMenuItem::SubMenu:
+ drawSubMenuIndicator = true;
+ break;
+ default:
+ break;
+ }
+ if (drawSeparator) {
+ painter->save();
+ painter->setPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 10, 0));
+ painter->drawLine(optionMenuItem.rect.topLeft(), optionMenuItem.rect.bottomRight());
+ painter->restore();
+ return;
+ }
+ const bool enabled = optionMenuItem.state & State_Enabled;
+ const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable;
+ bool ignoreCheckMark = false;
+
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox*>(widget))
+ ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
+#endif
+
+ uint text_flags = Qt::AlignLeading | Qt::TextShowMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine | Qt::AlignVCenter;
+ if (!styleHint(SH_UnderlineShortcut, menuItem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+
+ QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget);
+ QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
+
+ QStyleOptionMenuItem optionCheckBox;
+
+ //Regardless of checkbox visibility, make room for it, this mirrors native implementation,
+ //where text and icon placement is static regardless of content of menu item.
+ optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
+ optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
+ optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
+
+ const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
+ //The vertical spacing is doubled; it needs one spacing to separate checkbox from
+ //highlight and then it needs one to separate it whatever is shown after it (text/icon/both).
+ const int moveByX = optionCheckBox.rect.width() + 2 * vSpacing;
+ optionCheckBox.rect.moveCenter(QPoint(
+ optionCheckBox.rect.center().x() + moveByX >> 1,
+ menuItem->rect.center().y()));
+
+ if (optionMenuItem.direction != Qt::LeftToRight)
+ optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0);
+
+
+ const bool selected = (option->state & State_Selected) && (option->state & State_Enabled);
+ if (selected) {
+ const int spacing = ignoreCheckMark ? (vSpacing + QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth)) : 0;
+ const int start = optionMenuItem.rect.left() + spacing;
+ const int end = optionMenuItem.rect.right() - spacing;
+ //-1 adjustment to avoid highlight being on top of possible separator item
+ const QRect highlightRect = QRect(
+ QPoint(start, option->rect.top()),
+ QPoint(end, option->rect.bottom() - 1));
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags);
+ }
+
+ if (checkable && !ignoreCheckMark)
+ drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget);
+
+ //draw icon and/or checkState
+ QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize),
+ enabled ? QIcon::Normal : QIcon::Disabled);
+ const bool itemWithIcon = !pix.isNull();
+ if (itemWithIcon) {
+ drawItemPixmap(painter, iconRect, text_flags, pix);
+ if (optionMenuItem.direction == Qt::LeftToRight)
+ textRect.translate(vSpacing, 0);
+ else
+ textRect.translate(-vSpacing, 0);
+ textRect.setWidth(textRect.width() - vSpacing);
+ }
+
+ //draw indicators
+ if (drawSubMenuIndicator) {
+ QStyleOptionMenuItem arrowOptions;
+ arrowOptions.QStyleOption::operator=(*menuItem);
+ const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) +
+ pixelMetric(PM_LayoutVerticalSpacing, option, widget);
+ if (optionMenuItem.direction == Qt::LeftToRight)
+ arrowOptions.rect.setLeft(textRect.right());
+ arrowOptions.rect.setWidth(indicatorWidth);
+ //by default sub menu indicator in S60 points to east,so here icon
+ // direction is set to north (and south when in RightToLeft)
+ const QS60StylePrivate::SkinElementFlag arrowDirection = (arrowOptions.direction == Qt::LeftToRight) ?
+ QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth;
+ painter->save();
+ painter->setPen(option->palette.windowText().color());
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubmenu, painter, arrowOptions.rect,
+ (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection));
+ painter->restore();
+ }
+
+ //draw text
+ if (!enabled){
+ //In s60, if something becomes disabled, it is removed from menu, so no native look-alike available.
+ optionMenuItem.palette.setColor(QPalette::Disabled, QPalette::Text, QS60StylePrivate::lighterColor(
+ optionMenuItem.palette.color(QPalette::Disabled, QPalette::Text)));
+ painter->save();
+ painter->setOpacity(0.5);
+ }
+ if (selected)
+ optionMenuItem.palette.setColor(
+ QPalette::Active, QPalette::Text, optionMenuItem.palette.highlightedText().color());
+
+ QCommonStyle::drawItemText(painter, textRect, text_flags,
+ optionMenuItem.palette, enabled,
+ optionMenuItem.text, QPalette::Text);
+
+ //In Sym^3, native menu items have "lines" between them
+ if (QS60StylePrivate::isSingleClickUi()) {
+ int diff = widget->geometry().bottom() - optionMenuItem.rect.bottom();
+ if (const QComboBox *cb = qobject_cast<const QComboBox*>(widget))
+ diff = cb->view()->geometry().bottom() - optionMenuItem.rect.bottom();
+
+ // Skip drawing the horizontal line for the last menu item.
+ if (diff > optionMenuItem.rect.height()) {
+ const QColor lineColorAlpha = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 15, 0);
+ //native platform sets each color byte to same value for "line 16" which just defines alpha for
+ //menuitem lines; lets use first byte "red".
+ QColor lineColor = optionMenuItem.palette.text().color();
+ if (lineColorAlpha.isValid())
+ lineColor.setAlpha(lineColorAlpha.red());
+ painter->save();
+ painter->setPen(lineColor);
+ const int horizontalMargin = 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ const int lineStartX = optionMenuItem.rect.left() + horizontalMargin;
+ const int lineEndX = optionMenuItem.rect.right() - horizontalMargin;
+ painter->drawLine(QPoint(lineStartX, optionMenuItem.rect.bottom()), QPoint(lineEndX, optionMenuItem.rect.bottom()));
+ painter->restore();
+ }
+ }
+ if (!enabled)
+ painter->restore();
+ }
+ break;
+ case CE_MenuEmptyArea:
+ break;
+#endif //QT_NO_MENU
+
+#ifndef QT_NO_MENUBAR
+ case CE_MenuBarEmptyArea:
+ break;
+#endif //QT_NO_MENUBAR
+
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ painter->save();
+ QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
+ const int penWidth = (header->orientation == Qt::Horizontal) ?
+ linePen.width() + QS60StylePrivate::pixelMetric(PM_BoldLineWidth)
+ : linePen.width() + QS60StylePrivate::pixelMetric(PM_ThinLineWidth);
+ linePen.setWidth(penWidth);
+ painter->setPen(linePen);
+ if (header->orientation == Qt::Horizontal){
+ painter->drawLine(header->rect.bottomLeft(), header->rect.bottomRight());
+ } else {
+ if ( header->direction == Qt::LeftToRight ) {
+ painter->drawLine(header->rect.topRight(), header->rect.bottomRight());
+ } else {
+ painter->drawLine(header->rect.topLeft(), header->rect.bottomLeft());
+ }
+ }
+ painter->restore();
+
+ //Draw corner button as normal pushButton.
+ if (qobject_cast<const QAbstractButton *>(widget)) {
+ //Make cornerButton slightly smaller so that it is not on top of table border graphic.
+ QStyleOptionHeader subopt = *header;
+ const int borderTweak =
+ QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1;
+ if (subopt.direction == Qt::LeftToRight)
+ subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak);
+ else
+ subopt.rect.adjust(0, borderTweak, -borderTweak, -borderTweak);
+ drawPrimitive(PE_PanelButtonBevel, &subopt, painter, widget);
+ } else if ((header->palette.brush(QPalette::Button) != Qt::transparent)) {
+ //Draw non-themed background. Background for theme is drawn in CE_ShapedFrame
+ //to get continuous theme graphic across all the header cells.
+ qDrawShadePanel(painter, header->rect, header->palette,
+ header->state & (State_Sunken | State_On), penWidth,
+ &header->palette.brush(QPalette::Button));
+ }
+ }
+ break;
+ case CE_HeaderEmptyArea: // no need to draw this
+ break;
+ case CE_Header:
+ if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ drawControl(CE_HeaderSection, header, painter, widget);
+ QStyleOptionHeader subopt = *header;
+ subopt.rect = subElementRect(SE_HeaderLabel, header, widget);
+ if (subopt.rect.isValid())
+ drawControl(CE_HeaderLabel, &subopt, painter, widget);
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ subopt.rect = subElementRect(SE_HeaderArrow, option, widget);
+ drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget);
+ }
+ }
+ break;
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ const QToolBar *tbWidget = qobject_cast<const QToolBar *>(widget);
+
+ //toolbar within a toolbar, skip
+ if (!tbWidget || (widget && qobject_cast<QToolBar *>(widget->parentWidget())))
+ break;
+
+ // Normally in S60 5.0+ there is no background for toolbar, but in some cases with versatile QToolBar,
+ // it looks a bit strange. So, lets fillRect with Button.
+ if (!QS60StylePrivate::isToolBarBackground()) {
+ QList<QAction *> actions = tbWidget->actions();
+ bool justToolButtonsInToolBar = true;
+ for (int i = 0; i < actions.size(); ++i) {
+ QWidget *childWidget = tbWidget->widgetForAction(actions.at(i));
+ const QToolButton *button = qobject_cast<const QToolButton *>(childWidget);
+ if (!button){
+ justToolButtonsInToolBar = false;
+ }
+ }
+
+ // Draw frame background
+ // for vertical toolbars with text only and
+ // for toolbars with extension buttons and
+ // for toolbars with widgets in them.
+ if (!justToolButtonsInToolBar ||
+ (tbWidget &&
+ (tbWidget->orientation() == Qt::Vertical) &&
+ (tbWidget->toolButtonStyle() == Qt::ToolButtonTextOnly))) {
+ painter->save();
+ if (widget)
+ painter->setBrush(widget->palette().button());
+ painter->setOpacity(0.3);
+ painter->fillRect(toolBar->rect, painter->brush());
+ painter->restore();
+ }
+ } else {
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBar, painter, toolBar->rect, flags);
+ }
+ }
+ break;
+#endif //QT_NO_TOOLBAR
+ case CE_ShapedFrame:
+ if (const QTextEdit *textEdit = qobject_cast<const QTextEdit *>(widget)) {
+ const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option);
+ if (frame && QS60StylePrivate::canDrawThemeBackground(frame->palette.base(), widget))
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags);
+ else
+ QCommonStyle::drawControl(element, option, painter, widget);
+ } else if (qobject_cast<const QTableView *>(widget)) {
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags);
+ } else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) {
+ //QS60style draws header background here instead of in each headersection, to get
+ //continuous graphic from section to section.
+ QS60StylePrivate::SkinElementFlags adjustableFlags = flags;
+ QRect headerRect = option->rect;
+ if (header->orientation() != Qt::Horizontal) {
+ //todo: update to horizontal table graphic
+ adjustableFlags = (adjustableFlags | QS60StylePrivate::SF_PointWest);
+ } else {
+ const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ if (option->direction == Qt::LeftToRight)
+ headerRect.adjust(-2 * frameWidth, 0, 0, 0);
+ else
+ headerRect.adjust(0, 0, 2 * frameWidth, 0);
+ }
+ if (option->palette.brush(QPalette::Button).color() == Qt::transparent)
+ QS60StylePrivate::drawSkinElement(
+ QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, adjustableFlags);
+
+ } else if (qobject_cast<const QFrame *>(widget)) {
+ QCommonStyle::drawControl(element, option, painter, widget);
+ }
+ break;
+ case CE_MenuScroller:
+ break;
+ case CE_FocusFrame: {
+#ifdef QT_KEYPAD_NAVIGATION
+ bool editFocus = false;
+ if (const QFocusFrame *focusFrame = qobject_cast<const QFocusFrame*>(widget)) {
+ if (focusFrame->widget() && focusFrame->widget()->hasEditFocus())
+ editFocus = true;
+ }
+ const qreal opacity = editFocus ? 1 : 0.75; // Trial and error factors. Feel free to improve.
+#else
+ const qreal opacity = 0.85;
+#endif
+ // We need to reduce the focus frame size if LayoutSpacing is smaller than FocusFrameMargin
+ // Otherwise, we would overlay adjacent widgets.
+ const int frameHeightReduction =
+ qMin(0, pixelMetric(PM_LayoutVerticalSpacing)
+ - pixelMetric(PM_FocusFrameVMargin));
+ const int frameWidthReduction =
+ qMin(0, pixelMetric(PM_LayoutHorizontalSpacing)
+ - pixelMetric(PM_FocusFrameHMargin));
+ const int rounding =
+ qMin(pixelMetric(PM_FocusFrameVMargin),
+ pixelMetric(PM_LayoutVerticalSpacing));
+ const QRect frameRect =
+ option->rect.adjusted(-frameWidthReduction, -frameHeightReduction,
+ frameWidthReduction, frameHeightReduction);
+ QPainterPath framePath;
+ framePath.addRoundedRect(frameRect, rounding, rounding);
+
+ painter->save();
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->setOpacity(opacity);
+ painter->fillPath(framePath, option->palette.color(QPalette::Text));
+ painter->restore();
+ }
+ break;
+ case CE_Splitter:
+ if (option->state & State_Sunken && option->state & State_Enabled && QS60StylePrivate::themePalette()) {
+ painter->save();
+ painter->setOpacity(0.5);
+ painter->setBrush(QS60StylePrivate::themePalette()->light());
+ painter->setRenderHint(QPainter::Antialiasing);
+ const qreal roundRectRadius = 4 * goldenRatio;
+ painter->drawRoundedRect(option->rect, roundRectRadius, roundRectRadius);
+ painter->restore();
+ }
+ break;
+ default:
+ QCommonStyle::drawControl(element, option, painter, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+{
+ const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
+ bool commonStyleDraws = false;
+
+ switch (element) {
+ case PE_FrameFocusRect: {
+ //Draw themed highlight to radiobuttons and checkboxes.
+ //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle.
+ if (QS60StylePrivate::equalToThemePalette(option->palette.highlight().color(), QPalette::Highlight)) {
+ if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) &&
+ (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget))))
+ QS60StylePrivate::drawSkinElement(
+ QS60StylePrivate::isWidgetPressed(widget) ?
+ QS60StylePrivate::SE_ListItemPressed :
+ QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
+ } else {
+ commonStyleDraws = true;
+ }
+ }
+ break;
+#ifndef QT_NO_LINEEDIT
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+#ifndef QT_NO_COMBOBOX
+ if (widget && qobject_cast<const QComboBox *>(widget->parentWidget()))
+ break;
+#endif
+ if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget))
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, painter, option->rect, flags);
+ else
+ commonStyleDraws = true;
+ }
+ break;
+#endif // QT_NO_LINEEDIT
+ case PE_IndicatorCheckBox: {
+ // Draw checkbox indicator as color skinned graphics.
+ const QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ?
+ QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff;
+ painter->save();
+
+ if (QS60StylePrivate::equalToThemePalette(option->palette.windowText().color(), QPalette::WindowText))
+ painter->setPen(option->palette.windowText().color());
+
+ QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags | QS60StylePrivate::SF_ColorSkinned );
+ painter->restore();
+ }
+ break;
+ case PE_IndicatorViewItemCheck:
+#ifndef QT_NO_ITEMVIEWS
+ if (const QAbstractItemView *itemView = (qobject_cast<const QAbstractItemView *>(widget))) {
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator;
+ const bool singleSelection = itemView->selectionMode() ==
+ QAbstractItemView::SingleSelection || itemView->selectionMode() == QAbstractItemView::NoSelection;
+ // draw either checkbox at the beginning
+ if (checkBoxVisible && singleSelection) {
+ drawPrimitive(PE_IndicatorCheckBox, option, painter, widget);
+ // ... or normal "tick" selection at the end.
+ } else if (option->state & State_Selected) {
+ QRect tickRect = option->rect;
+ const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
+ // adjust tickmark rect to exclude frame border
+ tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth);
+ QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd;
+ QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect,
+ (flags | QS60StylePrivate::SF_ColorSkinned));
+ }
+ }
+ }
+#endif //QT_NO_ITEMVIEWS
+ break;
+ case PE_IndicatorRadioButton: {
+ QRect buttonRect = option->rect;
+ //there is empty (a. 33%) space in svg graphics for radiobutton
+ const qreal reduceWidth = (qreal)buttonRect.width() / 3.0;
+ const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0;
+ // Try to occupy the full area
+ const qreal scaler = 1 + (reduceWidth/rectWidth);
+ buttonRect.setWidth((int)((buttonRect.width()-reduceWidth) * scaler));
+ buttonRect.setHeight((int)(buttonRect.height() * scaler));
+ // move the rect up for half of the new height-gain
+ const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ;
+ buttonRect.adjust(0, -newY, -1, -newY);
+
+ painter->save();
+ const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option);
+ const QColor buttonTextColor = option->palette.buttonText().color();
+ if (themeColor != buttonTextColor)
+ painter->setPen(buttonTextColor);
+ else
+ painter->setPen(themeColor);
+
+ // Draw radiobutton indicator as color skinned graphics.
+ QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ?
+ QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff;
+ QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect,
+ (flags | QS60StylePrivate::SF_ColorSkinned));
+ painter->restore();
+ }
+ break;
+ case PE_PanelButtonCommand:
+ case PE_PanelButtonTool:
+ case PE_PanelButtonBevel:
+ case PE_FrameButtonBevel:
+ if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) {
+ const bool isPressed = (option->state & State_Sunken) || (option->state & State_On);
+ QS60StylePrivate::SkinElements skinElement;
+ if (element == PE_PanelButtonTool)
+ skinElement = isPressed ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
+ else
+ skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
+ QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
+ } else {
+ commonStyleDraws = true;
+ }
+ break;
+#ifndef QT_NO_TOOLBUTTON
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowLeft:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowUp: {
+ QS60StyleEnums::SkinParts skinPart;
+ if (element==PE_IndicatorArrowDown)
+ skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
+ else if (element==PE_IndicatorArrowLeft)
+ skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowLeft;
+ else if (element==PE_IndicatorArrowRight)
+ skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowRight;
+ else if (element==PE_IndicatorArrowUp)
+ skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowUp;
+
+ QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
+ }
+ break;
+#endif //QT_NO_TOOLBUTTON
+#ifndef QT_NO_SPINBOX
+ case PE_IndicatorSpinDown:
+ case PE_IndicatorSpinUp:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base(), widget)) {
+ QStyleOptionSpinBox optionSpinBox = *spinBox;
+ const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
+ QS60StyleEnums::SP_QgnGrafScrollArrowUp :
+ QS60StyleEnums::SP_QgnGrafScrollArrowDown;
+ const int iconMargin = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1;
+ optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
+ QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags);
+ } else {
+ commonStyleDraws = true;
+ }
+ }
+#endif //QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ if (QS60StylePrivate::canDrawThemeBackground( option->palette.base(), widget)) {
+ // We want to draw down arrow here for comboboxes as well.
+ QStyleOptionFrame optionsComboBox = *cmb;
+ const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
+ const int iconMargin = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1;
+ optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
+ QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags);
+ } else {
+ commonStyleDraws = true;
+ }
+ }
+#endif //QT_NO_COMBOBOX
+ break;
+ case PE_IndicatorSpinMinus:
+ case PE_IndicatorSpinPlus:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QStyleOptionSpinBox optionSpinBox = *spinBox;
+ QCommonStyle::drawPrimitive(element, &optionSpinBox, painter, widget);
+ }
+#ifndef QT_NO_COMBOBOX
+ else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ // We want to draw down arrow here for comboboxes as well.
+ QStyleOptionFrame comboBox = *cmb;
+ const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ comboBox.rect.adjust(0, frameWidth, 0, -frameWidth);
+ QCommonStyle::drawPrimitive(element, &comboBox, painter, widget);
+ }
+#endif //QT_NO_COMBOBOX
+ break;
+ case PE_Widget:
+ if (QS60StylePrivate::drawsOwnThemeBackground(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<const QComboBoxListView *>(widget)
+#endif //QT_NO_COMBOBOX
+#ifndef QT_NO_MENU
+ || qobject_cast<const QMenu *> (widget)
+#endif //QT_NO_MENU
+ ) {
+ //Need extra check since dialogs have their own theme background
+ if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)
+ && QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window)) {
+ const bool comboMenu = qobject_cast<const QComboBoxListView *>(widget);
+ // Add margin area to the background, to avoid background being cut for first and last item.
+ const int verticalMenuAdjustment = comboMenu ? QS60StylePrivate::pixelMetric(PM_MenuVMargin) : 0;
+ const QRect adjustedMenuRect = option->rect.adjusted(0, -verticalMenuAdjustment, 0, verticalMenuAdjustment);
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, adjustedMenuRect, flags);
+ } else {
+ commonStyleDraws = true;
+ }
+ }
+ break;
+ case PE_FrameWindow:
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *tabFrame = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
+ QStyleOptionTabWidgetFrame optionTabFrame = *tabFrame;
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PanelBackground, painter, optionTabFrame.rect, flags);
+ }
+ break;
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ if (header->sortIndicator & QStyleOptionHeader::SortUp)
+ drawPrimitive(PE_IndicatorArrowUp, header, painter, widget);
+ else if (header->sortIndicator & QStyleOptionHeader::SortDown)
+ drawPrimitive(PE_IndicatorArrowDown, header, painter, widget);
+ } // QStyleOptionHeader::None is not drawn => not needed
+ break;
+#ifndef QT_NO_GROUPBOX
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrameV2 *frame = qstyleoption_cast<const QStyleOptionFrameV2 *>(option))
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_SettingsList, painter, frame->rect, flags);
+ break;
+#endif //QT_NO_GROUPBOX
+
+ // Qt3 primitives are not supported
+ case PE_Q3CheckListController:
+ case PE_Q3CheckListExclusiveIndicator:
+ case PE_Q3CheckListIndicator:
+ case PE_Q3DockWindowSeparator:
+ case PE_Q3Separator:
+ Q_ASSERT(false);
+ break;
+ case PE_Frame:
+ break;
+#ifndef QT_NO_ITEMVIEWS
+ case PE_PanelItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ const bool isSelected = (vopt->state & State_Selected);
+ const bool hasFocus = (vopt->state & State_HasFocus);
+ const bool isPressed = QS60StylePrivate::isWidgetPressed(widget);
+
+ if (QS60StylePrivate::equalToThemePalette(option->palette.highlight().color(), QPalette::Highlight)) {
+ QRect highlightRect = vopt->rect.adjusted(1,1,-1,-1);
+ const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget);
+ QAbstractItemView::SelectionBehavior selectionBehavior =
+ itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems;
+ // Set the draw area for highlights (focus, select rect or pressed rect)
+ if (hasFocus || isPressed) {
+ if (selectionBehavior != QAbstractItemView::SelectItems) {
+ // set highlight rect so that it is continuous from cell to cell, yet sligthly
+ // smaller than cell rect
+ int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0;
+ if (selectionBehavior == QAbstractItemView::SelectRows) {
+ yBeginning = 1; yEnd = -1;
+ if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+ xBeginning = 1;
+ else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
+ xEnd = -1;
+ } else if (selectionBehavior == QAbstractItemView::SelectColumns) {
+ xBeginning = 1; xEnd = -1;
+ if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+ yBeginning = 1;
+ else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
+ yEnd = -1;
+ }
+ highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd);
+ }
+ }
+ bool tableView = false;
+ if (itemView && qobject_cast<const QTableView *>(widget))
+ tableView = true;
+
+ QS60StylePrivate::SkinElements element;
+ bool themeGraphicDefined = false;
+ QRect elementRect = option->rect;
+
+ //draw item is drawn as pressed, if it already has focus.
+ if (isPressed && hasFocus) {
+ themeGraphicDefined = true;
+ element = tableView ? QS60StylePrivate::SE_TableItemPressed : QS60StylePrivate::SE_ListItemPressed;
+ } else if (hasFocus || (isSelected && selectionBehavior != QAbstractItemView::SelectItems)) {
+ element = QS60StylePrivate::SE_ListHighlight;
+ elementRect = highlightRect;
+ themeGraphicDefined = true;
+ }
+ if (themeGraphicDefined)
+ QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags);
+ } else {
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ }
+ }
+ break;
+#endif //QT_NO_ITEMVIEWS
+
+ case PE_IndicatorMenuCheckMark:
+ if (const QStyleOptionMenuItem *checkBox = qstyleoption_cast<const QStyleOptionMenuItem *>(option)){
+ QStyleOptionMenuItem optionCheckBox = *checkBox;
+ if (optionCheckBox.checked)
+ optionCheckBox.state = (optionCheckBox.state | State_On);
+ drawPrimitive(PE_IndicatorCheckBox, &optionCheckBox, painter, widget);
+ }
+ break;
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarHandle:
+ // no toolbar handles in S60/AVKON UI
+ case PE_IndicatorToolBarSeparator:
+ // no separators in S60/AVKON UI
+ break;
+#endif //QT_NO_TOOLBAR
+
+ case PE_PanelMenuBar:
+ case PE_FrameMenu:
+ break; //disable frame in menu
+
+ case PE_IndicatorBranch:
+#if defined(Q_WS_S60)
+ // 3.1 AVKON UI does not have tree view component, use common style for drawing there
+ if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1) {
+#else
+ if (true) {
+#endif
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ } else {
+ if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(option)) {
+ const bool rightLine = option->state & State_Item;
+ const bool downLine = option->state & State_Sibling;
+ const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling);
+ QS60StylePrivate::SkinElementFlags adjustedFlags = flags;
+
+ QS60StyleEnums::SkinParts skinPart;
+ bool drawSkinPart = false;
+ if (rightLine && downLine && upLine) {
+ skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch;
+ drawSkinPart = true;
+ } else if (rightLine && upLine) {
+ skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd;
+ drawSkinPart = true;
+ } else if (upLine && downLine) {
+ skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight;
+ drawSkinPart = true;
+ }
+
+ if (option->direction == Qt::RightToLeft)
+ adjustedFlags |= QS60StylePrivate::SF_Mirrored_X_Axis;
+
+ if (drawSkinPart)
+ QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, adjustedFlags);
+
+ if (option->state & State_Children) {
+ QS60StyleEnums::SkinParts skinPart =
+ (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper;
+ const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
+ const int minDimension = qMin(option->rect.width(), option->rect.height());
+ const int magicTweak = (option->direction == Qt::RightToLeft) ? -3 : 3; //@todo: magic
+ //The branch indicator icon in S60 is supposed to be superimposed on top of branch lines.
+ QRect iconRect(QPoint(option->rect.left() + magicTweak, selectionRect.top() + 1), QSize(minDimension, minDimension));
+ if (!QS60StylePrivate::isTouchSupported())
+ iconRect.translate(0, -4); //@todo: magic
+ QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, adjustedFlags);
+ }
+ }
+ }
+ break;
+ case PE_PanelItemViewRow: // ### Qt 5: remove
+#ifndef QT_NO_ITEMVIEWS
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ if (!QS60StylePrivate::equalToThemePalette(vopt->palette.base().texture().cacheKey(), QPalette::Base)) {
+ //QPalette::Base has been changed, let commonstyle draw the item
+ commonStyleDraws = true;
+ } else {
+ QPalette::ColorGroup cg = vopt->state & State_Enabled ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & State_Active))
+ cg = QPalette::Inactive;
+ if (vopt->features & QStyleOptionViewItemV2::Alternate)
+ painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase));
+ //apart from alternate base, no background for list item is drawn for S60Style
+ }
+ }
+#endif
+ break;
+ case PE_PanelScrollAreaCorner:
+ break;
+ case PE_IndicatorItemViewItemDrop:
+ if (QS60StylePrivate::isTouchSupported())
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_DropArea, painter, option->rect, flags);
+ else
+ commonStyleDraws = true;
+ break;
+ // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
+ case PE_FrameLineEdit:
+ case PE_IndicatorDockWidgetResizeHandle:
+ case PE_PanelTipLabel:
+
+#ifndef QT_NO_TABBAR
+ case PE_IndicatorTabTear: // No tab tear in S60
+#endif // QT_NO_TABBAR
+ case PE_FrameDefaultButton:
+#ifndef QT_NO_DOCKWIDGET
+ case PE_FrameDockWidget:
+#endif //QT_NO_DOCKWIDGET
+#ifndef QT_NO_PROGRESSBAR
+ case PE_IndicatorProgressChunk:
+#endif //QT_NO_PROGRESSBAR
+#ifndef QT_NO_TOOLBAR
+ case PE_PanelToolBar:
+#endif //QT_NO_TOOLBAR
+#ifndef QT_NO_COLUMNVIEW
+ case PE_IndicatorColumnViewArrow:
+#endif //QT_NO_COLUMNVIEW
+ case PE_FrameTabBarBase: // since tabs are in S60 always in navipane, let's use common style for tab base in Qt.
+ default:
+ commonStyleDraws = true;
+ }
+ if (commonStyleDraws) {
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ }
+}
+
+/*! \reimp */
+int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ int metricValue = QS60StylePrivate::pixelMetric(metric);
+ if (metricValue == KNotFound)
+ metricValue = QCommonStyle::pixelMetric(metric, option, widget);
+
+ // Menu scrollers should be set to zero height for combobox popups
+ if (metric == PM_MenuScrollerHeight && !qobject_cast<const QMenu *>(widget))
+ metricValue = 0;
+
+ //if layout direction is mirrored, switch left and right border margins
+ if (option && option->direction == Qt::RightToLeft) {
+ if (metric == PM_LayoutLeftMargin)
+ metricValue = QS60StylePrivate::pixelMetric(PM_LayoutRightMargin);
+ else if (metric == PM_LayoutRightMargin)
+ metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin);
+ }
+
+ if (widget && (metric == PM_LayoutTopMargin || metric == PM_LayoutLeftMargin || metric == PM_LayoutRightMargin))
+ if (widget->windowType() == Qt::Dialog)
+ //double the layout margins (except bottom) for dialogs, it is very close to real value
+ //without having to define custom pixel metric
+ metricValue *= 2;
+
+#if defined(Q_WS_S60)
+ if (metric == PM_TabBarTabOverlap && (QSysInfo::s60Version() > QSysInfo::SV_S60_5_2))
+ metricValue = 0;
+#endif
+
+ return metricValue;
+}
+
+/*! \reimp */
+QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *widget) const
+{
+ QSize sz(csz);
+ switch (ct) {
+ case CT_ToolButton:
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ //FIXME properly - style should calculate the location of border frame-part
+ sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin));
+ if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
+ if (toolBtn->subControls & SC_ToolButtonMenu)
+ sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0);
+
+ //Make toolbuttons in toolbar stretch the whole screen area
+ if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
+ const QToolBar *tb = qobject_cast<const QToolBar *>(widget->parentWidget());
+ const bool parentCanGrowHorizontally = !(tb->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed ||
+ tb->sizePolicy().horizontalPolicy() == QSizePolicy::Maximum) && tb->orientation() == Qt::Horizontal;
+
+ if (parentCanGrowHorizontally) {
+ int buttons = 0;
+ //Make the auto-stretch to happen only for horizontal orientation
+ if (tb && tb->orientation() == Qt::Horizontal) {
+ QList<QAction*> actionList = tb->actions();
+ for (int i = 0; i < actionList.count(); i++) {
+ buttons++;
+ }
+ }
+
+ if (widget->parentWidget() && buttons > 0) {
+ QWidget *w = const_cast<QWidget *>(widget);
+ int toolBarMaxWidth = 0;
+ int totalMargin = 0;
+ while (w) {
+ //honor fixed width parents
+ if (w->maximumWidth() == w->minimumWidth())
+ toolBarMaxWidth = qMax(toolBarMaxWidth, w->maximumWidth());
+ if (w->layout() && w->windowType() == Qt::Widget) {
+ totalMargin += w->layout()->contentsMargins().left() +
+ w->layout()->contentsMargins().right();
+ }
+ w = w->parentWidget();
+ }
+ totalMargin += 2 * pixelMetric(QStyle::PM_ToolBarFrameWidth);
+
+ if (toolBarMaxWidth == 0)
+ toolBarMaxWidth =
+ QApplication::desktop()->availableGeometry(widget->parentWidget()).width();
+ //Reduce the margins, toolbar frame, item spacing and internal margin from available area
+ toolBarMaxWidth -= totalMargin;
+
+ //ensure that buttons are side-by-side and not on top of each other
+ const int toolButtonWidth = (toolBarMaxWidth / buttons)
+ - pixelMetric(QStyle::PM_ToolBarItemSpacing)
+ - pixelMetric(QStyle::PM_ToolBarItemMargin)
+ //toolbar frame needs to be reduced again, since QToolBarLayout adds it for each toolbar action
+ - 2 * pixelMetric(QStyle::PM_ToolBarFrameWidth) - 1;
+ sz.setWidth(qMax(toolButtonWidth, sz.width()));
+ }
+ }
+ }
+ break;
+ case CT_PushButton:
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ //FIXME properly - style should calculate the location of border frame-part
+ if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget))) {
+ if (buttonWidget->isCheckable())
+ sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
+ const int iconHeight = (!buttonWidget->icon().isNull()) ? buttonWidget->iconSize().height() : 0;
+ const int textHeight = (buttonWidget->text().length() > 0) ?
+ buttonWidget->fontMetrics().size(Qt::TextSingleLine, buttonWidget->text()).height() : opt->fontMetrics.height();
+ const int decoratorHeight = (buttonWidget->isCheckable()) ? pixelMetric(PM_IndicatorHeight) : 0;
+
+ const int contentHeight =
+ qMax(qMax(iconHeight, decoratorHeight) + pixelMetric(PM_ButtonMargin),
+ textHeight + 2*pixelMetric(PM_ButtonMargin));
+ sz.setHeight(qMax(sz.height(), contentHeight));
+ sz += QSize(2 * pixelMetric(PM_ButtonMargin), 0);
+ }
+ break;
+ case CT_LineEdit:
+ if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
+ sz += QSize(2 * f->lineWidth, 4 * f->lineWidth);
+ break;
+ case CT_TabBarTab: {
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ // Adjust beginning tabbar item size, if scrollbuttons are used. This is to ensure that the
+ // tabbar item content fits, since scrollbuttons are making beginning tabbar item smaller.
+ int scrollButtonSize = 0;
+ if (const QTabBar *tabBar = qobject_cast<const QTabBar *>(widget))
+ scrollButtonSize = tabBar->usesScrollButtons() ? pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ const bool verticalTabs = tab->shape == QTabBar::RoundedEast
+ || tab->shape == QTabBar::RoundedWest
+ || tab->shape == QTabBar::TriangularEast
+ || tab->shape == QTabBar::TriangularWest;
+ if (tab->position == QStyleOptionTab::Beginning)
+ sz += QSize(verticalTabs ? 0 : scrollButtonSize, !verticalTabs ? 0 : scrollButtonSize);
+ }
+ }
+ break;
+ case CT_MenuItem:
+ case CT_ItemViewItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ sz = QSize(menuItem->rect.width() - 2 * pixelMetric(PM_MenuHMargin) - 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 1);
+ break;
+ }
+ }
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ if (QS60StylePrivate::isTouchSupported()) {
+ //Make itemview easier to use in touch devices
+ sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
+ //QCommonStyle does not adjust height with horizontal margin, it only adjusts width
+ if (ct == CT_MenuItem)
+ sz.setHeight(sz.height() - 8); //QCommonstyle adds 8 to height that this style handles through PM values
+ }
+ break;
+#ifndef QT_NO_COMBOBOX
+ case CT_ComboBox: {
+ // Fixing Ui design issues with too wide QComboBoxes and greedy SizeHints
+ // Make sure, that the combobox stays within the screen.
+ const QSize desktopContentSize = QApplication::desktop()->availableGeometry().size()
+ - QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0);
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget).
+ boundedTo(desktopContentSize);
+ }
+ break;
+#endif
+ default:
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ break;
+ }
+ if (!sz.isValid())
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ return sz;
+}
+
+/*! \reimp */
+int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *hret) const
+{
+ int retValue = 0;
+ switch (sh) {
+ case SH_RequestSoftwareInputPanel:
+ if (QS60StylePrivate::isSingleClickUi())
+ retValue = RSIP_OnMouseClick;
+ else
+ retValue = RSIP_OnMouseClickAndAlreadyFocused;
+ break;
+ case SH_ComboBox_Popup:
+ retValue = true;
+ break;
+ case SH_Table_GridLineColor:
+ retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba());
+ break;
+ case SH_GroupBox_TextLabelColor:
+ retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0).rgba());
+ break;
+ case SH_ScrollBar_ScrollWhenPointerLeavesControl:
+ retValue = true;
+ break;
+ case SH_Slider_SnapToValue:
+ retValue = true;
+ break;
+ case SH_Slider_StopMouseOverSlider:
+ retValue = true;
+ break;
+ case SH_LineEdit_PasswordCharacter:
+ retValue = '*';
+ break;
+ case SH_ComboBox_PopupFrameStyle:
+ retValue = QFrame::NoFrame | QFrame::Plain;
+ break;
+ case SH_Dial_BackgroundRole:
+ retValue = QPalette::Base;
+ break;
+ case SH_ItemView_ActivateItemOnSingleClick: {
+ if (QS60StylePrivate::isSingleClickUi())
+ retValue = true;
+ else if (opt && opt->state & QStyle::State_Selected)
+ retValue = true;
+ break;
+ }
+ case SH_ProgressDialog_TextLabelAlignment:
+ retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ?
+ Qt::AlignLeft :
+ Qt::AlignRight;
+ break;
+ case SH_Menu_SubMenuPopupDelay:
+ retValue = 300;
+ break;
+ case SH_Menu_Scrollable:
+ retValue = true;
+ break;
+ case SH_Menu_SelectionWrap:
+ retValue = true;
+ break;
+ case SH_Menu_MouseTracking:
+ retValue = true;
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+ retValue = true;
+ break;
+ case SH_ToolBar_Movable:
+ retValue = false;
+ break;
+ case SH_BlinkCursorWhenTextSelected:
+ retValue = true;
+ break;
+ case SH_UnderlineShortcut:
+ retValue = 0;
+ break;
+ case SH_FormLayoutWrapPolicy:
+ retValue = QFormLayout::WrapLongRows;
+ break;
+ case SH_ScrollBar_ContextMenu:
+ retValue = false;
+ break;
+ default:
+ retValue = QCommonStyle::styleHint(sh, opt, widget, hret);
+ break;
+ }
+ return retValue;
+}
+
+/*! \reimp */
+QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget) const
+{
+ QRect ret;
+ switch (control) {
+#ifndef QT_NO_SCROLLBAR
+ // This implementation of subControlRect(CC_ScrollBar..) basically just removes the SC_ScrollBarSubLine and SC_ScrollBarAddLine
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbarOption = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ const QRect scrollBarRect = scrollbarOption->rect;
+ const bool isHorizontal = scrollbarOption->orientation == Qt::Horizontal;
+ const int maxlen = isHorizontal ? scrollBarRect.width() : scrollBarRect.height();
+ int sliderlen;
+
+ // calculate slider length
+ if (scrollbarOption->maximum != scrollbarOption->minimum) {
+ const uint range = scrollbarOption->maximum - scrollbarOption->minimum;
+ sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep);
+
+ const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget);
+ if (sliderlen < slidermin || range > (INT_MAX >> 1))
+ sliderlen = slidermin;
+ if (sliderlen > maxlen)
+ sliderlen = maxlen;
+ } else {
+ sliderlen = maxlen;
+ }
+
+ const int sliderstart = sliderPositionFromValue(scrollbarOption->minimum,
+ scrollbarOption->maximum,
+ scrollbarOption->sliderPosition,
+ maxlen - sliderlen,
+ scrollbarOption->upsideDown);
+
+ switch (scontrol) {
+ case SC_ScrollBarSubPage: // between top/left button and slider
+ if (isHorizontal)
+ ret.setRect(0, 0, sliderstart, scrollBarRect.height());
+ else
+ ret.setRect(0, 0, scrollBarRect.width(), sliderstart);
+ break;
+ case SC_ScrollBarAddPage: { // between bottom/right button and slider
+ const int addPageLength = sliderstart + sliderlen;
+ if (isHorizontal)
+ ret = scrollBarRect.adjusted(addPageLength, 0, 0, 0);
+ else
+ ret = scrollBarRect.adjusted(0, addPageLength, 0, 0);
+ }
+ break;
+ case SC_ScrollBarGroove:
+ ret = scrollBarRect;
+ break;
+ case SC_ScrollBarSlider:
+ if (scrollbarOption->orientation == Qt::Horizontal)
+ ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height());
+ else
+ ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen);
+ break;
+ case SC_ScrollBarSubLine: // top/left button
+ case SC_ScrollBarAddLine: // bottom/right button
+ default:
+ break;
+ }
+ ret = visualRect(scrollbarOption->direction, scrollBarRect, ret);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
+ const int buttonMargin = spinbox->frame ? 2 : 0;
+ const int buttonContentWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin;
+ // Spinbox buttons should be no larger than one fourth of total width.
+ // Thus, side-by-side buttons would take half of the total width.
+ const int maxSize = qMax(spinbox->rect.width() / 4, buttonContentWidth);
+ QSize buttonSize;
+ buttonSize.setHeight(qMin(maxSize, qMax(8, spinbox->rect.height() - frameThickness)));
+ //width should at least be equal to height
+ buttonSize.setWidth(qMax(buttonSize.height(), buttonContentWidth));
+ buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
+
+ // Normally spinbuttons should be side-by-side, but if spinbox grows very big
+ // and spinbuttons reach their maximum size, they can be deployed one top of the other.
+ const bool sideBySide = (buttonSize.height() * 2 < spinbox->rect.height()) ? false : true;
+ const int y = frameThickness + spinbox->rect.y() +
+ (spinbox->rect.height() - (sideBySide ? 1 : 2) * buttonSize.height()) / 2;
+ const int x = spinbox->rect.x() +
+ spinbox->rect.width() - frameThickness - (sideBySide ? 2 : 1) * buttonSize.width();
+
+ switch (scontrol) {
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ ret = QRect(x, y, buttonSize.width(), buttonSize.height());
+ break;
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ ret = QRect(x + (sideBySide ? buttonSize.width() : 0),
+ y + (sideBySide ? 0 : buttonSize.height()),
+ buttonSize.width(), buttonSize.height());
+ break;
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ ret = QRect(
+ frameThickness,
+ frameThickness,
+ spinbox->rect.width() - 2 * frameThickness,
+ spinbox->rect.height() - 2 * frameThickness);
+ else
+ ret = QRect(
+ frameThickness,
+ frameThickness,
+ x - frameThickness,
+ spinbox->rect.height() - 2 * frameThickness);
+ break;
+ case SC_SpinBoxFrame:
+ ret = spinbox->rect;
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(spinbox->direction, spinbox->rect, ret);
+ }
+ break;
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ ret = cmb->rect;
+ const int width = cmb->rect.width();
+ const int height = cmb->rect.height();
+ const int buttonMargin = cmb->frame ? 2 : 0;
+ // lets use spinbox frame here as well, as no combobox specific value available.
+ const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0;
+ const int buttonMinSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin;
+ QSize buttonSize;
+ //allow button to grow to one fourth of the frame height, if the frame is really tall
+ buttonSize.setHeight(qMin(height, qMax(width / 4, buttonMinSize)));
+ buttonSize.setWidth(buttonSize.height());
+ buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
+ switch (scontrol) {
+ case SC_ComboBoxArrow: {
+ const int xposMod = cmb->rect.x() + width - buttonMargin - buttonSize.width();
+ const int ypos = cmb->rect.y();
+ ret.setRect(xposMod, ypos + buttonMargin, buttonSize.width(), height - 2 * buttonMargin);
+ }
+ break;
+ case SC_ComboBoxEditField: {
+ ret = QRect(0, 0, cmb->rect.x() + width - buttonSize.width(), height);
+ }
+ break;
+ case SC_ComboBoxListBoxPopup: {
+ ret = QApplication::desktop()->availableGeometry();
+ }
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(cmb->direction, cmb->rect, ret);
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
+ switch (scontrol) {
+ case SC_GroupBoxCheckBox: //fallthrough
+ case SC_GroupBoxLabel: {
+ //slightly indent text and boxes, so that dialog border does not mess with them.
+ const int horizontalSpacing =
+ QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
+ ret.adjust(2, horizontalSpacing - 3, 0, 0);
+ }
+ break;
+ case SC_GroupBoxFrame: {
+ const QRect textBox = subControlRect(control, option, SC_GroupBoxLabel, widget);
+ const int tbHeight = textBox.height();
+ ret.translate(0, -ret.y());
+ // include title to within the groupBox frame
+ ret.setHeight(ret.height() + tbHeight);
+ if (widget && ret.bottom() > widget->rect().bottom())
+ ret.setBottom(widget->rect().bottom());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2 * pixelMetric(PM_ButtonMargin);
+ const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth);
+ ret = toolButton->rect;
+ const bool popup = (toolButton->features &
+ (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::MenuButtonPopup;
+ switch (scontrol) {
+ case SC_ToolButton:
+ if (popup)
+ ret.adjust(0, 0, -indicatorRect, 0);
+ break;
+ case SC_ToolButtonMenu:
+ if (popup)
+ ret.adjust(ret.width() - indicatorRect, border, -pixelMetric(PM_ButtonMargin), -border);
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(toolButton->direction, toolButton->rect, ret);
+ }
+ break;
+ default:
+ ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
+ }
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget) const
+{
+ QRect ret;
+ switch (element) {
+ case SE_RadioButtonFocusRect:
+ ret = opt->rect;
+ break;
+ case SE_LineEditContents: {
+ // in S60 the input text box doesn't start from line Edit's TL, but
+ // a bit indented (8 pixels).
+ const int KLineEditDefaultIndention = 8;
+ ret = visualRect(
+ opt->direction, opt->rect, opt->rect.adjusted(KLineEditDefaultIndention, 0, 0, 0));
+ }
+ break;
+ case SE_TabBarTearIndicator:
+ ret = QRect(0, 0, 0, 0);
+ break;
+ case SE_TabWidgetTabBar:
+ if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ ret = QCommonStyle::subElementRect(element, opt, widget);
+
+ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
+ const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget);
+ int gain = (tab) ? tabOverlap * tab->count() : 0;
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth: {
+ if (widget) {
+ // make sure that gain does not set the rect outside of widget boundaries
+ if (twf->direction == Qt::RightToLeft) {
+ if ((ret.left() - gain) < widget->rect().left())
+ gain = widget->rect().left() - ret.left();
+ ret.adjust(-gain, 0, 0, 0);
+ } else {
+ if ((ret.right() + gain) > widget->rect().right())
+ gain = widget->rect().right() - ret.right();
+ ret.adjust(0, 0, gain, 0);
+ }
+ }
+ break;
+ }
+ default: {
+ if (widget) {
+ if ((ret.bottom() + gain) > widget->rect().bottom())
+ gain = widget->rect().bottom() - ret.bottom();
+ ret.adjust(0, 0, 0, gain);
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case SE_ItemViewItemText:
+ case SE_ItemViewItemDecoration:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ const QAbstractItemView *listItem = qobject_cast<const QAbstractItemView *>(widget);
+ const bool multiSelection = !listItem ? false :
+ listItem->selectionMode() == QAbstractItemView::MultiSelection ||
+ listItem->selectionMode() == QAbstractItemView::ExtendedSelection ||
+ listItem->selectionMode() == QAbstractItemView::ContiguousSelection;
+ ret = QCommonStyle::subElementRect(element, opt, widget);
+ // If both multiselect & check-state, then remove checkbox and move
+ // text and decoration towards the beginning
+ if (listItem &&
+ multiSelection &&
+ (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) {
+ const int verticalSpacing =
+ QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
+ //const int horizontalSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
+ const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width();
+ ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0);
+ }
+ } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
+ const int indicatorWidth = checkable ?
+ pixelMetric(PM_ListViewIconSize, opt, widget) :
+ pixelMetric(PM_SmallIconSize, opt, widget);
+ ret = menuItem->rect;
+
+ QRect checkBoxRect = checkable ? menuItem->rect : QRect();
+ if (checkable) {
+ checkBoxRect.setWidth(pixelMetric(PM_IndicatorWidth));
+ checkBoxRect.setHeight(pixelMetric(PM_IndicatorHeight));
+ }
+
+ const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
+ //The vertical spacing is doubled; it needs one spacing to separate checkbox from
+ //highlight and then it needs one to separate it whatever is shown after it (text/icon/both).
+ const int moveByX = checkBoxRect.width() + 2 * vSpacing;
+
+ if (element == SE_ItemViewItemDecoration) {
+ if (menuItem->icon.isNull()) {
+ ret = QRect();
+ } else {
+ if (menuItem->direction == Qt::RightToLeft)
+ ret.translate(ret.width() - indicatorWidth - moveByX, 0);
+ else
+ ret.translate(moveByX, 0);
+ ret.setWidth(indicatorWidth);
+ }
+ } else {
+ if (!menuItem->icon.isNull()) {
+ if (menuItem->direction == Qt::LeftToRight)
+ ret.adjust(indicatorWidth, 0, 0, 0);
+ else
+ ret.adjust(0, 0, -indicatorWidth, 0);
+ }
+ if (menuItem->direction == Qt::LeftToRight)
+ ret.adjust(moveByX, 0, 0, 0);
+ else
+ ret.adjust(0, 0, -moveByX, 0);
+
+ // Make room for submenu indicator
+ if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){
+ // submenu indicator is very small, so lets halve the rect
+ if (menuItem->direction == Qt::LeftToRight)
+ ret.adjust(0, 0, -(indicatorWidth >> 1), 0);
+ else
+ ret.adjust((indicatorWidth >> 1), 0, 0, 0);
+ }
+ }
+ }
+ break;
+ case SE_ItemViewItemCheckIndicator:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ const QAbstractItemView *listItem = qobject_cast<const QAbstractItemView *>(widget);
+
+ const bool singleSelection = listItem &&
+ (listItem->selectionMode() == QAbstractItemView::SingleSelection ||
+ listItem->selectionMode() == QAbstractItemView::NoSelection);
+ const bool checkBoxOnly = (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) &&
+ listItem &&
+ singleSelection && vopt->text.isEmpty() && vopt->icon.isNull();
+
+ // Selection check mark rect.
+ const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth);
+ const int indicatorHeight = QS60StylePrivate::pixelMetric(PM_IndicatorHeight);
+ const int spacing = QS60StylePrivate::pixelMetric(PM_CheckBoxLabelSpacing);
+
+ const int itemHeight = opt->rect.height();
+ int heightOffset = 0;
+ if (indicatorHeight < itemHeight)
+ heightOffset = ((itemHeight - indicatorHeight) >> 1);
+ if (checkBoxOnly) {
+ // Move rect and make it slightly smaller, so that
+ // a) highlight border does not cross the rect
+ // b) in s60 list checkbox is smaller than normal checkbox
+ //todo; magic three
+ ret.setRect(opt->rect.left() + 3, opt->rect.top() + heightOffset,
+ indicatorWidth - 3, indicatorHeight - 3);
+ } else {
+ ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset,
+ indicatorWidth, indicatorHeight);
+ }
+ } else {
+ ret = QCommonStyle::subElementRect(element, opt, widget);
+ }
+ break;
+ case SE_HeaderLabel:
+ ret = QCommonStyle::subElementRect(element, opt, widget);
+ if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ // Subtract area needed for line
+ if (opt->state & State_Horizontal)
+ ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_BoldLineWidth));
+ else
+ ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_ThinLineWidth));
+ }
+ ret = visualRect(opt->direction, opt->rect, ret);
+ break;
+ case SE_RadioButtonIndicator: {
+ const int height = pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget);
+ ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1),
+ pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), height);
+ ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it
+ ret = visualRect(opt->direction, opt->rect, ret);
+ }
+ break;
+ case SE_CheckBoxIndicator: {
+ const int height = pixelMetric(PM_IndicatorHeight, opt, widget);
+ ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1),
+ pixelMetric(PM_IndicatorWidth, opt, widget), height);
+ ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it
+ ret = visualRect(opt->direction, opt->rect, ret);
+ }
+ break;
+ case SE_CheckBoxFocusRect:
+ ret = opt->rect;
+ break;
+ case SE_ProgressBarLabel:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarGroove:
+ ret = opt->rect;
+ break;
+ default:
+ ret = QCommonStyle::subElementRect(element, opt, widget);
+ }
+ return ret;
+}
+
+/*!
+ \reimp
+ */
+void QS60Style::polish(QWidget *widget)
+{
+ Q_D(const QS60Style);
+ QCommonStyle::polish(widget);
+
+ if (!widget)
+ return;
+
+ //Currently we only support animations in QProgressBar.
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+
+ if (false
+#ifndef QT_NO_SCROLLBAR
+ || qobject_cast<QScrollBar *>(widget)
+#endif
+ ) {
+ widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
+ }
+
+ if (QS60StylePrivate::drawsOwnThemeBackground(widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ } else if (false
+#ifndef QT_NO_MENU
+ || qobject_cast<const QMenu *> (widget)
+#endif // QT_NO_MENU
+ ) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ } else if (false
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<const QComboBoxListView *>(widget)
+#endif //QT_NO_COMBOBOX
+ ) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ }
+ d->setThemePalette(widget);
+ d->setFont(widget);
+}
+
+/*!
+ \reimp
+ */
+void QS60Style::unpolish(QWidget *widget)
+{
+ Q_D(QS60Style);
+
+ if (false
+ #ifndef QT_NO_SCROLLBAR
+ || qobject_cast<QScrollBar *>(widget)
+ #endif
+ )
+ widget->setAttribute(Qt::WA_OpaquePaintEvent);
+
+ if (QS60StylePrivate::drawsOwnThemeBackground(widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ } else if (false
+#ifndef QT_NO_MENU
+ || qobject_cast<const QMenu *> (widget)
+#endif // QT_NO_MENU
+ ) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ } else if (false
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<const QComboBoxListView *>(widget)
+#endif //QT_NO_COMBOBOX
+ ) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ }
+
+ if (widget)
+ widget->setPalette(QPalette());
+
+#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR)
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(widget)) {
+ widget->removeEventFilter(this);
+ d->m_bars.removeAll(bar);
+ }
+#else
+ Q_UNUSED(d)
+#endif
+ QCommonStyle::unpolish(widget);
+}
+
+/*!
+ \reimp
+ */
+void QS60Style::polish(QApplication *application)
+{
+ Q_D(QS60Style);
+ QCommonStyle::polish(qApp);
+ d->m_originalPalette = application->palette();
+ d->setThemePalette(application);
+ if (QS60StylePrivate::isTouchSupported())
+ qApp->installEventFilter(this);
+}
+
+/*!
+ \reimp
+ */
+void QS60Style::unpolish(QApplication *application)
+{
+ Q_UNUSED(application)
+
+ Q_D(QS60Style);
+ QCommonStyle::unpolish(qApp);
+ const QPalette newPalette = QApplication::style()->standardPalette();
+ QApplication::setPalette(newPalette);
+ QApplicationPrivate::setSystemPalette(d->m_originalPalette);
+ if (QS60StylePrivate::isTouchSupported())
+ qApp->removeEventFilter(this);
+}
+
+/*!
+ \reimp
+ */
+bool QS60Style::event(QEvent *e)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ Q_D(QS60Style);
+ const QEvent::Type eventType = e->type();
+ if ((eventType == QEvent::FocusIn ||
+ eventType == QEvent::FocusOut ||
+ eventType == QEvent::EnterEditFocus ||
+ eventType == QEvent::LeaveEditFocus) &&
+ QS60StylePrivate::isTouchSupported())
+ return false;
+#endif
+
+ switch (e->type()) {
+ case QEvent::Timer: {
+ QTimerEvent *te = static_cast<QTimerEvent*>(e);
+ timerEvent(te);
+ }
+ break;
+#ifdef QT_KEYPAD_NAVIGATION
+ case QEvent::FocusIn:
+ if (QWidget *focusWidget = QApplication::focusWidget()) {
+
+ // Menus and combobox popups do not draw focus frame around them
+ if (qobject_cast<QComboBoxListView *>(focusWidget) ||
+ qobject_cast<QMenu *>(focusWidget))
+ break;
+
+ if (!d->m_focusFrame)
+ d->m_focusFrame = new QFocusFrame(focusWidget);
+ d->m_focusFrame->setWidget(focusWidget);
+ } else if (d->m_focusFrame) {
+ d->m_focusFrame->setWidget(0);
+ }
+ break;
+ case QEvent::FocusOut:
+ if (d->m_focusFrame)
+ d->m_focusFrame->setWidget(0);
+ break;
+ case QEvent::EnterEditFocus:
+ case QEvent::LeaveEditFocus:
+ if (d->m_focusFrame)
+ d->m_focusFrame->update();
+ break;
+#endif
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \internal
+ */
+QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option, const QWidget *widget) const
+{
+ QS60StyleEnums::SkinParts part;
+ qreal iconHeightMultiplier = 1.0;
+ qreal iconWidthMultiplier = 1.0;
+ QS60StylePrivate::SkinElementFlags adjustedFlags;
+ if (option)
+ adjustedFlags = (option->state & State_Enabled || option->state == 0) ?
+ QS60StylePrivate::SF_StateEnabled :
+ QS60StylePrivate::SF_StateDisabled;
+
+ switch(standardIcon) {
+ case SP_MessageBoxWarning:
+ // By default, S60 messagebox icons have 4:3 ratio. Value is from S60 LAF documentation.
+ iconHeightMultiplier = 1.33;
+ part = QS60StyleEnums::SP_QgnNoteWarning;
+ break;
+ case SP_MessageBoxInformation:
+ iconHeightMultiplier = 1.33;
+ part = QS60StyleEnums::SP_QgnNoteInfo;
+ break;
+ case SP_MessageBoxCritical:
+ iconHeightMultiplier = 1.33;
+ part = QS60StyleEnums::SP_QgnNoteError;
+ break;
+ case SP_MessageBoxQuestion:
+ iconHeightMultiplier = 1.33;
+ part = QS60StyleEnums::SP_QgnNoteQuery;
+ break;
+ case SP_ArrowRight:
+ part = QS60StyleEnums::SP_QgnIndiNaviArrowRight;
+ break;
+ case SP_ArrowLeft:
+ part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
+ break;
+ case SP_ArrowUp:
+ part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
+ adjustedFlags |= QS60StylePrivate::SF_PointEast;
+ break;
+ case SP_ArrowDown:
+ part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
+ adjustedFlags |= QS60StylePrivate::SF_PointWest;
+ break;
+ case SP_ArrowBack:
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ return QS60Style::standardIcon(SP_ArrowRight, option, widget);
+ return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
+ case SP_ArrowForward:
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
+ return QS60Style::standardIcon(SP_ArrowRight, option, widget);
+ case SP_ComputerIcon:
+ part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge;
+ break;
+ case SP_DirClosedIcon:
+ part = QS60StyleEnums::SP_QgnPropFolderSmall;
+ break;
+ case SP_DirOpenIcon:
+ part = QS60StyleEnums::SP_QgnPropFolderCurrent;
+ break;
+ case SP_DirIcon:
+ part = QS60StyleEnums::SP_QgnPropFolderSmall;
+ break;
+ case SP_FileDialogNewFolder:
+ part = QS60StyleEnums::SP_QgnPropFolderSmallNew;
+ break;
+ case SP_FileIcon:
+ part = QS60StyleEnums::SP_QgnPropFileSmall;
+ break;
+ case SP_TrashIcon:
+ part = QS60StyleEnums::SP_QgnNoteErased;
+ break;
+ case SP_ToolBarHorizontalExtensionButton:
+ part = QS60StyleEnums::SP_QgnIndiSubmenu;
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ adjustedFlags |= QS60StylePrivate::SF_PointSouth;
+ break;
+ case SP_ToolBarVerticalExtensionButton:
+ adjustedFlags |= QS60StylePrivate::SF_PointEast;
+ part = QS60StyleEnums::SP_QgnIndiSubmenu;
+ break;
+ default:
+ return QCommonStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+ const QS60StylePrivate::SkinElementFlags flags = adjustedFlags;
+ const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize);
+ const QRect iconSize = (!option) ?
+ QRect(0, 0, iconDimension * iconWidthMultiplier, iconDimension * iconHeightMultiplier) : option->rect;
+ const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), 0, flags));
+ return cachedPixMap.isNull() ?
+ QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap);
+}
+
+/*!
+ \internal
+ Animate indeterminate progress bars only when visible
+*/
+bool QS60Style::eventFilter(QObject *object, QEvent *event)
+{
+ Q_D(QS60Style);
+ switch(event->type()) {
+ case QEvent::MouseButtonPress: {
+ QWidget *w = QApplication::widgetAt(QCursor::pos());
+ if (w) {
+ QWidget *focusW = w->focusProxy();
+ if (qobject_cast<QAbstractItemView *>(focusW) ||
+ qobject_cast<QRadioButton *>(focusW) ||
+ qobject_cast<QCheckBox *>(focusW))
+ d->m_pressedWidget = focusW;
+ else if (qobject_cast<QAbstractItemView *>(w)||
+ qobject_cast<QRadioButton *>(w) ||
+ qobject_cast<QCheckBox *>(w))
+ d->m_pressedWidget = w;
+
+ if (d->m_pressedWidget)
+ d->m_pressedWidget->update();
+ }
+ break;
+ }
+ case QEvent::MouseButtonRelease: {
+ if (d->m_pressedWidget) {
+ d->m_pressedWidget->update();
+ d->m_pressedWidget = 0;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+#ifdef Q_WS_S60
+#ifndef QT_NO_PROGRESSBAR
+ switch(event->type()) {
+ case QEvent::StyleChange:
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(object)) {
+ if (!d->m_bars.contains(bar))
+ d->m_bars << bar;
+ if (d->m_bars.size() == 1) //only start with first animated progressbar
+ d->startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(object)) {
+ d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+ d->m_bars.removeAll(bar);
+ }
+ break;
+ default:
+ break;
+ }
+#endif // QT_NO_PROGRESSBAR
+#endif // Q_WS_S60
+ return QCommonStyle::eventFilter(object, event);
+}
+
+/*!
+ \internal
+ Handle the timer \a event.
+*/
+void QS60Style::timerEvent(QTimerEvent *event)
+{
+#ifdef Q_WS_S60
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QS60Style);
+
+ QS60StyleAnimation *progressBarAnimation =
+ QS60StylePrivate::animationDefinition(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+
+ if (event->timerId() == progressBarAnimation->timerId()) {
+
+ Q_ASSERT(progressBarAnimation->interval() > 0);
+
+ if (progressBarAnimation->currentFrame() == progressBarAnimation->frameCount() )
+ if (progressBarAnimation->playMode() == QS60StyleEnums::AM_Looping)
+ progressBarAnimation->setCurrentFrame(0);
+ else
+ d->stopAnimation(progressBarAnimation->animationId());
+
+ foreach (QProgressBar *bar, d->m_bars) {
+ if ((bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ progressBarAnimation->setCurrentFrame(progressBarAnimation->currentFrame() + 1);
+ }
+#endif // QT_NO_PROGRESSBAR
+#endif // Q_WS_S60
+ event->ignore();
+}
+
+extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget);
+
+bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
+{
+ // Check if the widget's palette matches placeholder or actual background texture.
+ // When accessing backgroundTexture, use parameter value 'true' to avoid creating
+ // the texture, if it is not already created.
+
+ const QPixmap placeHolder(QS60StylePrivate::placeHolderTexture());
+ const QPixmap bg(QS60StylePrivate::backgroundTexture(true));
+ if (placeHolder.cacheKey() != brush.texture().cacheKey()
+ && bg.cacheKey() != brush.texture().cacheKey())
+ return false;
+
+ const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture());
+
+ const QPaintDevice *target = painter->device();
+ if (target->devType() == QInternal::Widget) {
+ const QWidget *widget = static_cast<const QWidget *>(target);
+ if (!widget->testAttribute(Qt::WA_TranslucentBackground)) {
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect rect(rects.at(i));
+ painter->drawPixmap(rect.topLeft(), backgroundTexture,
+ rect.translated(qt_s60_fill_background_offset(widget)));
+ }
+ }
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_S60 || QT_PLUGIN
diff --git a/src/widgets/styles/qs60style.h b/src/widgets/styles/qs60style.h
new file mode 100644
index 0000000000..0bd22bdb36
--- /dev/null
+++ b/src/widgets/styles/qs60style.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QS60STYLE_H
+#define QS60STYLE_H
+
+#include <QtWidgets/qcommonstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+//Public custom pixel metrics values.
+//These can be used to fetch custom pixel metric value from outside QS60Style.
+enum {
+ PM_FrameCornerWidth = QStyle::PM_CustomBase + 1,
+ PM_FrameCornerHeight,
+ PM_BoldLineWidth,
+ PM_ThinLineWidth,
+ PM_MessageBoxHeight
+ };
+
+class QS60StylePrivate;
+
+class Q_GUI_EXPORT QS60Style : public QCommonStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QS60Style)
+
+public:
+ QS60Style();
+ ~QS60Style();
+
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w = 0) const;
+ int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+ QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget = 0) const;
+ QRect subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QApplication *application);
+ void unpolish(QApplication *application);
+#ifndef Q_NO_USING_KEYWORD
+ using QCommonStyle::polish;
+#endif
+ bool event(QEvent *e);
+
+#ifndef Q_OS_SYMBIAN
+ static QStringList partKeys();
+ static QStringList colorListKeys();
+ void setS60Theme(const QHash<QString, QPicture> &parts,
+ const QHash<QPair<QString , int>, QColor> &colors);
+ bool loadS60ThemeFromBlob(const QString &blobFile);
+ bool saveS60ThemeToBlob(const QString &blobFile) const;
+#endif // !Q_OS_SYMBIAN
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(
+ StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const;
+
+protected:
+ void timerEvent(QTimerEvent *event);
+ bool eventFilter(QObject *o, QEvent *e);
+private:
+ Q_DISABLE_COPY(QS60Style)
+ friend class QStyleFactory;
+ friend class QApplicationPrivate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QS60STYLE_H
diff --git a/src/widgets/styles/qs60style_p.h b/src/widgets/styles/qs60style_p.h
new file mode 100644
index 0000000000..ee981c036b
--- /dev/null
+++ b/src/widgets/styles/qs60style_p.h
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QS60STYLE_P_H
+#define QS60STYLE_P_H
+
+#include "qs60style.h"
+#include "qcommonstyle_p.h"
+#include <QtCore/qhash.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+const int MAX_NON_CUSTOM_PIXELMETRICS = 92;
+const int CUSTOMVALUESCOUNT = 5;
+
+const int MAX_PIXELMETRICS = MAX_NON_CUSTOM_PIXELMETRICS + CUSTOMVALUESCOUNT;
+
+typedef struct {
+ unsigned short height;
+ unsigned short width;
+ int major_version;
+ int minor_version;
+ const char* layoutName;
+} layoutHeader;
+
+#ifdef Q_OS_SYMBIAN
+NONSHARABLE_CLASS (QS60StyleEnums)
+#else
+class QS60StyleEnums
+#endif
+: public QObject
+{
+#ifndef Q_WS_S60
+ Q_OBJECT
+ Q_ENUMS(FontCategories)
+ Q_ENUMS(SkinParts)
+ Q_ENUMS(ColorLists)
+#endif // !Q_WS_S60
+
+public:
+
+ // S60 definitions within theme
+ enum ThemeDefinitions {
+ TD_AnimationData,
+ };
+
+ //Defines which values are contained within animation data (retrieved using TD_AnimationData).
+ //Additionally defines the order in which the items are given out in QList<QVariant>.
+ enum AnimationData {
+ AD_Interval = 0,
+ AD_NumberOfFrames,
+ AD_AnimationPlayMode, //currently not used as themes seem to contain invalid data
+ };
+
+ // Animation modes
+ enum AnimationMode {
+ AM_PlayOnce = 0, //animation is played exactly once
+ AM_Looping, //animation is repeated until stopped
+ AM_Bounce //animation is played repeatedly until stopped,
+ //but frames are played in reverse order every second time
+ //(no support yet)
+ };
+
+ // S60 look-and-feel font categories
+ enum FontCategories {
+ FC_Undefined,
+ FC_Primary,
+ FC_Secondary,
+ FC_Title,
+ FC_PrimarySmall,
+ FC_Digital
+ };
+
+ enum SkinParts {
+ SP_QgnGrafBarWaitAnim,
+ SP_QgnGrafBarFrameCenter,
+ SP_QgnGrafBarFrameSideL,
+ SP_QgnGrafBarFrameSideR,
+ SP_QgnGrafBarProgress,
+ SP_QgnGrafOrgBgGrid,
+ SP_QgnGrafScrollArrowDown,
+ SP_QgnGrafScrollArrowLeft,
+ SP_QgnGrafScrollArrowRight,
+ SP_QgnGrafScrollArrowUp,
+ SP_QgnGrafTabActiveL,
+ SP_QgnGrafTabActiveM,
+ SP_QgnGrafTabActiveR,
+ SP_QgnGrafTabPassiveL,
+ SP_QgnGrafTabPassiveM,
+ SP_QgnGrafTabPassiveR,
+ SP_QgnGrafNsliderEndLeft,
+ SP_QgnGrafNsliderEndRight,
+ SP_QgnGrafNsliderMiddle,
+ SP_QgnIndiCheckboxOff,
+ SP_QgnIndiCheckboxOn,
+ SP_QgnIndiHlColSuper, // Available in S60 release 3.2 and later.
+ SP_QgnIndiHlExpSuper, // Available in S60 release 3.2 and later.
+ SP_QgnIndiHlLineBranch, // Available in S60 release 3.2 and later.
+ SP_QgnIndiHlLineEnd, // Available in S60 release 3.2 and later.
+ SP_QgnIndiHlLineStraight, // Available in S60 release 3.2 and later.
+ SP_QgnIndiMarkedAdd,
+ SP_QgnIndiNaviArrowLeft,
+ SP_QgnIndiNaviArrowRight,
+ SP_QgnIndiRadiobuttOff,
+ SP_QgnIndiRadiobuttOn,
+ SP_QgnGrafNsliderMarker,
+ SP_QgnGrafNsliderMarkerSelected,
+ SP_QgnIndiSubmenu,
+ SP_QgnNoteErased,
+ SP_QgnNoteError,
+ SP_QgnNoteInfo,
+ SP_QgnNoteOk,
+ SP_QgnNoteQuery,
+ SP_QgnNoteWarning,
+ SP_QgnPropFileSmall,
+ SP_QgnPropFolderCurrent,
+ SP_QgnPropFolderSmall,
+ SP_QgnPropFolderSmallNew,
+ SP_QgnPropPhoneMemcLarge,
+ SP_QgnFrSctrlButtonCornerTl, // Toolbar button
+ SP_QgnFrSctrlButtonCornerTr,
+ SP_QgnFrSctrlButtonCornerBl,
+ SP_QgnFrSctrlButtonCornerBr,
+ SP_QgnFrSctrlButtonSideT,
+ SP_QgnFrSctrlButtonSideB,
+ SP_QgnFrSctrlButtonSideL,
+ SP_QgnFrSctrlButtonSideR,
+ SP_QgnFrSctrlButtonCenter,
+ SP_QgnFrSctrlButtonCornerTlPressed, // Toolbar button, pressed
+ SP_QgnFrSctrlButtonCornerTrPressed,
+ SP_QgnFrSctrlButtonCornerBlPressed,
+ SP_QgnFrSctrlButtonCornerBrPressed,
+ SP_QgnFrSctrlButtonSideTPressed,
+ SP_QgnFrSctrlButtonSideBPressed,
+ SP_QgnFrSctrlButtonSideLPressed,
+ SP_QgnFrSctrlButtonSideRPressed,
+ SP_QgnFrSctrlButtonCenterPressed,
+ SP_QsnCpScrollHandleBottomPressed, //ScrollBar handle, pressed state
+ SP_QsnCpScrollHandleMiddlePressed,
+ SP_QsnCpScrollHandleTopPressed,
+ SP_QsnBgScreen,
+ SP_QsnCpScrollBgBottom,
+ SP_QsnCpScrollBgMiddle,
+ SP_QsnCpScrollBgTop,
+ SP_QsnCpScrollHandleBottom,
+ SP_QsnCpScrollHandleMiddle,
+ SP_QsnCpScrollHandleTop,
+ SP_QsnFrButtonTbCornerTl, // Button, normal state
+ SP_QsnFrButtonTbCornerTr,
+ SP_QsnFrButtonTbCornerBl,
+ SP_QsnFrButtonTbCornerBr,
+ SP_QsnFrButtonTbSideT,
+ SP_QsnFrButtonTbSideB,
+ SP_QsnFrButtonTbSideL,
+ SP_QsnFrButtonTbSideR,
+ SP_QsnFrButtonTbCenter,
+ SP_QsnFrButtonTbCornerTlPressed, // Button, pressed state
+ SP_QsnFrButtonTbCornerTrPressed,
+ SP_QsnFrButtonTbCornerBlPressed,
+ SP_QsnFrButtonTbCornerBrPressed,
+ SP_QsnFrButtonTbSideTPressed,
+ SP_QsnFrButtonTbSideBPressed,
+ SP_QsnFrButtonTbSideLPressed,
+ SP_QsnFrButtonTbSideRPressed,
+ SP_QsnFrButtonTbCenterPressed,
+ SP_QsnFrCaleCornerTl, // calendar grid item
+ SP_QsnFrCaleCornerTr,
+ SP_QsnFrCaleCornerBl,
+ SP_QsnFrCaleCornerBr,
+ SP_QsnFrCaleSideT,
+ SP_QsnFrCaleSideB,
+ SP_QsnFrCaleSideL,
+ SP_QsnFrCaleSideR,
+ SP_QsnFrCaleCenter,
+ SP_QsnFrCaleHeadingCornerTl, // calendar grid header
+ SP_QsnFrCaleHeadingCornerTr,
+ SP_QsnFrCaleHeadingCornerBl,
+ SP_QsnFrCaleHeadingCornerBr,
+ SP_QsnFrCaleHeadingSideT,
+ SP_QsnFrCaleHeadingSideB,
+ SP_QsnFrCaleHeadingSideL,
+ SP_QsnFrCaleHeadingSideR,
+ SP_QsnFrCaleHeadingCenter,
+ SP_QsnFrInputCornerTl, // Text input field
+ SP_QsnFrInputCornerTr,
+ SP_QsnFrInputCornerBl,
+ SP_QsnFrInputCornerBr,
+ SP_QsnFrInputSideT,
+ SP_QsnFrInputSideB,
+ SP_QsnFrInputSideL,
+ SP_QsnFrInputSideR,
+ SP_QsnFrInputCenter,
+ SP_QsnFrListCornerTl, // List background
+ SP_QsnFrListCornerTr,
+ SP_QsnFrListCornerBl,
+ SP_QsnFrListCornerBr,
+ SP_QsnFrListSideT,
+ SP_QsnFrListSideB,
+ SP_QsnFrListSideL,
+ SP_QsnFrListSideR,
+ SP_QsnFrListCenter,
+ SP_QsnFrPopupCornerTl, // Option menu background
+ SP_QsnFrPopupCornerTr,
+ SP_QsnFrPopupCornerBl,
+ SP_QsnFrPopupCornerBr,
+ SP_QsnFrPopupSideT,
+ SP_QsnFrPopupSideB,
+ SP_QsnFrPopupSideL,
+ SP_QsnFrPopupSideR,
+ SP_QsnFrPopupCenter,
+ SP_QsnFrPopupPreviewCornerTl, // tool tip background
+ SP_QsnFrPopupPreviewCornerTr,
+ SP_QsnFrPopupPreviewCornerBl,
+ SP_QsnFrPopupPreviewCornerBr,
+ SP_QsnFrPopupPreviewSideT,
+ SP_QsnFrPopupPreviewSideB,
+ SP_QsnFrPopupPreviewSideL,
+ SP_QsnFrPopupPreviewSideR,
+ SP_QsnFrPopupPreviewCenter,
+ SP_QsnFrSetOptCornerTl, // Settings list
+ SP_QsnFrSetOptCornerTr,
+ SP_QsnFrSetOptCornerBl,
+ SP_QsnFrSetOptCornerBr,
+ SP_QsnFrSetOptSideT,
+ SP_QsnFrSetOptSideB,
+ SP_QsnFrSetOptSideL,
+ SP_QsnFrSetOptSideR,
+ SP_QsnFrSetOptCenter,
+ SP_QsnFrPopupSubCornerTl, // Toolbar background
+ SP_QsnFrPopupSubCornerTr,
+ SP_QsnFrPopupSubCornerBl,
+ SP_QsnFrPopupSubCornerBr,
+ SP_QsnFrPopupSubSideT,
+ SP_QsnFrPopupSubSideB,
+ SP_QsnFrPopupSubSideL,
+ SP_QsnFrPopupSubSideR,
+ SP_QsnFrPopupSubCenter,
+ SP_QsnFrButtonCornerTlInactive, // Inactive button
+ SP_QsnFrButtonCornerTrInactive,
+ SP_QsnFrButtonCornerBlInactive,
+ SP_QsnFrButtonCornerBrInactive,
+ SP_QsnFrButtonSideTInactive,
+ SP_QsnFrButtonSideBInactive,
+ SP_QsnFrButtonSideLInactive,
+ SP_QsnFrButtonSideRInactive,
+ SP_QsnFrButtonCenterInactive,
+ SP_QsnFrGridCornerTlPressed, // Pressed table item
+ SP_QsnFrGridCornerTrPressed,
+ SP_QsnFrGridCornerBlPressed,
+ SP_QsnFrGridCornerBrPressed,
+ SP_QsnFrGridSideTPressed,
+ SP_QsnFrGridSideBPressed,
+ SP_QsnFrGridSideLPressed,
+ SP_QsnFrGridSideRPressed,
+ SP_QsnFrGridCenterPressed,
+ SP_QsnFrListCornerTlPressed, // Pressed list item
+ SP_QsnFrListCornerTrPressed,
+ SP_QsnFrListCornerBlPressed,
+ SP_QsnFrListCornerBrPressed,
+ SP_QsnFrListSideTPressed,
+ SP_QsnFrListSideBPressed,
+ SP_QsnFrListSideLPressed,
+ SP_QsnFrListSideRPressed,
+ SP_QsnFrListCenterPressed,
+ };
+
+ enum ColorLists {
+ CL_QsnHighlightColors,
+ CL_QsnIconColors,
+ CL_QsnLineColors,
+ CL_QsnOtherColors,
+ CL_QsnParentColors,
+ CL_QsnTextColors
+ };
+};
+
+#ifdef Q_WS_S60
+class CAknBitmapAnimation;
+NONSHARABLE_CLASS (AnimationData) : public QObject
+{
+public:
+ AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval);
+
+ const QS60StyleEnums::SkinParts m_id;
+ int m_frames;
+ int m_interval;
+ QS60StyleEnums::AnimationMode m_mode;
+};
+
+
+NONSHARABLE_CLASS (AnimationDataV2) : public AnimationData
+{
+public:
+ AnimationDataV2(const AnimationData &data);
+ ~AnimationDataV2();
+
+ CAknBitmapAnimation *m_animation;
+ int m_currentFrame;
+ bool m_resourceBased;
+ int m_timerId;
+};
+
+
+class QS60StyleAnimation : public QObject
+{
+public:
+ QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval);
+ ~QS60StyleAnimation();
+
+public:
+ QS60StyleEnums::SkinParts animationId() const {return m_currentData->m_id;}
+ int frameCount() const { return m_currentData->m_frames;}
+ int interval() const {return m_currentData->m_interval;}
+ QS60StyleEnums::AnimationMode playMode() const {return m_currentData->m_mode;}
+ CAknBitmapAnimation* animationObject() const {return m_currentData->m_animation;}
+ bool isResourceBased() const {return m_currentData->m_resourceBased;}
+ int timerId() const {return m_currentData->m_timerId;}
+ int currentFrame() const {return m_currentData->m_currentFrame;}
+
+ void setFrameCount(int frameCount) {m_currentData->m_frames = frameCount;}
+ void setInterval(int interval) {m_currentData->m_interval = interval;}
+ void setAnimationObject(CAknBitmapAnimation* animation);
+ void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;}
+ void setTimerId(int timerId) {m_currentData->m_timerId = timerId;}
+ void setCurrentFrame(int currentFrame) {m_currentData->m_currentFrame = currentFrame;}
+
+ void resetToDefaults();
+
+private: //data members
+ //TODO: consider changing these to non-pointers as the classes are rather small anyway
+ AnimationData *m_defaultData;
+ AnimationDataV2 *m_currentData;
+};
+
+#endif //Q_WS_S60
+
+
+class QFocusFrame;
+class QProgressBar;
+class QS60StyleAnimation;
+
+// Private class
+#ifdef Q_OS_SYMBIAN
+NONSHARABLE_CLASS (QS60StylePrivate)
+#else
+class QS60StylePrivate
+#endif
+: public QCommonStylePrivate
+{
+ Q_DECLARE_PUBLIC(QS60Style)
+
+public:
+ QS60StylePrivate();
+ ~QS60StylePrivate();
+
+ enum SkinElements {
+ SE_ButtonNormal,
+ SE_ButtonPressed,
+ SE_FrameLineEdit,
+ SE_ProgressBarGrooveHorizontal,
+ SE_ProgressBarIndicatorHorizontal,
+ SE_ProgressBarGrooveVertical,
+ SE_ProgressBarIndicatorVertical,
+ SE_ScrollBarGrooveHorizontal,
+ SE_ScrollBarGrooveVertical,
+ SE_ScrollBarHandleHorizontal,
+ SE_ScrollBarHandleVertical,
+ SE_SliderHandleHorizontal,
+ SE_SliderHandleVertical,
+ SE_SliderHandleSelectedHorizontal,
+ SE_SliderHandleSelectedVertical,
+ SE_SliderGrooveVertical,
+ SE_SliderGrooveHorizontal,
+ SE_TabBarTabEastActive,
+ SE_TabBarTabEastInactive,
+ SE_TabBarTabNorthActive,
+ SE_TabBarTabNorthInactive,
+ SE_TabBarTabSouthActive,
+ SE_TabBarTabSouthInactive,
+ SE_TabBarTabWestActive,
+ SE_TabBarTabWestInactive,
+ SE_ListHighlight,
+ SE_PopupBackground,
+ SE_SettingsList,
+ SE_TableItem,
+ SE_TableHeaderItem,
+ SE_ToolTip, //own graphic available on 3.2+ releases,
+ SE_ToolBar,
+ SE_ToolBarButton,
+ SE_ToolBarButtonPressed,
+ SE_PanelBackground,
+ SE_ScrollBarHandlePressedHorizontal,
+ SE_ScrollBarHandlePressedVertical,
+ SE_ButtonInactive,
+ SE_Editor,
+ SE_DropArea,
+ SE_TableItemPressed,
+ SE_ListItemPressed,
+ };
+
+ enum SkinFrameElements {
+ SF_ButtonNormal,
+ SF_ButtonPressed,
+ SF_FrameLineEdit,
+ SF_ListHighlight,
+ SF_PopupBackground,
+ SF_SettingsList,
+ SF_TableItem,
+ SF_TableHeaderItem,
+ SF_ToolTip,
+ SF_ToolBar,
+ SF_ToolBarButton,
+ SF_ToolBarButtonPressed,
+ SF_PanelBackground,
+ SF_ButtonInactive,
+ SF_TableItemPressed,
+ SF_ListItemPressed,
+ };
+
+ enum SkinElementFlag {
+ SF_PointNorth = 0x0001, // North = the default
+ SF_PointEast = 0x0002,
+ SF_PointSouth = 0x0004,
+ SF_PointWest = 0x0008,
+
+ SF_StateEnabled = 0x0010, // Enabled = the default
+ SF_StateDisabled = 0x0020,
+ SF_ColorSkinned = 0x0040, // pixmap is colored with foreground pen color
+ SF_Animation = 0x0080,
+ SF_Mirrored_X_Axis = 0x0100,
+ SF_Mirrored_Y_Axis = 0x0200
+ };
+
+ enum CacheClearReason {
+ CC_UndefinedChange = 0,
+ CC_LayoutChange,
+ CC_ThemeChange
+ };
+
+ Q_DECLARE_FLAGS(SkinElementFlags, SkinElementFlag)
+
+ // draws skin element
+ static void drawSkinElement(SkinElements element, QPainter *painter,
+ const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
+ // draws a specific skin part
+ static void drawSkinPart(QS60StyleEnums::SkinParts part, QPainter *painter,
+ const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
+ // gets pixel metrics value
+ static short pixelMetric(int metric);
+ // gets color. 'index' is NOT 0-based.
+ // It corresponds to the enum key 1-based numbers of TAknsQsnXYZColorsIndex, not the values.
+ static QColor s60Color(QS60StyleEnums::ColorLists list,
+ int index, const QStyleOption *option);
+ // gets state specific color
+ static QColor stateColor(const QColor &color, const QStyleOption *option);
+ // gets lighter color than base color
+ static QColor lighterColor(const QColor &baseColor);
+ //deduces if the given widget should have separately themeable background
+ static bool drawsOwnThemeBackground(const QWidget *widget);
+
+ QFont s60Font(QS60StyleEnums::FontCategories fontCategory,
+ int pointSize = -1, bool resolveFontSize = true) const;
+ // clears all style caches (fonts, colors, pixmaps)
+ void clearCaches(CacheClearReason reason = CC_UndefinedChange);
+
+ // themed main background oprations
+ void setBackgroundTexture(QApplication *application) const;
+ static void deleteBackground();
+
+ static bool isTouchSupported();
+ static bool isToolBarBackground();
+ static bool hasSliderGrooveGraphic();
+ static bool isSingleClickUi();
+ static bool isWidgetPressed(const QWidget *widget);
+
+#ifdef Q_WS_S60
+ static void deleteStoredSettings();
+ // calculates average color based on theme graphics (minus borders).
+ QColor colorFromFrameGraphics(SkinFrameElements frame) const;
+#endif
+ QColor calculatedColor(SkinFrameElements frame) const;
+
+ //set theme palette for application
+ void setThemePalette(QApplication *application) const;
+ //access to theme palette
+ static QPalette* themePalette();
+
+ static const layoutHeader m_layoutHeaders[];
+ static const short data[][MAX_PIXELMETRICS];
+
+ void setCurrentLayout(int layoutIndex);
+ void setActiveLayout();
+ // Pointer
+ static short const *m_pmPointer;
+ // number of layouts supported by the style
+ static const int m_numberOfLayouts;
+
+ mutable QHash<QPair<QS60StyleEnums::FontCategories , int>, QFont> m_mappedFontsCache;
+
+ // Has one entry per SkinFrameElements
+ static const struct frameElementCenter {
+ SkinElements element;
+ QS60StyleEnums::SkinParts center;
+ } m_frameElementsData[];
+
+ static QPixmap frame(SkinFrameElements frame, const QSize &size,
+ SkinElementFlags flags = KDefaultSkinElementFlags);
+ static QPixmap backgroundTexture(bool skipCreation = false);
+ static QPixmap placeHolderTexture();
+
+#ifdef Q_WS_S60
+ void handleDynamicLayoutVariantSwitch();
+ void handleSkinChange();
+#endif // Q_WS_S60
+
+ //Checks that the current brush is transparent or has BrushStyle NoBrush,
+ //so that theme graphic background can be drawn.
+ static bool canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget);
+
+ static int currentAnimationFrame(QS60StyleEnums::SkinParts part);
+#ifdef Q_WS_S60
+
+ //No support for animations on emulated style
+ void startAnimation(QS60StyleEnums::SkinParts animation);
+ void stopAnimation(QS60StyleEnums::SkinParts animation);
+ static QS60StyleAnimation* animationDefinition(QS60StyleEnums::SkinParts part);
+ static void removeAnimations();
+
+#endif
+
+private:
+ static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter,
+ const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
+ static void drawRow(QS60StyleEnums::SkinParts start, QS60StyleEnums::SkinParts middle,
+ QS60StyleEnums::SkinParts end, Qt::Orientation orientation, QPainter *painter,
+ const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
+ static void drawFrame(SkinFrameElements frame, QPainter *painter,
+ const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags);
+
+ static QPixmap cachedPart(QS60StyleEnums::SkinParts part, const QSize &size,
+ QPainter *painter, SkinElementFlags flags = KDefaultSkinElementFlags);
+ static QPixmap cachedFrame(SkinFrameElements frame, const QSize &size,
+ SkinElementFlags flags = KDefaultSkinElementFlags);
+
+ // set S60 font for widget
+ void setFont(QWidget *widget) const;
+ static void setThemePalette(QWidget *widget);
+ void setThemePalette(QPalette *palette) const;
+ static void setThemePaletteHash(QPalette *palette);
+ static void storeThemePalette(QPalette *palette);
+ static void deleteThemePalette();
+ static bool equalToThemePalette(QColor color, QPalette::ColorRole role);
+ static bool equalToThemePalette(qint64 cacheKey, QPalette::ColorRole role);
+
+ static QSize partSize(QS60StyleEnums::SkinParts part,
+ SkinElementFlags flags = KDefaultSkinElementFlags);
+ static QPixmap part(QS60StyleEnums::SkinParts part, const QSize &size,
+ QPainter *painter, SkinElementFlags flags = KDefaultSkinElementFlags);
+
+ static QFont s60Font_specific(QS60StyleEnums::FontCategories fontCategory,
+ int pointSize, bool resolveFontSize);
+
+ static QSize screenSize();
+
+ // Contains background texture.
+ static QPixmap *m_background;
+ // Placeholder pixmap for the real background texture.
+ static QPixmap *m_placeHolderTexture;
+
+ const static SkinElementFlags KDefaultSkinElementFlags;
+ // defined theme palette
+ static QPalette *m_themePalette;
+ QPalette m_originalPalette;
+
+ QPointer<QFocusFrame> m_focusFrame;
+ static qint64 m_webPaletteKey;
+
+ static QPointer<QWidget> m_pressedWidget;
+
+#ifdef Q_WS_S60
+ //list of progress bars having animation running
+ QList<QProgressBar *> m_bars;
+#endif
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QS60STYLE_P_H
diff --git a/src/widgets/styles/qs60style_s60.cpp b/src/widgets/styles/qs60style_s60.cpp
new file mode 100644
index 0000000000..f272ff4a90
--- /dev/null
+++ b/src/widgets/styles/qs60style_s60.cpp
@@ -0,0 +1,1591 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qs60style.h"
+#include "qs60style_p.h"
+#include "qpainter.h"
+#include "qstyleoption.h"
+#include "qstyle.h"
+#include "private/qt_s60_p.h"
+#include "private/qpixmap_s60_p.h"
+#include "private/qcore_symbian_p.h"
+#include "private/qvolatileimage_p.h"
+#include "qapplication.h"
+#include "qsettings.h"
+
+#include <w32std.h>
+#include <AknsConstants.h>
+#include <aknconsts.h>
+#include <AknsItemID.h>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <AknsSkinInstance.h>
+#include <AknsBasicBackgroundControlContext.h>
+#include <avkon.mbg>
+#include <AknFontAccess.h>
+#include <AknLayoutFont.h>
+#include <AknUtils.h>
+#include <aknnavi.h>
+#include <gulicon.h>
+#include <AknBitmapAnimation.h>
+#include <centralrepository.h>
+
+#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+enum TDrawType {
+ EDrawIcon,
+ EDrawGulIcon,
+ EDrawBackground,
+ EDrawAnimation,
+ ENoDraw
+};
+
+const TUid personalisationUID = { 0x101F876F };
+
+enum TSupportRelease {
+ ES60_None = 0x0000, //indicates that the commonstyle should draw the graphics
+ ES60_3_1 = 0x0001,
+ ES60_3_2 = 0x0002,
+ ES60_5_0 = 0x0004,
+ ES60_5_1 = 0x0008,
+ ES60_5_2 = 0x0010,
+ ES60_5_3 = 0x0020,
+ ES60_3_X = ES60_3_1 | ES60_3_2,
+ // Releases before Symbian Foundation
+ ES60_PreSF = ES60_3_1 | ES60_3_2 | ES60_5_0,
+ // Releases before the S60 5.2
+ ES60_Pre52 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1,
+ // Releases before S60 5.3
+ ES60_Pre53 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2,
+ // Add all new releases here
+ ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 | ES60_5_3
+};
+
+typedef struct {
+ const TAknsItemID &skinID; // Determines default theme graphics ID.
+ TDrawType drawType; // Determines which native drawing routine is used to draw this item.
+ int supportInfo; // Defines the S60 versions that use the default graphics.
+ // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases.
+ // In general, these are given in numeric form to allow style compilation in earlier
+ // native releases that do not contain the new graphics.
+ int newMajorSkinId;
+ int newMinorSkinId;
+} partMapEntry;
+
+AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part),
+ m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping)
+{
+}
+
+AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval),
+ m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0)
+{
+}
+AnimationDataV2::~AnimationDataV2()
+{
+ delete m_animation;
+}
+
+QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval)
+{
+ QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval));
+ QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
+}
+
+QS60StyleAnimation::~QS60StyleAnimation()
+{
+ delete m_currentData;
+ delete m_defaultData;
+}
+
+void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation)
+{
+ Q_ASSERT(animation);
+ if (m_currentData->m_animation)
+ delete m_currentData->m_animation;
+ m_currentData->m_animation = animation;
+}
+
+void QS60StyleAnimation::resetToDefaults()
+{
+ delete m_currentData;
+ m_currentData = 0;
+ QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
+}
+
+class QS60StyleModeSpecifics
+{
+public:
+ static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap skinnedGraphics(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart,
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
+ static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex);
+ static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize& targetSize);
+ static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part);
+ static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame);
+ static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static TAknsItemID partSpecificThemeId(int part);
+
+ static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part);
+
+private:
+ static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart,
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
+ static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId);
+ static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect);
+ static void fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex);
+ static bool checkSupport(const int supportedRelease);
+ // Array to match the skin ID, fallback graphics and Qt widget graphics.
+ static const partMapEntry m_partMap[];
+};
+
+const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
+ /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1},
+ // No drop area for 3.x non-touch devices
+ /* SP_QgnGrafOrgBgGrid */ {KAknsIIDNone, EDrawIcon, ES60_3_X, EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid
+ /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
+
+ // In S60 5.3 there is a new tab graphic
+ /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2219}, //KAknsIIDQtgFrTabActiveNormalL
+ /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221b}, //KAknsIIDQtgFrTabActiveNormalC
+ /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221a}, //KAknsIIDQtgFrTabActiveNormalR
+ /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2221}, //KAknsIIDQtgFrTabPassiveNormalL
+ /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2223}, //KAknsIIDQtgFrTabPassiveNormalC
+ /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2222}, //KAknsIIDQtgFrTabPassiveNormalR
+
+ // In 3.1 there is no slider groove.
+ /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
+ /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */},
+ /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */},
+ /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1},
+
+ // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2.
+ // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI.
+ /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
+ /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
+ /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
+ /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
+ /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
+ /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1},
+
+ // In 3.1 there different slider graphic and no pressed state.
+ /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */},
+ /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */},
+ /* SP_QgnIndiSubmenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1},
+
+ // Toolbar graphics is different in 3.1/3.2 vs. 5.0
+ /* SP_QgnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/
+ /* SP_QgnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2302},
+ /* SP_QgnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2303},
+ /* SP_QgnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2304},
+ /* SP_QgnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2305},
+ /* SP_QgnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2306},
+ /* SP_QgnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2307},
+ /* SP_QgnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2308},
+ /* SP_QgnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/
+
+ // No pressed state for toolbar button in 3.1/3.2.
+ /* SP_QgnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2621}, /*KAknsIIDQgnFrSctrlButtonCornerTlPressed*/
+ /* SP_QgnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2622},
+ /* SP_QgnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2623},
+ /* SP_QgnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2624},
+ /* SP_QgnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2625},
+ /* SP_QgnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2626},
+ /* SP_QgnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2627},
+ /* SP_QgnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2628},
+ /* SP_QgnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2629},
+
+ // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead.
+ /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
+ /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/
+ /* SP_QsnCpScrollHandleTopPressed*/ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/
+
+ /* SP_QsnBgScreen */ {KAknsIIDQsnBgScreen, EDrawBackground, ES60_All, -1,-1},
+
+ /* SP_QsnCpScrollBgBottom */ {KAknsIIDQsnCpScrollBgBottom, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollBgMiddle */ {KAknsIIDQsnCpScrollBgMiddle, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollBgTop */ {KAknsIIDQsnCpScrollBgTop, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnCpScrollHandleBottom */ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollHandleMiddle */ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollHandleTop */ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnFrButtonTbCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCenter */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_All, -1, -1},
+
+ /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideTPressed */ {KAknsIIDQsnFrButtonTbSideTPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideBPressed */ {KAknsIIDQsnFrButtonTbSideBPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideLPressed */ {KAknsIIDQsnFrButtonTbSideLPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideRPressed */ {KAknsIIDQsnFrButtonTbSideRPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCenterPressed */ {KAknsIIDQsnFrButtonTbCenterPressed, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnFrCaleCornerTl */ {KAknsIIDQsnFrCaleCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerTr */ {KAknsIIDQsnFrCaleHeadingCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerBl */ {KAknsIIDQsnFrCaleHeadingCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerBr */ {KAknsIIDQsnFrCaleHeadingCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideT */ {KAknsIIDQsnFrCaleHeadingSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideB */ {KAknsIIDQsnFrCaleHeadingSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideL */ {KAknsIIDQsnFrCaleHeadingSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideR */ {KAknsIIDQsnFrCaleHeadingSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCenter */ {KAknsIIDQsnFrCaleHeadingCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrInputCornerTl */ {KAknsIIDQsnFrInputCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerTr */ {KAknsIIDQsnFrInputCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerBl */ {KAknsIIDQsnFrInputCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerBr */ {KAknsIIDQsnFrInputCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideT */ {KAknsIIDQsnFrInputSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideB */ {KAknsIIDQsnFrInputSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideL */ {KAknsIIDQsnFrInputSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideR */ {KAknsIIDQsnFrInputSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCenter */ {KAknsIIDQsnFrInputCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrListCornerTl */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerTr */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerBl */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerBr */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideT */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideB */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideL */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideR */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCenter */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrPopupCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_All, -1,-1},
+
+ // ToolTip graphics different in 3.1 vs. 3.2+.
+ /* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
+ /* SP_QsnFrPopupPreviewCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c6},
+ /* SP_QsnFrPopupPreviewCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c3},
+ /* SP_QsnFrPopupPreviewCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c4},
+ /* SP_QsnFrPopupPreviewSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19ca},
+ /* SP_QsnFrPopupPreviewSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c7},
+ /* SP_QsnFrPopupPreviewSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c8},
+ /* SP_QsnFrPopupPreviewSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c9},
+ /* SP_QsnFrPopupPreviewCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c2},
+
+ /* SP_QsnFrSetOptCornerTl */ {KAknsIIDQsnFrSetOptCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerTr */ {KAknsIIDQsnFrSetOptCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerBl */ {KAknsIIDQsnFrSetOptCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerBr */ {KAknsIIDQsnFrSetOptCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideT */ {KAknsIIDQsnFrSetOptSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideB */ {KAknsIIDQsnFrSetOptSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideL */ {KAknsIIDQsnFrSetOptSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideR */ {KAknsIIDQsnFrSetOptSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCenter */ {KAknsIIDQsnFrSetOptCenter, ENoDraw, ES60_All, -1,-1},
+
+ // No toolbar frame for 5.0+ releases.
+ /* SP_QsnFrPopupSubCornerTl */ {KAknsIIDQsnFrPopupSubCornerTl, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerTr */ {KAknsIIDQsnFrPopupSubCornerTr, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerBl */ {KAknsIIDQsnFrPopupSubCornerBl, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerBr */ {KAknsIIDQsnFrPopupSubCornerBr, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideT */ {KAknsIIDQsnFrPopupSubSideT, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideB */ {KAknsIIDQsnFrPopupSubSideB, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideL */ {KAknsIIDQsnFrPopupSubSideL, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_X, -1,-1},
+
+ // No inactive button graphics in 3.1/3.2
+ /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/
+ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b2},
+ /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b3},
+ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b4},
+ /* SP_QsnFrButtonSideTInactive */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b5},
+ /* SP_QsnFrButtonSideBInactive */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b6},
+ /* SP_QsnFrButtonSideLInactive */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b7},
+ /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b8},
+ /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_X, EAknsMajorSkin, 0x21b9},
+
+ // No pressed down grid in 3.1/3.2
+ /* SP_QsnFrGridCornerTlPressed */ {KAknsIIDQsnFrGridCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2681}, /*KAknsIIDQsnFrGridCornerTlPressed*/
+ /* SP_QsnFrGridCornerTrPressed */ {KAknsIIDQsnFrGridCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2682},
+ /* SP_QsnFrGridCornerBlPressed */ {KAknsIIDQsnFrGridCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2683},
+ /* SP_QsnFrGridCornerBrPressed */ {KAknsIIDQsnFrGridCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2684},
+ /* SP_QsnFrGridSideTPressed */ {KAknsIIDQsnFrGridSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2685},
+ /* SP_QsnFrGridSideBPressed */ {KAknsIIDQsnFrGridSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2686},
+ /* SP_QsnFrGridSideLPressed */ {KAknsIIDQsnFrGridSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2687},
+ /* SP_QsnFrGridSideRPressed */ {KAknsIIDQsnFrGridSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2688},
+ /* SP_QsnFrGridCenterPressed */ {KAknsIIDQsnFrGridCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2689},
+
+ // No pressed down list in 3.1/3.2
+ /* SP_QsnFrListCornerTlPressed */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268b}, /*KAknsIIDQsnFrListCornerTlPressed*/
+ /* SP_QsnFrListCornerTrPressed */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268c},
+ /* SP_QsnFrListCornerBlPressed */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268d},
+ /* SP_QsnFrListCornerBrPressed */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268e},
+ /* SP_QsnFrListSideTPressed */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268f},
+ /* SP_QsnFrListSideBPressed */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2690},
+ /* SP_QsnFrListSideLPressed */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2691},
+ /* SP_QsnFrListSideRPressed */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2692},
+ /* SP_QsnFrListCenterPressed */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2693},
+};
+
+QPixmap QS60StyleModeSpecifics::skinnedGraphics(
+ QS60StyleEnums::SkinParts stylepart, const QSize &size,
+ QS60StylePrivate::SkinElementFlags flags)
+{
+ QPixmap themedImage;
+ TRAPD( error, QT_TRYCATCH_LEAVING({
+ const QPixmap skinnedImage = createSkinnedGraphicsLX(stylepart, size, flags);
+ themedImage = skinnedImage;
+ }));
+ if (error)
+ return themedImage = QPixmap();
+ return themedImage;
+}
+
+QPixmap QS60StyleModeSpecifics::skinnedGraphics(
+ QS60StylePrivate::SkinFrameElements frame, const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+{
+ QPixmap themedImage;
+ TRAPD( error, QT_TRYCATCH_LEAVING({
+ const QPixmap skinnedImage = createSkinnedGraphicsLX(frame, size, flags);
+ themedImage = skinnedImage;
+ }));
+ if (error)
+ return themedImage = QPixmap();
+ return themedImage;
+}
+
+QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
+ const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
+ QS60StylePrivate::SkinElementFlags flags)
+{
+ QPixmap colorGraphics;
+ TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, painter, flags)));
+ return error ? QPixmap() : colorGraphics;
+}
+
+void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex)
+{
+ switch(stylePart) {
+ case QS60StyleEnums::SP_QgnGrafBarWaitAnim:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameCenter:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_frame_center;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_l;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_r;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarProgress:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_progress;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveL:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_active_l;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveM:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_active_m;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveR:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_active_r;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabPassiveL:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_passive_l;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabPassiveM:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_passive_m;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabPassiveR:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_passive_r;
+ break;
+ case QS60StyleEnums::SP_QgnIndiCheckboxOff:
+ fallbackIndex = EMbmAvkonQgn_indi_checkbox_off;
+ break;
+ case QS60StyleEnums::SP_QgnIndiCheckboxOn:
+ fallbackIndex = EMbmAvkonQgn_indi_checkbox_on;
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlColSuper:
+ fallbackIndex = 0x4456; /* EMbmAvkonQgn_indi_hl_col_super */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlExpSuper:
+ fallbackIndex = 0x4458; /* EMbmAvkonQgn_indi_hl_exp_super */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlLineBranch:
+ fallbackIndex = 0x445A; /* EMbmAvkonQgn_indi_hl_line_branch */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlLineEnd:
+ fallbackIndex = 0x445C; /* EMbmAvkonQgn_indi_hl_line_end */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlLineStraight:
+ fallbackIndex = 0x445E; /* EMbmAvkonQgn_indi_hl_line_straight */
+ break;
+ case QS60StyleEnums::SP_QgnIndiMarkedAdd:
+ fallbackIndex = EMbmAvkonQgn_indi_marked_add;
+ break;
+ case QS60StyleEnums::SP_QgnIndiNaviArrowLeft:
+ fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_left;
+ break;
+ case QS60StyleEnums::SP_QgnIndiNaviArrowRight:
+ fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_right;
+ break;
+ case QS60StyleEnums::SP_QgnIndiRadiobuttOff:
+ fallbackIndex = EMbmAvkonQgn_indi_radiobutt_off;
+ break;
+ case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
+ fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on;
+ break;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */
+ break;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
+ fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */
+ break;
+ case QS60StyleEnums::SP_QgnIndiSubmenu:
+ fallbackIndex = EMbmAvkonQgn_indi_submenu;
+ break;
+ case QS60StyleEnums::SP_QgnNoteErased:
+ fallbackIndex = EMbmAvkonQgn_note_erased;
+ break;
+ case QS60StyleEnums::SP_QgnNoteError:
+ fallbackIndex = EMbmAvkonQgn_note_error;
+ break;
+ case QS60StyleEnums::SP_QgnNoteInfo:
+ fallbackIndex = EMbmAvkonQgn_note_info;
+ break;
+ case QS60StyleEnums::SP_QgnNoteOk:
+ fallbackIndex = EMbmAvkonQgn_note_ok;
+ break;
+ case QS60StyleEnums::SP_QgnNoteQuery:
+ fallbackIndex = EMbmAvkonQgn_note_query;
+ break;
+ case QS60StyleEnums::SP_QgnNoteWarning:
+ fallbackIndex = EMbmAvkonQgn_note_warning;
+ break;
+ case QS60StyleEnums::SP_QgnPropFileSmall:
+ fallbackIndex = EMbmAvkonQgn_prop_file_small;
+ break;
+ case QS60StyleEnums::SP_QgnPropFolderCurrent:
+ fallbackIndex = EMbmAvkonQgn_prop_folder_current;
+ break;
+ case QS60StyleEnums::SP_QgnPropFolderSmall:
+ fallbackIndex = EMbmAvkonQgn_prop_folder_small;
+ break;
+ case QS60StyleEnums::SP_QgnPropFolderSmallNew:
+ fallbackIndex = EMbmAvkonQgn_prop_folder_small_new;
+ break;
+ case QS60StyleEnums::SP_QgnPropPhoneMemcLarge:
+ fallbackIndex = EMbmAvkonQgn_prop_phone_memc_large;
+ break;
+ default:
+ fallbackIndex = -1;
+ break;
+ }
+}
+
+QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
+ const QS60StyleEnums::SkinParts &stylepart,
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags)
+{
+ // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
+ const int stylepartIndex = (int)stylepart;
+ const TAknsItemID skinId = m_partMap[stylepartIndex].skinID;
+
+ TInt fallbackGraphicID = -1;
+ HBufC* iconFile = HBufC::NewLC( KMaxFileName );
+ fallbackInfo(stylepart, fallbackGraphicID);
+
+ TAknsItemID colorGroup = KAknsIIDQsnIconColors;
+ TRgb defaultColor = KRgbBlack;
+ int colorIndex = -1; //set a bogus value to color index to ensure that painter color is used
+ //to color the icon
+ if (painter) {
+ QRgb widgetColor = painter->pen().color().rgb();
+ defaultColor = TRgb(qRed(widgetColor), qGreen(widgetColor), qBlue(widgetColor));
+ }
+
+ const bool rotatedBy90or270 =
+ (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
+ const TSize targetSize =
+ rotatedBy90or270?TSize(size.height(), size.width()):TSize(size.width(), size.height());
+ CFbsBitmap *icon = 0;
+ CFbsBitmap *iconMask = 0;
+ const TInt fallbackGraphicsMaskID =
+ fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ AknsUtils::CreateColorIconLC(
+ skinInstance,
+ skinId,
+ colorGroup,
+ colorIndex,
+ icon,
+ iconMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID,
+ fallbackGraphicsMaskID,
+ defaultColor);
+
+ QPixmap result = fromFbsBitmap(icon, iconMask, flags, targetSize);
+ CleanupStack::PopAndDestroy(3); //icon, iconMask, iconFile
+ return result;
+}
+
+QColor QS60StyleModeSpecifics::colorValue(const TAknsItemID &colorGroup, int colorIndex)
+{
+ TRgb skinnedColor;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsUtils::GetCachedColor(skin, skinnedColor, colorGroup, colorIndex);
+ return QColor(skinnedColor.Red(),skinnedColor.Green(),skinnedColor.Blue());
+}
+
+struct QAutoFbsBitmapHeapLock
+{
+ QAutoFbsBitmapHeapLock(CFbsBitmap* aBmp) : mBmp(aBmp) { mBmp->LockHeap(); }
+ ~QAutoFbsBitmapHeapLock() { mBmp->UnlockHeap(); }
+ CFbsBitmap* mBmp;
+};
+
+QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize &targetSize)
+{
+ Q_ASSERT(icon);
+
+ AknIconUtils::DisableCompression(icon);
+ TInt error = AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved);
+
+ if (mask && !error) {
+ AknIconUtils::DisableCompression(mask);
+ error = AknIconUtils::SetSize(mask, targetSize, EAspectRatioNotPreserved);
+ }
+ if (error)
+ return QPixmap();
+
+ QPixmap pixmap;
+ QScopedPointer<QPixmapData> pd(QPixmapData::create(0, 0, QPixmapData::PixmapType));
+ if (mask) {
+ // Try the efficient path with less copying and conversion.
+ QVolatileImage img(icon, mask);
+ pd->fromNativeType(&img, QPixmapData::VolatileImage);
+ if (!pd->isNull())
+ pixmap = QPixmap(pd.take());
+ }
+ if (pixmap.isNull()) {
+ // Potentially more expensive path.
+ pd->fromNativeType(icon, QPixmapData::FbsBitmap);
+ pixmap = QPixmap(pd.take());
+ if (mask) {
+ pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+ }
+ }
+
+ if ((flags & QS60StylePrivate::SF_PointEast) ||
+ (flags & QS60StylePrivate::SF_PointSouth) ||
+ (flags & QS60StylePrivate::SF_PointWest)) {
+ QImage iconImage = pixmap.toImage();
+ QTransform imageTransform;
+ if (flags & QS60StylePrivate::SF_PointEast) {
+ imageTransform.rotate(90);
+ } else if (flags & QS60StylePrivate::SF_PointSouth) {
+ imageTransform.rotate(180);
+ iconImage = iconImage.transformed(imageTransform);
+ } else if (flags & QS60StylePrivate::SF_PointWest) {
+ imageTransform.rotate(270);
+ }
+ if (imageTransform.isRotating())
+ iconImage = iconImage.transformed(imageTransform);
+
+ pixmap = QPixmap::fromImage(iconImage);
+ }
+ if ((flags & QS60StylePrivate::SF_Mirrored_X_Axis) ||
+ (flags & QS60StylePrivate::SF_Mirrored_Y_Axis)) {
+ QImage iconImage = pixmap.toImage().mirrored(
+ flags & QS60StylePrivate::SF_Mirrored_X_Axis,
+ flags & QS60StylePrivate::SF_Mirrored_Y_Axis);
+ pixmap = QPixmap::fromImage(iconImage);
+ }
+
+ return pixmap;
+}
+
+bool QS60StylePrivate::isTouchSupported()
+{
+ return bool(AknLayoutUtils::PenEnabled());
+}
+
+bool QS60StylePrivate::isToolBarBackground()
+{
+ return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
+}
+
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
+}
+
+bool QS60StylePrivate::isSingleClickUi()
+{
+ return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0);
+}
+
+void QS60StylePrivate::deleteStoredSettings()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QS60Style"));
+ settings.remove(QString());
+ settings.endGroup();
+}
+
+// Since S60Style has 'button' as a graphic, we don't have any native color which to use
+// for QPalette::Button. Therefore S60Style needs to guesstimate palette color by calculating
+// average rgb values for button pixels.
+// Returns Qt::black if there is an issue with the graphics (image is NULL, or no constBits() found).
+QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
+{
+#ifndef QT_NO_SETTINGS
+ TInt themeID = 0;
+ //First we need to fetch active theme ID. We need to store the themeID at the same time
+ //as color, so that we can later check if the stored color is still from the same theme.
+ //Native side stores active theme UID/Timestamp into central repository.
+ int error = 0;
+ QT_TRAP_THROWING(
+ CRepository *themeRepository = CRepository::NewLC(personalisationUID);
+ if (themeRepository) {
+ TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space
+ const TUint32 key = 0x00000002; //active theme key in the repository
+ error = themeRepository->Get(key, value);
+ if (error == KErrNone) {
+ TLex lex(value);
+ TPtrC numberToken(lex.NextToken());
+ if (numberToken.Length())
+ error = TLex(numberToken).Val(themeID);
+ else
+ error = KErrArgument;
+ }
+ }
+ CleanupStack::PopAndDestroy(themeRepository);
+ );
+
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QS60Style"));
+ if (themeID != 0) {
+ QVariant buttonColor = settings.value(QLatin1String("ButtonColor"));
+ if (!buttonColor.isNull()) {
+ //there is a stored color value, lets see if the theme ID matches
+ if (error == KErrNone) {
+ QVariant themeUID = settings.value(QLatin1String("ThemeUID"));
+ if (!themeUID.isNull() && themeUID.toInt() == themeID) {
+ QColor storedColor(buttonColor.value<QColor>());
+ if (storedColor.isValid())
+ return storedColor;
+ }
+ }
+ settings.remove(QString()); //if color was invalid, or theme has been changed, just delete all stored settings
+ }
+ }
+#endif
+
+ QColor color = calculatedColor(frame);
+
+#ifndef QT_NO_SETTINGS
+ settings.setValue(QLatin1String("ThemeUID"), QVariant(themeID));
+ if (frame == SF_ButtonNormal) //other colors are not currently calculated from graphics
+ settings.setValue(QLatin1String("ButtonColor"), QVariant(color));
+ settings.endGroup();
+#endif
+
+ return color;
+}
+
+QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
+{
+ CCoeControl *control = targetWidget->effectiveWinId();
+ TPoint pos(0,0);
+ if (control)
+ pos = control->PositionRelativeToScreen();
+ return QPoint(pos.iX, pos.iY);
+}
+
+QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
+ QS60StyleEnums::SkinParts part, const QSize &size,
+ QS60StylePrivate::SkinElementFlags flags)
+{
+ // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
+ if (!size.isValid())
+ return QPixmap();
+
+ // Check release support and change part, if necessary.
+ const TAknsItemID skinId = partSpecificThemeId((int)part);
+ const int stylepartIndex = (int)part;
+ const TDrawType drawType = m_partMap[stylepartIndex].drawType;
+ Q_ASSERT(drawType != ENoDraw);
+ const bool rotatedBy90or270 =
+ (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
+ const TSize targetSize =
+ rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
+
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
+ static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamRGBOnly;
+
+ QPixmap result;
+
+ switch (drawType) {
+ case EDrawGulIcon: {
+ CGulIcon* icon = AknsUtils::CreateGulIconL( AknsUtils::SkinInstance(), skinId, EFalse );
+ if (icon)
+ result = fromFbsBitmap(icon->Bitmap(), icon->Mask(), flags, targetSize);
+ delete icon;
+ break;
+ }
+ case EDrawIcon: {
+ TInt fallbackGraphicID = -1;
+ fallbackInfo(part, fallbackGraphicID);
+
+ CFbsBitmap *icon = 0;
+ CFbsBitmap *iconMask = 0;
+ const TInt fallbackGraphicsMaskID =
+ fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
+
+ AknsUtils::CreateIconL(
+ skinInstance,
+ skinId,
+ icon,
+ iconMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID ,
+ fallbackGraphicsMaskID);
+
+ result = fromFbsBitmap(icon, iconMask, flags, targetSize);
+ delete icon;
+ delete iconMask;
+ break;
+ }
+ case EDrawBackground: {
+ // QS60WindowSurface::unlockBitmapHeap();
+ CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen
+ CleanupStack::PushL(background);
+ User::LeaveIfError(background->Create(targetSize, displayMode));
+
+ CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
+ CleanupStack::PushL(dev);
+ CFbsBitGc *gc = NULL;
+ User::LeaveIfError(dev->CreateContext(gc));
+ CleanupStack::PushL(gc);
+
+ CAknsBasicBackgroundControlContext *bgContext = CAknsBasicBackgroundControlContext::NewL(
+ skinId,
+ targetSize,
+ EFalse);
+ CleanupStack::PushL(bgContext);
+
+ const TBool drawn = AknsDrawUtils::DrawBackground(
+ skinInstance,
+ bgContext,
+ NULL,
+ *gc,
+ TPoint(),
+ targetSize,
+ drawParam);
+
+ if (drawn)
+ result = fromFbsBitmap(background, NULL, flags, targetSize);
+ // if drawing fails in skin server, just ignore the background (probably OOM case)
+
+ CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext
+ // QS60WindowSurface::lockBitmapHeap();
+ break;
+ }
+ case EDrawAnimation: {
+ CFbsBitmap* animationFrame;
+ CFbsBitmap* frameMask;
+ CAknBitmapAnimation* aknAnimation = 0;
+ TBool constructedFromTheme = ETrue;
+
+ QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed
+ if (animation) {
+ if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation
+ CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL();
+ CleanupStack::PushL(newAnimation);
+ if (newAnimation)
+ constructedFromTheme = newAnimation->ConstructFromSkinL(skinId);
+ if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
+ animation->setResourceBased(false);
+ animation->setAnimationObject(newAnimation); //animation takes ownership
+ }
+ CleanupStack::Pop(newAnimation);
+ }
+ //fill-in stored information
+ aknAnimation = animation->animationObject();
+ constructedFromTheme = !animation->isResourceBased();
+ }
+
+ const int currentFrame = QS60StylePrivate::currentAnimationFrame(part);
+ if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
+ //Animation was created successfully and contains frames, just fetch current frame
+ if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count())
+ User::Leave(KErrOverflow);
+ const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame);
+ if (frameData) {
+ animationFrame = frameData->Bitmap();
+ frameMask = frameData->Mask();
+ }
+ } else {
+ //Theme does not contain animation theming, create frames from resource file
+ TInt fallbackGraphicID = -1;
+ fallbackInfo(part, fallbackGraphicID);
+ fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks
+ TInt fallbackGraphicsMaskID =
+ (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files
+ if (fallbackGraphicsMaskID != KErrNotFound)
+ fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics
+
+ //Then draw animation frame
+ AknsUtils::CreateIconL(
+ skinInstance,
+ KAknsIIDDefault, //animation is not themed, lets force fallback graphics
+ animationFrame,
+ frameMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID ,
+ fallbackGraphicsMaskID);
+ }
+ result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize);
+ if (!constructedFromTheme) {
+ delete animationFrame;
+ animationFrame = 0;
+ delete frameMask;
+ frameMask = 0;
+ }
+ break;
+ }
+ }
+ if (!result)
+ result = QPixmap();
+
+ return result;
+}
+
+QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+{
+ // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
+ if (!size.isValid())
+ return QPixmap();
+
+ const bool rotatedBy90or270 =
+ (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
+ const TSize targetSize =
+ rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
+
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ QPixmap result;
+
+ static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
+ static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
+
+ CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen
+ CleanupStack::PushL(frame);
+ User::LeaveIfError(frame->Create(targetSize, displayMode));
+
+ CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL(frame);
+ CleanupStack::PushL(bitmapDev);
+ CFbsBitGc* bitmapGc = NULL;
+ User::LeaveIfError(bitmapDev->CreateContext(bitmapGc));
+ CleanupStack::PushL(bitmapGc);
+
+ frame->LockHeap();
+ memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4); // 4: argb bytes
+ frame->UnlockHeap();
+
+ const TRect outerRect(TPoint(0, 0), targetSize);
+ const TRect innerRect = innerRectFromElement(frameElement, outerRect);
+
+ TAknsItemID frameSkinID, centerSkinID;
+ frameSkinID = centerSkinID = partSpecificThemeId(QS60StylePrivate::m_frameElementsData[frameElement].center);
+ frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
+
+ TBool drawn = AknsDrawUtils::DrawFrame(
+ skinInstance,
+ *bitmapGc,
+ outerRect,
+ innerRect,
+ frameSkinID,
+ centerSkinID,
+ drawParam );
+
+ if (S60->supportsPremultipliedAlpha) {
+ if (drawn) {
+ result = fromFbsBitmap(frame, NULL, flags, targetSize);
+ } else {
+ // Drawing might fail due to OOM (we can do nothing about that),
+ // or due to skin item not being available.
+ // If the latter occurs, lets try switch to non-release specific items (if available)
+ // and re-try the drawing.
+ frameSkinID = centerSkinID = m_partMap[(int)QS60StylePrivate::m_frameElementsData[frameElement].center].skinID;
+ frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
+ drawn = AknsDrawUtils::DrawFrame( skinInstance,
+ *bitmapGc, outerRect, innerRect,
+ frameSkinID, centerSkinID,
+ drawParam );
+ // in case drawing fails, even after using default graphics, ignore the error
+ if (drawn)
+ result = fromFbsBitmap(frame, NULL, flags, targetSize);
+ }
+ } else {
+ TDisplayMode maskDepth = EGray256;
+ // Query the skin item for possible frame graphics mask details.
+ if (skinInstance) {
+ CAknsMaskedBitmapItemData* skinMaskedBmp = static_cast<CAknsMaskedBitmapItemData*>(
+ skinInstance->GetCachedItemData(frameSkinID,EAknsITMaskedBitmap));
+ if (skinMaskedBmp && skinMaskedBmp->Mask())
+ maskDepth = skinMaskedBmp->Mask()->DisplayMode();
+ }
+ if (maskDepth != ENone) {
+ CFbsBitmap *frameMask = new (ELeave) CFbsBitmap(); //offscreen
+ CleanupStack::PushL(frameMask);
+ User::LeaveIfError(frameMask->Create(targetSize, maskDepth));
+
+ CFbsBitmapDevice* maskBitmapDevice = CFbsBitmapDevice::NewL(frameMask);
+ CleanupStack::PushL(maskBitmapDevice);
+ CFbsBitGc* maskBitGc = NULL;
+ User::LeaveIfError(maskBitmapDevice->CreateContext(maskBitGc));
+ CleanupStack::PushL(maskBitGc);
+
+ if (drawn) {
+ //ensure that the mask is really transparent
+ maskBitGc->Activate( maskBitmapDevice );
+ maskBitGc->SetPenStyle(CGraphicsContext::ENullPen);
+ maskBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ maskBitGc->SetBrushColor(KRgbWhite);
+ maskBitGc->Clear();
+ maskBitGc->SetBrushStyle(CGraphicsContext::ENullBrush);
+
+ drawn = AknsDrawUtils::DrawFrame(skinInstance,
+ *maskBitGc, outerRect, innerRect,
+ frameSkinID, centerSkinID,
+ KAknsSDMAlphaOnly |KAknsDrawParamNoClearUnderImage);
+ if (drawn)
+ result = fromFbsBitmap(frame, frameMask, flags, targetSize);
+ }
+ CleanupStack::PopAndDestroy(3, frameMask);
+ }
+ }
+ CleanupStack::PopAndDestroy(3, frame); //frame, bitmapDev, bitmapGc
+ return result;
+}
+
+void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId)
+{
+// There are some major mix-ups in skin declarations for some frames.
+// First, the frames are not declared in sequence.
+// Second, the parts use different major than the frame-master.
+
+ switch(frameElement) {
+ case QS60StylePrivate::SF_ToolTip:
+ if (QSysInfo::s60Version() != QSysInfo::SV_S60_3_1) {
+ centerId.Set(EAknsMajorGeneric, 0x19c2);
+ frameId.Set(EAknsMajorSkin, 0x5300);
+ } else {
+ centerId.Set(KAknsIIDQsnFrPopupCenter);
+ frameId.iMinor = centerId.iMinor - 9;
+ }
+ break;
+ case QS60StylePrivate::SF_ToolBar:
+ if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 ||
+ QSysInfo::s60Version() == QSysInfo::SV_S60_3_2) {
+ centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
+ frameId.Set(KAknsIIDQsnFrPopupSub);
+ }
+ break;
+ case QS60StylePrivate::SF_PopupBackground:
+ centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
+ frameId.Set(KAknsIIDQsnFrPopupSub);
+ break;
+ case QS60StylePrivate::SF_PanelBackground:
+ // remove center piece for panel graphics, so that only border is drawn
+ centerId.Set(KAknsIIDNone);
+ frameId.Set(KAknsIIDQsnFrSetOpt);
+ break;
+ default:
+ // center should be correct here
+ frameId.iMinor = centerId.iMinor - 9;
+ break;
+ }
+}
+
+TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect)
+{
+ TInt widthShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
+ TInt heightShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerHeight);
+ switch(frameElement) {
+ case QS60StylePrivate::SF_PanelBackground:
+ // panel should have slightly slimmer border to enable thin line of background graphics between closest component
+ widthShrink = widthShrink - 2;
+ heightShrink = heightShrink - 2;
+ break;
+ case QS60StylePrivate::SF_ToolTip:
+ widthShrink = widthShrink >> 1;
+ heightShrink = heightShrink >> 1;
+ break;
+ case QS60StylePrivate::SF_ListHighlight:
+ //In Sym^3 devices highlights are less blocky
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ widthShrink += 2;
+ heightShrink += 2;
+ } else {
+ widthShrink -= 2;
+ heightShrink -= 2;
+ }
+ break;
+ case QS60StylePrivate::SF_PopupBackground:
+ widthShrink = widthShrink + 5;
+ heightShrink = heightShrink + 5;
+ break;
+ default:
+ break;
+ }
+ TRect innerRect(outerRect);
+ innerRect.Shrink(widthShrink, heightShrink);
+ return innerRect;
+}
+
+bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
+{
+ const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
+ return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) ||
+ (currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) ||
+ (currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0) ||
+ (currentRelease == QSysInfo::SV_S60_5_1 && supportedRelease & ES60_5_1) ||
+ (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2) ||
+ (currentRelease == QSysInfo::SV_S60_5_3 && supportedRelease & ES60_5_3) );
+}
+
+TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
+{
+ TAknsItemID newSkinId;
+ if (!checkSupport(m_partMap[(int)part].supportInfo))
+ newSkinId.Set(m_partMap[(int)part].newMajorSkinId, m_partMap[(int)part].newMinorSkinId);
+ else
+ newSkinId.Set(m_partMap[(int)part].skinID);
+ return newSkinId;
+}
+
+QFont QS60StylePrivate::s60Font_specific(
+ QS60StyleEnums::FontCategories fontCategory,
+ int pointSize, bool resolveFontSize)
+{
+ Q_UNUSED(resolveFontSize);
+
+ TAknFontCategory aknFontCategory = EAknFontCategoryUndefined;
+ switch (fontCategory) {
+ case QS60StyleEnums::FC_Primary:
+ aknFontCategory = EAknFontCategoryPrimary;
+ break;
+ case QS60StyleEnums::FC_Secondary:
+ aknFontCategory = EAknFontCategorySecondary;
+ break;
+ case QS60StyleEnums::FC_Title:
+ aknFontCategory = EAknFontCategoryTitle;
+ break;
+ case QS60StyleEnums::FC_PrimarySmall:
+ aknFontCategory = EAknFontCategoryPrimarySmall;
+ break;
+ case QS60StyleEnums::FC_Digital:
+ aknFontCategory = EAknFontCategoryDigital;
+ break;
+ case QS60StyleEnums::FC_Undefined:
+ default:
+ break;
+ }
+
+ // Create AVKON font according the given parameters
+ CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice();
+ TAknFontSpecification spec(aknFontCategory, TFontSpec(), NULL);
+ if (pointSize > 0) {
+ const TInt pixelSize = dev->VerticalTwipsToPixels(pointSize * KTwipsPerPoint);
+ spec.SetTextPaneHeight(pixelSize + 4); // TODO: Is 4 a reasonable top+bottom margin?
+ }
+
+ QFont result;
+ TRAPD( error, QT_TRYCATCH_LEAVING({
+ const CAknLayoutFont* aknFont =
+ AknFontAccess::CreateLayoutFontFromSpecificationL(*dev, spec);
+
+ result = qt_TFontSpec2QFontL(aknFont->DoFontSpecInTwips());
+ if (result.pointSize() != pointSize)
+ result.setPointSize(pointSize); // Correct the font size returned by CreateLayoutFontFromSpecificationL()
+
+ delete aknFont;
+ }));
+ if (error) result = QFont();
+ return result;
+}
+
+void QS60StylePrivate::setActiveLayout()
+{
+ const QSize activeScreenSize(screenSize());
+ int activeLayoutIndex = -1;
+ const short screenHeight = (short)activeScreenSize.height();
+ const short screenWidth = (short)activeScreenSize.width();
+ for (int i=0; i<m_numberOfLayouts; i++) {
+ if (screenHeight==m_layoutHeaders[i].height &&
+ screenWidth==m_layoutHeaders[i].width) {
+ activeLayoutIndex = i;
+ break;
+ }
+ }
+
+ //not found, lets try with either of dimensions
+ if (activeLayoutIndex==-1){
+ const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
+ const bool landscape = screenHeight < screenWidth;
+
+ activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 2;
+ activeLayoutIndex += (!landscape) ? 1 : 0;
+ }
+
+ setCurrentLayout(activeLayoutIndex);
+}
+
+Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations)
+
+QS60StylePrivate::QS60StylePrivate()
+{
+ //Animation defaults need to be created when style is instantiated
+ QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100);
+ m_animations()->append(progressBarAnimation);
+ // No need to set active layout, if dynamic metrics API is available
+ setActiveLayout();
+}
+
+void QS60StylePrivate::removeAnimations()
+{
+ //currently only one animation in the list.
+ m_animations()->removeFirst();
+}
+
+QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
+ int index, const QStyleOption *option)
+{
+ static const TAknsItemID *idMap[] = {
+ &KAknsIIDQsnHighlightColors,
+ &KAknsIIDQsnIconColors,
+ &KAknsIIDQsnLineColors,
+ &KAknsIIDQsnOtherColors,
+ &KAknsIIDQsnParentColors,
+ &KAknsIIDQsnTextColors
+ };
+ Q_ASSERT((int)list < (int)sizeof(idMap)/sizeof(idMap[0]));
+ const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1);
+ return option ? QS60StylePrivate::stateColor(color, option) : color;
+}
+
+// In some cases, the AVKON UI themegraphic is already in 'disabled state'.
+// If so, return true for these parts.
+bool QS60StyleModeSpecifics::disabledPartGraphic(QS60StyleEnums::SkinParts &part)
+{
+ bool disabledGraphic = false;
+ switch(part){
+ // inactive button graphics are available from 5.0 onwards
+ case QS60StyleEnums::SP_QsnFrButtonCornerTlInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCornerTrInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCornerBlInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCornerBrInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideTInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideBInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideLInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideRInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCenterInactive:
+ if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
+ QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
+ disabledGraphic = true;
+ break;
+ default:
+ break;
+ }
+ return disabledGraphic;
+}
+
+// In some cases, the AVKON UI themegraphic is already in 'disabled state'.
+// If so, return true for these frames.
+bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame)
+{
+ bool disabledGraphic = false;
+ switch(frame){
+ // inactive button graphics are available from 5.0 onwards
+ case QS60StylePrivate::SF_ButtonInactive:
+ if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
+ QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
+ disabledGraphic = true;
+ break;
+ default:
+ break;
+ }
+ return disabledGraphic;
+}
+
+QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+{
+ if (!QS60StylePrivate::isTouchSupported())
+ return QPixmap();
+
+ QS60StyleEnums::SkinParts updatedPart = part;
+ switch(part){
+ // AVKON UI has a abnormal handling for scrollbar graphics. It is possible that the root
+ // skin does not contain mandatory graphics for scrollbar pressed states. Therefore, AVKON UI
+ // creates dynamically these graphics by modifying the normal state scrollbar graphics slightly.
+ // S60Style needs to work similarly. Therefore if skingraphics call provides to be a miss
+ // (i.e. result is not valid), style needs to draw normal graphics instead and apply some
+ // modifications (similar to generatedIconPixmap()) to the result.
+ case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
+ updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleBottom;
+ break;
+ case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
+ updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleMiddle;
+ break;
+ case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
+ updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleTop;
+ break;
+ default:
+ break;
+ }
+ if (part==updatedPart) {
+ return QPixmap();
+ } else {
+ QPixmap result = skinnedGraphics(updatedPart, size, flags);
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+
+ // For now, always generate new icon based on "selected". In the future possibly, expand
+ // this to consist other possibilities as well.
+ result = QApplication::style()->generatedIconPixmap(QIcon::Selected, result, &opt);
+ return result;
+ }
+}
+
+QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part,
+ const QSize &size, QPainter *painter, SkinElementFlags flags)
+{
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+
+ QPixmap result = (flags & SF_ColorSkinned)?
+ QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, painter, flags)
+ : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags);
+
+ lock.relock();
+
+ if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) {
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+ result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
+ }
+
+ if (!result)
+ result = QS60StyleModeSpecifics::generateMissingThemeGraphic(part, size, flags);
+
+ return result;
+}
+
+QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags)
+{
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ QPixmap result = QS60StyleModeSpecifics::skinnedGraphics(frame, size, flags);
+ lock.relock();
+
+ if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledFrameGraphic(frame)) {
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+ result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
+ }
+ return result;
+}
+
+QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
+{
+ bool createNewBackground = false;
+ TRect applicationRect = (static_cast<CEikAppUi*>(S60->appUi())->ApplicationRect());
+ if (!m_background) {
+ createNewBackground = true;
+ } else {
+ //if background brush does not match screensize, re-create it
+ if (m_background->width() != applicationRect.Width() ||
+ m_background->height() != applicationRect.Height()) {
+ delete m_background;
+ m_background = 0;
+ createNewBackground = true;
+ }
+ }
+
+ if (createNewBackground && !skipCreation) {
+ QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
+ QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
+ m_background = new QPixmap(background);
+
+ // Notify all widgets that palette is updated with the actual background texture.
+ QPalette pal = QApplication::palette();
+ pal.setBrush(QPalette::Window, *m_background);
+ QApplication::setPalette(pal);
+ setThemePaletteHash(&pal);
+ storeThemePalette(&pal);
+ foreach (QWidget *widget, QApplication::allWidgets()){
+ QEvent e(QEvent::PaletteChange);
+ QApplication::sendEvent(widget, &e);
+ setThemePalette(widget);
+ widget->ensurePolished();
+ }
+ }
+ if (!m_background)
+ return QPixmap();
+ return *m_background;
+}
+
+QSize QS60StylePrivate::screenSize()
+{
+ return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
+}
+
+QS60Style::QS60Style()
+ : QCommonStyle(*new QS60StylePrivate)
+{
+}
+
+#ifdef Q_WS_S60
+void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
+{
+ clearCaches(QS60StylePrivate::CC_LayoutChange);
+ setBackgroundTexture(qApp);
+ setActiveLayout();
+ foreach (QWidget *widget, QApplication::allWidgets())
+ widget->ensurePolished();
+}
+
+void QS60StylePrivate::handleSkinChange()
+{
+ clearCaches(QS60StylePrivate::CC_ThemeChange);
+ setThemePalette(qApp);
+ foreach (QWidget *topLevelWidget, QApplication::allWidgets()){
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(topLevelWidget, &e);
+ setThemePalette(topLevelWidget);
+ topLevelWidget->ensurePolished();
+ }
+#ifndef QT_NO_PROGRESSBAR
+ //re-start animation timer
+ stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones"
+ startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones"
+#endif
+}
+
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ QS60StyleAnimation *animation = animationDefinition(part);
+ // todo: looping could be done in QS60Style::timerEvent
+ if (animation->frameCount() == animation->currentFrame())
+ animation->setCurrentFrame(0);
+ return animation->currentFrame();
+}
+
+QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part)
+{
+ int i = 0;
+ const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count();
+ for(; i < animationsCount; i++) {
+ if (part == m_animations()->at(i)->animationId())
+ break;
+ }
+ return m_animations()->at(i);
+}
+
+void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ //Query animation data from theme and store values to local struct.
+ QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::TD_AnimationData, animationPart);
+ QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList();
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0)
+ animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt());
+
+ if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0)
+ animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt());
+
+ //todo: playmode is ignored for now, since it seems to return invalid data on some themes
+ //lets use the table values for play mode
+
+ animation->setCurrentFrame(0); //always initialize
+ const int timerId = q->startTimer(animation->interval());
+ animation->setTimerId(timerId);
+ }
+}
+
+void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ animation->setCurrentFrame(0);
+ if (animation->timerId() != 0) {
+ q->killTimer(animation->timerId());
+ animation->setTimerId(0);
+ }
+ animation->resetToDefaults();
+ }
+}
+
+QVariant QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part)
+{
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+
+ Q_ASSERT(skinInstance);
+
+ switch(definition) {
+ //Animation definitions
+ case QS60StyleEnums::TD_AnimationData:
+ {
+ CAknsBmpAnimItemData *animationData;
+ TAknsItemID animationSkinId = partSpecificThemeId(part);
+ QList<QVariant> list;
+
+ TRAPD( error, QT_TRYCATCH_LEAVING(
+ animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL(
+ animationSkinId, EAknsITBmpAnim))));
+ if (error)
+ return list;
+
+ if (animationData) {
+ list.append((int)animationData->FrameInterval());
+ list.append((int)animationData->NumberOfImages());
+
+ QS60StyleEnums::AnimationMode playMode;
+ switch(animationData->PlayMode()) {
+ case CBitmapAnimClientData::EPlay:
+ playMode = QS60StyleEnums::AM_PlayOnce;
+ break;
+ case CBitmapAnimClientData::ECycle:
+ playMode = QS60StyleEnums::AM_Looping;
+ break;
+ case CBitmapAnimClientData::EBounce:
+ playMode = QS60StyleEnums::AM_Bounce;
+ break;
+ default:
+ break;
+ }
+ list.append(QVariant((int)playMode));
+ delete animationData;
+ } else {
+ list.append(0);
+ list.append(0);
+ }
+ return list;
+ }
+ break;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+#endif // Q_WS_S60
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_S60 || QT_PLUGIN
diff --git a/src/widgets/styles/qs60style_simulated.cpp b/src/widgets/styles/qs60style_simulated.cpp
new file mode 100644
index 0000000000..ca02cdf5e1
--- /dev/null
+++ b/src/widgets/styles/qs60style_simulated.cpp
@@ -0,0 +1,457 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qs60style.h"
+#include "qs60style_p.h"
+#include "qfile.h"
+#include "qhash.h"
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qpicture.h"
+#include "qstyleoption.h"
+#include "qtransform.h"
+#include "qlayout.h"
+#include "qpixmapcache.h"
+#include "qmetaobject.h"
+#include "qdebug.h"
+#include "qbuffer.h"
+#include "qdesktopwidget.h"
+
+#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+static const quint32 blobVersion = 1;
+static const int pictureSize = 256;
+
+#if defined(Q_CC_GNU)
+#if __GNUC__ >= 2
+#define __FUNCTION__ __func__
+#endif
+#endif
+
+
+bool saveThemeToBlob(const QString &themeBlob,
+ const QHash<QString, QPicture> &partPictures,
+ const QHash<QPair<QString, int>, QColor> &colors)
+{
+ QFile blob(themeBlob);
+ if (!blob.open(QIODevice::WriteOnly)) {
+ qWarning() << __FUNCTION__ << ": Could not create blob: " << themeBlob;
+ return false;
+ }
+
+ QByteArray data;
+ QBuffer dataBuffer(&data);
+ dataBuffer.open(QIODevice::WriteOnly);
+ QDataStream dataOut(&dataBuffer);
+
+ const int colorsCount = colors.count();
+ dataOut << colorsCount;
+ const QList<QPair<QString, int> > colorKeys = colors.keys();
+ for (int i = 0; i < colorsCount; ++i) {
+ const QPair<QString, int> &key = colorKeys.at(i);
+ dataOut << key;
+ const QColor color = colors.value(key);
+ dataOut << color;
+ }
+
+ dataOut << partPictures.count();
+ QHashIterator<QString, QPicture> i(partPictures);
+ while (i.hasNext()) {
+ i.next();
+ dataOut << i.key();
+ dataOut << i.value(); // the QPicture
+ }
+
+ QDataStream blobOut(&blob);
+ blobOut << blobVersion;
+ blobOut << qCompress(data);
+ return blobOut.status() == QDataStream::Ok;
+}
+
+bool loadThemeFromBlob(const QString &themeBlob,
+ QHash<QString, QPicture> &partPictures,
+ QHash<QPair<QString, int>, QColor> &colors)
+{
+ QFile blob(themeBlob);
+ if (!blob.open(QIODevice::ReadOnly)) {
+ qWarning() << __FUNCTION__ << ": Could not read blob: " << themeBlob;
+ return false;
+ }
+ QDataStream blobIn(&blob);
+
+ quint32 version;
+ blobIn >> version;
+
+ if (version != blobVersion) {
+ qWarning() << __FUNCTION__ << ": Invalid blob version: " << version << " ...expected: " << blobVersion;
+ return false;
+ }
+
+ QByteArray data;
+ blobIn >> data;
+ data = qUncompress(data);
+ QBuffer dataBuffer(&data);
+ dataBuffer.open(QIODevice::ReadOnly);
+ QDataStream dataIn(&dataBuffer);
+
+ int colorsCount;
+ dataIn >> colorsCount;
+ for (int i = 0; i < colorsCount; ++i) {
+ QPair<QString, int> key;
+ dataIn >> key;
+ QColor value;
+ dataIn >> value;
+ colors.insert(key, value);
+ }
+
+ int picturesCount;
+ dataIn >> picturesCount;
+ for (int i = 0; i < picturesCount; ++i) {
+ QString key;
+ dataIn >> key;
+ QPicture value;
+ dataIn >> value;
+ value.setBoundingRect(QRect(0, 0, pictureSize, pictureSize)); // Bug? The forced bounding rect was not deserialized.
+ partPictures.insert(key, value);
+ }
+
+ if (dataIn.status() != QDataStream::Ok) {
+ qWarning() << __FUNCTION__ << ": Invalid data blob: " << themeBlob;
+ return false;
+ }
+ return true;
+}
+
+class QS60StyleModeSpecifics
+{
+public:
+ static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QHash<QString, QPicture> m_partPictures;
+ static QHash<QPair<QString , int>, QColor> m_colors;
+};
+QHash<QString, QPicture> QS60StyleModeSpecifics::m_partPictures;
+QHash<QPair<QString , int>, QColor> QS60StyleModeSpecifics::m_colors;
+
+QS60StylePrivate::QS60StylePrivate()
+{
+ setCurrentLayout(0);
+}
+
+QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
+ int index, const QStyleOption *option)
+{
+ const QString listKey = QS60Style::colorListKeys().at(list);
+ return QS60StylePrivate::stateColor(
+ QS60StyleModeSpecifics::m_colors.value(QPair<QString, int>(listKey, index)),
+ option
+ );
+}
+
+QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, const QSize &size,
+ QPainter *painter, QS60StylePrivate::SkinElementFlags flags)
+{
+ Q_UNUSED(painter);
+
+ const QString partKey = QS60Style::partKeys().at(part);
+ const QPicture partPicture = QS60StyleModeSpecifics::m_partPictures.value(partKey);
+ QSize partSize(partPicture.boundingRect().size());
+ if (flags & (SF_PointEast | SF_PointWest)) {
+ const int temp = partSize.width();
+ partSize.setWidth(partSize.height());
+ partSize.setHeight(temp);
+ }
+ const qreal scaleX = size.width() / (qreal)partSize.width();
+ const qreal scaleY = size.height() / (qreal)partSize.height();
+
+ QImage partImage(size, QImage::Format_ARGB32);
+ partImage.fill(Qt::transparent);
+ QPainter resultPainter(&partImage);
+ QTransform t;
+
+ if (flags & SF_PointEast)
+ t.translate(size.width(), 0);
+ else if (flags & SF_PointSouth)
+ t.translate(size.width(), size.height());
+ else if (flags & SF_PointWest)
+ t.translate(0, size.height());
+
+ t.scale(scaleX, scaleY);
+
+ if (flags & SF_PointEast)
+ t.rotate(90);
+ else if (flags & SF_PointSouth)
+ t.rotate(180);
+ else if (flags & SF_PointWest)
+ t.rotate(270);
+
+ resultPainter.setTransform(t, true);
+ const_cast<QPicture *>(&partPicture)->play(&resultPainter);
+ resultPainter.end();
+
+ QPixmap result = QPixmap::fromImage(partImage);
+ if (flags & SF_StateDisabled) {
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+ result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
+ }
+
+ return result;
+}
+
+QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size,
+ SkinElementFlags flags)
+{
+ const QS60StyleEnums::SkinParts center = m_frameElementsData[frame].center;
+ const QS60StyleEnums::SkinParts topLeft = QS60StyleEnums::SkinParts(center - 8);
+ const QS60StyleEnums::SkinParts topRight = QS60StyleEnums::SkinParts(center - 7);
+ const QS60StyleEnums::SkinParts bottomLeft = QS60StyleEnums::SkinParts(center - 6);
+ const QS60StyleEnums::SkinParts bottomRight = QS60StyleEnums::SkinParts(center - 5);
+ const QS60StyleEnums::SkinParts top = QS60StyleEnums::SkinParts(center - 4);
+ const QS60StyleEnums::SkinParts bottom = QS60StyleEnums::SkinParts(center - 3);
+ const QS60StyleEnums::SkinParts left = QS60StyleEnums::SkinParts(center - 2);
+ const QS60StyleEnums::SkinParts right = QS60StyleEnums::SkinParts(center - 1);
+
+ // The size of topLeft defines all other sizes
+ const QSize cornerSize(partSize(topLeft));
+ // if frame is so small that corners would cover it completely, draw only center piece
+ const bool drawOnlyCenter =
+ 2 * cornerSize.width() + 1 >= size.width() || 2 * cornerSize.height() + 1 >= size.height();
+
+ const int cornerWidth = cornerSize.width();
+ const int cornerHeight = cornerSize.height();
+ const int rectWidth = size.width();
+ const int rectHeight = size.height();
+ const QRect rect(QPoint(), size);
+
+ const QRect topLeftRect = QRect(rect.topLeft(), cornerSize);
+ const QRect topRect = rect.adjusted(cornerWidth, 0, -cornerWidth, -(rectHeight - cornerHeight));
+ const QRect topRightRect = topLeftRect.translated(rectWidth - cornerWidth, 0);
+ const QRect rightRect = rect.adjusted(rectWidth - cornerWidth, cornerHeight, 0, -cornerHeight);
+ const QRect bottomRightRect = topRightRect.translated(0, rectHeight - cornerHeight);
+ const QRect bottomRect = topRect.translated(0, rectHeight - cornerHeight);
+ const QRect bottomLeftRect = topLeftRect.translated(0, rectHeight - cornerHeight);
+ const QRect leftRect = rightRect.translated(cornerWidth - rectWidth, 0);
+ const QRect centerRect = drawOnlyCenter ? rect : rect.adjusted(cornerWidth, cornerWidth, -cornerWidth, -cornerWidth);
+
+ QPixmap result(size);
+ result.fill(Qt::transparent);
+ QPainter painter(&result);
+
+#if 0
+ painter.save();
+ painter.setOpacity(.3);
+ painter.fillRect(topLeftRect, Qt::red);
+ painter.fillRect(topRect, Qt::green);
+ painter.fillRect(topRightRect, Qt::blue);
+ painter.fillRect(rightRect, Qt::green);
+ painter.fillRect(bottomRightRect, Qt::red);
+ painter.fillRect(bottomRect, Qt::blue);
+ painter.fillRect(bottomLeftRect, Qt::green);
+ painter.fillRect(leftRect, Qt::blue);
+ painter.fillRect(centerRect, Qt::red);
+ painter.restore();
+#else
+ drawPart(topLeft, &painter, topLeftRect, flags);
+ drawPart(top, &painter, topRect, flags);
+ drawPart(topRight, &painter, topRightRect, flags);
+ drawPart(right, &painter, rightRect, flags);
+ drawPart(bottomRight, &painter, bottomRightRect, flags);
+ drawPart(bottom, &painter, bottomRect, flags);
+ drawPart(bottomLeft, &painter, bottomLeftRect, flags);
+ drawPart(left, &painter, leftRect, flags);
+ drawPart(center, &painter, centerRect, flags);
+#endif
+
+ return result;
+}
+
+QPixmap QS60StylePrivate::backgroundTexture(bool /*skipCreation*/)
+{
+ if (!m_background) {
+ const QSize size = QApplication::desktop()->screen()->size();
+ QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, size, 0);
+ m_background = new QPixmap(background);
+ }
+ return *m_background;
+}
+
+bool QS60StylePrivate::isTouchSupported()
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ return !QApplication::keypadNavigationEnabled();
+#else
+ return true;
+#endif
+}
+
+bool QS60StylePrivate::isToolBarBackground()
+{
+ return true;
+}
+
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return false;
+}
+
+bool QS60StylePrivate::isSingleClickUi()
+{
+ return false;
+}
+
+QFont QS60StylePrivate::s60Font_specific(
+ QS60StyleEnums::FontCategories fontCategory,
+ int pointSize, bool resolveFontSize)
+{
+ QFont result;
+ if (resolveFontSize)
+ result.setPointSize(pointSize);
+ switch (fontCategory) {
+ case QS60StyleEnums::FC_Primary:
+ result.setBold(true);
+ break;
+ case QS60StyleEnums::FC_Secondary:
+ case QS60StyleEnums::FC_Title:
+ case QS60StyleEnums::FC_PrimarySmall:
+ case QS60StyleEnums::FC_Digital:
+ case QS60StyleEnums::FC_Undefined:
+ default:
+ break;
+ }
+ return result;
+}
+
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ return 0;
+}
+
+/*!
+ Constructs a QS60Style object.
+*/
+QS60Style::QS60Style()
+ : QCommonStyle(*new QS60StylePrivate)
+{
+ const QString defaultBlob = QString::fromLatin1(":/trolltech/styles/s60style/images/defaults60theme.blob");
+ if (QFile::exists(defaultBlob))
+ loadS60ThemeFromBlob(defaultBlob);
+}
+
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, enumPartKeys, {
+ const int enumIndex = QS60StyleEnums::staticMetaObject.indexOfEnumerator("SkinParts");
+ Q_ASSERT(enumIndex >= 0);
+ const QMetaEnum metaEnum = QS60StyleEnums::staticMetaObject.enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i) {
+ const QString enumKey = QString::fromLatin1(metaEnum.key(i));
+ QString partKey;
+ // Following loop does following conversions: "SP_QgnNoteInfo" to "qgn_note_info"...
+ for (int charPosition = 3; charPosition < enumKey.length(); charPosition++) {
+ if (charPosition > 3 && enumKey[charPosition].isUpper())
+ partKey.append(QChar::fromLatin1('_'));
+ partKey.append(enumKey[charPosition].toLower());
+ }
+ x->append(partKey);
+ }
+})
+
+QStringList QS60Style::partKeys()
+{
+ return *enumPartKeys();
+}
+
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, enumColorListKeys, {
+ const int enumIndex = QS60StyleEnums::staticMetaObject.indexOfEnumerator("ColorLists");
+ Q_ASSERT(enumIndex >= 0);
+ const QMetaEnum metaEnum = QS60StyleEnums::staticMetaObject.enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); i++) {
+ const QString enumKey = QString::fromLatin1(metaEnum.key(i));
+ // Following line does following conversions: CL_QsnTextColors to "text"...
+ x->append(enumKey.mid(6, enumKey.length() - 12).toLower());
+ }
+})
+
+QStringList QS60Style::colorListKeys()
+{
+ return *enumColorListKeys();
+}
+
+void QS60Style::setS60Theme(const QHash<QString, QPicture> &parts,
+ const QHash<QPair<QString , int>, QColor> &colors)
+{
+ Q_D(QS60Style);
+ QS60StyleModeSpecifics::m_partPictures = parts;
+ QS60StyleModeSpecifics::m_colors = colors;
+ d->clearCaches(QS60StylePrivate::CC_ThemeChange);
+ d->setBackgroundTexture(qApp);
+ d->setThemePalette(qApp);
+}
+
+bool QS60Style::loadS60ThemeFromBlob(const QString &blobFile)
+{
+ QHash<QString, QPicture> partPictures;
+ QHash<QPair<QString, int>, QColor> colors;
+
+ if (!loadThemeFromBlob(blobFile, partPictures, colors))
+ return false;
+ setS60Theme(partPictures, colors);
+ return true;
+}
+
+bool QS60Style::saveS60ThemeToBlob(const QString &blobFile) const
+{
+ return saveThemeToBlob(blobFile,
+ QS60StyleModeSpecifics::m_partPictures, QS60StyleModeSpecifics::m_colors);
+}
+
+QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
+{
+ Q_UNUSED(targetWidget)
+ return QPoint();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_S60 || QT_PLUGIN
diff --git a/src/widgets/styles/qs60style_stub.cpp b/src/widgets/styles/qs60style_stub.cpp
new file mode 100644
index 0000000000..ce2f7743ad
--- /dev/null
+++ b/src/widgets/styles/qs60style_stub.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qs60style.h"
+#include "qdebug.h"
+
+#if defined(QT_NO_STYLE_S60)
+QT_BEGIN_NAMESPACE
+
+QS60Style::QS60Style()
+{
+ qWarning() << "QS60Style stub created";
+}
+
+QS60Style::~QS60Style()
+{
+}
+
+void QS60Style::drawComplexControl(ComplexControl , const QStyleOptionComplex *, QPainter *, const QWidget *) const
+{
+}
+
+void QS60Style::drawControl(ControlElement , const QStyleOption *, QPainter *, const QWidget *) const
+{
+}
+
+void QS60Style::drawPrimitive(PrimitiveElement , const QStyleOption *, QPainter *, const QWidget *) const
+{
+}
+
+int QS60Style::pixelMetric(PixelMetric , const QStyleOption *, const QWidget *) const
+{
+ return 0;
+}
+
+QSize QS60Style::sizeFromContents(ContentsType , const QStyleOption *, const QSize &, const QWidget *) const
+{
+ return QSize();
+}
+
+int QS60Style::styleHint(StyleHint , const QStyleOption *, const QWidget *, QStyleHintReturn *) const
+{
+ return 0;
+}
+
+QRect QS60Style::subControlRect(ComplexControl , const QStyleOptionComplex *, SubControl , const QWidget *) const
+{
+ return QRect();
+}
+
+QRect QS60Style::subElementRect(SubElement , const QStyleOption *, const QWidget *) const
+{
+ return QRect();
+}
+
+void QS60Style::polish(QWidget *)
+{
+}
+
+void QS60Style::unpolish(QWidget *)
+{
+}
+
+void QS60Style::polish(QApplication *)
+{
+}
+
+void QS60Style::unpolish(QApplication *)
+{
+}
+
+bool QS60Style::event(QEvent *)
+{
+ return false;
+}
+
+QIcon QS60Style::standardIconImplementation(StandardPixmap , const QStyleOption *, const QWidget *) const
+{
+ return QIcon();
+}
+
+void QS60Style::timerEvent(QTimerEvent *)
+{
+}
+
+bool QS60Style::eventFilter(QObject *, QEvent *)
+{
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_S60
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
new file mode 100644
index 0000000000..c6e4b488c1
--- /dev/null
+++ b/src/widgets/styles/qstyle.cpp
@@ -0,0 +1,2459 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstyle.h"
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qwidget.h"
+#include "qbitmap.h"
+#include "qpixmapcache.h"
+#include "qstyleoption.h"
+#include "private/qstyle_p.h"
+#include "private/qguiapplication_p.h"
+#ifndef QT_NO_DEBUG
+#include "qdebug.h"
+#endif
+
+#ifdef Q_WS_X11
+#include <qx11info_x11.h>
+#endif
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int MaxBits = 8 * sizeof(QSizePolicy::ControlType);
+
+static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::ControlType *array)
+{
+ if (!controls)
+ return 0;
+
+ // optimization: exactly one bit is set
+ if ((controls & (controls - 1)) == 0) {
+ array[0] = QSizePolicy::ControlType(uint(controls));
+ return 1;
+ }
+
+ int count = 0;
+ for (int i = 0; i < MaxBits; ++i) {
+ if (uint bit = (controls & (0x1 << i)))
+ array[count++] = QSizePolicy::ControlType(bit);
+ }
+ return count;
+}
+
+/*!
+ \class QStyle
+ \brief The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
+
+ \ingroup appearance
+
+ Qt contains a set of QStyle subclasses that emulate the styles of
+ the different platforms supported by Qt (QWindowsStyle,
+ QMacStyle, QMotifStyle, etc.). By default, these styles are built
+ into the QtGui library. Styles can also be made available as
+ plugins.
+
+ Qt's built-in widgets use QStyle to perform nearly all of their
+ drawing, ensuring that they look exactly like the equivalent
+ native widgets. The diagram below shows a QComboBox in eight
+ different styles.
+
+ \img qstyle-comboboxes.png Eight combo boxes
+
+ Topics:
+
+ \tableofcontents
+
+ \section1 Setting a Style
+
+ The style of the entire application can be set using the
+ QApplication::setStyle() function. It can also be specified by the
+ user of the application, using the \c -style command-line option:
+
+ \snippet doc/src/snippets/code/src_gui_styles_qstyle.cpp 0
+
+ If no style is specified, Qt will choose the most appropriate
+ style for the user's platform or desktop environment.
+
+ A style can also be set on an individual widget using the
+ QWidget::setStyle() function.
+
+ \section1 Developing Style-Aware Custom Widgets
+
+ If you are developing custom widgets and want them to look good on
+ all platforms, you can use QStyle functions to perform parts of
+ the widget drawing, such as drawItemText(), drawItemPixmap(),
+ drawPrimitive(), drawControl(), and drawComplexControl().
+
+ Most QStyle draw functions take four arguments:
+ \list
+ \o an enum value specifying which graphical element to draw
+ \o a QStyleOption specifying how and where to render that element
+ \o a QPainter that should be used to draw the element
+ \o a QWidget on which the drawing is performed (optional)
+ \endlist
+
+ For example, if you want to draw a focus rectangle on your
+ widget, you can write:
+
+ \snippet doc/src/snippets/styles/styles.cpp 1
+
+ QStyle gets all the information it needs to render the graphical
+ element from QStyleOption. The widget is passed as the last
+ argument in case the style needs it to perform special effects
+ (such as animated default buttons on Mac OS X), but it isn't
+ mandatory. In fact, you can use QStyle to draw on any paint
+ device, not just widgets, by setting the QPainter properly.
+
+ QStyleOption has various subclasses for the various types of
+ graphical elements that can be drawn. For example,
+ PE_FrameFocusRect expects a QStyleOptionFocusRect argument.
+
+ To ensure that drawing operations are as fast as possible,
+ QStyleOption and its subclasses have public data members. See the
+ QStyleOption class documentation for details on how to use it.
+
+ For convenience, Qt provides the QStylePainter class, which
+ combines a QStyle, a QPainter, and a QWidget. This makes it
+ possible to write
+
+ \snippet doc/src/snippets/styles/styles.cpp 5
+ \dots
+ \snippet doc/src/snippets/styles/styles.cpp 7
+
+ instead of
+
+ \snippet doc/src/snippets/styles/styles.cpp 2
+ \dots
+ \snippet doc/src/snippets/styles/styles.cpp 3
+
+ \section1 Creating a Custom Style
+
+ You can create a custom look and feel for your application by
+ creating a custom style. There are two approaches to creating a
+ custom style. In the static approach, you either choose an
+ existing QStyle class, subclass it, and reimplement virtual
+ functions to provide the custom behavior, or you create an entire
+ QStyle class from scratch. In the dynamic approach, you modify the
+ behavior of your system style at runtime. The static approach is
+ described below. The dynamic approach is described in QProxyStyle.
+
+ The first step in the static approach is to pick one of the styles
+ provided by Qt from which you will build your custom style. Your
+ choice of QStyle class will depend on which style resembles your
+ desired style the most. The most general class that you can use as
+ a base is QCommonStyle (not QStyle). This is because Qt requires
+ its styles to be \l{QCommonStyle}s.
+
+ Depending on which parts of the base style you want to change,
+ you must reimplement the functions that are used to draw those
+ parts of the interface. To illustrate this, we will modify the
+ look of the spin box arrows drawn by QWindowsStyle. The arrows
+ are \e{primitive elements} that are drawn by the drawPrimitive()
+ function, so we need to reimplement that function. We need the
+ following class declaration:
+
+ \snippet doc/src/snippets/customstyle/customstyle.h 0
+
+ To draw its up and down arrows, QSpinBox uses the
+ PE_IndicatorSpinUp and PE_IndicatorSpinDown primitive elements.
+ Here's how to reimplement the drawPrimitive() function to draw
+ them differently:
+
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 2
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 3
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 4
+
+ Notice that we don't use the \c widget argument, except to pass it
+ on to the QWindowStyle::drawPrimitive() function. As mentioned
+ earlier, the information about what is to be drawn and how it
+ should be drawn is specified by a QStyleOption object, so there is
+ no need to ask the widget.
+
+ If you need to use the \c widget argument to obtain additional
+ information, be careful to ensure that it isn't 0 and that it is
+ of the correct type before using it. For example:
+
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 0
+ \dots
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 1
+
+ When implementing a custom style, you cannot assume that the
+ widget is a QSpinBox just because the enum value is called
+ PE_IndicatorSpinUp or PE_IndicatorSpinDown.
+
+ The documentation for the \l{widgets/styles}{Styles} example
+ covers this topic in more detail.
+
+ \warning Qt style sheets are currently not supported for custom QStyle
+ subclasses. We plan to address this in some future release.
+
+
+ \section1 Using a Custom Style
+
+ There are several ways of using a custom style in a Qt
+ application. The simplest way is to pass the custom style to the
+ QApplication::setStyle() static function before creating the
+ QApplication object:
+
+ \snippet snippets/customstyle/main.cpp using a custom style
+
+ You can call QApplication::setStyle() at any time, but by calling
+ it before the constructor, you ensure that the user's preference,
+ set using the \c -style command-line option, is respected.
+
+ You may want to make your custom style available for use in other
+ applications, which may not be yours and hence not available for
+ you to recompile. The Qt Plugin system makes it possible to create
+ styles as plugins. Styles created as plugins are loaded as shared
+ objects at runtime by Qt itself. Please refer to the \link
+ plugins-howto.html Qt Plugin\endlink documentation for more
+ information on how to go about creating a style plugin.
+
+ Compile your plugin and put it into Qt's \c plugins/styles
+ directory. We now have a pluggable style that Qt can load
+ automatically. To use your new style with existing applications,
+ simply start the application with the following argument:
+
+ \snippet doc/src/snippets/code/src_gui_styles_qstyle.cpp 1
+
+ The application will use the look and feel from the custom style you
+ implemented.
+
+ \section1 Right-to-Left Desktops
+
+ Languages written from right to left (such as Arabic and Hebrew)
+ usually also mirror the whole layout of widgets, and require the
+ light to come from the screen's top-right corner instead of
+ top-left.
+
+ If you create a custom style, you should take special care when
+ drawing asymmetric elements to make sure that they also look
+ correct in a mirrored layout. An easy way to test your styles is
+ to run applications with the \c -reverse command-line option or
+ to call QApplication::setLayoutDirection() in your \c main()
+ function.
+
+ Here are some things to keep in mind when making a style work well in a
+ right-to-left environment:
+
+ \list
+ \o subControlRect() and subElementRect() return rectangles in screen coordinates
+ \o QStyleOption::direction indicates in which direction the item should be drawn in
+ \o If a style is not right-to-left aware it will display items as if it were left-to-right
+ \o visualRect(), visualPos(), and visualAlignment() are helpful functions that will
+ translate from logical to screen representations.
+ \o alignedRect() will return a logical rect aligned for the current direction
+ \endlist
+
+ \section1 Styles in Item Views
+
+ The painting of items in views is performed by a delegate. Qt's
+ default delegate, QStyledItemDelegate, is also used for for calculating bounding
+ rectangles of items, and their sub-elements for the various kind
+ of item \l{Qt::ItemDataRole}{data roles}
+ QStyledItemDelegate supports. See the QStyledItemDelegate class
+ description to find out which datatypes and roles are supported. You
+ can read more about item data roles in \l{Model/View Programming}.
+
+ When QStyledItemDelegate paints its items, it draws
+ CE_ItemViewItem, and calculates their size with CT_ItemViewItem.
+ Note also that it uses SE_ItemViewItemText to set the size of
+ editors. When implementing a style to customize drawing of item
+ views, you need to check the implementation of QCommonStyle (and
+ any other subclasses from which your style
+ inherits). This way, you find out which and how
+ other style elements are painted, and you can then reimplement the
+ painting of elements that should be drawn differently.
+
+ We include a small example where we customize the drawing of item
+ backgrounds.
+
+ \snippet doc/src/snippets/customviewstyle.cpp 0
+
+ The primitive element PE_PanelItemViewItem is responsible for
+ painting the background of items, and is called from
+ \l{QCommonStyle}'s implementation of CE_ItemViewItem.
+
+ To add support for drawing of new datatypes and item data roles,
+ it is necessary to create a custom delegate. But if you only
+ need to support the datatypes implemented by the default
+ delegate, a custom style does not need an accompanying
+ delegate. The QStyledItemDelegate class description gives more
+ information on custom delegates.
+
+ The drawing of item view headers is also done by the style, giving
+ control over size of header items and row and column sizes.
+
+ \sa QStyleOption, QStylePainter, {Styles Example},
+ {Styles and Style Aware Widgets}, QStyledItemDelegate
+*/
+
+/*!
+ Constructs a style object.
+*/
+QStyle::QStyle()
+ : QObject(*new QStylePrivate)
+{
+ Q_D(QStyle);
+ d->proxyStyle = this;
+}
+
+/*!
+ \internal
+
+ Constructs a style object.
+*/
+QStyle::QStyle(QStylePrivate &dd)
+ : QObject(dd)
+{
+ Q_D(QStyle);
+ d->proxyStyle = this;
+}
+
+/*!
+ Destroys the style object.
+*/
+QStyle::~QStyle()
+{
+}
+
+/*!
+ Initializes the appearance of the given \a widget.
+
+ This function is called for every widget at some point after it
+ has been fully created but just \e before it is shown for the very
+ first time.
+
+ Note that the default implementation does nothing. Reasonable
+ actions in this function might be to call the
+ QWidget::setBackgroundMode() function for the widget. Do not use
+ the function to set, for example, the geometry. Reimplementing
+ this function provides a back-door through which the appearance
+ of a widget can be changed, but with Qt's style engine it is
+ rarely necessary to implement this function; reimplement
+ drawItemPixmap(), drawItemText(), drawPrimitive(), etc. instead.
+
+ The QWidget::inherits() function may provide enough information to
+ allow class-specific customizations. But because new QStyle
+ subclasses are expected to work reasonably with all current and \e
+ future widgets, limited use of hard-coded customization is
+ recommended.
+
+ \sa unpolish()
+*/
+void QStyle::polish(QWidget * /* widget */)
+{
+}
+
+/*!
+ Uninitialize the given \a{widget}'s appearance.
+
+ This function is the counterpart to polish(). It is called for
+ every polished widget whenever the style is dynamically changed;
+ the former style has to unpolish its settings before the new style
+ can polish them again.
+
+ Note that unpolish() will only be called if the widget is
+ destroyed. This can cause problems in some cases, e.g, if you
+ remove a widget from the UI, cache it, and then reinsert it after
+ the style has changed; some of Qt's classes cache their widgets.
+
+ \sa polish()
+*/
+void QStyle::unpolish(QWidget * /* widget */)
+{
+}
+
+/*!
+ \fn void QStyle::polish(QApplication * application)
+ \overload
+
+ Late initialization of the given \a application object.
+*/
+void QStyle::polish(QApplication * /* app */)
+{
+}
+
+/*!
+ \fn void QStyle::unpolish(QApplication * application)
+ \overload
+
+ Uninitialize the given \a application.
+*/
+void QStyle::unpolish(QApplication * /* app */)
+{
+}
+
+/*!
+ \fn void QStyle::polish(QPalette & palette)
+ \overload
+
+ Changes the \a palette according to style specific requirements
+ for color palettes (if any).
+
+ \sa QPalette, QApplication::setPalette()
+*/
+void QStyle::polish(QPalette & /* pal */)
+{
+}
+
+/*!
+ \fn QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const
+
+ Returns the area within the given \a rectangle in which to draw
+ the provided \a text according to the specified font \a metrics
+ and \a alignment. The \a enabled parameter indicates whether or
+ not the associated item is enabled.
+
+ If the given \a rectangle is larger than the area needed to render
+ the \a text, the rectangle that is returned will be offset within
+ \a rectangle according to the specified \a alignment. For
+ example, if \a alignment is Qt::AlignCenter, the returned
+ rectangle will be centered within \a rectangle. If the given \a
+ rectangle is smaller than the area needed, the returned rectangle
+ will be the smallest rectangle large enough to render the \a text.
+
+ \sa Qt::Alignment
+*/
+QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled,
+ const QString &text) const
+{
+ QRect result;
+ int x, y, w, h;
+ rect.getRect(&x, &y, &w, &h);
+ if (!text.isEmpty()) {
+ result = metrics.boundingRect(x, y, w, h, alignment, text);
+ if (!enabled && proxy()->styleHint(SH_EtchDisabledText)) {
+ result.setWidth(result.width()+1);
+ result.setHeight(result.height()+1);
+ }
+ } else {
+ result = QRect(x, y, w, h);
+ }
+ return result;
+}
+
+/*!
+ \fn QRect QStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const
+
+ Returns the area within the given \a rectangle in which to draw
+ the specified \a pixmap according to the defined \a alignment.
+*/
+QRect QStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const
+{
+ QRect result;
+ int x, y, w, h;
+ rect.getRect(&x, &y, &w, &h);
+ if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
+ y += h/2 - pixmap.height()/2;
+ else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
+ y += h - pixmap.height();
+ if ((alignment & Qt::AlignRight) == Qt::AlignRight)
+ x += w - pixmap.width();
+ else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
+ x += w/2 - pixmap.width()/2;
+ else if ((alignment & Qt::AlignLeft) != Qt::AlignLeft && QApplication::isRightToLeft())
+ x += w - pixmap.width();
+ result = QRect(x, y, pixmap.width(), pixmap.height());
+ return result;
+}
+
+/*!
+ \fn void QStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString& text, QPalette::ColorRole textRole) const
+
+ Draws the given \a text in the specified \a rectangle using the
+ provided \a painter and \a palette.
+
+ The text is drawn using the painter's pen, and aligned and wrapped
+ according to the specified \a alignment. If an explicit \a
+ textRole is specified, the text is drawn using the \a palette's
+ color for the given role. The \a enabled parameter indicates
+ whether or not the item is enabled; when reimplementing this
+ function, the \a enabled parameter should influence how the item is
+ drawn.
+
+ \sa Qt::Alignment, drawItemPixmap()
+*/
+void QStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ if (text.isEmpty())
+ return;
+ QPen savedPen;
+ if (textRole != QPalette::NoRole) {
+ savedPen = painter->pen();
+ painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
+ }
+ if (!enabled) {
+ if (proxy()->styleHint(SH_DitherDisabledText)) {
+ QRect br;
+ painter->drawText(rect, alignment, text, &br);
+ painter->fillRect(br, QBrush(painter->background().color(), Qt::Dense5Pattern));
+ return;
+ } else if (proxy()->styleHint(SH_EtchDisabledText)) {
+ QPen pen = painter->pen();
+ painter->setPen(pal.light().color());
+ painter->drawText(rect.adjusted(1, 1, 1, 1), alignment, text);
+ painter->setPen(pen);
+ }
+ }
+ painter->drawText(rect, alignment, text);
+ if (textRole != QPalette::NoRole)
+ painter->setPen(savedPen);
+}
+
+/*!
+ \fn void QStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment,
+ const QPixmap &pixmap) const
+
+ Draws the given \a pixmap in the specified \a rectangle, according
+ to the specified \a alignment, using the provided \a painter.
+
+ \sa drawItemText()
+*/
+
+void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
+ const QPixmap &pixmap) const
+{
+ QRect aligned = alignedRect(QApplication::layoutDirection(), QFlag(alignment), pixmap.size(), rect);
+ QRect inter = aligned.intersected(rect);
+
+ painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
+}
+
+/*!
+ \enum QStyle::PrimitiveElement
+
+ This enum describes the various primitive elements. A
+ primitive element is a common GUI element, such as a checkbox
+ indicator or button bevel.
+
+ \omitvalue PE_IndicatorViewItemCheck
+ \value PE_FrameStatusBar Frame
+
+ \value PE_PanelButtonCommand Button used to initiate an action, for
+ example, a QPushButton.
+
+ \value PE_FrameDefaultButton This frame around a default button, e.g. in a dialog.
+ \value PE_PanelButtonBevel Generic panel with a button bevel.
+ \value PE_PanelButtonTool Panel for a Tool button, used with QToolButton.
+ \value PE_PanelLineEdit Panel for a QLineEdit.
+ \value PE_IndicatorButtonDropDown Indicator for a drop down button, for example, a tool
+ button that displays a menu.
+
+ \value PE_FrameFocusRect Generic focus indicator.
+
+ \value PE_IndicatorArrowUp Generic Up arrow.
+ \value PE_IndicatorArrowDown Generic Down arrow.
+ \value PE_IndicatorArrowRight Generic Right arrow.
+ \value PE_IndicatorArrowLeft Generic Left arrow.
+
+ \value PE_IndicatorSpinUp Up symbol for a spin widget, for example a QSpinBox.
+ \value PE_IndicatorSpinDown Down symbol for a spin widget.
+ \value PE_IndicatorSpinPlus Increase symbol for a spin widget.
+ \value PE_IndicatorSpinMinus Decrease symbol for a spin widget.
+
+ \value PE_IndicatorItemViewItemCheck On/off indicator for a view item.
+
+ \value PE_IndicatorCheckBox On/off indicator, for example, a QCheckBox.
+ \value PE_IndicatorRadioButton Exclusive on/off indicator, for example, a QRadioButton.
+
+ \value PE_Q3DockWindowSeparator Item separator for Qt 3 compatible dock window
+ and toolbar contents.
+ \value PE_IndicatorDockWidgetResizeHandle Resize handle for dock windows.
+
+ \value PE_Frame Generic frame
+ \value PE_FrameMenu Frame for popup windows/menus; see also QMenu.
+ \value PE_PanelMenuBar Panel for menu bars.
+ \value PE_PanelScrollAreaCorner Panel at the bottom-right (or
+ bottom-left) corner of a scroll area.
+
+ \value PE_FrameDockWidget Panel frame for dock windows and toolbars.
+ \value PE_FrameTabWidget Frame for tab widgets.
+ \value PE_FrameLineEdit Panel frame for line edits.
+ \value PE_FrameGroupBox Panel frame around group boxes.
+ \value PE_FrameButtonBevel Panel frame for a button bevel.
+ \value PE_FrameButtonTool Panel frame for a tool button.
+
+ \value PE_IndicatorHeaderArrow Arrow used to indicate sorting on a list or table
+ header.
+ \value PE_FrameStatusBarItem Frame for an item of a status bar; see also QStatusBar.
+
+ \value PE_FrameWindow Frame around a MDI window or a docking window.
+
+ \value PE_Q3Separator Qt 3 compatible generic separator.
+
+ \value PE_IndicatorMenuCheckMark Check mark used in a menu.
+
+ \value PE_IndicatorProgressChunk Section of a progress bar indicator; see also QProgressBar.
+
+ \value PE_Q3CheckListController Qt 3 compatible controller part of a list view item.
+ \value PE_Q3CheckListIndicator Qt 3 compatible checkbox part of a list view item.
+ \value PE_Q3CheckListExclusiveIndicator Qt 3 compatible radio button part of a list view item.
+
+ \value PE_IndicatorBranch Lines used to represent the branch of a tree in a tree view.
+ \value PE_IndicatorToolBarHandle The handle of a toolbar.
+ \value PE_IndicatorToolBarSeparator The separator in a toolbar.
+ \value PE_PanelToolBar The panel for a toolbar.
+ \value PE_PanelTipLabel The panel for a tip label.
+ \value PE_FrameTabBarBase The frame that is drawn for a tab bar, ususally drawn for a tab bar that isn't part of a tab widget.
+ \value PE_IndicatorTabTear An indicator that a tab is partially scrolled out of the visible tab bar when there are many tabs.
+ \value PE_IndicatorColumnViewArrow An arrow in a QColumnView.
+
+ \value PE_Widget A plain QWidget.
+
+ \value PE_CustomBase Base value for custom primitive elements.
+ All values above this are reserved for custom use. Custom values
+ must be greater than this value.
+
+ \value PE_IndicatorItemViewItemDrop An indicator that is drawn to show where an item in an item view is about to be dropped
+ during a drag-and-drop operation in an item view.
+ \value PE_PanelItemViewItem The background for an item in an item view.
+ \value PE_PanelItemViewRow The background of a row in an item view.
+
+ \value PE_PanelStatusBar The panel for a status bar.
+
+ \value PE_IndicatorTabClose The close button on a tab bar.
+ \value PE_PanelMenu The panel for a menu.
+
+ \sa drawPrimitive()
+*/
+
+/*!
+ \typedef QStyle::SFlags
+ \internal
+*/
+
+/*!
+ \typedef QStyle::SCFlags
+ \internal
+*/
+
+/*!
+ \enum QStyle::StateFlag
+
+ This enum describes flags that are used when drawing primitive
+ elements.
+
+ Note that not all primitives use all of these flags, and that the
+ flags may mean different things to different items.
+
+ \value State_None Indicates that the widget does not have a state.
+ \value State_Active Indicates that the widget is active.
+ \value State_AutoRaise Used to indicate if auto-raise appearance should be usd on a tool button.
+ \value State_Children Used to indicate if an item view branch has children.
+ \value State_DownArrow Used to indicate if a down arrow should be visible on the widget.
+ \value State_Editing Used to indicate if an editor is opened on the widget.
+ \value State_Enabled Used to indicate if the widget is enabled.
+ \value State_HasEditFocus Used to indicate if the widget currently has edit focus.
+ \value State_HasFocus Used to indicate if the widget has focus.
+ \value State_Horizontal Used to indicate if the widget is laid out horizontally, for example. a tool bar.
+ \value State_KeyboardFocusChange Used to indicate if the focus was changed with the keyboard, e.g., tab, backtab or shortcut.
+ \value State_MouseOver Used to indicate if the widget is under the mouse.
+ \value State_NoChange Used to indicate a tri-state checkbox.
+ \value State_Off Used to indicate if the widget is not checked.
+ \value State_On Used to indicate if the widget is checked.
+ \value State_Raised Used to indicate if a button is raised.
+ \value State_ReadOnly Used to indicate if a widget is read-only.
+ \value State_Selected Used to indicate if a widget is selected.
+ \value State_Item Used by item views to indicate if a horizontal branch should be drawn.
+ \value State_Open Used by item views to indicate if the tree branch is open.
+ \value State_Sibling Used by item views to indicate if a vertical line needs to be drawn (for siblings).
+ \value State_Sunken Used to indicate if the widget is sunken or pressed.
+ \value State_UpArrow Used to indicate if an up arrow should be visible on the widget.
+ \value State_Mini Used to indicate a mini style Mac widget or button.
+ \value State_Small Used to indicate a small style Mac widget or button.
+ \omitvalue State_Window
+ \omitvalue State_Bottom
+ \omitvalue State_Default
+ \omitvalue State_FocusAtBorder
+ \omitvalue State_Top
+
+ \sa drawPrimitive()
+*/
+
+/*!
+ \fn void QStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, \
+ QPainter *painter, const QWidget *widget) const
+
+ Draws the given primitive \a element with the provided \a painter using the style
+ options specified by \a option.
+
+ The \a widget argument is optional and may contain a widget that may
+ aid in drawing the primitive element.
+
+ The table below is listing the primitive elements and their
+ associated style option subclasses. The style options contain all
+ the parameters required to draw the elements, including
+ QStyleOption::state which holds the style flags that are used when
+ drawing. The table also describes which flags that are set when
+ casting the given option to the appropriate subclass.
+
+ Note that if a primitive element is not listed here, it is because
+ it uses a plain QStyleOption object.
+
+ \table
+ \header \o Primitive Element \o QStyleOption Subclass \o Style Flag \o Remark
+ \row \o \l PE_FrameFocusRect \o \l QStyleOptionFocusRect
+ \o \l State_FocusAtBorder
+ \o Whether the focus is is at the border or inside the widget.
+ \row \o{1,2} \l PE_IndicatorCheckBox \o{1,2} \l QStyleOptionButton
+ \o \l State_NoChange \o Indicates a "tri-state" checkbox.
+ \row \o \l State_On \o Indicates the indicator is checked.
+ \row \o \l PE_IndicatorRadioButton \o \l QStyleOptionButton
+ \o \l State_On \o Indicates that a radio button is selected.
+ \row \o{1,3} \l PE_Q3CheckListExclusiveIndicator, \l PE_Q3CheckListIndicator
+ \o{1,3} \l QStyleOptionQ3ListView \o \l State_On
+ \o Indicates whether or not the controller is selected.
+ \row \o \l State_NoChange \o Indicates a "tri-state" controller.
+ \row \o \l State_Enabled \o Indicates the controller is enabled.
+ \row \o{1,4} \l PE_IndicatorBranch \o{1,4} \l QStyleOption
+ \o \l State_Children \o Indicates that the control for expanding the tree to show child items, should be drawn.
+ \row \o \l State_Item \o Indicates that a horizontal branch (to show a child item), should be drawn.
+ \row \o \l State_Open \o Indicates that the tree branch is expanded.
+ \row \o \l State_Sibling \o Indicates that a vertical line (to show a sibling item), should be drawn.
+ \row \o \l PE_IndicatorHeaderArrow \o \l QStyleOptionHeader
+ \o \l State_UpArrow \o Indicates that the arrow should be drawn up;
+ otherwise it should be down.
+ \row \o \l PE_FrameGroupBox, \l PE_Frame, \l PE_FrameLineEdit,
+ \l PE_FrameMenu, \l PE_FrameDockWidget, \l PE_FrameWindow
+ \o \l QStyleOptionFrame \o \l State_Sunken
+ \o Indicates that the Frame should be sunken.
+ \row \o \l PE_IndicatorToolBarHandle \o \l QStyleOption
+ \o \l State_Horizontal \o Indicates that the window handle is horizontal
+ instead of vertical.
+ \row \o \l PE_Q3DockWindowSeparator \o \l QStyleOption
+ \o \l State_Horizontal \o Indicates that the separator is horizontal
+ instead of vertical.
+ \row \o \l PE_IndicatorSpinPlus, \l PE_IndicatorSpinMinus, \l PE_IndicatorSpinUp,
+ \l PE_IndicatorSpinDown,
+ \o \l QStyleOptionSpinBox
+ \o \l State_Sunken \o Indicates that the button is pressed.
+ \row \o{1,5} \l PE_PanelButtonCommand
+ \o{1,5} \l QStyleOptionButton
+ \o \l State_Enabled \o Set if the button is enabled.
+ \row \o \l State_HasFocus \o Set if the button has input focus.
+ \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
+ \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
+ \row \o \l State_Sunken
+ \o Set if the button is down (i.e., the mouse button or the
+ space bar is pressed on the button).
+ \endtable
+
+ \sa drawComplexControl(), drawControl()
+*/
+
+/*!
+ \enum QStyle::ControlElement
+
+ This enum represents a control element. A control element is a
+ part of a widget that performs some action or displays information
+ to the user.
+
+ \value CE_PushButton A QPushButton, draws CE_PushButtonBevel, CE_PushButtonLabel and PE_FrameFocusRect.
+ \value CE_PushButtonBevel The bevel and default indicator of a QPushButton.
+ \value CE_PushButtonLabel The label (an icon with text or pixmap) of a QPushButton.
+
+ \value CE_DockWidgetTitle Dock window title.
+ \value CE_Splitter Splitter handle; see also QSplitter.
+
+
+ \value CE_CheckBox A QCheckBox, draws a PE_IndicatorCheckBox, a CE_CheckBoxLabel and a PE_FrameFocusRect.
+ \value CE_CheckBoxLabel The label (text or pixmap) of a QCheckBox.
+
+ \value CE_RadioButton A QRadioButton, draws a PE_IndicatorRadioButton, a CE_RadioButtonLabel and a PE_FrameFocusRect.
+ \value CE_RadioButtonLabel The label (text or pixmap) of a QRadioButton.
+
+ \value CE_TabBarTab The tab and label within a QTabBar.
+ \value CE_TabBarTabShape The tab shape within a tab bar.
+ \value CE_TabBarTabLabel The label within a tab.
+
+ \value CE_ProgressBar A QProgressBar, draws CE_ProgressBarGroove, CE_ProgressBarContents and CE_ProgressBarLabel.
+ \value CE_ProgressBarGroove The groove where the progress
+ indicator is drawn in a QProgressBar.
+ \value CE_ProgressBarContents The progress indicator of a QProgressBar.
+ \value CE_ProgressBarLabel The text label of a QProgressBar.
+
+ \value CE_ToolButtonLabel A tool button's label.
+
+ \value CE_MenuBarItem A menu item in a QMenuBar.
+ \value CE_MenuBarEmptyArea The empty area of a QMenuBar.
+
+ \value CE_MenuItem A menu item in a QMenu.
+ \value CE_MenuScroller Scrolling areas in a QMenu when the
+ style supports scrolling.
+ \value CE_MenuTearoff A menu item representing the tear off section of
+ a QMenu.
+ \value CE_MenuEmptyArea The area in a menu without menu items.
+ \value CE_MenuHMargin The horizontal extra space on the left/right of a menu.
+ \value CE_MenuVMargin The vertical extra space on the top/bottom of a menu.
+
+ \value CE_Q3DockWindowEmptyArea The empty area of a QDockWidget.
+
+ \value CE_ToolBoxTab The toolbox's tab and label within a QToolBox.
+ \value CE_SizeGrip Window resize handle; see also QSizeGrip.
+
+ \value CE_Header A header.
+ \value CE_HeaderSection A header section.
+ \value CE_HeaderLabel The header's label.
+
+ \value CE_ScrollBarAddLine Scroll bar line increase indicator.
+ (i.e., scroll down); see also QScrollBar.
+ \value CE_ScrollBarSubLine Scroll bar line decrease indicator (i.e., scroll up).
+ \value CE_ScrollBarAddPage Scolllbar page increase indicator (i.e., page down).
+ \value CE_ScrollBarSubPage Scroll bar page decrease indicator (i.e., page up).
+ \value CE_ScrollBarSlider Scroll bar slider.
+ \value CE_ScrollBarFirst Scroll bar first line indicator (i.e., home).
+ \value CE_ScrollBarLast Scroll bar last line indicator (i.e., end).
+
+ \value CE_RubberBand Rubber band used in for example an icon view.
+
+ \value CE_FocusFrame Focus frame that is style controlled.
+
+ \value CE_ItemViewItem An item inside an item view.
+
+ \value CE_CustomBase Base value for custom control elements;
+ custom values must be greater than this value.
+ \value CE_ComboBoxLabel The label of a non-editable QComboBox.
+ \value CE_ToolBar A toolbar like QToolBar.
+ \value CE_ToolBoxTabShape The toolbox's tab shape.
+ \value CE_ToolBoxTabLabel The toolbox's tab label.
+ \value CE_HeaderEmptyArea The area of a header view where there are no header sections.
+
+ \value CE_ShapedFrame The frame with the shape specified in the QStyleOptionFrameV3; see QFrame.
+
+ \omitvalue CE_ColumnViewGrip
+
+ \sa drawControl()
+*/
+
+/*!
+ \fn void QStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+
+ Draws the given \a element with the provided \a painter with the
+ style options specified by \a option.
+
+ The \a widget argument is optional and can be used as aid in
+ drawing the control. The \a option parameter is a pointer to a
+ QStyleOption object that can be cast to the correct subclass
+ using the qstyleoption_cast() function.
+
+ The table below is listing the control elements and their
+ associated style option subclass. The style options contain all
+ the parameters required to draw the controls, including
+ QStyleOption::state which holds the style flags that are used when
+ drawing. The table also describes which flags that are set when
+ casting the given option to the appropriate subclass.
+
+ Note that if a control element is not listed here, it is because
+ it uses a plain QStyleOption object.
+
+ \table
+ \header \o Control Element \o QStyleOption Subclass \o Style Flag \o Remark
+ \row \o{1,5} \l CE_MenuItem, \l CE_MenuBarItem
+ \o{1,5} \l QStyleOptionMenuItem
+ \o \l State_Selected \o The menu item is currently selected item.
+ \row \o \l State_Enabled \o The item is enabled.
+ \row \o \l State_DownArrow \o Indicates that a scroll down arrow should be drawn.
+ \row \o \l State_UpArrow \o Indicates that a scroll up arrow should be drawn
+ \row \o \l State_HasFocus \o Set if the menu bar has input focus.
+
+ \row \o{1,5} \l CE_PushButton, \l CE_PushButtonBevel, \l CE_PushButtonLabel
+ \o{1,5} \l QStyleOptionButton
+ \o \l State_Enabled \o Set if the button is enabled.
+ \row \o \l State_HasFocus \o Set if the button has input focus.
+ \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
+ \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
+ \row \o \l State_Sunken
+ \o Set if the button is down (i.e., the mouse button or the
+ space bar is pressed on the button).
+
+ \row \o{1,6} \l CE_RadioButton, \l CE_RadioButtonLabel,
+ \l CE_CheckBox, \l CE_CheckBoxLabel
+ \o{1,6} \l QStyleOptionButton
+ \o \l State_Enabled \o Set if the button is enabled.
+ \row \o \l State_HasFocus \o Set if the button has input focus.
+ \row \o \l State_On \o Set if the button is checked.
+ \row \o \l State_Off \o Set if the button is not checked.
+ \row \o \l State_NoChange \o Set if the button is in the NoChange state.
+ \row \o \l State_Sunken
+ \o Set if the button is down (i.e., the mouse button or
+ the space bar is pressed on the button).
+
+ \row \o{1,2} \l CE_ProgressBarContents, \l CE_ProgressBarLabel,
+ \l CE_ProgressBarGroove
+ \o{1,2} \l QStyleOptionProgressBar
+ \o \l State_Enabled \o Set if the progress bar is enabled.
+ \row \o \l State_HasFocus \o Set if the progress bar has input focus.
+
+ \row \o \l CE_Header, \l CE_HeaderSection, \l CE_HeaderLabel \o \l QStyleOptionHeader \o \o
+
+ \row \o{1,3} \l CE_TabBarTab, CE_TabBarTabShape, CE_TabBarTabLabel
+ \o{1,3} \l QStyleOptionTab
+ \o \l State_Enabled \o Set if the tab bar is enabled.
+ \row \o \l State_Selected \o The tab bar is the currently selected tab bar.
+ \row \o \l State_HasFocus \o Set if the tab bar tab has input focus.
+
+ \row \o{1,7} \l CE_ToolButtonLabel
+ \o{1,7} \l QStyleOptionToolButton
+ \o \l State_Enabled \o Set if the tool button is enabled.
+ \row \o \l State_HasFocus \o Set if the tool button has input focus.
+ \row \o \l State_Sunken
+ \o Set if the tool button is down (i.e., a mouse button or
+ the space bar is pressed).
+ \row \o \l State_On \o Set if the tool button is a toggle button and is toggled on.
+ \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
+ \row \o \l State_MouseOver \o Set if the mouse pointer is over the tool button.
+ \row \o \l State_Raised \o Set if the button is not down and is not on.
+
+ \row \o \l CE_ToolBoxTab \o \l QStyleOptionToolBox
+ \o \l State_Selected \o The tab is the currently selected tab.
+ \row \o{1,3} \l CE_HeaderSection \o{1,3} \l QStyleOptionHeader
+ \o \l State_Sunken \o Indicates that the section is pressed.
+ \row \o \l State_UpArrow \o Indicates that the sort indicator should be pointing up.
+ \row \o \l State_DownArrow \o Indicates that the sort indicator should be pointing down.
+ \endtable
+
+ \sa drawPrimitive(), drawComplexControl()
+*/
+
+/*!
+ \enum QStyle::SubElement
+
+ This enum represents a sub-area of a widget. Style implementations
+ use these areas to draw the different parts of a widget.
+
+ \value SE_PushButtonContents Area containing the label (icon
+ with text or pixmap).
+ \value SE_PushButtonFocusRect Area for the focus rect (usually
+ larger than the contents rect).
+ \value SE_PushButtonLayoutItem Area that counts for the parent layout.
+
+ \value SE_CheckBoxIndicator Area for the state indicator (e.g., check mark).
+ \value SE_CheckBoxContents Area for the label (text or pixmap).
+ \value SE_CheckBoxFocusRect Area for the focus indicator.
+ \value SE_CheckBoxClickRect Clickable area, defaults to SE_CheckBoxFocusRect.
+ \value SE_CheckBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_DateTimeEditLayoutItem Area that counts for the parent layout.
+
+ \value SE_RadioButtonIndicator Area for the state indicator.
+ \value SE_RadioButtonContents Area for the label.
+ \value SE_RadioButtonFocusRect Area for the focus indicator.
+ \value SE_RadioButtonClickRect Clickable area, defaults to SE_RadioButtonFocusRect.
+ \value SE_RadioButtonLayoutItem Area that counts for the parent layout.
+
+ \value SE_ComboBoxFocusRect Area for the focus indicator.
+
+ \value SE_SliderFocusRect Area for the focus indicator.
+ \value SE_SliderLayoutItem Area that counts for the parent layout.
+
+ \value SE_SpinBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_Q3DockWindowHandleRect Area for the tear-off handle.
+
+ \value SE_ProgressBarGroove Area for the groove.
+ \value SE_ProgressBarContents Area for the progress indicator.
+ \value SE_ProgressBarLabel Area for the text label.
+ \value SE_ProgressBarLayoutItem Area that counts for the parent layout.
+
+ \omitvalue SE_DialogButtonAccept
+ \omitvalue SE_DialogButtonReject
+ \omitvalue SE_DialogButtonApply
+ \omitvalue SE_DialogButtonHelp
+ \omitvalue SE_DialogButtonAll
+ \omitvalue SE_DialogButtonRetry
+ \omitvalue SE_DialogButtonAbort
+ \omitvalue SE_DialogButtonIgnore
+ \omitvalue SE_DialogButtonCustom
+ \omitvalue SE_ViewItemCheckIndicator
+
+ \value SE_FrameContents Area for a frame's contents.
+ \value SE_ShapedFrameContents Area for a frame's contents using the shape in QStyleOptionFrameV3; see QFrame
+ \value SE_FrameLayoutItem Area that counts for the parent layout.
+
+ \value SE_HeaderArrow Area for the sort indicator for a header.
+ \value SE_HeaderLabel Area for the label in a header.
+
+ \value SE_LabelLayoutItem Area that counts for the parent layout.
+
+ \value SE_LineEditContents Area for a line edit's contents.
+
+ \value SE_TabWidgetLeftCorner Area for the left corner widget in a tab widget.
+ \value SE_TabWidgetRightCorner Area for the right corner widget in a tab widget.
+ \value SE_TabWidgetTabBar Area for the tab bar widget in a tab widget.
+ \value SE_TabWidgetTabContents Area for the contents of the tab widget.
+ \value SE_TabWidgetTabPane Area for the pane of a tab widget.
+ \value SE_TabWidgetLayoutItem Area that counts for the parent layout.
+
+ \value SE_ToolBoxTabContents Area for a toolbox tab's icon and label.
+
+ \value SE_ToolButtonLayoutItem Area that counts for the parent layout.
+
+ \value SE_ItemViewItemCheckIndicator Area for a view item's check mark.
+
+ \value SE_TabBarTearIndicator Area for the tear indicator on a tab bar with scroll arrows.
+
+ \value SE_TreeViewDisclosureItem Area for the actual disclosure item in a tree branch.
+
+ \value SE_DialogButtonBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_GroupBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_CustomBase Base value for custom sub-elements.
+ Custom values must be greater than this value.
+
+ \value SE_DockWidgetFloatButton The float button of a dock
+ widget.
+ \value SE_DockWidgetTitleBarText The text bounds of the dock
+ widgets title.
+ \value SE_DockWidgetCloseButton The close button of a dock
+ widget.
+ \value SE_DockWidgetIcon The icon of a dock widget.
+ \value SE_ComboBoxLayoutItem Area that counts for the parent layout.
+
+
+ \value SE_ItemViewItemDecoration Area for a view item's decoration (icon).
+ \value SE_ItemViewItemText Area for a view item's text.
+ \value SE_ItemViewItemFocusRect Area for a view item's focus rect.
+
+ \value SE_TabBarTabLeftButton Area for a widget on the left side of a tab in a tab bar.
+ \value SE_TabBarTabRightButton Area for a widget on the right side of a tab in a tab bar.
+ \value SE_TabBarTabText Area for the text on a tab in a tab bar.
+
+ \value SE_ToolBarHandle Area for the handle of a tool bar.
+
+ \sa subElementRect()
+*/
+
+/*!
+ \fn QRect QStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+
+ Returns the sub-area for the given \a element as described in the
+ provided style \a option. The returned rectangle is defined in
+ screen coordinates.
+
+ The \a widget argument is optional and can be used to aid
+ determining the area. The QStyleOption object can be cast to the
+ appropriate type using the qstyleoption_cast() function. See the
+ table below for the appropriate \a option casts:
+
+ \table
+ \header \o Sub Element \o QStyleOption Subclass
+ \row \o \l SE_PushButtonContents \o \l QStyleOptionButton
+ \row \o \l SE_PushButtonFocusRect \o \l QStyleOptionButton
+ \row \o \l SE_CheckBoxIndicator \o \l QStyleOptionButton
+ \row \o \l SE_CheckBoxContents \o \l QStyleOptionButton
+ \row \o \l SE_CheckBoxFocusRect \o \l QStyleOptionButton
+ \row \o \l SE_RadioButtonIndicator \o \l QStyleOptionButton
+ \row \o \l SE_RadioButtonContents \o \l QStyleOptionButton
+ \row \o \l SE_RadioButtonFocusRect \o \l QStyleOptionButton
+ \row \o \l SE_ComboBoxFocusRect \o \l QStyleOptionComboBox
+ \row \o \l SE_Q3DockWindowHandleRect \o \l QStyleOptionQ3DockWindow
+ \row \o \l SE_ProgressBarGroove \o \l QStyleOptionProgressBar
+ \row \o \l SE_ProgressBarContents \o \l QStyleOptionProgressBar
+ \row \o \l SE_ProgressBarLabel \o \l QStyleOptionProgressBar
+ \endtable
+*/
+
+/*!
+ \enum QStyle::ComplexControl
+
+ This enum describes the available complex controls. Complex
+ controls have different behavior depending upon where the user
+ clicks on them or which keys are pressed.
+
+ \value CC_SpinBox A spinbox, like QSpinBox.
+ \value CC_ComboBox A combobox, like QComboBox.
+ \value CC_ScrollBar A scroll bar, like QScrollBar.
+ \value CC_Slider A slider, like QSlider.
+ \value CC_ToolButton A tool button, like QToolButton.
+ \value CC_TitleBar A Title bar, like those used in QMdiSubWindow.
+ \value CC_Q3ListView Used for drawing the Q3ListView class.
+ \value CC_GroupBox A group box, like QGroupBox.
+ \value CC_Dial A dial, like QDial.
+ \value CC_MdiControls The minimize, close, and normal
+ button in the menu bar for a
+ maximized MDI subwindow.
+
+ \value CC_CustomBase Base value for custom complex controls. Custom
+ values must be greater than this value.
+
+ \sa SubControl drawComplexControl()
+*/
+
+/*!
+ \enum QStyle::SubControl
+
+ This enum describes the available sub controls. A subcontrol is a
+ control element within a complex control (ComplexControl).
+
+ \value SC_None Special value that matches no other sub control.
+
+ \value SC_ScrollBarAddLine Scroll bar add line (i.e., down/right
+ arrow); see also QScrollBar.
+ \value SC_ScrollBarSubLine Scroll bar sub line (i.e., up/left arrow).
+ \value SC_ScrollBarAddPage Scroll bar add page (i.e., page down).
+ \value SC_ScrollBarSubPage Scroll bar sub page (i.e., page up).
+ \value SC_ScrollBarFirst Scroll bar first line (i.e., home).
+ \value SC_ScrollBarLast Scroll bar last line (i.e., end).
+ \value SC_ScrollBarSlider Scroll bar slider handle.
+ \value SC_ScrollBarGroove Special sub-control which contains the
+ area in which the slider handle may move.
+
+ \value SC_SpinBoxUp Spin widget up/increase; see also QSpinBox.
+ \value SC_SpinBoxDown Spin widget down/decrease.
+ \value SC_SpinBoxFrame Spin widget frame.
+ \value SC_SpinBoxEditField Spin widget edit field.
+
+ \value SC_ComboBoxEditField Combobox edit field; see also QComboBox.
+ \value SC_ComboBoxArrow Combobox arrow button.
+ \value SC_ComboBoxFrame Combobox frame.
+ \value SC_ComboBoxListBoxPopup The reference rectangle for the combobox popup.
+ Used to calculate the position of the popup.
+
+ \value SC_SliderGroove Special sub-control which contains the area
+ in which the slider handle may move.
+ \value SC_SliderHandle Slider handle.
+ \value SC_SliderTickmarks Slider tickmarks.
+
+ \value SC_ToolButton Tool button (see also QToolButton).
+ \value SC_ToolButtonMenu Sub-control for opening a popup menu in a
+ tool button; see also Q3PopupMenu.
+
+ \value SC_TitleBarSysMenu System menu button (i.e., restore, close, etc.).
+ \value SC_TitleBarMinButton Minimize button.
+ \value SC_TitleBarMaxButton Maximize button.
+ \value SC_TitleBarCloseButton Close button.
+ \value SC_TitleBarLabel Window title label.
+ \value SC_TitleBarNormalButton Normal (restore) button.
+ \value SC_TitleBarShadeButton Shade button.
+ \value SC_TitleBarUnshadeButton Unshade button.
+ \value SC_TitleBarContextHelpButton Context Help button.
+
+ \value SC_Q3ListView The list view area.
+ \value SC_Q3ListViewExpand Expand item (i.e., show/hide child items).
+
+ \value SC_DialHandle The handle of the dial (i.e. what you use to control the dial).
+ \value SC_DialGroove The groove for the dial.
+ \value SC_DialTickmarks The tickmarks for the dial.
+
+ \value SC_GroupBoxFrame The frame of a group box.
+ \value SC_GroupBoxLabel The title of a group box.
+ \value SC_GroupBoxCheckBox The optional check box of a group box.
+ \value SC_GroupBoxContents The group box contents.
+
+ \value SC_MdiNormalButton The normal button for a MDI
+ subwindow in the menu bar.
+ \value SC_MdiMinButton The minimize button for a MDI
+ subwindow in the menu bar.
+ \value SC_MdiCloseButton The close button for a MDI subwindow
+ in the menu bar.
+
+ \value SC_All Special value that matches all sub-controls.
+ \omitvalue SC_Q3ListViewBranch
+ \omitvalue SC_CustomBase
+
+ \sa ComplexControl
+*/
+
+/*!
+ \fn void QStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
+
+ Draws the given \a control using the provided \a painter with the
+ style options specified by \a option.
+
+ The \a widget argument is optional and can be used as aid in
+ drawing the control.
+
+ The \a option parameter is a pointer to a QStyleOptionComplex
+ object that can be cast to the correct subclass using the
+ qstyleoption_cast() function. Note that the \c rect member of the
+ specified \a option must be in logical
+ coordinates. Reimplementations of this function should use
+ visualRect() to change the logical coordinates into screen
+ coordinates before calling the drawPrimitive() or drawControl()
+ function.
+
+ The table below is listing the complex control elements and their
+ associated style option subclass. The style options contain all
+ the parameters required to draw the controls, including
+ QStyleOption::state which holds the \l {QStyle::StateFlag}{style
+ flags} that are used when drawing. The table also describes which
+ flags that are set when casting the given \a option to the
+ appropriate subclass.
+
+ \table
+ \header \o Complex Control \o QStyleOptionComplex Subclass \o Style Flag \o Remark
+ \row \o{1,2} \l{CC_SpinBox} \o{1,2} \l QStyleOptionSpinBox
+ \o \l State_Enabled \o Set if the spin box is enabled.
+ \row \o \l State_HasFocus \o Set if the spin box has input focus.
+
+ \row \o{1,2} \l {CC_ComboBox} \o{1,2} \l QStyleOptionComboBox
+ \o \l State_Enabled \o Set if the combobox is enabled.
+ \row \o \l State_HasFocus \o Set if the combobox has input focus.
+
+ \row \o{1,2} \l {CC_ScrollBar} \o{1,2} \l QStyleOptionSlider
+ \o \l State_Enabled \o Set if the scroll bar is enabled.
+ \row \o \l State_HasFocus \o Set if the scroll bar has input focus.
+
+ \row \o{1,2} \l {CC_Slider} \o{1,2} \l QStyleOptionSlider
+ \o \l State_Enabled \o Set if the slider is enabled.
+ \row \o \l State_HasFocus \o Set if the slider has input focus.
+
+ \row \o{1,2} \l {CC_Dial} \o{1,2} \l QStyleOptionSlider
+ \o \l State_Enabled \o Set if the dial is enabled.
+ \row \o \l State_HasFocus \o Set if the dial has input focus.
+
+ \row \o{1,6} \l {CC_ToolButton} \o{1,6} \l QStyleOptionToolButton
+ \o \l State_Enabled \o Set if the tool button is enabled.
+ \row \o \l State_HasFocus \o Set if the tool button has input focus.
+ \row \o \l State_DownArrow \o Set if the tool button is down (i.e., a mouse
+ button or the space bar is pressed).
+ \row \o \l State_On \o Set if the tool button is a toggle button
+ and is toggled on.
+ \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
+ \row \o \l State_Raised \o Set if the button is not down, not on, and doesn't
+ contain the mouse when auto-raise is enabled.
+
+ \row \o \l{CC_TitleBar} \o \l QStyleOptionTitleBar
+ \o \l State_Enabled \o Set if the title bar is enabled.
+
+ \row \o \l{CC_Q3ListView} \o \l QStyleOptionQ3ListView
+ \o \l State_Enabled \o Set if the list view is enabled.
+
+ \endtable
+
+ \sa drawPrimitive(), drawControl()
+*/
+
+
+/*!
+ \fn QRect QStyle::subControlRect(ComplexControl control,
+ const QStyleOptionComplex *option, SubControl subControl,
+ const QWidget *widget) const = 0
+
+ Returns the rectangle containing the specified \a subControl of
+ the given complex \a control (with the style specified by \a
+ option). The rectangle is defined in screen coordinates.
+
+ The \a option argument is a pointer to QStyleOptionComplex or
+ one of its subclasses, and can be cast to the appropriate type
+ using the qstyleoption_cast() function. See drawComplexControl()
+ for details. The \a widget is optional and can contain additional
+ information for the function.
+
+ \sa drawComplexControl()
+*/
+
+/*!
+ \fn QStyle::SubControl QStyle::hitTestComplexControl(ComplexControl control,
+ const QStyleOptionComplex *option, const QPoint &position,
+ const QWidget *widget) const = 0
+
+ Returns the sub control at the given \a position in the given
+ complex \a control (with the style options specified by \a
+ option).
+
+ Note that the \a position is expressed in screen coordinates.
+
+ The \a option argument is a pointer to a QStyleOptionComplex
+ object (or one of its subclasses). The object can be cast to the
+ appropriate type using the qstyleoption_cast() function. See
+ drawComplexControl() for details. The \a widget argument is
+ optional and can contain additional information for the function.
+
+ \sa drawComplexControl(), subControlRect()
+*/
+
+/*!
+ \enum QStyle::PixelMetric
+
+ This enum describes the various available pixel metrics. A pixel
+ metric is a style dependent size represented by a single pixel
+ value.
+
+ \value PM_ButtonMargin Amount of whitespace between push button
+ labels and the frame.
+ \value PM_DockWidgetTitleBarButtonMargin Amount of whitespace between dock widget's
+ title bar button labels and the frame.
+ \value PM_ButtonDefaultIndicator Width of the default-button indicator frame.
+ \value PM_MenuButtonIndicator Width of the menu button indicator
+ proportional to the widget height.
+ \value PM_ButtonShiftHorizontal Horizontal contents shift of a
+ button when the button is down.
+ \value PM_ButtonShiftVertical Vertical contents shift of a button when the
+ button is down.
+
+ \value PM_DefaultFrameWidth Default frame width (usually 2).
+ \value PM_SpinBoxFrameWidth Frame width of a spin box, defaults to PM_DefaultFrameWidth.
+ \value PM_ComboBoxFrameWidth Frame width of a combo box, defaults to PM_DefaultFrameWidth.
+
+ \value PM_MDIFrameWidth Obsolete. Use PM_MdiSubWindowFrameWidth instead.
+ \value PM_MdiSubWindowFrameWidth Frame width of an MDI window.
+ \value PM_MDIMinimizedWidth Obsolete. Use PM_MdiSubWindowMinimizedWidth instead.
+ \value PM_MdiSubWindowMinimizedWidth Width of a minimized MDI window.
+
+ \value PM_LayoutLeftMargin Default \l{QLayout::setContentsMargins()}{left margin} for a
+ QLayout.
+ \value PM_LayoutTopMargin Default \l{QLayout::setContentsMargins()}{top margin} for a QLayout.
+ \value PM_LayoutRightMargin Default \l{QLayout::setContentsMargins()}{right margin} for a
+ QLayout.
+ \value PM_LayoutBottomMargin Default \l{QLayout::setContentsMargins()}{bottom margin} for a
+ QLayout.
+ \value PM_LayoutHorizontalSpacing Default \l{QLayout::spacing}{horizontal spacing} for a
+ QLayout.
+ \value PM_LayoutVerticalSpacing Default \l{QLayout::spacing}{vertical spacing} for a QLayout.
+
+ \value PM_MaximumDragDistance The maximum allowed distance between
+ the mouse and a scrollbar when dragging. Exceeding the specified
+ distance will cause the slider to jump back to the original
+ position; a value of -1 disables this behavior.
+
+ \value PM_ScrollBarExtent Width of a vertical scroll bar and the
+ height of a horizontal scroll bar.
+ \value PM_ScrollBarSliderMin The minimum height of a vertical
+ scroll bar's slider and the minimum width of a horizontal
+ scroll bar's slider.
+
+ \value PM_SliderThickness Total slider thickness.
+ \value PM_SliderControlThickness Thickness of the slider handle.
+ \value PM_SliderLength Length of the slider.
+ \value PM_SliderTickmarkOffset The offset between the tickmarks
+ and the slider.
+ \value PM_SliderSpaceAvailable The available space for the slider to move.
+
+ \value PM_DockWidgetSeparatorExtent Width of a separator in a
+ horizontal dock window and the height of a separator in a
+ vertical dock window.
+ \value PM_DockWidgetHandleExtent Width of the handle in a
+ horizontal dock window and the height of the handle in a
+ vertical dock window.
+ \value PM_DockWidgetFrameWidth Frame width of a dock window.
+ \value PM_DockWidgetTitleMargin Margin of the dock window title.
+
+ \value PM_MenuBarPanelWidth Frame width of a menu bar, defaults to PM_DefaultFrameWidth.
+ \value PM_MenuBarItemSpacing Spacing between menu bar items.
+ \value PM_MenuBarHMargin Spacing between menu bar items and left/right of bar.
+ \value PM_MenuBarVMargin Spacing between menu bar items and top/bottom of bar.
+
+ \value PM_ToolBarFrameWidth Width of the frame around toolbars.
+ \value PM_ToolBarHandleExtent Width of a toolbar handle in a
+ horizontal toolbar and the height of the handle in a vertical toolbar.
+ \value PM_ToolBarItemMargin Spacing between the toolbar frame and the items.
+ \value PM_ToolBarItemSpacing Spacing between toolbar items.
+ \value PM_ToolBarSeparatorExtent Width of a toolbar separator in a
+ horizontal toolbar and the height of a separator in a vertical toolbar.
+ \value PM_ToolBarExtensionExtent Width of a toolbar extension
+ button in a horizontal toolbar and the height of the button in a
+ vertical toolbar.
+
+ \value PM_TabBarTabOverlap Number of pixels the tabs should overlap.
+ (Currently only used in styles, not inside of QTabBar)
+ \value PM_TabBarTabHSpace Extra space added to the tab width.
+ \value PM_TabBarTabVSpace Extra space added to the tab height.
+ \value PM_TabBarBaseHeight Height of the area between the tab bar
+ and the tab pages.
+ \value PM_TabBarBaseOverlap Number of pixels the tab bar overlaps
+ the tab bar base.
+ \value PM_TabBarScrollButtonWidth
+ \value PM_TabBarTabShiftHorizontal Horizontal pixel shift when a
+ tab is selected.
+ \value PM_TabBarTabShiftVertical Vertical pixel shift when a
+ tab is selected.
+
+ \value PM_ProgressBarChunkWidth Width of a chunk in a progress bar indicator.
+
+ \value PM_SplitterWidth Width of a splitter.
+
+ \value PM_TitleBarHeight Height of the title bar.
+
+ \value PM_IndicatorWidth Width of a check box indicator.
+ \value PM_IndicatorHeight Height of a checkbox indicator.
+ \value PM_ExclusiveIndicatorWidth Width of a radio button indicator.
+ \value PM_ExclusiveIndicatorHeight Height of a radio button indicator.
+
+ \value PM_MenuPanelWidth Border width (applied on all sides) for a QMenu.
+ \value PM_MenuHMargin Additional border (used on left and right) for a QMenu.
+ \value PM_MenuVMargin Additional border (used for bottom and top) for a QMenu.
+ \value PM_MenuScrollerHeight Height of the scroller area in a QMenu.
+ \value PM_MenuTearoffHeight Height of a tear off area in a QMenu.
+ \value PM_MenuDesktopFrameWidth The frame width for the menu on the desktop.
+
+ \value PM_CheckListButtonSize Area (width/height) of the
+ checkbox/radio button in a Q3CheckListItem.
+ \value PM_CheckListControllerSize Area (width/height) of the
+ controller in a Q3CheckListItem.
+
+ \omitvalue PM_DialogButtonsSeparator
+ \omitvalue PM_DialogButtonsButtonWidth
+ \omitvalue PM_DialogButtonsButtonHeight
+
+ \value PM_HeaderMarkSize The size of the sort indicator in a header.
+ \value PM_HeaderGripMargin The size of the resize grip in a header.
+ \value PM_HeaderMargin The size of the margin between the sort indicator and the text.
+ \value PM_SpinBoxSliderHeight The height of the optional spin box slider.
+
+ \value PM_ToolBarIconSize Default tool bar icon size
+ \value PM_SmallIconSize Default small icon size
+ \value PM_LargeIconSize Default large icon size
+
+ \value PM_FocusFrameHMargin Horizontal margin that the focus frame will outset the widget by.
+ \value PM_FocusFrameVMargin Vertical margin that the focus frame will outset the widget by.
+ \value PM_IconViewIconSize The default size for icons in an icon view.
+ \value PM_ListViewIconSize The default size for icons in a list view.
+
+ \value PM_ToolTipLabelFrameWidth The frame width for a tool tip label.
+ \value PM_CheckBoxLabelSpacing The spacing between a check box indicator and its label.
+ \value PM_RadioButtonLabelSpacing The spacing between a radio button indicator and its label.
+ \value PM_TabBarIconSize The default icon size for a tab bar.
+ \value PM_SizeGripSize The size of a size grip.
+ \value PM_MessageBoxIconSize The size of the standard icons in a message box
+ \value PM_ButtonIconSize The default size of button icons
+ \value PM_TextCursorWidth The width of the cursor in a line edit or text edit
+ \value PM_TabBar_ScrollButtonOverlap The distance between the left and right buttons in a tab bar.
+
+ \value PM_TabCloseIndicatorWidth The default width of a close button on a tab in a tab bar.
+ \value PM_TabCloseIndicatorHeight The default height of a close button on a tab in a tab bar.
+
+ \value PM_CustomBase Base value for custom pixel metrics. Custom
+ values must be greater than this value.
+
+ The following values are obsolete:
+
+ \value PM_DefaultTopLevelMargin Use PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin, and
+ PM_LayoutBottomMargin instead.
+ \value PM_DefaultChildMargin Use PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin, and
+ PM_LayoutBottomMargin instead.
+ \value PM_DefaultLayoutSpacing Use PM_LayoutHorizontalSpacing
+ and PM_LayoutVerticalSpacing
+ instead.
+
+ \value PM_ScrollView_ScrollBarSpacing Distance between frame and scrollbar
+ with SH_ScrollView_FrameOnlyAroundContents set.
+ \value PM_SubMenuOverlap The horizontal overlap between a submenu and its parent.
+
+
+ \sa pixelMetric()
+*/
+
+/*!
+ \fn int QStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
+
+ Returns the value of the given pixel \a metric.
+
+ The specified \a option and \a widget can be used for calculating
+ the metric. In general, the \a widget argument is not used. The \a
+ option can be cast to the appropriate type using the
+ qstyleoption_cast() function. Note that the \a option may be zero
+ even for PixelMetrics that can make use of it. See the table below
+ for the appropriate \a option casts:
+
+ \table
+ \header \o Pixel Metric \o QStyleOption Subclass
+ \row \o \l PM_SliderControlThickness \o \l QStyleOptionSlider
+ \row \o \l PM_SliderLength \o \l QStyleOptionSlider
+ \row \o \l PM_SliderTickmarkOffset \o \l QStyleOptionSlider
+ \row \o \l PM_SliderSpaceAvailable \o \l QStyleOptionSlider
+ \row \o \l PM_ScrollBarExtent \o \l QStyleOptionSlider
+ \row \o \l PM_TabBarTabOverlap \o \l QStyleOptionTab
+ \row \o \l PM_TabBarTabHSpace \o \l QStyleOptionTab
+ \row \o \l PM_TabBarTabVSpace \o \l QStyleOptionTab
+ \row \o \l PM_TabBarBaseHeight \o \l QStyleOptionTab
+ \row \o \l PM_TabBarBaseOverlap \o \l QStyleOptionTab
+ \endtable
+
+ Some pixel metrics are called from widgets and some are only called
+ internally by the style. If the metric is not called by a widget, it is the
+ discretion of the style author to make use of it. For some styles, this
+ may not be appropriate.
+*/
+
+/*!
+ \enum QStyle::ContentsType
+
+ This enum describes the available contents types. These are used to
+ calculate sizes for the contents of various widgets.
+
+ \value CT_CheckBox A check box, like QCheckBox.
+ \value CT_ComboBox A combo box, like QComboBox.
+ \omitvalue CT_DialogButtons
+ \value CT_Q3DockWindow A Q3DockWindow.
+ \value CT_HeaderSection A header section, like QHeader.
+ \value CT_LineEdit A line edit, like QLineEdit.
+ \value CT_Menu A menu, like QMenu.
+ \value CT_Q3Header A Qt 3 header section, like Q3Header.
+ \value CT_MenuBar A menu bar, like QMenuBar.
+ \value CT_MenuBarItem A menu bar item, like the buttons in a QMenuBar.
+ \value CT_MenuItem A menu item, like QMenuItem.
+ \value CT_ProgressBar A progress bar, like QProgressBar.
+ \value CT_PushButton A push button, like QPushButton.
+ \value CT_RadioButton A radio button, like QRadioButton.
+ \value CT_SizeGrip A size grip, like QSizeGrip.
+ \value CT_Slider A slider, like QSlider.
+ \value CT_ScrollBar A scroll bar, like QScrollBar.
+ \value CT_SpinBox A spin box, like QSpinBox.
+ \value CT_Splitter A splitter, like QSplitter.
+ \value CT_TabBarTab A tab on a tab bar, like QTabBar.
+ \value CT_TabWidget A tab widget, like QTabWidget.
+ \value CT_ToolButton A tool button, like QToolButton.
+ \value CT_GroupBox A group box, like QGroupBox.
+ \value CT_ItemViewItem An item inside an item view.
+
+ \value CT_CustomBase Base value for custom contents types.
+ Custom values must be greater than this value.
+
+ \value CT_MdiControls The minimize, normal, and close button
+ in the menu bar for a maximized MDI
+ subwindow.
+
+ \sa sizeFromContents()
+*/
+
+/*!
+ \fn QSize QStyle::sizeFromContents(ContentsType type, const QStyleOption *option, \
+ const QSize &contentsSize, const QWidget *widget) const
+
+ Returns the size of the element described by the specified
+ \a option and \a type, based on the provided \a contentsSize.
+
+ The \a option argument is a pointer to a QStyleOption or one of
+ its subclasses. The \a option can be cast to the appropriate type
+ using the qstyleoption_cast() function. The \a widget is an
+ optional argument and can contain extra information used for
+ calculating the size.
+
+ See the table below for the appropriate \a option casts:
+
+ \table
+ \header \o Contents Type \o QStyleOption Subclass
+ \row \o \l CT_PushButton \o \l QStyleOptionButton
+ \row \o \l CT_CheckBox \o \l QStyleOptionButton
+ \row \o \l CT_RadioButton \o \l QStyleOptionButton
+ \row \o \l CT_ToolButton \o \l QStyleOptionToolButton
+ \row \o \l CT_ComboBox \o \l QStyleOptionComboBox
+ \row \o \l CT_Splitter \o \l QStyleOption
+ \row \o \l CT_Q3DockWindow \o \l QStyleOptionQ3DockWindow
+ \row \o \l CT_ProgressBar \o \l QStyleOptionProgressBar
+ \row \o \l CT_MenuItem \o \l QStyleOptionMenuItem
+ \endtable
+
+ \sa ContentsType QStyleOption
+*/
+
+/*!
+ \enum QStyle::RequestSoftwareInputPanel
+
+ This enum describes under what circumstances a software input panel will be
+ requested by input capable widgets.
+
+ \value RSIP_OnMouseClickAndAlreadyFocused Requests an input panel if the user
+ clicks on the widget, but only if it is already focused.
+ \value RSIP_OnMouseClick Requests an input panel if the user clicks on the
+ widget.
+
+ \sa QEvent::RequestSoftwareInputPanel, QInputContext
+*/
+
+/*!
+ \enum QStyle::StyleHint
+
+ This enum describes the available style hints. A style hint is a general look
+ and/or feel hint.
+
+ \value SH_EtchDisabledText Disabled text is "etched" as it is on Windows.
+
+ \value SH_DitherDisabledText Disabled text is dithered as it is on Motif.
+
+ \value SH_GUIStyle The GUI style to use.
+
+ \value SH_ScrollBar_ContextMenu Whether or not a scroll bar has a context menu.
+
+ \value SH_ScrollBar_MiddleClickAbsolutePosition A boolean value.
+ If true, middle clicking on a scroll bar causes the slider to
+ jump to that position. If false, middle clicking is
+ ignored.
+
+ \value SH_ScrollBar_LeftClickAbsolutePosition A boolean value.
+ If true, left clicking on a scroll bar causes the slider to
+ jump to that position. If false, left clicking will
+ behave as appropriate for each control.
+
+ \value SH_ScrollBar_ScrollWhenPointerLeavesControl A boolean
+ value. If true, when clicking a scroll bar SubControl, holding
+ the mouse button down and moving the pointer outside the
+ SubControl, the scroll bar continues to scroll. If false, the
+ scollbar stops scrolling when the pointer leaves the
+ SubControl.
+
+ \value SH_ScrollBar_RollBetweenButtons A boolean value.
+ If true, when clicking a scroll bar button (SC_ScrollBarAddLine or
+ SC_ScrollBarSubLine) and dragging over to the opposite button (rolling)
+ will press the new button and release the old one. When it is false, the
+ original button is released and nothing happens (like a push button).
+
+ \value SH_TabBar_Alignment The alignment for tabs in a
+ QTabWidget. Possible values are Qt::AlignLeft,
+ Qt::AlignCenter and Qt::AlignRight.
+
+ \value SH_Header_ArrowAlignment The placement of the sorting
+ indicator may appear in list or table headers. Possible values
+ are Qt::Left or Qt::Right.
+
+ \value SH_Slider_SnapToValue Sliders snap to values while moving,
+ as they do on Windows.
+
+ \value SH_Slider_SloppyKeyEvents Key presses handled in a sloppy
+ manner, i.e., left on a vertical slider subtracts a line.
+
+ \value SH_ProgressDialog_CenterCancelButton Center button on
+ progress dialogs, like Motif, otherwise right aligned.
+
+ \value SH_ProgressDialog_TextLabelAlignment The alignment for text
+ labels in progress dialogs; Qt::AlignCenter on Windows,
+ Qt::AlignVCenter otherwise.
+
+ \value SH_PrintDialog_RightAlignButtons Right align buttons in
+ the print dialog, as done on Windows.
+
+ \value SH_MainWindow_SpaceBelowMenuBar One or two pixel space between
+ the menu bar and the dockarea, as done on Windows.
+
+ \value SH_FontDialog_SelectAssociatedText Select the text in the
+ line edit, or when selecting an item from the listbox, or when
+ the line edit receives focus, as done on Windows.
+
+ \value SH_Menu_KeyboardSearch Typing causes a menu to be search
+ for relevant items, otherwise only mnemnonic is considered.
+
+ \value SH_Menu_AllowActiveAndDisabled Allows disabled menu
+ items to be active.
+
+ \value SH_Menu_SpaceActivatesItem Pressing the space bar activates
+ the item, as done on Motif.
+
+ \value SH_Menu_SubMenuPopupDelay The number of milliseconds
+ to wait before opening a submenu (256 on Windows, 96 on Motif).
+
+ \value SH_Menu_Scrollable Whether popup menus must support scrolling.
+
+ \value SH_Menu_SloppySubMenus Whether popupmenu's must support
+ sloppy submenu; as implemented on Mac OS.
+
+ \value SH_ScrollView_FrameOnlyAroundContents Whether scrollviews
+ draw their frame only around contents (like Motif), or around
+ contents, scroll bars and corner widgets (like Windows).
+
+ \value SH_MenuBar_AltKeyNavigation Menu bars items are navigable
+ by pressing Alt, followed by using the arrow keys to select
+ the desired item.
+
+ \value SH_ComboBox_ListMouseTracking Mouse tracking in combobox
+ drop-down lists.
+
+ \value SH_Menu_MouseTracking Mouse tracking in popup menus.
+
+ \value SH_MenuBar_MouseTracking Mouse tracking in menu bars.
+
+ \value SH_Menu_FillScreenWithScroll Whether scrolling popups
+ should fill the screen as they are scrolled.
+
+ \value SH_Menu_SelectionWrap Whether popups should allow the selections
+ to wrap, that is when selection should the next item be the first item.
+
+ \value SH_ItemView_ChangeHighlightOnFocus Gray out selected items
+ when losing focus.
+
+ \value SH_Widget_ShareActivation Turn on sharing activation with
+ floating modeless dialogs.
+
+ \value SH_TabBar_SelectMouseType Which type of mouse event should
+ cause a tab to be selected.
+
+ \value SH_Q3ListViewExpand_SelectMouseType Which type of mouse event should
+ cause a list view expansion to be selected.
+
+ \value SH_TabBar_PreferNoArrows Whether a tab bar should suggest a size
+ to prevent scoll arrows.
+
+ \value SH_ComboBox_Popup Allows popups as a combobox drop-down
+ menu.
+
+ \value SH_Workspace_FillSpaceOnMaximize The workspace should
+ maximize the client area.
+
+ \value SH_TitleBar_NoBorder The title bar has no border.
+
+ \value SH_ScrollBar_StopMouseOverSlider Obsolete. Use
+ SH_Slider_StopMouseOverSlider instead.
+
+ \value SH_Slider_StopMouseOverSlider Stops auto-repeat when
+ the slider reaches the mouse position.
+
+ \value SH_BlinkCursorWhenTextSelected Whether cursor should blink
+ when text is selected.
+
+ \value SH_RichText_FullWidthSelection Whether richtext selections
+ should extend to the full width of the document.
+
+ \value SH_GroupBox_TextLabelVerticalAlignment How to vertically align a
+ group box's text label.
+
+ \value SH_GroupBox_TextLabelColor How to paint a group box's text label.
+
+ \value SH_DialogButtons_DefaultButton Which button gets the
+ default status in a dialog's button widget.
+
+ \value SH_ToolBox_SelectedPageTitleBold Boldness of the selected
+ page title in a QToolBox.
+
+ \value SH_LineEdit_PasswordCharacter The Unicode character to be
+ used for passwords.
+
+ \value SH_Table_GridLineColor The RGB value of the grid for a table.
+
+ \value SH_UnderlineShortcut Whether shortcuts are underlined.
+
+ \value SH_SpellCheckUnderlineStyle A
+ QTextCharFormat::UnderlineStyle value that specifies the way
+ misspelled words should be underlined.
+
+ \value SH_SpinBox_AnimateButton Animate a click when up or down is
+ pressed in a spin box.
+ \value SH_SpinBox_KeyPressAutoRepeatRate Auto-repeat interval for
+ spinbox key presses.
+ \value SH_SpinBox_ClickAutoRepeatRate Auto-repeat interval for
+ spinbox mouse clicks.
+ \value SH_SpinBox_ClickAutoRepeatThreshold Auto-repeat threshold for
+ spinbox mouse clicks.
+ \value SH_ToolTipLabel_Opacity An integer indicating the opacity for
+ the tip label, 0 is completely transparent, 255 is completely
+ opaque.
+ \value SH_DrawMenuBarSeparator Indicates whether or not the menu bar draws separators.
+ \value SH_TitleBar_ModifyNotification Indicates if the title bar should show
+ a '*' for windows that are modified.
+
+ \value SH_Button_FocusPolicy The default focus policy for buttons.
+
+ \value SH_CustomBase Base value for custom style hints.
+ Custom values must be greater than this value.
+
+ \value SH_MenuBar_DismissOnSecondClick A boolean indicating if a menu in
+ the menu bar should be dismissed when it is clicked on a second time. (Example:
+ Clicking and releasing on the File Menu in a menu bar and then
+ immediately clicking on the File Menu again.)
+
+ \value SH_MessageBox_UseBorderForButtonSpacing A boolean indicating what the to
+ use the border of the buttons (computed as half the button height) for the spacing
+ of the button in a message box.
+
+ \value SH_MessageBox_CenterButtons A boolean indicating whether the buttons in the
+ message box should be centered or not (see QDialogButtonBox::setCentered()).
+
+ \value SH_MessageBox_TextInteractionFlags A boolean indicating if
+ the text in a message box should allow user interfactions (e.g.
+ selection) or not.
+
+ \value SH_TitleBar_AutoRaise A boolean indicating whether
+ controls on a title bar ought to update when the mouse is over them.
+
+ \value SH_ToolButton_PopupDelay An int indicating the popup delay in milliseconds
+ for menus attached to tool buttons.
+
+ \value SH_FocusFrame_Mask The mask of the focus frame.
+
+ \value SH_RubberBand_Mask The mask of the rubber band.
+
+ \value SH_WindowFrame_Mask The mask of the window frame.
+
+ \value SH_SpinControls_DisableOnBounds Determines if the spin controls will shown
+ as disabled when reaching the spin range boundary.
+
+ \value SH_Dial_BackgroundRole Defines the style's preferred
+ background role (as QPalette::ColorRole) for a dial widget.
+
+ \value SH_ScrollBar_BackgroundMode The background mode for a scroll bar.
+
+ \value SH_ComboBox_LayoutDirection The layout direction for the
+ combo box. By default it should be the same as indicated by the
+ QStyleOption::direction variable.
+
+ \value SH_ItemView_EllipsisLocation The location where ellipses should be
+ added for item text that is too long to fit in an view item.
+
+ \value SH_ItemView_ShowDecorationSelected When an item in an item
+ view is selected, also highlight the branch or other decoration.
+
+ \value SH_ItemView_ActivateItemOnSingleClick Emit the activated signal
+ when the user single clicks on an item in an item in an item view.
+ Otherwise the signal is emitted when the user double clicks on an item.
+
+ \value SH_Slider_AbsoluteSetButtons Which mouse buttons cause a slider
+ to set the value to the position clicked on.
+
+ \value SH_Slider_PageSetButtons Which mouse buttons cause a slider
+ to page step the value.
+
+ \value SH_TabBar_ElideMode The default eliding style for a tab bar.
+
+ \value SH_DialogButtonLayout Controls how buttons are laid out in a QDialogButtonBox, returns a QDialogButtonBox::ButtonLayout enum.
+
+ \value SH_WizardStyle Controls the look and feel of a QWizard. Returns a QWizard::WizardStyle enum.
+
+ \value SH_FormLayoutWrapPolicy Provides a default for how rows are wrapped in a QFormLayout. Returns a QFormLayout::RowWrapPolicy enum.
+ \value SH_FormLayoutFieldGrowthPolicy Provides a default for how fields can grow in a QFormLayout. Returns a QFormLayout::FieldGrowthPolicy enum.
+ \value SH_FormLayoutFormAlignment Provides a default for how a QFormLayout aligns its contents within the available space. Returns a Qt::Alignment enum.
+ \value SH_FormLayoutLabelAlignment Provides a default for how a QFormLayout aligns labels within the available space. Returns a Qt::Alignment enum.
+
+ \value SH_ItemView_ArrowKeysNavigateIntoChildren Controls whether the tree view will select the first child when it is exapanded and the right arrow key is pressed.
+ \value SH_ComboBox_PopupFrameStyle The frame style used when drawing a combobox popup menu.
+
+ \value SH_DialogButtonBox_ButtonsHaveIcons Indicates whether or not StandardButtons in QDialogButtonBox should have icons or not.
+ \value SH_ItemView_MovementWithoutUpdatingSelection The item view is able to indicate a current item without changing the selection.
+ \value SH_ToolTip_Mask The mask of a tool tip.
+
+ \value SH_FocusFrame_AboveWidget The FocusFrame is stacked above the widget that it is "focusing on".
+
+ \value SH_TextControl_FocusIndicatorTextCharFormat Specifies the text format used to highlight focused anchors in rich text
+ documents displayed for example in QTextBrowser. The format has to be a QTextCharFormat returned in the variant of the
+ QStyleHintReturnVariant return value. The QTextFormat::OutlinePen property is used for the outline and QTextFormat::BackgroundBrush
+ for the background of the highlighted area.
+
+ \value SH_Menu_FlashTriggeredItem Flash triggered item.
+ \value SH_Menu_FadeOutOnHide Fade out the menu instead of hiding it immediately.
+
+ \value SH_TabWidget_DefaultTabPosition Default position of the tab bar in a tab widget.
+
+ \value SH_ToolBar_Movable Determines if the tool bar is movable by default.
+
+ \value SH_ItemView_PaintAlternatingRowColorsForEmptyArea Whether QTreeView paints alternating row colors for the area that does not have any items.
+
+ \value SH_Menu_Mask The mask for a popup menu.
+
+ \value SH_ItemView_DrawDelegateFrame Determines if there should be a frame for a delegate widget.
+
+ \value SH_TabBar_CloseButtonPosition Determines the position of the close button on a tab in a tab bar.
+
+ \value SH_DockWidget_ButtonsHaveFrame Determines if dockwidget buttons should have frames. Default is true.
+
+ \value SH_ToolButtonStyle Determines the default system style for tool buttons that uses Qt::ToolButtonFollowStyle.
+
+ \value SH_RequestSoftwareInputPanel Determines when a software input panel should
+ be requested by input widgets. Returns an enum of type QStyle::RequestSoftwareInputPanel.
+
+ \omitvalue SH_UnderlineAccelerator
+
+ \sa styleHint()
+*/
+
+/*!
+ \fn int QStyle::styleHint(StyleHint hint, const QStyleOption *option, \
+ const QWidget *widget, QStyleHintReturn *returnData) const
+
+ Returns an integer representing the specified style \a hint for
+ the given \a widget described by the provided style \a option.
+
+ \a returnData is used when the querying widget needs more detailed data than
+ the integer that styleHint() returns. See the QStyleHintReturn class
+ description for details.
+*/
+
+/*!
+ \enum QStyle::StandardPixmap
+
+ This enum describes the available standard pixmaps. A standard pixmap is a pixmap that
+ can follow some existing GUI style or guideline.
+
+ \value SP_TitleBarMinButton Minimize button on title bars (e.g.,
+ in QMdiSubWindow).
+ \value SP_TitleBarMenuButton Menu button on a title bar.
+ \value SP_TitleBarMaxButton Maximize button on title bars.
+ \value SP_TitleBarCloseButton Close button on title bars.
+ \value SP_TitleBarNormalButton Normal (restore) button on title bars.
+ \value SP_TitleBarShadeButton Shade button on title bars.
+ \value SP_TitleBarUnshadeButton Unshade button on title bars.
+ \value SP_TitleBarContextHelpButton The Context help button on title bars.
+ \value SP_MessageBoxInformation The "information" icon.
+ \value SP_MessageBoxWarning The "warning" icon.
+ \value SP_MessageBoxCritical The "critical" icon.
+ \value SP_MessageBoxQuestion The "question" icon.
+ \value SP_DesktopIcon The "desktop" icon.
+ \value SP_TrashIcon The "trash" icon.
+ \value SP_ComputerIcon The "My computer" icon.
+ \value SP_DriveFDIcon The floppy icon.
+ \value SP_DriveHDIcon The harddrive icon.
+ \value SP_DriveCDIcon The CD icon.
+ \value SP_DriveDVDIcon The DVD icon.
+ \value SP_DriveNetIcon The network icon.
+ \value SP_DirHomeIcon The home directory icon.
+ \value SP_DirOpenIcon The open directory icon.
+ \value SP_DirClosedIcon The closed directory icon.
+ \value SP_DirIcon The directory icon.
+ \value SP_DirLinkIcon The link to directory icon.
+ \value SP_FileIcon The file icon.
+ \value SP_FileLinkIcon The link to file icon.
+ \value SP_FileDialogStart The "start" icon in a file dialog.
+ \value SP_FileDialogEnd The "end" icon in a file dialog.
+ \value SP_FileDialogToParent The "parent directory" icon in a file dialog.
+ \value SP_FileDialogNewFolder The "create new folder" icon in a file dialog.
+ \value SP_FileDialogDetailedView The detailed view icon in a file dialog.
+ \value SP_FileDialogInfoView The file info icon in a file dialog.
+ \value SP_FileDialogContentsView The contents view icon in a file dialog.
+ \value SP_FileDialogListView The list view icon in a file dialog.
+ \value SP_FileDialogBack The back arrow in a file dialog.
+ \value SP_DockWidgetCloseButton Close button on dock windows (see also QDockWidget).
+ \value SP_ToolBarHorizontalExtensionButton Extension button for horizontal toolbars.
+ \value SP_ToolBarVerticalExtensionButton Extension button for vertical toolbars.
+ \value SP_DialogOkButton Icon for a standard OK button in a QDialogButtonBox.
+ \value SP_DialogCancelButton Icon for a standard Cancel button in a QDialogButtonBox.
+ \value SP_DialogHelpButton Icon for a standard Help button in a QDialogButtonBox.
+ \value SP_DialogOpenButton Icon for a standard Open button in a QDialogButtonBox.
+ \value SP_DialogSaveButton Icon for a standard Save button in a QDialogButtonBox.
+ \value SP_DialogCloseButton Icon for a standard Close button in a QDialogButtonBox.
+ \value SP_DialogApplyButton Icon for a standard Apply button in a QDialogButtonBox.
+ \value SP_DialogResetButton Icon for a standard Reset button in a QDialogButtonBox.
+ \value SP_DialogDiscardButton Icon for a standard Discard button in a QDialogButtonBox.
+ \value SP_DialogYesButton Icon for a standard Yes button in a QDialogButtonBox.
+ \value SP_DialogNoButton Icon for a standard No button in a QDialogButtonBox.
+ \value SP_ArrowUp Icon arrow pointing up.
+ \value SP_ArrowDown Icon arrow pointing down.
+ \value SP_ArrowLeft Icon arrow pointing left.
+ \value SP_ArrowRight Icon arrow pointing right.
+ \value SP_ArrowBack Equivalent to SP_ArrowLeft when the current layout direction is Qt::LeftToRight, otherwise SP_ArrowRight.
+ \value SP_ArrowForward Equivalent to SP_ArrowRight when the current layout direction is Qt::LeftToRight, otherwise SP_ArrowLeft.
+ \value SP_CommandLink Icon used to indicate a Vista style command link glyph.
+ \value SP_VistaShield Icon used to indicate UAC prompts on Windows Vista. This will return a null pixmap or icon on all other platforms.
+ \value SP_BrowserReload Icon indicating that the current page should be reloaded.
+ \value SP_BrowserStop Icon indicating that the page loading should stop.
+ \value SP_MediaPlay Icon indicating that media should begin playback.
+ \value SP_MediaStop Icon indicating that media should stop playback.
+ \value SP_MediaPause Icon indicating that media should pause playback.
+ \value SP_MediaSkipForward Icon indicating that media should skip forward.
+ \value SP_MediaSkipBackward Icon indicating that media should skip backward.
+ \value SP_MediaSeekForward Icon indicating that media should seek forward.
+ \value SP_MediaSeekBackward Icon indicating that media should seek backward.
+ \value SP_MediaVolume Icon indicating a volume control.
+ \value SP_MediaVolumeMuted Icon indicating a muted volume control.
+ \value SP_CustomBase Base value for custom standard pixmaps;
+ custom values must be greater than this value.
+
+ \sa standardIcon()
+*/
+
+/*!
+ \fn QPixmap QStyle::generatedIconPixmap(QIcon::Mode iconMode,
+ const QPixmap &pixmap, const QStyleOption *option) const
+
+ Returns a copy of the given \a pixmap, styled to conform to the
+ specified \a iconMode and taking into account the palette
+ specified by \a option.
+
+ The \a option parameter can pass extra information, but
+ it must contain a palette.
+
+ Note that not all pixmaps will conform, in which case the returned
+ pixmap is a plain copy.
+
+ \sa QIcon
+*/
+
+/*!
+ \fn QPixmap QStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, \
+ const QWidget *widget) const
+
+ \obsolete
+ Returns a pixmap for the given \a standardPixmap.
+
+ A standard pixmap is a pixmap that can follow some existing GUI
+ style or guideline. The \a option argument can be used to pass
+ extra information required when defining the appropriate
+ pixmap. The \a widget argument is optional and can also be used to
+ aid the determination of the pixmap.
+
+ Developers calling standardPixmap() should instead call standardIcon()
+ Developers who re-implemented standardPixmap() should instead re-implement
+ the slot standardIconImplementation().
+
+ \sa standardIcon()
+*/
+
+
+/*!
+ \fn QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QRect &logicalRectangle)
+
+ Returns the given \a logicalRectangle converted to screen
+ coordinates based on the specified \a direction. The \a
+ boundingRectangle is used when performing the translation.
+
+ This function is provided to support right-to-left desktops, and
+ is typically used in implementations of the subControlRect()
+ function.
+
+ \sa QWidget::layoutDirection
+*/
+QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
+{
+ if (direction == Qt::LeftToRight)
+ return logicalRect;
+ QRect rect = logicalRect;
+ rect.translate(2 * (boundingRect.right() - logicalRect.right()) +
+ logicalRect.width() - boundingRect.width(), 0);
+ return rect;
+}
+
+/*!
+ \fn QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QPoint &logicalPosition)
+
+ Returns the given \a logicalPosition converted to screen
+ coordinates based on the specified \a direction. The \a
+ boundingRectangle is used when performing the translation.
+
+ \sa QWidget::layoutDirection
+*/
+QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos)
+{
+ if (direction == Qt::LeftToRight)
+ return logicalPos;
+ return QPoint(boundingRect.right() - logicalPos.x(), logicalPos.y());
+}
+
+/*!
+ Returns a new rectangle of the specified \a size that is aligned to the given \a
+ rectangle according to the specified \a alignment and \a direction.
+ */
+QRect QStyle::alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
+{
+ alignment = visualAlignment(direction, alignment);
+ int x = rectangle.x();
+ int y = rectangle.y();
+ int w = size.width();
+ int h = size.height();
+ if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
+ y += rectangle.size().height()/2 - h/2;
+ else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
+ y += rectangle.size().height() - h;
+ if ((alignment & Qt::AlignRight) == Qt::AlignRight)
+ x += rectangle.size().width() - w;
+ else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
+ x += rectangle.size().width()/2 - w/2;
+ return QRect(x, y, w, h);
+}
+
+/*!
+ Transforms an \a alignment of Qt::AlignLeft or Qt::AlignRight
+ without Qt::AlignAbsolute into Qt::AlignLeft or Qt::AlignRight with
+ Qt::AlignAbsolute according to the layout \a direction. The other
+ alignment flags are left untouched.
+
+ If no horizontal alignment was specified, the function returns the
+ default alignment for the given layout \a direction.
+
+ QWidget::layoutDirection
+*/
+Qt::Alignment QStyle::visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
+{
+ return QGuiApplicationPrivate::visualAlignment(direction, alignment);
+}
+
+/*!
+ Converts the given \a logicalValue to a pixel position. The \a min
+ parameter maps to 0, \a max maps to \a span and other values are
+ distributed evenly in-between.
+
+ This function can handle the entire integer range without
+ overflow, providing that \a span is less than 4096.
+
+ By default, this function assumes that the maximum value is on the
+ right for horizontal items and on the bottom for vertical items.
+ Set the \a upsideDown parameter to true to reverse this behavior.
+
+ \sa sliderValueFromPosition()
+*/
+
+int QStyle::sliderPositionFromValue(int min, int max, int logicalValue, int span, bool upsideDown)
+{
+ if (span <= 0 || logicalValue < min || max <= min)
+ return 0;
+ if (logicalValue > max)
+ return upsideDown ? span : min;
+
+ uint range = max - min;
+ uint p = upsideDown ? max - logicalValue : logicalValue - min;
+
+ if (range > (uint)INT_MAX/4096) {
+ double dpos = (double(p))/(double(range)/span);
+ return int(dpos);
+ } else if (range > (uint)span) {
+ return (2 * p * span + range) / (2*range);
+ } else {
+ uint div = span / range;
+ uint mod = span % range;
+ return p * div + (2 * p * mod + range) / (2 * range);
+ }
+ // equiv. to (p * span) / range + 0.5
+ // no overflow because of this implicit assumption:
+ // span <= 4096
+}
+
+/*!
+ \fn int QStyle::sliderValueFromPosition(int min, int max, int position, int span, bool upsideDown)
+
+ Converts the given pixel \a position to a logical value. 0 maps to
+ the \a min parameter, \a span maps to \a max and other values are
+ distributed evenly in-between.
+
+ This function can handle the entire integer range without
+ overflow.
+
+ By default, this function assumes that the maximum value is on the
+ right for horizontal items and on the bottom for vertical
+ items. Set the \a upsideDown parameter to true to reverse this
+ behavior.
+
+ \sa sliderPositionFromValue()
+*/
+
+int QStyle::sliderValueFromPosition(int min, int max, int pos, int span, bool upsideDown)
+{
+ if (span <= 0 || pos <= 0)
+ return upsideDown ? max : min;
+ if (pos >= span)
+ return upsideDown ? min : max;
+
+ uint range = max - min;
+
+ if ((uint)span > range) {
+ int tmp = (2 * pos * range + span) / (2 * span);
+ return upsideDown ? max - tmp : tmp + min;
+ } else {
+ uint div = range / span;
+ uint mod = range % span;
+ int tmp = pos * div + (2 * pos * mod + span) / (2 * span);
+ return upsideDown ? max - tmp : tmp + min;
+ }
+ // equiv. to min + (pos*range)/span + 0.5
+ // no overflow because of this implicit assumption:
+ // pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX)
+}
+
+/*!
+ Returns the style's standard palette.
+
+ Note that on systems that support system colors, the style's
+ standard palette is not used. In particular, the Windows XP,
+ Vista, and Mac styles do not use the standard palette, but make
+ use of native theme engines. With these styles, you should not set
+ the palette with QApplication::setStandardPalette().
+
+ */
+QPalette QStyle::standardPalette() const
+{
+#ifdef Q_WS_X11
+ QColor background;
+ if (QX11Info::appDepth() > 8)
+ background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
+ else
+ background = QColor(192, 192, 192);
+#else
+ QColor background(0xd4, 0xd0, 0xc8); // win 2000 grey
+#endif
+ QColor light(background.lighter());
+ QColor dark(background.darker());
+ QColor mid(Qt::gray);
+ QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, background);
+ return palette;
+}
+
+/*!
+ \since 4.1
+
+ Returns an icon for the given \a standardIcon.
+
+ The \a standardIcon is a standard pixmap which can follow some
+ existing GUI style or guideline. The \a option argument can be
+ used to pass extra information required when defining the
+ appropriate icon. The \a widget argument is optional and can also
+ be used to aid the determination of the icon.
+
+ \warning Because of binary compatibility constraints, this
+ function is not virtual. If you want to provide your own icons in
+ a QStyle subclass, reimplement the standardIconImplementation()
+ slot in your subclass instead. The standardIcon() function will
+ dynamically detect the slot and call it.
+
+ \sa standardIconImplementation()
+*/
+QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ QIcon result;
+ // ### Qt 4.1: invokeMethod should accept const functions, to avoid this dirty cast
+ QMetaObject::invokeMethod(const_cast<QStyle*>(this),
+ "standardIconImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QIcon, result),
+ Q_ARG(StandardPixmap, standardIcon),
+ Q_ARG(const QStyleOption*, option),
+ Q_ARG(const QWidget*, widget));
+ return result;
+}
+
+/*!
+ \since 4.1
+
+ Returns an icon for the given \a standardIcon.
+
+ Reimplement this slot to provide your own icons in a QStyle
+ subclass; because of binary compatibility constraints, the
+ standardIcon() function (introduced in Qt 4.1) is not
+ virtual. Instead, standardIcon() will dynamically detect and call
+ \e this slot.
+
+ The \a standardIcon is a standard pixmap which can follow some
+ existing GUI style or guideline. The \a option argument can be
+ used to pass extra information required when defining the
+ appropriate icon. The \a widget argument is optional and can also
+ be used to aid the determination of the icon.
+
+ \sa standardIcon()
+*/
+QIcon QStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ return QIcon(standardPixmap(standardIcon, option, widget));
+}
+
+/*!
+ \since 4.3
+
+ Returns the spacing that should be used between \a control1 and
+ \a control2 in a layout. \a orientation specifies whether the
+ controls are laid out side by side or stacked vertically. The \a
+ option parameter can be used to pass extra information about the
+ parent widget. The \a widget parameter is optional and can also
+ be used if \a option is 0.
+
+ This function is called by the layout system. It is used only if
+ PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
+ negative value.
+
+ For binary compatibility reasons, this function is not virtual.
+ If you want to specify custom layout spacings in a QStyle
+ subclass, implement a slot called layoutSpacingImplementation().
+ QStyle will discover the slot at run-time (using Qt's
+ \l{meta-object system}) and direct all calls to layoutSpacing()
+ to layoutSpacingImplementation().
+
+ \sa combinedLayoutSpacing(), layoutSpacingImplementation()
+*/
+int QStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QStyle);
+ if (d->layoutSpacingIndex == -1) {
+ d->layoutSpacingIndex = metaObject()->indexOfMethod(
+ "layoutSpacingImplementation(QSizePolicy::ControlType,QSizePolicy::ControlType,"
+ "Qt::Orientation,const QStyleOption*,const QWidget*)"
+ );
+ }
+ if (d->layoutSpacingIndex < 0)
+ return -1;
+ int result = -1;
+ void *param[] = {&result, &control1, &control2, &orientation, &option, &widget};
+
+ const_cast<QStyle *>(this)->qt_metacall(QMetaObject::InvokeMetaMethod,
+ d->layoutSpacingIndex, param);
+ return result;
+}
+
+/*!
+ \since 4.3
+
+ Returns the spacing that should be used between \a controls1 and
+ \a controls2 in a layout. \a orientation specifies whether the
+ controls are laid out side by side or stacked vertically. The \a
+ option parameter can be used to pass extra information about the
+ parent widget. The \a widget parameter is optional and can also
+ be used if \a option is 0.
+
+ \a controls1 and \a controls2 are OR-combination of zero or more
+ \l{QSizePolicy::ControlTypes}{control types}.
+
+ This function is called by the layout system. It is used only if
+ PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
+ negative value.
+
+ \sa layoutSpacing(), layoutSpacingImplementation()
+*/
+int QStyle::combinedLayoutSpacing(QSizePolicy::ControlTypes controls1,
+ QSizePolicy::ControlTypes controls2, Qt::Orientation orientation,
+ QStyleOption *option, QWidget *widget) const
+{
+ QSizePolicy::ControlType array1[MaxBits];
+ QSizePolicy::ControlType array2[MaxBits];
+ int count1 = unpackControlTypes(controls1, array1);
+ int count2 = unpackControlTypes(controls2, array2);
+ int result = -1;
+
+ for (int i = 0; i < count1; ++i) {
+ for (int j = 0; j < count2; ++j) {
+ int spacing = layoutSpacing(array1[i], array2[j], orientation, option, widget);
+ result = qMax(spacing, result);
+ }
+ }
+ return result;
+}
+
+/*!
+ \since 4.3
+
+ This slot is called by layoutSpacing() to determine the spacing
+ that should be used between \a control1 and \a control2 in a
+ layout. \a orientation specifies whether the controls are laid
+ out side by side or stacked vertically. The \a option parameter
+ can be used to pass extra information about the parent widget.
+ The \a widget parameter is optional and can also be used if \a
+ option is 0.
+
+ If you want to provide custom layout spacings in a QStyle
+ subclass, implement a slot called layoutSpacingImplementation()
+ in your subclass. Be aware that this slot will only be called if
+ PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
+ negative value.
+
+ The default implementation returns -1.
+
+ \sa layoutSpacing(), combinedLayoutSpacing()
+*/
+int QStyle::layoutSpacingImplementation(QSizePolicy::ControlType /* control1 */,
+ QSizePolicy::ControlType /* control2 */,
+ Qt::Orientation /*orientation*/,
+ const QStyleOption * /* option */,
+ const QWidget * /* widget */) const
+{
+ return -1;
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QDebug>
+QT_END_INCLUDE_NAMESPACE
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug debug, QStyle::State state)
+{
+#if !defined(QT_NO_DEBUG)
+ debug << "QStyle::State(";
+
+ QStringList states;
+ if (state & QStyle::State_Active) states << QLatin1String("Active");
+ if (state & QStyle::State_AutoRaise) states << QLatin1String("AutoRaise");
+ if (state & QStyle::State_Bottom) states << QLatin1String("Bottom");
+ if (state & QStyle::State_Children) states << QLatin1String("Children");
+ if (state & QStyle::State_DownArrow) states << QLatin1String("DownArrow");
+ if (state & QStyle::State_Editing) states << QLatin1String("Editing");
+ if (state & QStyle::State_Enabled) states << QLatin1String("Enabled");
+ if (state & QStyle::State_FocusAtBorder) states << QLatin1String("FocusAtBorder");
+ if (state & QStyle::State_HasFocus) states << QLatin1String("HasFocus");
+ if (state & QStyle::State_Horizontal) states << QLatin1String("Horizontal");
+ if (state & QStyle::State_Item) states << QLatin1String("Item");
+ if (state & QStyle::State_KeyboardFocusChange) states << QLatin1String("KeyboardFocusChange");
+ if (state & QStyle::State_MouseOver) states << QLatin1String("MouseOver");
+ if (state & QStyle::State_NoChange) states << QLatin1String("NoChange");
+ if (state & QStyle::State_Off) states << QLatin1String("Off");
+ if (state & QStyle::State_On) states << QLatin1String("On");
+ if (state & QStyle::State_Open) states << QLatin1String("Open");
+ if (state & QStyle::State_Raised) states << QLatin1String("Raised");
+ if (state & QStyle::State_ReadOnly) states << QLatin1String("ReadOnly");
+ if (state & QStyle::State_Selected) states << QLatin1String("Selected");
+ if (state & QStyle::State_Sibling) states << QLatin1String("Sibling");
+ if (state & QStyle::State_Sunken) states << QLatin1String("Sunken");
+ if (state & QStyle::State_Top) states << QLatin1String("Top");
+ if (state & QStyle::State_UpArrow) states << QLatin1String("UpArrow");
+
+ qSort(states);
+ debug << states.join(QLatin1String(" | "));
+ debug << ')';
+#else
+ Q_UNUSED(state);
+#endif
+ return debug;
+}
+#endif
+
+/*!
+ \since 4.6
+
+ \fn const QStyle *QStyle::proxy() const
+
+ This function returns the current proxy for this style.
+ By default most styles will return themselves. However
+ when a proxy style is in use, it will allow the style to
+ call back into its proxy.
+*/
+const QStyle * QStyle::proxy() const
+{
+ Q_D(const QStyle);
+ return d->proxyStyle;
+}
+
+/* \internal
+
+ This function sets the base style that style calls will be
+ redirected to. Note that ownership is not transferred.
+*/
+void QStyle::setProxy(QStyle *style)
+{
+ Q_D(QStyle);
+ d->proxyStyle = style;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
new file mode 100644
index 0000000000..e87556d932
--- /dev/null
+++ b/src/widgets/styles/qstyle.h
@@ -0,0 +1,889 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLE_H
+#define QSTYLE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qsize.h>
+#include <QtWidgets/qicon.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qpalette.h>
+#include <QtWidgets/qsizepolicy.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QAction;
+class QDebug;
+class QTab;
+class QFontMetrics;
+class QStyleHintReturn;
+class QStyleOption;
+class QStyleOptionComplex;
+class QStylePrivate;
+
+class Q_GUI_EXPORT QStyle : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QStyle)
+
+protected:
+ QStyle(QStylePrivate &dd);
+
+public:
+ QStyle();
+ virtual ~QStyle();
+
+ virtual void polish(QWidget *);
+ virtual void unpolish(QWidget *);
+
+ virtual void polish(QApplication *);
+ virtual void unpolish(QApplication *);
+
+ virtual void polish(QPalette &);
+
+ virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r,
+ int flags, bool enabled,
+ const QString &text) const;
+
+ virtual QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+ virtual void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+
+ virtual void drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const;
+
+ virtual QPalette standardPalette() const;
+
+ enum StateFlag {
+ State_None = 0x00000000,
+#ifdef QT3_SUPPORT
+ State_Default = State_None,
+#endif
+ State_Enabled = 0x00000001,
+ State_Raised = 0x00000002,
+ State_Sunken = 0x00000004,
+ State_Off = 0x00000008,
+ State_NoChange = 0x00000010,
+ State_On = 0x00000020,
+ State_DownArrow = 0x00000040,
+ State_Horizontal = 0x00000080,
+ State_HasFocus = 0x00000100,
+ State_Top = 0x00000200,
+ State_Bottom = 0x00000400,
+ State_FocusAtBorder = 0x00000800,
+ State_AutoRaise = 0x00001000,
+ State_MouseOver = 0x00002000,
+ State_UpArrow = 0x00004000,
+ State_Selected = 0x00008000,
+ State_Active = 0x00010000,
+ State_Window = 0x00020000,
+ State_Open = 0x00040000,
+ State_Children = 0x00080000,
+ State_Item = 0x00100000,
+ State_Sibling = 0x00200000,
+ State_Editing = 0x00400000,
+ State_KeyboardFocusChange = 0x00800000,
+#ifdef QT_KEYPAD_NAVIGATION
+ State_HasEditFocus = 0x01000000,
+#endif
+ State_ReadOnly = 0x02000000,
+ State_Small = 0x04000000,
+ State_Mini = 0x08000000
+ };
+ Q_DECLARE_FLAGS(State, StateFlag)
+
+#ifdef QT3_SUPPORT
+ typedef State SFlags;
+#endif
+
+ enum PrimitiveElement {
+ PE_Q3CheckListController,
+ PE_Q3CheckListExclusiveIndicator,
+ PE_Q3CheckListIndicator,
+ PE_Q3DockWindowSeparator,
+ PE_Q3Separator,
+
+ PE_Frame,
+ PE_FrameDefaultButton,
+ PE_FrameDockWidget,
+ PE_FrameFocusRect,
+ PE_FrameGroupBox,
+ PE_FrameLineEdit,
+ PE_FrameMenu,
+ PE_FrameStatusBar, // obsolete
+ PE_FrameStatusBarItem = PE_FrameStatusBar,
+ PE_FrameTabWidget,
+ PE_FrameWindow,
+ PE_FrameButtonBevel,
+ PE_FrameButtonTool,
+ PE_FrameTabBarBase,
+
+ PE_PanelButtonCommand,
+ PE_PanelButtonBevel,
+ PE_PanelButtonTool,
+ PE_PanelMenuBar,
+ PE_PanelToolBar,
+ PE_PanelLineEdit,
+
+ PE_IndicatorArrowDown,
+ PE_IndicatorArrowLeft,
+ PE_IndicatorArrowRight,
+ PE_IndicatorArrowUp,
+ PE_IndicatorBranch,
+ PE_IndicatorButtonDropDown,
+ PE_IndicatorViewItemCheck,
+ PE_IndicatorItemViewItemCheck = PE_IndicatorViewItemCheck,
+ PE_IndicatorCheckBox,
+ PE_IndicatorDockWidgetResizeHandle,
+ PE_IndicatorHeaderArrow,
+ PE_IndicatorMenuCheckMark,
+ PE_IndicatorProgressChunk,
+ PE_IndicatorRadioButton,
+ PE_IndicatorSpinDown,
+ PE_IndicatorSpinMinus,
+ PE_IndicatorSpinPlus,
+ PE_IndicatorSpinUp,
+ PE_IndicatorToolBarHandle,
+ PE_IndicatorToolBarSeparator,
+ PE_PanelTipLabel,
+ PE_IndicatorTabTear,
+ PE_PanelScrollAreaCorner,
+
+ PE_Widget,
+
+ PE_IndicatorColumnViewArrow,
+ PE_IndicatorItemViewItemDrop,
+
+ PE_PanelItemViewItem,
+ PE_PanelItemViewRow, // ### Qt 5: remove
+
+ PE_PanelStatusBar,
+
+ PE_IndicatorTabClose,
+ PE_PanelMenu,
+
+ // do not add any values below/greater this
+ PE_CustomBase = 0xf000000
+ };
+
+ virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const = 0;
+ enum ControlElement {
+ CE_PushButton,
+ CE_PushButtonBevel,
+ CE_PushButtonLabel,
+
+ CE_CheckBox,
+ CE_CheckBoxLabel,
+
+ CE_RadioButton,
+ CE_RadioButtonLabel,
+
+ CE_TabBarTab,
+ CE_TabBarTabShape,
+ CE_TabBarTabLabel,
+
+ CE_ProgressBar,
+ CE_ProgressBarGroove,
+ CE_ProgressBarContents,
+ CE_ProgressBarLabel,
+
+ CE_MenuItem,
+ CE_MenuScroller,
+ CE_MenuVMargin,
+ CE_MenuHMargin,
+ CE_MenuTearoff,
+ CE_MenuEmptyArea,
+
+ CE_MenuBarItem,
+ CE_MenuBarEmptyArea,
+
+ CE_ToolButtonLabel,
+
+ CE_Header,
+ CE_HeaderSection,
+ CE_HeaderLabel,
+
+ CE_Q3DockWindowEmptyArea,
+ CE_ToolBoxTab,
+ CE_SizeGrip,
+ CE_Splitter,
+ CE_RubberBand,
+ CE_DockWidgetTitle,
+
+ CE_ScrollBarAddLine,
+ CE_ScrollBarSubLine,
+ CE_ScrollBarAddPage,
+ CE_ScrollBarSubPage,
+ CE_ScrollBarSlider,
+ CE_ScrollBarFirst,
+ CE_ScrollBarLast,
+
+ CE_FocusFrame,
+ CE_ComboBoxLabel,
+
+ CE_ToolBar,
+ CE_ToolBoxTabShape,
+ CE_ToolBoxTabLabel,
+ CE_HeaderEmptyArea,
+
+ CE_ColumnViewGrip,
+
+ CE_ItemViewItem,
+
+ CE_ShapedFrame,
+
+ // do not add any values below/greater than this
+ CE_CustomBase = 0xf0000000
+ };
+
+ virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const = 0;
+
+ enum SubElement {
+ SE_PushButtonContents,
+ SE_PushButtonFocusRect,
+
+ SE_CheckBoxIndicator,
+ SE_CheckBoxContents,
+ SE_CheckBoxFocusRect,
+ SE_CheckBoxClickRect,
+
+ SE_RadioButtonIndicator,
+ SE_RadioButtonContents,
+ SE_RadioButtonFocusRect,
+ SE_RadioButtonClickRect,
+
+ SE_ComboBoxFocusRect,
+
+ SE_SliderFocusRect,
+
+ SE_Q3DockWindowHandleRect,
+
+ SE_ProgressBarGroove,
+ SE_ProgressBarContents,
+ SE_ProgressBarLabel,
+
+ // ### Qt 5: These values are unused; eliminate them
+ SE_DialogButtonAccept,
+ SE_DialogButtonReject,
+ SE_DialogButtonApply,
+ SE_DialogButtonHelp,
+ SE_DialogButtonAll,
+ SE_DialogButtonAbort,
+ SE_DialogButtonIgnore,
+ SE_DialogButtonRetry,
+ SE_DialogButtonCustom,
+
+ SE_ToolBoxTabContents,
+
+ SE_HeaderLabel,
+ SE_HeaderArrow,
+
+ SE_TabWidgetTabBar,
+ SE_TabWidgetTabPane,
+ SE_TabWidgetTabContents,
+ SE_TabWidgetLeftCorner,
+ SE_TabWidgetRightCorner,
+
+ SE_ViewItemCheckIndicator,
+ SE_ItemViewItemCheckIndicator = SE_ViewItemCheckIndicator,
+
+ SE_TabBarTearIndicator,
+
+ SE_TreeViewDisclosureItem,
+
+ SE_LineEditContents,
+ SE_FrameContents,
+
+ SE_DockWidgetCloseButton,
+ SE_DockWidgetFloatButton,
+ SE_DockWidgetTitleBarText,
+ SE_DockWidgetIcon,
+
+ SE_CheckBoxLayoutItem,
+ SE_ComboBoxLayoutItem,
+ SE_DateTimeEditLayoutItem,
+ SE_DialogButtonBoxLayoutItem, // ### remove
+ SE_LabelLayoutItem,
+ SE_ProgressBarLayoutItem,
+ SE_PushButtonLayoutItem,
+ SE_RadioButtonLayoutItem,
+ SE_SliderLayoutItem,
+ SE_SpinBoxLayoutItem,
+ SE_ToolButtonLayoutItem,
+
+ SE_FrameLayoutItem,
+ SE_GroupBoxLayoutItem,
+ SE_TabWidgetLayoutItem,
+
+ SE_ItemViewItemDecoration,
+ SE_ItemViewItemText,
+ SE_ItemViewItemFocusRect,
+
+ SE_TabBarTabLeftButton,
+ SE_TabBarTabRightButton,
+ SE_TabBarTabText,
+
+ SE_ShapedFrameContents,
+
+ SE_ToolBarHandle,
+
+ // do not add any values below/greater than this
+ SE_CustomBase = 0xf0000000
+ };
+
+ virtual QRect subElementRect(SubElement subElement, const QStyleOption *option,
+ const QWidget *widget = 0) const = 0;
+
+
+ enum ComplexControl {
+ CC_SpinBox,
+ CC_ComboBox,
+ CC_ScrollBar,
+ CC_Slider,
+ CC_ToolButton,
+ CC_TitleBar,
+ CC_Q3ListView,
+ CC_Dial,
+ CC_GroupBox,
+ CC_MdiControls,
+
+ // do not add any values below/greater than this
+ CC_CustomBase = 0xf0000000
+ };
+
+ enum SubControl {
+ SC_None = 0x00000000,
+
+ SC_ScrollBarAddLine = 0x00000001,
+ SC_ScrollBarSubLine = 0x00000002,
+ SC_ScrollBarAddPage = 0x00000004,
+ SC_ScrollBarSubPage = 0x00000008,
+ SC_ScrollBarFirst = 0x00000010,
+ SC_ScrollBarLast = 0x00000020,
+ SC_ScrollBarSlider = 0x00000040,
+ SC_ScrollBarGroove = 0x00000080,
+
+ SC_SpinBoxUp = 0x00000001,
+ SC_SpinBoxDown = 0x00000002,
+ SC_SpinBoxFrame = 0x00000004,
+ SC_SpinBoxEditField = 0x00000008,
+
+ SC_ComboBoxFrame = 0x00000001,
+ SC_ComboBoxEditField = 0x00000002,
+ SC_ComboBoxArrow = 0x00000004,
+ SC_ComboBoxListBoxPopup = 0x00000008,
+
+ SC_SliderGroove = 0x00000001,
+ SC_SliderHandle = 0x00000002,
+ SC_SliderTickmarks = 0x00000004,
+
+ SC_ToolButton = 0x00000001,
+ SC_ToolButtonMenu = 0x00000002,
+
+ SC_TitleBarSysMenu = 0x00000001,
+ SC_TitleBarMinButton = 0x00000002,
+ SC_TitleBarMaxButton = 0x00000004,
+ SC_TitleBarCloseButton = 0x00000008,
+ SC_TitleBarNormalButton = 0x00000010,
+ SC_TitleBarShadeButton = 0x00000020,
+ SC_TitleBarUnshadeButton = 0x00000040,
+ SC_TitleBarContextHelpButton = 0x00000080,
+ SC_TitleBarLabel = 0x00000100,
+
+ SC_Q3ListView = 0x00000001,
+ SC_Q3ListViewBranch = 0x00000002,
+ SC_Q3ListViewExpand = 0x00000004,
+
+ SC_DialGroove = 0x00000001,
+ SC_DialHandle = 0x00000002,
+ SC_DialTickmarks = 0x00000004,
+
+ SC_GroupBoxCheckBox = 0x00000001,
+ SC_GroupBoxLabel = 0x00000002,
+ SC_GroupBoxContents = 0x00000004,
+ SC_GroupBoxFrame = 0x00000008,
+
+ SC_MdiMinButton = 0x00000001,
+ SC_MdiNormalButton = 0x00000002,
+ SC_MdiCloseButton = 0x00000004,
+
+ SC_CustomBase = 0xf0000000,
+ SC_All = 0xffffffff
+ };
+ Q_DECLARE_FLAGS(SubControls, SubControl)
+
+#ifdef QT3_SUPPORT
+ typedef SubControls SCFlags;
+#endif
+
+ virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget = 0) const = 0;
+ virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *widget = 0) const = 0;
+ virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget = 0) const = 0;
+
+ enum PixelMetric {
+ PM_ButtonMargin,
+ PM_ButtonDefaultIndicator,
+ PM_MenuButtonIndicator,
+ PM_ButtonShiftHorizontal,
+ PM_ButtonShiftVertical,
+
+ PM_DefaultFrameWidth,
+ PM_SpinBoxFrameWidth,
+ PM_ComboBoxFrameWidth,
+
+ PM_MaximumDragDistance,
+
+ PM_ScrollBarExtent,
+ PM_ScrollBarSliderMin,
+
+ PM_SliderThickness, // total slider thickness
+ PM_SliderControlThickness, // thickness of the business part
+ PM_SliderLength, // total length of slider
+ PM_SliderTickmarkOffset, //
+ PM_SliderSpaceAvailable, // available space for slider to move
+
+ PM_DockWidgetSeparatorExtent,
+ PM_DockWidgetHandleExtent,
+ PM_DockWidgetFrameWidth,
+
+ PM_TabBarTabOverlap,
+ PM_TabBarTabHSpace,
+ PM_TabBarTabVSpace,
+ PM_TabBarBaseHeight,
+ PM_TabBarBaseOverlap,
+
+ PM_ProgressBarChunkWidth,
+
+ PM_SplitterWidth,
+ PM_TitleBarHeight,
+
+ PM_MenuScrollerHeight,
+ PM_MenuHMargin,
+ PM_MenuVMargin,
+ PM_MenuPanelWidth,
+ PM_MenuTearoffHeight,
+ PM_MenuDesktopFrameWidth,
+
+ PM_MenuBarPanelWidth,
+ PM_MenuBarItemSpacing,
+ PM_MenuBarVMargin,
+ PM_MenuBarHMargin,
+
+ PM_IndicatorWidth,
+ PM_IndicatorHeight,
+ PM_ExclusiveIndicatorWidth,
+ PM_ExclusiveIndicatorHeight,
+ PM_CheckListButtonSize,
+ PM_CheckListControllerSize,
+
+ PM_DialogButtonsSeparator,
+ PM_DialogButtonsButtonWidth,
+ PM_DialogButtonsButtonHeight,
+
+ PM_MdiSubWindowFrameWidth,
+ PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, //obsolete
+ PM_MdiSubWindowMinimizedWidth,
+ PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, //obsolete
+
+ PM_HeaderMargin,
+ PM_HeaderMarkSize,
+ PM_HeaderGripMargin,
+ PM_TabBarTabShiftHorizontal,
+ PM_TabBarTabShiftVertical,
+ PM_TabBarScrollButtonWidth,
+
+ PM_ToolBarFrameWidth,
+ PM_ToolBarHandleExtent,
+ PM_ToolBarItemSpacing,
+ PM_ToolBarItemMargin,
+ PM_ToolBarSeparatorExtent,
+ PM_ToolBarExtensionExtent,
+
+ PM_SpinBoxSliderHeight,
+
+ PM_DefaultTopLevelMargin,
+ PM_DefaultChildMargin,
+ PM_DefaultLayoutSpacing,
+
+ PM_ToolBarIconSize,
+ PM_ListViewIconSize,
+ PM_IconViewIconSize,
+ PM_SmallIconSize,
+ PM_LargeIconSize,
+
+ PM_FocusFrameVMargin,
+ PM_FocusFrameHMargin,
+
+ PM_ToolTipLabelFrameWidth,
+ PM_CheckBoxLabelSpacing,
+ PM_TabBarIconSize,
+ PM_SizeGripSize,
+ PM_DockWidgetTitleMargin,
+ PM_MessageBoxIconSize,
+ PM_ButtonIconSize,
+
+ PM_DockWidgetTitleBarButtonMargin,
+
+ PM_RadioButtonLabelSpacing,
+ PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin,
+ PM_LayoutBottomMargin,
+ PM_LayoutHorizontalSpacing,
+ PM_LayoutVerticalSpacing,
+ PM_TabBar_ScrollButtonOverlap,
+
+ PM_TextCursorWidth,
+
+ PM_TabCloseIndicatorWidth,
+ PM_TabCloseIndicatorHeight,
+
+ PM_ScrollView_ScrollBarSpacing,
+ PM_SubMenuOverlap,
+
+ // do not add any values below/greater than this
+ PM_CustomBase = 0xf0000000
+ };
+
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const = 0;
+
+ enum ContentsType {
+ CT_PushButton,
+ CT_CheckBox,
+ CT_RadioButton,
+ CT_ToolButton,
+ CT_ComboBox,
+ CT_Splitter,
+ CT_Q3DockWindow,
+ CT_ProgressBar,
+ CT_MenuItem,
+ CT_MenuBarItem,
+ CT_MenuBar,
+ CT_Menu,
+ CT_TabBarTab,
+ CT_Slider,
+ CT_ScrollBar,
+ CT_Q3Header,
+ CT_LineEdit,
+ CT_SpinBox,
+ CT_SizeGrip,
+ CT_TabWidget,
+ CT_DialogButtons,
+ CT_HeaderSection,
+ CT_GroupBox,
+ CT_MdiControls,
+ CT_ItemViewItem,
+ // do not add any values below/greater than this
+ CT_CustomBase = 0xf0000000
+ };
+
+ virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *w = 0) const = 0;
+
+ enum RequestSoftwareInputPanel {
+ RSIP_OnMouseClickAndAlreadyFocused,
+ RSIP_OnMouseClick
+ };
+
+ enum StyleHint {
+ SH_EtchDisabledText,
+ SH_DitherDisabledText,
+ SH_ScrollBar_MiddleClickAbsolutePosition,
+ SH_ScrollBar_ScrollWhenPointerLeavesControl,
+ SH_TabBar_SelectMouseType,
+ SH_TabBar_Alignment,
+ SH_Header_ArrowAlignment,
+ SH_Slider_SnapToValue,
+ SH_Slider_SloppyKeyEvents,
+ SH_ProgressDialog_CenterCancelButton,
+ SH_ProgressDialog_TextLabelAlignment,
+ SH_PrintDialog_RightAlignButtons,
+ SH_MainWindow_SpaceBelowMenuBar,
+ SH_FontDialog_SelectAssociatedText,
+ SH_Menu_AllowActiveAndDisabled,
+ SH_Menu_SpaceActivatesItem,
+ SH_Menu_SubMenuPopupDelay,
+ SH_ScrollView_FrameOnlyAroundContents,
+ SH_MenuBar_AltKeyNavigation,
+ SH_ComboBox_ListMouseTracking,
+ SH_Menu_MouseTracking,
+ SH_MenuBar_MouseTracking,
+ SH_ItemView_ChangeHighlightOnFocus,
+ SH_Widget_ShareActivation,
+ SH_Workspace_FillSpaceOnMaximize,
+ SH_ComboBox_Popup,
+ SH_TitleBar_NoBorder,
+ SH_Slider_StopMouseOverSlider,
+ SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // obsolete
+ SH_BlinkCursorWhenTextSelected,
+ SH_RichText_FullWidthSelection,
+ SH_Menu_Scrollable,
+ SH_GroupBox_TextLabelVerticalAlignment,
+ SH_GroupBox_TextLabelColor,
+ SH_Menu_SloppySubMenus,
+ SH_Table_GridLineColor,
+ SH_LineEdit_PasswordCharacter,
+ SH_DialogButtons_DefaultButton,
+ SH_ToolBox_SelectedPageTitleBold,
+ SH_TabBar_PreferNoArrows,
+ SH_ScrollBar_LeftClickAbsolutePosition,
+ SH_Q3ListViewExpand_SelectMouseType,
+ SH_UnderlineShortcut,
+ SH_SpinBox_AnimateButton,
+ SH_SpinBox_KeyPressAutoRepeatRate,
+ SH_SpinBox_ClickAutoRepeatRate,
+ SH_Menu_FillScreenWithScroll,
+ SH_ToolTipLabel_Opacity,
+ SH_DrawMenuBarSeparator,
+ SH_TitleBar_ModifyNotification,
+ SH_Button_FocusPolicy,
+ SH_MenuBar_DismissOnSecondClick,
+ SH_MessageBox_UseBorderForButtonSpacing,
+ SH_TitleBar_AutoRaise,
+ SH_ToolButton_PopupDelay,
+ SH_FocusFrame_Mask,
+ SH_RubberBand_Mask,
+ SH_WindowFrame_Mask,
+ SH_SpinControls_DisableOnBounds,
+ SH_Dial_BackgroundRole,
+ SH_ComboBox_LayoutDirection,
+ SH_ItemView_EllipsisLocation,
+ SH_ItemView_ShowDecorationSelected,
+ SH_ItemView_ActivateItemOnSingleClick,
+ SH_ScrollBar_ContextMenu,
+ SH_ScrollBar_RollBetweenButtons,
+ SH_Slider_AbsoluteSetButtons,
+ SH_Slider_PageSetButtons,
+ SH_Menu_KeyboardSearch,
+ SH_TabBar_ElideMode,
+ SH_DialogButtonLayout,
+ SH_ComboBox_PopupFrameStyle,
+ SH_MessageBox_TextInteractionFlags,
+ SH_DialogButtonBox_ButtonsHaveIcons,
+ SH_SpellCheckUnderlineStyle,
+ SH_MessageBox_CenterButtons,
+ SH_Menu_SelectionWrap,
+ SH_ItemView_MovementWithoutUpdatingSelection,
+ SH_ToolTip_Mask,
+ SH_FocusFrame_AboveWidget,
+ SH_TextControl_FocusIndicatorTextCharFormat,
+ SH_WizardStyle,
+ SH_ItemView_ArrowKeysNavigateIntoChildren,
+ SH_Menu_Mask,
+ SH_Menu_FlashTriggeredItem,
+ SH_Menu_FadeOutOnHide,
+ SH_SpinBox_ClickAutoRepeatThreshold,
+ SH_ItemView_PaintAlternatingRowColorsForEmptyArea,
+ SH_FormLayoutWrapPolicy,
+ SH_TabWidget_DefaultTabPosition,
+ SH_ToolBar_Movable,
+ SH_FormLayoutFieldGrowthPolicy,
+ SH_FormLayoutFormAlignment,
+ SH_FormLayoutLabelAlignment,
+ SH_ItemView_DrawDelegateFrame,
+ SH_TabBar_CloseButtonPosition,
+ SH_DockWidget_ButtonsHaveFrame,
+ SH_ToolButtonStyle,
+ SH_RequestSoftwareInputPanel,
+ // Add new style hint values here
+
+#ifdef QT3_SUPPORT
+ SH_GUIStyle = 0x00000100,
+ SH_ScrollBar_BackgroundMode,
+ // Add other compat values here
+
+ SH_UnderlineAccelerator = SH_UnderlineShortcut,
+#endif
+ SH_CustomBase = 0xf0000000
+ };
+
+ virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = 0,
+ const QWidget *widget = 0, QStyleHintReturn* returnData = 0) const = 0;
+
+ enum StandardPixmap {
+ SP_TitleBarMenuButton,
+ SP_TitleBarMinButton,
+ SP_TitleBarMaxButton,
+ SP_TitleBarCloseButton,
+ SP_TitleBarNormalButton,
+ SP_TitleBarShadeButton,
+ SP_TitleBarUnshadeButton,
+ SP_TitleBarContextHelpButton,
+ SP_DockWidgetCloseButton,
+ SP_MessageBoxInformation,
+ SP_MessageBoxWarning,
+ SP_MessageBoxCritical,
+ SP_MessageBoxQuestion,
+ SP_DesktopIcon,
+ SP_TrashIcon,
+ SP_ComputerIcon,
+ SP_DriveFDIcon,
+ SP_DriveHDIcon,
+ SP_DriveCDIcon,
+ SP_DriveDVDIcon,
+ SP_DriveNetIcon,
+ SP_DirOpenIcon,
+ SP_DirClosedIcon,
+ SP_DirLinkIcon,
+ SP_FileIcon,
+ SP_FileLinkIcon,
+ SP_ToolBarHorizontalExtensionButton,
+ SP_ToolBarVerticalExtensionButton,
+ SP_FileDialogStart,
+ SP_FileDialogEnd,
+ SP_FileDialogToParent,
+ SP_FileDialogNewFolder,
+ SP_FileDialogDetailedView,
+ SP_FileDialogInfoView,
+ SP_FileDialogContentsView,
+ SP_FileDialogListView,
+ SP_FileDialogBack,
+ SP_DirIcon,
+ SP_DialogOkButton,
+ SP_DialogCancelButton,
+ SP_DialogHelpButton,
+ SP_DialogOpenButton,
+ SP_DialogSaveButton,
+ SP_DialogCloseButton,
+ SP_DialogApplyButton,
+ SP_DialogResetButton,
+ SP_DialogDiscardButton,
+ SP_DialogYesButton,
+ SP_DialogNoButton,
+ SP_ArrowUp,
+ SP_ArrowDown,
+ SP_ArrowLeft,
+ SP_ArrowRight,
+ SP_ArrowBack,
+ SP_ArrowForward,
+ SP_DirHomeIcon,
+ SP_CommandLink,
+ SP_VistaShield,
+ SP_BrowserReload,
+ SP_BrowserStop,
+ SP_MediaPlay,
+ SP_MediaStop,
+ SP_MediaPause,
+ SP_MediaSkipForward,
+ SP_MediaSkipBackward,
+ SP_MediaSeekForward,
+ SP_MediaSeekBackward,
+ SP_MediaVolume,
+ SP_MediaVolumeMuted,
+ // do not add any values below/greater than this
+ SP_CustomBase = 0xf0000000
+ };
+
+ virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const = 0;
+
+ QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+ virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const = 0;
+
+ static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect,
+ const QRect &logicalRect);
+ static QPoint visualPos(Qt::LayoutDirection direction, const QRect &boundingRect,
+ const QPoint &logicalPos);
+ static int sliderPositionFromValue(int min, int max, int val, int space,
+ bool upsideDown = false);
+ static int sliderValueFromPosition(int min, int max, int pos, int space,
+ bool upsideDown = false);
+ static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment);
+ static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment,
+ const QSize &size, const QRect &rectangle);
+
+ int layoutSpacing(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2, Qt::Orientation orientation,
+ const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ int combinedLayoutSpacing(QSizePolicy::ControlTypes controls1,
+ QSizePolicy::ControlTypes controls2, Qt::Orientation orientation,
+ QStyleOption *option = 0, QWidget *widget = 0) const;
+
+ const QStyle * proxy() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QStyle)
+ friend class QWidget;
+ friend class QWidgetPrivate;
+ friend class QApplication;
+ friend class QProxyStyle;
+ friend class QProxyStylePrivate;
+ void setProxy(QStyle *style);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls)
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, QStyle::State state);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLE_H
diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
new file mode 100644
index 0000000000..8654e66a37
--- /dev/null
+++ b/src/widgets/styles/qstyle.qrc
@@ -0,0 +1,135 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/styles/commonstyle">
+<file>images/filelink-16.png</file>
+<file>images/filelink-32.png</file>
+<file>images/filelink-128.png</file>
+<file>images/file-16.png</file>
+<file>images/file-32.png</file>
+<file>images/file-128.png</file>
+<file>images/newdirectory-16.png</file>
+<file>images/newdirectory-32.png</file>
+<file>images/newdirectory-128.png</file>
+<file>images/parentdir-16.png</file>
+<file>images/parentdir-32.png</file>
+<file>images/parentdir-128.png</file>
+<file>images/dvd-16.png</file>
+<file>images/dvd-32.png</file>
+<file>images/dvd-128.png</file>
+<file>images/cdr-16.png</file>
+<file>images/cdr-32.png</file>
+<file>images/cdr-128.png</file>
+<file>images/floppy-16.png</file>
+<file>images/floppy-32.png</file>
+<file>images/floppy-128.png</file>
+<file>images/harddrive-16.png</file>
+<file>images/harddrive-32.png</file>
+<file>images/harddrive-128.png</file>
+<file>images/trash-16.png</file>
+<file>images/trash-32.png</file>
+<file>images/trash-128.png</file>
+<file>images/networkdrive-16.png</file>
+<file>images/networkdrive-32.png</file>
+<file>images/networkdrive-128.png</file>
+<file>images/computer-16.png</file>
+<file>images/computer-32.png</file>
+<file>images/desktop-16.png</file>
+<file>images/desktop-32.png</file>
+<file>images/dirclosed-16.png</file>
+<file>images/dirclosed-32.png</file>
+<file>images/dirclosed-128.png</file>
+<file>images/dirlink-16.png</file>
+<file>images/dirlink-32.png</file>
+<file>images/dirlink-128.png</file>
+<file>images/diropen-16.png</file>
+<file>images/diropen-32.png</file>
+<file>images/diropen-128.png</file>
+<file>images/left-16.png</file>
+<file>images/left-32.png</file>
+<file>images/left-128.png</file>
+<file>images/right-16.png</file>
+<file>images/right-32.png</file>
+<file>images/right-128.png</file>
+<file>images/up-16.png</file>
+<file>images/up-32.png</file>
+<file>images/up-128.png</file>
+<file>images/down-16.png</file>
+<file>images/down-32.png</file>
+<file>images/down-128.png</file>
+<file>images/filecontents-16.png</file>
+<file>images/filecontents-32.png</file>
+<file>images/filecontents-128.png</file>
+<file>images/fileinfo-16.png</file>
+<file>images/fileinfo-32.png</file>
+<file>images/fileinfo-128.png</file>
+<file>images/viewdetailed-16.png</file>
+<file>images/viewdetailed-32.png</file>
+<file>images/viewdetailed-128.png</file>
+<file>images/viewlist-16.png</file>
+<file>images/viewlist-32.png</file>
+<file>images/viewlist-128.png</file>
+<file>images/fontbitmap-16.png</file>
+<file>images/fonttruetype-16.png</file>
+<file>images/standardbutton-apply-128.png</file>
+<file>images/standardbutton-apply-16.png</file>
+<file>images/standardbutton-apply-32.png</file>
+<file>images/standardbutton-cancel-128.png</file>
+<file>images/standardbutton-cancel-16.png</file>
+<file>images/standardbutton-cancel-32.png</file>
+<file>images/standardbutton-clear-128.png</file>
+<file>images/standardbutton-clear-16.png</file>
+<file>images/standardbutton-clear-32.png</file>
+<file>images/standardbutton-close-128.png</file>
+<file>images/standardbutton-close-16.png</file>
+<file>images/standardbutton-close-32.png</file>
+<file>images/standardbutton-delete-128.png</file>
+<file>images/standardbutton-delete-16.png</file>
+<file>images/standardbutton-delete-32.png</file>
+<file>images/standardbutton-help-128.png</file>
+<file>images/standardbutton-help-16.png</file>
+<file>images/standardbutton-help-32.png</file>
+<file>images/standardbutton-no-128.png</file>
+<file>images/standardbutton-no-16.png</file>
+<file>images/standardbutton-no-32.png</file>
+<file>images/standardbutton-ok-128.png</file>
+<file>images/standardbutton-ok-16.png</file>
+<file>images/standardbutton-ok-32.png</file>
+<file>images/standardbutton-open-128.png</file>
+<file>images/standardbutton-open-16.png</file>
+<file>images/standardbutton-open-32.png</file>
+<file>images/standardbutton-save-128.png</file>
+<file>images/standardbutton-save-16.png</file>
+<file>images/standardbutton-save-32.png</file>
+<file>images/standardbutton-yes-128.png</file>
+<file>images/standardbutton-yes-16.png</file>
+<file>images/standardbutton-yes-32.png</file>
+<file>images/standardbutton-closetab-16.png</file>
+<file>images/standardbutton-closetab-down-16.png</file>
+<file>images/standardbutton-closetab-hover-16.png</file>
+<file>images/refresh-24.png</file>
+<file>images/refresh-32.png</file>
+<file>images/stop-24.png</file>
+<file>images/stop-32.png</file>
+<file>images/media-stop-16.png</file>
+<file>images/media-stop-32.png</file>
+<file>images/media-play-16.png</file>
+<file>images/media-play-32.png</file>
+<file>images/media-pause-16.png</file>
+<file>images/media-pause-32.png</file>
+<file>images/media-seek-forward-16.png</file>
+<file>images/media-seek-forward-32.png</file>
+<file>images/media-seek-backward-16.png</file>
+<file>images/media-seek-backward-32.png</file>
+<file>images/media-skip-forward-16.png</file>
+<file>images/media-skip-forward-32.png</file>
+<file>images/media-skip-backward-16.png</file>
+<file>images/media-skip-backward-32.png</file>
+<file>images/media-volume-16.png</file>
+<file>images/media-volume-muted-16.png</file>
+</qresource>
+<qresource prefix="/trolltech/styles/macstyle">
+<file>images/closedock-16.png</file>
+<file>images/closedock-down-16.png</file>
+<file>images/dockdock-16.png</file>
+<file>images/dockdock-down-16.png</file>
+</qresource>
+</RCC>
diff --git a/src/widgets/styles/qstyle_p.h b/src/widgets/styles/qstyle_p.h
new file mode 100644
index 0000000000..dfb0e95731
--- /dev/null
+++ b/src/widgets/styles/qstyle_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLE_P_H
+#define QSTYLE_P_H
+
+#include "private/qobject_p.h"
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qstyle_*.cpp. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+// Private class
+
+class QStyle;
+
+class QStylePrivate: public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QStyle)
+public:
+ inline QStylePrivate()
+ : layoutSpacingIndex(-1), proxyStyle(0) {}
+ mutable int layoutSpacingIndex;
+ QStyle *proxyStyle;
+};
+
+
+#define BEGIN_STYLE_PIXMAPCACHE(a) \
+ QRect rect = option->rect; \
+ QPixmap internalPixmapCache; \
+ QImage imageCache; \
+ QPainter *p = painter; \
+ QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
+ int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
+ bool doPixmapCache = txType <= QTransform::TxTranslate; \
+ if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \
+ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
+ } else { \
+ if (doPixmapCache) { \
+ rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
+ imageCache = QImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); \
+ imageCache.fill(0); \
+ p = new QPainter(&imageCache); \
+ }
+
+
+
+#define END_STYLE_PIXMAPCACHE \
+ if (doPixmapCache) { \
+ p->end(); \
+ delete p; \
+ internalPixmapCache = QPixmap::fromImage(imageCache); \
+ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
+ QPixmapCache::insert(unique, internalPixmapCache); \
+ } \
+ }
+
+QT_END_NAMESPACE
+
+#endif //QSTYLE_P_H
diff --git a/src/widgets/styles/qstyle_s60.qrc b/src/widgets/styles/qstyle_s60.qrc
new file mode 100644
index 0000000000..dbee38b266
--- /dev/null
+++ b/src/widgets/styles/qstyle_s60.qrc
@@ -0,0 +1,137 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/styles/commonstyle">
+<!-- <file>images/filelink-16.png</file> -->
+<file>images/filelink-32.png</file>
+<!-- <file>images/filelink-128.png</file> -->
+<!-- <file>images/file-16.png</file> -->
+<file>images/file-32.png</file>
+<!-- <file>images/file-128.png</file> -->
+<!-- <file>images/newdirectory-16.png</file> -->
+<file>images/newdirectory-32.png</file>
+<!-- <file>images/newdirectory-128.png</file> -->
+<!-- <file>images/parentdir-16.png</file> -->
+<file>images/parentdir-32.png</file>
+<!-- <file>images/parentdir-128.png</file> -->
+<!-- <file>images/dvd-16.png</file> -->
+<!-- <file>images/dvd-32.png</file> -->
+<!-- <file>images/dvd-128.png</file> -->
+<!-- <file>images/cdr-16.png</file> -->
+<!-- <file>images/cdr-32.png</file> -->
+<!-- <file>images/cdr-128.png</file> -->
+<!-- <file>images/floppy-16.png</file> -->
+<!-- <file>images/floppy-32.png</file> -->
+<!-- <file>images/floppy-128.png</file> -->
+<!-- <file>images/harddrive-16.png</file> -->
+<file>images/harddrive-32.png</file>
+<!-- <file>images/harddrive-128.png</file> -->
+<!-- <file>images/trash-16.png</file> -->
+<!-- <file>images/trash-32.png</file> -->
+<!-- <file>images/trash-128.png</file> -->
+<!-- <file>images/networkdrive-16.png</file> -->
+<!-- <file>images/networkdrive-32.png</file> -->
+<!-- <file>images/networkdrive-128.png</file> -->
+<!-- <file>images/computer-16.png</file> -->
+<!-- <file>images/computer-32.png</file> -->
+<!-- <file>images/desktop-16.png</file> -->
+<file>images/desktop-32.png</file>
+<!-- <file>images/dirclosed-16.png</file> -->
+<file>images/dirclosed-32.png</file>
+<!-- <file>images/dirclosed-128.png</file> -->
+<!-- <file>images/dirlink-16.png</file> -->
+<file>images/dirlink-32.png</file>
+<!-- <file>images/dirlink-128.png</file> -->
+<!-- <file>images/diropen-16.png</file> -->
+<file>images/diropen-32.png</file>
+<!-- <file>images/diropen-128.png</file> -->
+<!-- <file>images/left-16.png</file> -->
+<file>images/left-32.png</file>
+<!-- <file>images/left-128.png</file> -->
+<!-- <file>images/right-16.png</file> -->
+<file>images/right-32.png</file>
+<!-- <file>images/right-128.png</file> -->
+<!-- <file>images/up-16.png</file> -->
+<file>images/up-32.png</file>
+<!-- <file>images/up-128.png</file> -->
+<!-- <file>images/down-16.png</file> -->
+<file>images/down-32.png</file>
+<!-- <file>images/down-128.png</file> -->
+<!-- <file>images/filecontents-16.png</file> -->
+<file>images/filecontents-32.png</file>
+<!-- <file>images/filecontents-128.png</file> -->
+<!-- <file>images/fileinfo-16.png</file> -->
+<file>images/fileinfo-32.png</file>
+<!-- <file>images/fileinfo-128.png</file> -->
+<!-- <file>images/viewdetailed-16.png</file> -->
+<file>images/viewdetailed-32.png</file>
+<!-- <file>images/viewdetailed-128.png</file> -->
+<!-- <file>images/viewlist-16.png</file> -->
+<file>images/viewlist-32.png</file>
+<!-- <file>images/viewlist-128.png</file> -->
+<file>images/fontbitmap-16.png</file>
+<file>images/fonttruetype-16.png</file>
+<!-- <file>images/standardbutton-apply-128.png</file> -->
+<!-- <file>images/standardbutton-apply-16.png</file> -->
+<file>images/standardbutton-apply-32.png</file>
+<!-- <file>images/standardbutton-cancel-128.png</file> -->
+<!-- <file>images/standardbutton-cancel-16.png</file> -->
+<file>images/standardbutton-cancel-32.png</file>
+<!-- <file>images/standardbutton-clear-128.png</file> -->
+<!-- <file>images/standardbutton-clear-16.png</file> -->
+<file>images/standardbutton-clear-32.png</file>
+<!-- <file>images/standardbutton-close-128.png</file> -->
+<!-- <file>images/standardbutton-close-16.png</file> -->
+<file>images/standardbutton-close-32.png</file>
+<!-- <file>images/standardbutton-delete-128.png</file> -->
+<!-- <file>images/standardbutton-delete-16.png</file> -->
+<file>images/standardbutton-delete-32.png</file>
+<!-- <file>images/standardbutton-help-128.png</file> -->
+<!-- <file>images/standardbutton-help-16.png</file> -->
+<file>images/standardbutton-help-32.png</file>
+<!-- <file>images/standardbutton-no-128.png</file> -->
+<!-- <file>images/standardbutton-no-16.png</file> -->
+<file>images/standardbutton-no-32.png</file>
+<!-- <file>images/standardbutton-ok-128.png</file> -->
+<!-- <file>images/standardbutton-ok-16.png</file> -->
+<file>images/standardbutton-ok-32.png</file>
+<!-- <file>images/standardbutton-open-128.png</file> -->
+<!-- <file>images/standardbutton-open-16.png</file> -->
+<file>images/standardbutton-open-32.png</file>
+<!-- <file>images/standardbutton-save-128.png</file> -->
+<!-- <file>images/standardbutton-save-16.png</file> -->
+<file>images/standardbutton-save-32.png</file>
+<!-- <file>images/standardbutton-yes-128.png</file> -->
+<!-- <file>images/standardbutton-yes-16.png</file> -->
+<file>images/standardbutton-yes-32.png</file>
+<file>images/standardbutton-closetab-16.png</file>
+<file>images/standardbutton-closetab-down-16.png</file>
+<file>images/standardbutton-closetab-hover-16.png</file>
+<!-- <file>images/refresh-24.png</file> -->
+<file>images/refresh-32.png</file>
+<!-- <file>images/stop-24.png</file> -->
+<file>images/stop-32.png</file>
+<!-- <file>images/media-stop-16.png</file> -->
+<file>images/media-stop-32.png</file>
+<!-- <file>images/media-play-16.png</file> -->
+<file>images/media-play-32.png</file>
+<!-- <file>images/media-pause-16.png</file> -->
+<file>images/media-pause-32.png</file>
+<!-- <file>images/media-seek-forward-16.png</file> -->
+<file>images/media-seek-forward-32.png</file>
+<!-- <file>images/media-seek-backward-16.png</file> -->
+<file>images/media-seek-backward-32.png</file>
+<!-- <file>images/media-skip-forward-16.png</file> -->
+<file>images/media-skip-forward-32.png</file>
+<!-- <file>images/media-skip-backward-16.png</file> -->
+<file>images/media-skip-backward-32.png</file>
+<file>images/media-volume-16.png</file>
+<file>images/media-volume-muted-16.png</file>
+</qresource>
+<!--
+<qresource prefix="/trolltech/styles/macstyle">
+<file>images/closedock-16.png</file>
+<file>images/closedock-down-16.png</file>
+<file>images/dockdock-16.png</file>
+<file>images/dockdock-down-16.png</file>
+</qresource>
+-->
+</RCC>
diff --git a/src/widgets/styles/qstyle_s60_simulated.qrc b/src/widgets/styles/qstyle_s60_simulated.qrc
new file mode 100644
index 0000000000..969732e1e0
--- /dev/null
+++ b/src/widgets/styles/qstyle_s60_simulated.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource prefix="/trolltech/styles/s60style">
+ <file>images/defaults60theme.blob</file>
+ </qresource>
+</RCC>
diff --git a/src/widgets/styles/qstyle_wince.qrc b/src/widgets/styles/qstyle_wince.qrc
new file mode 100644
index 0000000000..bdcf604625
--- /dev/null
+++ b/src/widgets/styles/qstyle_wince.qrc
@@ -0,0 +1,97 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/styles/commonstyle">
+<file>images/filelink-16.png</file>
+<file>images/filelink-32.png</file>
+<file>images/file-16.png</file>
+<file>images/file-32.png</file>
+<file>images/newdirectory-16.png</file>
+<file>images/newdirectory-32.png</file>
+<file>images/parentdir-16.png</file>
+<file>images/parentdir-32.png</file>
+<file>images/dvd-16.png</file>
+<file>images/dvd-32.png</file>
+<file>images/cdr-16.png</file>
+<file>images/cdr-32.png</file>
+<file>images/floppy-16.png</file>
+<file>images/floppy-32.png</file>
+<file>images/harddrive-16.png</file>
+<file>images/harddrive-32.png</file>
+<file>images/trash-16.png</file>
+<file>images/trash-32.png</file>
+<file>images/networkdrive-16.png</file>
+<file>images/networkdrive-32.png</file>
+<file>images/computer-16.png</file>
+<file>images/computer-32.png</file>
+<file>images/desktop-16.png</file>
+<file>images/desktop-32.png</file>
+<file>images/dirclosed-16.png</file>
+<file>images/dirclosed-32.png</file>
+<file>images/dirlink-16.png</file>
+<file>images/dirlink-32.png</file>
+<file>images/diropen-16.png</file>
+<file>images/diropen-32.png</file>
+<file>images/left-16.png</file>
+<file>images/left-32.png</file>
+<file>images/right-16.png</file>
+<file>images/right-32.png</file>
+<file>images/up-16.png</file>
+<file>images/up-32.png</file>
+<file>images/down-16.png</file>
+<file>images/down-32.png</file>
+<file>images/filecontents-16.png</file>
+<file>images/filecontents-32.png</file>
+<file>images/fileinfo-16.png</file>
+<file>images/fileinfo-32.png</file>
+<file>images/viewdetailed-16.png</file>
+<file>images/viewdetailed-32.png</file>
+<file>images/viewlist-16.png</file>
+<file>images/viewlist-32.png</file>
+<file>images/fontbitmap-16.png</file>
+<file>images/fonttruetype-16.png</file>
+<file>images/standardbutton-apply-16.png</file>
+<file>images/standardbutton-apply-32.png</file>
+<file>images/standardbutton-cancel-16.png</file>
+<file>images/standardbutton-cancel-32.png</file>
+<file>images/standardbutton-clear-16.png</file>
+<file>images/standardbutton-clear-32.png</file>
+<file>images/standardbutton-close-16.png</file>
+<file>images/standardbutton-close-32.png</file>
+<file>images/standardbutton-delete-16.png</file>
+<file>images/standardbutton-delete-32.png</file>
+<file>images/standardbutton-help-16.png</file>
+<file>images/standardbutton-help-32.png</file>
+<file>images/standardbutton-no-16.png</file>
+<file>images/standardbutton-no-32.png</file>
+<file>images/standardbutton-ok-16.png</file>
+<file>images/standardbutton-ok-32.png</file>
+<file>images/standardbutton-open-16.png</file>
+<file>images/standardbutton-open-32.png</file>
+<file>images/standardbutton-save-16.png</file>
+<file>images/standardbutton-save-32.png</file>
+<file>images/standardbutton-yes-16.png</file>
+<file>images/standardbutton-yes-32.png</file>
+<file>images/standardbutton-closetab-16.png</file>
+<file>images/standardbutton-closetab-down-16.png</file>
+<file>images/standardbutton-closetab-hover-16.png</file>
+<file>images/refresh-24.png</file>
+<file>images/refresh-32.png</file>
+<file>images/stop-24.png</file>
+<file>images/stop-32.png</file>
+<file>images/media-stop-16.png</file>
+<file>images/media-stop-32.png</file>
+<file>images/media-play-16.png</file>
+<file>images/media-play-32.png</file>
+<file>images/media-pause-16.png</file>
+<file>images/media-pause-32.png</file>
+<file>images/media-seek-forward-16.png</file>
+<file>images/media-seek-forward-32.png</file>
+<file>images/media-seek-backward-16.png</file>
+<file>images/media-seek-backward-32.png</file>
+<file>images/media-skip-forward-16.png</file>
+<file>images/media-skip-forward-32.png</file>
+<file>images/media-skip-backward-16.png</file>
+<file>images/media-skip-backward-32.png</file>
+<file>images/media-volume-16.png</file>
+<file>images/media-volume-muted-16.png</file>
+</qresource>
+</RCC>
diff --git a/src/widgets/styles/qstylefactory.cpp b/src/widgets/styles/qstylefactory.cpp
new file mode 100644
index 0000000000..83b67484b8
--- /dev/null
+++ b/src/widgets/styles/qstylefactory.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstylefactory.h"
+#include "qstyleplugin.h"
+#include "private/qfactoryloader_p.h"
+#include "qmutex.h"
+
+#include "qapplication.h"
+#include "qwindowsstyle.h"
+#include "qmotifstyle.h"
+#include "qcdestyle.h"
+#ifndef QT_NO_STYLE_PLASTIQUE
+#include "qplastiquestyle.h"
+#endif
+#ifndef QT_NO_STYLE_CLEANLOOKS
+#include "qcleanlooksstyle.h"
+#endif
+#ifndef QT_NO_STYLE_GTK
+#include "qgtkstyle.h"
+#endif
+#ifndef QT_NO_STYLE_WINDOWSXP
+#include "qwindowsxpstyle.h"
+#endif
+#ifndef QT_NO_STYLE_WINDOWSVISTA
+#include "qwindowsvistastyle.h"
+#endif
+#ifndef QT_NO_STYLE_WINDOWSCE
+#include "qwindowscestyle.h"
+#endif
+#ifndef QT_NO_STYLE_WINDOWSMOBILE
+#include "qwindowsmobilestyle.h"
+#endif
+#ifndef QT_NO_STYLE_S60
+#include "qs60style.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_STYLE_MAC) && defined(Q_WS_MAC)
+QT_BEGIN_INCLUDE_NAMESPACE
+# include "qmacstyle_mac.h"
+QT_END_INCLUDE_NAMESPACE
+#endif
+
+#ifndef QT_NO_LIBRARY
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QStyleFactoryInterface_iid, QLatin1String("/styles"), Qt::CaseInsensitive))
+#endif
+
+/*!
+ \class QStyleFactory
+ \brief The QStyleFactory class creates QStyle objects.
+
+ \ingroup appearance
+
+ The QStyle class is an abstract base class that encapsulates the
+ look and feel of a GUI. QStyleFactory creates a QStyle object
+ using the create() function and a key identifying the style. The
+ styles are either built-in or dynamically loaded from a style
+ plugin (see QStylePlugin).
+
+ The valid keys can be retrieved using the keys()
+ function. Typically they include "windows", "motif", "cde",
+ "plastique" and "cleanlooks". Depending on the platform,
+ "windowsxp", "windowsvista" and "macintosh" may be available.
+ Note that keys are case insensitive.
+
+ \sa QStyle
+*/
+
+/*!
+ Creates and returns a QStyle object that matches the given \a key, or
+ returns 0 if no matching style is found.
+
+ Both built-in styles and styles from style plugins are queried for a
+ matching style.
+
+ \note The keys used are case insensitive.
+
+ \sa keys()
+*/
+QStyle *QStyleFactory::create(const QString& key)
+{
+ QStyle *ret = 0;
+ QString style = key.toLower();
+#ifndef QT_NO_STYLE_WINDOWS
+ if (style == QLatin1String("windows"))
+ ret = new QWindowsStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_WINDOWSCE
+ if (style == QLatin1String("windowsce"))
+ ret = new QWindowsCEStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_WINDOWSMOBILE
+ if (style == QLatin1String("windowsmobile"))
+ ret = new QWindowsMobileStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_WINDOWSXP
+ if (style == QLatin1String("windowsxp"))
+ ret = new QWindowsXPStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_WINDOWSVISTA
+ if (style == QLatin1String("windowsvista"))
+ ret = new QWindowsVistaStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_MOTIF
+ if (style == QLatin1String("motif"))
+ ret = new QMotifStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_CDE
+ if (style == QLatin1String("cde"))
+ ret = new QCDEStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_S60
+ if (style == QLatin1String("s60"))
+ ret = new QS60Style;
+ else
+#endif
+#ifndef QT_NO_STYLE_PLASTIQUE
+ if (style == QLatin1String("plastique"))
+ ret = new QPlastiqueStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_CLEANLOOKS
+ if (style == QLatin1String("cleanlooks"))
+ ret = new QCleanlooksStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_GTK
+ if (style == QLatin1String("gtk") || style == QLatin1String("gtk+"))
+ ret = new QGtkStyle;
+ else
+#endif
+#ifndef QT_NO_STYLE_MAC
+ if (style.startsWith(QLatin1String("macintosh"))) {
+ ret = new QMacStyle;
+# ifdef Q_WS_MAC
+ if (style == QLatin1String("macintosh"))
+ style += QLatin1String(" (aqua)");
+# endif
+ } else
+#endif
+ { } // Keep these here - they make the #ifdefery above work
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ if(!ret) {
+ if (QStyleFactoryInterface *factory = qobject_cast<QStyleFactoryInterface*>(loader()->instance(style)))
+ ret = factory->create(style);
+ }
+#endif
+ if(ret)
+ ret->setObjectName(style);
+ return ret;
+}
+
+/*!
+ Returns the list of valid keys, i.e. the keys this factory can
+ create styles for.
+
+ \sa create()
+*/
+QStringList QStyleFactory::keys()
+{
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QStringList list = loader()->keys();
+#else
+ QStringList list;
+#endif
+#ifndef QT_NO_STYLE_WINDOWS
+ if (!list.contains(QLatin1String("Windows")))
+ list << QLatin1String("Windows");
+#endif
+#ifndef QT_NO_STYLE_WINDOWSCE
+ if (!list.contains(QLatin1String("WindowsCE")))
+ list << QLatin1String("WindowsCE");
+#endif
+#ifndef QT_NO_STYLE_WINDOWSMOBILE
+ if (!list.contains(QLatin1String("WindowsMobile")))
+ list << QLatin1String("WindowsMobile");
+#endif
+#ifndef QT_NO_STYLE_WINDOWSXP
+ if (!list.contains(QLatin1String("WindowsXP")) &&
+ (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ list << QLatin1String("WindowsXP");
+#endif
+#ifndef QT_NO_STYLE_WINDOWSVISTA
+ if (!list.contains(QLatin1String("WindowsVista")) &&
+ (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ list << QLatin1String("WindowsVista");
+#endif
+#ifndef QT_NO_STYLE_MOTIF
+ if (!list.contains(QLatin1String("Motif")))
+ list << QLatin1String("Motif");
+#endif
+#ifndef QT_NO_STYLE_CDE
+ if (!list.contains(QLatin1String("CDE")))
+ list << QLatin1String("CDE");
+#endif
+#ifndef QT_NO_STYLE_S60
+ if (!list.contains(QLatin1String("S60")))
+ list << QLatin1String("S60");
+#endif
+#ifndef QT_NO_STYLE_PLASTIQUE
+ if (!list.contains(QLatin1String("Plastique")))
+ list << QLatin1String("Plastique");
+#endif
+#ifndef QT_NO_STYLE_GTK
+ if (!list.contains(QLatin1String("GTK+")))
+ list << QLatin1String("GTK+");
+#endif
+#ifndef QT_NO_STYLE_CLEANLOOKS
+ if (!list.contains(QLatin1String("Cleanlooks")))
+ list << QLatin1String("Cleanlooks");
+#endif
+#ifndef QT_NO_STYLE_MAC
+ QString mstyle = QLatin1String("Macintosh");
+# ifdef Q_WS_MAC
+ mstyle += QLatin1String(" (aqua)");
+# endif
+ if (!list.contains(mstyle))
+ list << mstyle;
+#endif
+ return list;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstylefactory.h b/src/widgets/styles/qstylefactory.h
new file mode 100644
index 0000000000..92bd24fddb
--- /dev/null
+++ b/src/widgets/styles/qstylefactory.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEFACTORY_H
+#define QSTYLEFACTORY_H
+
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyle;
+
+class Q_GUI_EXPORT QStyleFactory
+{
+public:
+ static QStringList keys();
+ static QStyle *create(const QString&);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEFACTORY_H
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
new file mode 100644
index 0000000000..bf7cb49bcf
--- /dev/null
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qstyleoption.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <private/qmath_p.h>
+#include <private/qstyle_p.h>
+#include <qmath.h>
+
+#if defined(Q_WS_WIN)
+#include "qt_windows.h"
+#elif defined(Q_WS_MAC)
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+#include "qstylehelper_p.h"
+#include <qstringbuilder.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QStyleHelper {
+
+QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
+{
+ const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
+ QString tmp = key % HexString<uint>(option->state)
+ % HexString<uint>(option->direction)
+ % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u)
+ % HexString<quint64>(option->palette.cacheKey())
+ % HexString<uint>(size.width())
+ % HexString<uint>(size.height());
+
+#ifndef QT_NO_SPINBOX
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ tmp = tmp % HexString<uint>(spinBox->buttonSymbols)
+ % HexString<uint>(spinBox->stepEnabled)
+ % QLatin1Char(spinBox->frame ? '1' : '0'); ;
+ }
+#endif // QT_NO_SPINBOX
+ return tmp;
+}
+
+qreal dpiScaled(qreal value)
+{
+ static qreal scale = -1;
+ if (scale < 0) {
+ scale = 1.0;
+#if defined(Q_WS_WIN)
+ {
+ HDC hdcScreen = GetDC(0);
+ int dpi = GetDeviceCaps(hdcScreen, LOGPIXELSX);
+ ReleaseDC(0, hdcScreen);
+ scale = dpi/96.0;
+ }
+#elif defined(Q_WS_MAC)
+ scale = qt_mac_get_scalefactor();
+#endif
+ }
+ return value * scale;
+}
+
+
+#ifndef QT_NO_DIAL
+
+int calcBigLineSize(int radius)
+{
+ int bigLineSize = radius / 6;
+ if (bigLineSize < 4)
+ bigLineSize = 4;
+ if (bigLineSize > radius / 2)
+ bigLineSize = radius / 2;
+ return bigLineSize;
+}
+
+static QPointF calcRadialPos(const QStyleOptionSlider *dial, qreal offset)
+{
+ const int width = dial->rect.width();
+ const int height = dial->rect.height();
+ const int r = qMin(width, height) / 2;
+ const int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
+ qreal a = 0;
+ if (dial->maximum == dial->minimum)
+ a = Q_PI / 2;
+ else if (dial->dialWrapping)
+ a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI
+ / (dial->maximum - dial->minimum);
+ else
+ a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI
+ / (dial->maximum - dial->minimum)) / 6;
+ qreal xc = width / 2.0;
+ qreal yc = height / 2.0;
+ qreal len = r - QStyleHelper::calcBigLineSize(r) - 3;
+ qreal back = offset * len;
+ QPointF pos(QPointF(xc + back * qCos(a), yc - back * qSin(a)));
+ return pos;
+}
+
+qreal angle(const QPointF &p1, const QPointF &p2)
+{
+ static const qreal rad_factor = 180 / Q_PI;
+ qreal _angle = 0;
+
+ if (p1.x() == p2.x()) {
+ if (p1.y() < p2.y())
+ _angle = 270;
+ else
+ _angle = 90;
+ } else {
+ qreal x1, x2, y1, y2;
+
+ if (p1.x() <= p2.x()) {
+ x1 = p1.x(); y1 = p1.y();
+ x2 = p2.x(); y2 = p2.y();
+ } else {
+ x2 = p1.x(); y2 = p1.y();
+ x1 = p2.x(); y1 = p2.y();
+ }
+
+ qreal m = -(y2 - y1) / (x2 - x1);
+ _angle = qAtan(m) * rad_factor;
+
+ if (p1.x() < p2.x())
+ _angle = 180 - _angle;
+ else
+ _angle = -_angle;
+ }
+ return _angle;
+}
+
+QPolygonF calcLines(const QStyleOptionSlider *dial)
+{
+ QPolygonF poly;
+ int width = dial->rect.width();
+ int height = dial->rect.height();
+ qreal r = qMin(width, height) / 2;
+ int bigLineSize = calcBigLineSize(int(r));
+
+ qreal xc = width / 2 + 0.5;
+ qreal yc = height / 2 + 0.5;
+ int ns = dial->tickInterval;
+ int notches = (dial->maximum + ns - 1 - dial->minimum) / ns;
+ if (notches <= 0)
+ return poly;
+ if (dial->maximum < dial->minimum || dial->maximum - dial->minimum > 1000) {
+ int maximum = dial->minimum + 1000;
+ notches = (maximum + ns - 1 - dial->minimum) / ns;
+ }
+
+ poly.resize(2 + 2 * notches);
+ int smallLineSize = bigLineSize / 2;
+ for (int i = 0; i <= notches; ++i) {
+ qreal angle = dial->dialWrapping ? Q_PI * 3 / 2 - i * 2 * Q_PI / notches
+ : (Q_PI * 8 - i * 10 * Q_PI / notches) / 6;
+ qreal s = qSin(angle);
+ qreal c = qCos(angle);
+ if (i == 0 || (((ns * i) % (dial->pageStep ? dial->pageStep : 1)) == 0)) {
+ poly[2 * i] = QPointF(xc + (r - bigLineSize) * c,
+ yc - (r - bigLineSize) * s);
+ poly[2 * i + 1] = QPointF(xc + r * c, yc - r * s);
+ } else {
+ poly[2 * i] = QPointF(xc + (r - 1 - smallLineSize) * c,
+ yc - (r - 1 - smallLineSize) * s);
+ poly[2 * i + 1] = QPointF(xc + (r - 1) * c, yc -(r - 1) * s);
+ }
+ }
+ return poly;
+}
+
+// This will draw a nice and shiny QDial for us. We don't want
+// all the shinyness in QWindowsStyle, hence we place it here
+
+void drawDial(const QStyleOptionSlider *option, QPainter *painter)
+{
+ QPalette pal = option->palette;
+ QColor buttonColor = pal.button().color();
+ const int width = option->rect.width();
+ const int height = option->rect.height();
+ const bool enabled = option->state & QStyle::State_Enabled;
+ qreal r = qMin(width, height) / 2;
+ r -= r/50;
+ const qreal penSize = r/20.0;
+
+ painter->save();
+ painter->setRenderHint(QPainter::Antialiasing);
+
+ // Draw notches
+ if (option->subControls & QStyle::SC_DialTickmarks) {
+ painter->setPen(option->palette.dark().color().darker(120));
+ painter->drawLines(QStyleHelper::calcLines(option));
+ }
+
+ // Cache dial background
+ BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial"));
+ p->setRenderHint(QPainter::Antialiasing);
+
+ const qreal d_ = r / 6;
+ const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1;
+ const qreal dy = option->rect.y() + d_ + (height - 2 * r) / 2 + 1;
+
+ QRectF br = QRectF(dx + 0.5, dy + 0.5,
+ int(r * 2 - 2 * d_ - 2),
+ int(r * 2 - 2 * d_ - 2));
+ buttonColor.setHsv(buttonColor .hue(),
+ qMin(140, buttonColor .saturation()),
+ qMax(180, buttonColor.value()));
+ QColor shadowColor(0, 0, 0, 20);
+
+ if (enabled) {
+ // Drop shadow
+ qreal shadowSize = qMax(1.0, penSize/2.0);
+ QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize,
+ 2*shadowSize, 2*shadowSize);
+ QRadialGradient shadowGradient(shadowRect.center().x(),
+ shadowRect.center().y(), shadowRect.width()/2.0,
+ shadowRect.center().x(), shadowRect.center().y());
+ shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40));
+ shadowGradient.setColorAt(qreal(1.0), Qt::transparent);
+ p->setBrush(shadowGradient);
+ p->setPen(Qt::NoPen);
+ p->translate(shadowSize, shadowSize);
+ p->drawEllipse(shadowRect);
+ p->translate(-shadowSize, -shadowSize);
+
+ // Main gradient
+ QRadialGradient gradient(br.center().x() - br.width()/3, dy,
+ br.width()*1.3, br.center().x(),
+ br.center().y() - br.height()/2);
+ gradient.setColorAt(0, buttonColor.lighter(110));
+ gradient.setColorAt(qreal(0.5), buttonColor);
+ gradient.setColorAt(qreal(0.501), buttonColor.darker(102));
+ gradient.setColorAt(1, buttonColor.darker(115));
+ p->setBrush(gradient);
+ } else {
+ p->setBrush(Qt::NoBrush);
+ }
+
+ p->setPen(QPen(buttonColor.darker(280)));
+ p->drawEllipse(br);
+ p->setBrush(Qt::NoBrush);
+ p->setPen(buttonColor.lighter(110));
+ p->drawEllipse(br.adjusted(1, 1, -1, -1));
+
+ if (option->state & QStyle::State_HasFocus) {
+ QColor highlight = pal.highlight().color();
+ highlight.setHsv(highlight.hue(),
+ qMin(160, highlight.saturation()),
+ qMax(230, highlight.value()));
+ highlight.setAlpha(127);
+ p->setPen(QPen(highlight, 2.0));
+ p->setBrush(Qt::NoBrush);
+ p->drawEllipse(br.adjusted(-1, -1, 1, 1));
+ }
+
+ END_STYLE_PIXMAPCACHE
+
+ QPointF dp = calcRadialPos(option, qreal(0.70));
+ buttonColor = buttonColor.lighter(104);
+ buttonColor.setAlphaF(qreal(0.8));
+ const qreal ds = r/qreal(7.0);
+ QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds);
+ QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2,
+ dialRect.center().y() + dialRect.width(),
+ dialRect.width()*2,
+ dialRect.center().x(), dialRect.center().y());
+ dialGradient.setColorAt(1, buttonColor.darker(140));
+ dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120));
+ dialGradient.setColorAt(0, buttonColor.darker(110));
+ if (penSize > 3.0) {
+ painter->setPen(QPen(QColor(0, 0, 0, 25), penSize));
+ painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96)));
+ }
+
+ painter->setBrush(dialGradient);
+ painter->setPen(QColor(255, 255, 255, 150));
+ painter->drawEllipse(dialRect.adjusted(-1, -1, 1, 1));
+ painter->setPen(QColor(0, 0, 0, 80));
+ painter->drawEllipse(dialRect);
+ painter->restore();
+}
+#endif //QT_NO_DIAL
+
+void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect,
+ int left, int top, int right,
+ int bottom)
+{
+ QSize size = pixmap.size();
+ //painter->setRenderHint(QPainter::SmoothPixmapTransform);
+
+ //top
+ if (top > 0) {
+ painter->drawPixmap(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), pixmap,
+ QRect(left, 0, size.width() -right - left, top));
+
+ //top-left
+ if(left > 0)
+ painter->drawPixmap(QRect(rect.left(), rect.top(), left, top), pixmap,
+ QRect(0, 0, left, top));
+
+ //top-right
+ if (right > 0)
+ painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top(), right, top), pixmap,
+ QRect(size.width() - right, 0, right, top));
+ }
+
+ //left
+ if (left > 0)
+ painter->drawPixmap(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), pixmap,
+ QRect(0, top, left, size.height() - bottom - top));
+
+ //center
+ painter->drawPixmap(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left,
+ rect.height() - bottom - top), pixmap,
+ QRect(left, top, size.width() -right -left,
+ size.height() - bottom - top));
+ //right
+ if (right > 0)
+ painter->drawPixmap(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), pixmap,
+ QRect(size.width() - right, top, right, size.height() - bottom - top));
+
+ //bottom
+ if (bottom > 0) {
+ painter->drawPixmap(QRect(rect.left() +left, rect.top() + rect.height() - bottom,
+ rect.width() - right - left, bottom), pixmap,
+ QRect(left, size.height() - bottom,
+ size.width() - right - left, bottom));
+ //bottom-left
+ if (left > 0)
+ painter->drawPixmap(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), pixmap,
+ QRect(0, size.height() - bottom, left, bottom));
+
+ //bottom-right
+ if (right > 0)
+ painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), pixmap,
+ QRect(size.width() - right, size.height() - bottom, right, bottom));
+
+ }
+}
+}
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h
new file mode 100644
index 0000000000..f2bb81929c
--- /dev/null
+++ b/src/widgets/styles/qstylehelper_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qpolygon.h>
+#include <QtCore/qstringbuilder.h>
+
+#ifndef QSTYLEHELPER_P_H
+#define QSTYLEHELPER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qhexstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPainter;
+class QPixmap;
+class QStyleOptionSlider;
+class QStyleOption;
+
+namespace QStyleHelper
+{
+ QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size);
+ qreal dpiScaled(qreal value);
+#ifndef QT_NO_DIAL
+ qreal angle(const QPointF &p1, const QPointF &p2);
+ QPolygonF calcLines(const QStyleOptionSlider *dial);
+ int calcBigLineSize(int radius);
+ void drawDial(const QStyleOptionSlider *dial, QPainter *painter);
+#endif //QT_NO_DIAL
+ void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect,
+ int left = 0, int top = 0, int right = 0,
+ int bottom = 0);
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QSTYLEHELPER_P_H
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
new file mode 100644
index 0000000000..90cfd427ed
--- /dev/null
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -0,0 +1,5508 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstyleoption.h"
+#include "qapplication.h"
+#ifdef Q_WS_MAC
+# include "private/qt_mac_p.h"
+# include "qmacstyle_mac.h"
+#endif
+#include <qdebug.h>
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QStyleOption
+ \brief The QStyleOption class stores the parameters used by QStyle functions.
+
+ \ingroup appearance
+
+ QStyleOption and its subclasses contain all the information that
+ QStyle functions need to draw a graphical element.
+
+ For performance reasons, there are few member functions and the
+ access to the member variables is direct (i.e., using the \c . or
+ \c -> operator). This low-level feel makes the structures
+ straightforward to use and emphasizes that these are simply
+ parameters used by the style functions.
+
+ The caller of a QStyle function usually creates QStyleOption
+ objects on the stack. This combined with Qt's extensive use of
+ \l{implicit sharing} for types such as QString, QPalette, and
+ QColor ensures that no memory allocation needlessly takes place.
+
+ The following code snippet shows how to use a specific
+ QStyleOption subclass to paint a push button:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 0
+
+ In our example, the control is a QStyle::CE_PushButton, and
+ according to the QStyle::drawControl() documentation the
+ corresponding class is QStyleOptionButton.
+
+ When reimplementing QStyle functions that take a QStyleOption
+ parameter, you often need to cast the QStyleOption to a subclass.
+ For safety, you can use qstyleoption_cast() to ensure that the
+ pointer type is correct. For example:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 4
+
+ The qstyleoption_cast() function will return 0 if the object to
+ which \c option points is not of the correct type.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyle, QStylePainter
+*/
+
+/*!
+ \enum QStyleOption::OptionType
+
+ This enum is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \value SO_Button \l QStyleOptionButton
+ \value SO_ComboBox \l QStyleOptionComboBox
+ \value SO_Complex \l QStyleOptionComplex
+ \value SO_Default QStyleOption
+ \value SO_DockWidget \l QStyleOptionDockWidget
+ \value SO_FocusRect \l QStyleOptionFocusRect
+ \value SO_Frame \l QStyleOptionFrame \l QStyleOptionFrameV2
+ \value SO_GraphicsItem \l QStyleOptionGraphicsItem
+ \value SO_GroupBox \l QStyleOptionGroupBox
+ \value SO_Header \l QStyleOptionHeader
+ \value SO_MenuItem \l QStyleOptionMenuItem
+ \value SO_ProgressBar \l QStyleOptionProgressBar \l QStyleOptionProgressBarV2
+ \value SO_RubberBand \l QStyleOptionRubberBand
+ \value SO_SizeGrip \l QStyleOptionSizeGrip
+ \value SO_Slider \l QStyleOptionSlider
+ \value SO_SpinBox \l QStyleOptionSpinBox
+ \value SO_Tab \l QStyleOptionTab
+ \value SO_TabBarBase \l QStyleOptionTabBarBase
+ \value SO_TabWidgetFrame \l QStyleOptionTabWidgetFrame
+ \value SO_TitleBar \l QStyleOptionTitleBar
+ \value SO_ToolBar \l QStyleOptionToolBar
+ \value SO_ToolBox \l QStyleOptionToolBox
+ \value SO_ToolButton \l QStyleOptionToolButton
+ \value SO_ViewItem \l QStyleOptionViewItem (used in Interviews)
+
+ The following values are used for custom controls:
+
+ \value SO_CustomBase Reserved for custom QStyleOptions;
+ all custom controls values must be above this value
+ \value SO_ComplexCustomBase Reserved for custom QStyleOptions;
+ all custom complex controls values must be above this value
+
+ Some style options are defined for various Qt3Support controls:
+
+ \value SO_Q3DockWindow \l QStyleOptionQ3DockWindow
+ \value SO_Q3ListView \l QStyleOptionQ3ListView
+ \value SO_Q3ListViewItem \l QStyleOptionQ3ListViewItem
+
+ \sa type
+*/
+
+/*!
+ Constructs a QStyleOption with the specified \a version and \a
+ type.
+
+ The version has no special meaning for QStyleOption; it can be
+ used by subclasses to distinguish between different version of
+ the same option type.
+
+ The \l state member variable is initialized to
+ QStyle::State_None.
+
+ \sa version, type
+*/
+
+QStyleOption::QStyleOption(int version, int type)
+ : version(version), type(type), state(QStyle::State_None),
+ direction(QApplication::layoutDirection()), fontMetrics(QFont())
+{
+}
+
+
+/*!
+ Destroys this style option object.
+*/
+QStyleOption::~QStyleOption()
+{
+}
+
+/*!
+ \fn void QStyleOption::initFrom(const QWidget *widget)
+ \since 4.1
+
+ Initializes the \l state, \l direction, \l rect, \l palette, and
+ \l fontMetrics member variables based on the specified \a widget.
+
+ This is a convenience function; the member variables can also be
+ initialized manually.
+
+ \sa QWidget::layoutDirection(), QWidget::rect(),
+ QWidget::palette(), QWidget::fontMetrics()
+*/
+
+/*!
+ \obsolete
+
+ Use initFrom(\a widget) instead.
+*/
+void QStyleOption::init(const QWidget *widget)
+{
+ QWidget *window = widget->window();
+ state = QStyle::State_None;
+ if (widget->isEnabled())
+ state |= QStyle::State_Enabled;
+ if (widget->hasFocus())
+ state |= QStyle::State_HasFocus;
+ if (window->testAttribute(Qt::WA_KeyboardFocusChange))
+ state |= QStyle::State_KeyboardFocusChange;
+ if (widget->underMouse())
+ state |= QStyle::State_MouseOver;
+ if (window->isActiveWindow())
+ state |= QStyle::State_Active;
+ if (widget->isWindow())
+ state |= QStyle::State_Window;
+#ifdef Q_WS_MAC
+ extern bool qt_mac_can_clickThrough(const QWidget *w); //qwidget_mac.cpp
+ if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget))
+ state &= ~QStyle::State_Enabled;
+
+ switch (QMacStyle::widgetSizePolicy(widget)) {
+ case QMacStyle::SizeSmall:
+ state |= QStyle::State_Small;
+ break;
+ case QMacStyle::SizeMini:
+ state |= QStyle::State_Mini;
+ break;
+ default:
+ ;
+ }
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ if (widget->hasEditFocus())
+ state |= QStyle::State_HasEditFocus;
+#endif
+
+ direction = widget->layoutDirection();
+ rect = widget->rect();
+ palette = widget->palette();
+ fontMetrics = widget->fontMetrics();
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+QStyleOption::QStyleOption(const QStyleOption &other)
+ : version(Version), type(Type), state(other.state),
+ direction(other.direction), rect(other.rect), fontMetrics(other.fontMetrics),
+ palette(other.palette)
+{
+}
+
+/*!
+ Assign \a other to this QStyleOption.
+*/
+QStyleOption &QStyleOption::operator=(const QStyleOption &other)
+{
+ state = other.state;
+ direction = other.direction;
+ rect = other.rect;
+ fontMetrics = other.fontMetrics;
+ palette = other.palette;
+ return *this;
+}
+
+/*!
+ \enum QStyleOption::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Default} for
+ this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOption::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOption::palette
+ \brief the palette that should be used when painting the control
+
+ By default, the application's default palette is used.
+
+ \sa initFrom()
+*/
+
+/*!
+ \variable QStyleOption::direction
+ \brief the text layout direction that should be used when drawing text in the control
+
+ By default, the layout direction is Qt::LeftToRight.
+
+ \sa initFrom()
+*/
+
+/*!
+ \variable QStyleOption::fontMetrics
+ \brief the font metrics that should be used when drawing text in the control
+
+ By default, the application's default font is used.
+
+ \sa initFrom()
+*/
+
+/*!
+ \variable QStyleOption::rect
+ \brief the area that should be used for various calculations and painting
+
+ This can have different meanings for different types of elements.
+ For example, for a \l QStyle::CE_PushButton element it would be
+ the rectangle for the entire button, while for a \l
+ QStyle::CE_PushButtonLabel element it would be just the area for
+ the push button label.
+
+ The default value is a null rectangle, i.e. a rectangle with both
+ the width and the height set to 0.
+
+ \sa initFrom()
+*/
+
+/*!
+ \variable QStyleOption::state
+ \brief the style flags that are used when drawing the control
+
+ The default value is QStyle::State_None.
+
+ \sa initFrom(), QStyle::drawPrimitive(), QStyle::drawControl(),
+ QStyle::drawComplexControl(), QStyle::State
+*/
+
+/*!
+ \variable QStyleOption::type
+ \brief the option type of the style option
+
+ The default value is SO_Default.
+
+ \sa OptionType
+*/
+
+/*!
+ \variable QStyleOption::version
+ \brief the version of the style option
+
+ This value can be used by subclasses to implement extensions
+ without breaking compatibility. If you use the qstyleoption_cast()
+ function, you normally do not need to check it.
+
+ The default value is 1.
+*/
+
+/*!
+ \class QStyleOptionFocusRect
+ \brief The QStyleOptionFocusRect class is used to describe the
+ parameters for drawing a focus rectangle with QStyle.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionFocusRect, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionFocusRect::QStyleOptionFocusRect()
+ : QStyleOption(Version, SO_FocusRect)
+{
+ state |= QStyle::State_KeyboardFocusChange; // assume we had one, will be corrected in initFrom()
+}
+
+/*!
+ \internal
+*/
+QStyleOptionFocusRect::QStyleOptionFocusRect(int version)
+ : QStyleOption(version, SO_FocusRect)
+{
+ state |= QStyle::State_KeyboardFocusChange; // assume we had one, will be corrected in initFrom()
+}
+
+/*!
+ \enum QStyleOptionFocusRect::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_FocusRect} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionFocusRect::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \fn QStyleOptionFocusRect::QStyleOptionFocusRect(const QStyleOptionFocusRect &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \variable QStyleOptionFocusRect::backgroundColor
+ \brief the background color on which the focus rectangle is being drawn
+
+ The default value is an invalid color with the RGB value (0, 0,
+ 0). An invalid color is a color that is not properly set up for
+ the underlying window system.
+*/
+
+/*!
+ \class QStyleOptionFrame
+ \brief The QStyleOptionFrame class is used to describe the
+ parameters for drawing a frame.
+
+ QStyleOptionFrame is used for drawing several built-in Qt widgets,
+ including QFrame, QGroupBox, QLineEdit, and QMenu. Note that to
+ describe the parameters necessary for drawing a frame in Qt 4.1 or
+ above, you must use the QStyleOptionFrameV2 subclass.
+
+ An instance of the QStyleOptionFrame class has
+ \l{QStyleOption::type} {type} SO_Frame and \l{QStyleOption::version}
+ {version} 1.
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles. The
+ version is used by QStyleOption subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast(),
+ you normally do not need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionFrame and QStyleOptionFrameV2.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionFrameV2, QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionFrame, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionFrame::QStyleOptionFrame()
+ : QStyleOption(Version, SO_Frame), lineWidth(0), midLineWidth(0)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionFrame::QStyleOptionFrame(int version)
+ : QStyleOption(version, SO_Frame), lineWidth(0), midLineWidth(0)
+{
+}
+
+/*!
+ \fn QStyleOptionFrame::QStyleOptionFrame(const QStyleOptionFrame &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionFrame::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Frame} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionFrame::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionFrame::lineWidth
+ \brief the line width for drawing the frame
+
+ The default value is 0.
+
+ \sa QFrame::lineWidth
+*/
+
+/*!
+ \variable QStyleOptionFrame::midLineWidth
+ \brief the mid-line width for drawing the frame
+
+ This is usually used in drawing sunken or raised frames.
+
+ The default value is 0.
+
+ \sa QFrame::midLineWidth
+*/
+
+/*!
+ \class QStyleOptionFrameV2
+ \brief The QStyleOptionFrameV2 class is used to describe the
+ parameters necessary for drawing a frame in Qt 4.1 or above.
+
+ \since 4.1
+
+ QStyleOptionFrameV2 inherits QStyleOptionFrame which is used for
+ drawing several built-in Qt widgets, including QFrame, QGroupBox,
+ QLineEdit, and QMenu.
+
+ An instance of the QStyleOptionFrameV2 class has
+ \l{QStyleOption::type} {type} SO_Frame and
+ \l{QStyleOption::version} {version} 2. The type is used
+ internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles. The
+ version is used by QStyleOption subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast(),
+ you normally do not need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionFrame and QStyleOptionFrameV2. One way to achieve this
+ is to use the QStyleOptionFrameV2 copy constructor. For example:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 1
+
+ In the example above: If the \c frameOption's version is 1, \l
+ FrameFeature is set to \l None for \c frameOptionV2. If \c
+ frameOption's version is 2, the constructor will simply copy the
+ \c frameOption's \l FrameFeature value.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionFrame, QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionFrameV2 object.
+*/
+QStyleOptionFrameV2::QStyleOptionFrameV2()
+ : QStyleOptionFrame(Version), features(None)
+{
+}
+
+/*!
+ \fn QStyleOptionFrameV2::QStyleOptionFrameV2(const QStyleOptionFrameV2 &other)
+
+ Constructs a QStyleOptionFrameV2 copy of the \a other style option.
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionFrameV2::QStyleOptionFrameV2(int version)
+ : QStyleOptionFrame(version), features(None)
+{
+}
+
+/*!
+ Constructs a QStyleOptionFrameV2 copy of the \a other style option
+ which can be either of the QStyleOptionFrameV2 or
+ QStyleOptionFrame types.
+
+ If the \a other style option's version is 1, the new style option's \l
+ FrameFeature value is set to \l QStyleOptionFrameV2::None. If its
+ version is 2, its \l FrameFeature value is simply copied to the
+ new style option.
+
+ \sa version
+*/
+QStyleOptionFrameV2::QStyleOptionFrameV2(const QStyleOptionFrame &other)
+{
+ QStyleOptionFrame::operator=(other);
+
+ const QStyleOptionFrameV2 *f2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(&other);
+ features = f2 ? f2->features : FrameFeatures(QStyleOptionFrameV2::None);
+ version = Version;
+}
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionFrameV2 or
+ QStyleOptionFrame types.
+
+ If the \a{other} style option's version is 1, this style option's
+ \l FrameFeature value is set to \l QStyleOptionFrameV2::None. If
+ its version is 2, its \l FrameFeature value is simply copied to
+ this style option.
+*/
+QStyleOptionFrameV2 &QStyleOptionFrameV2::operator=(const QStyleOptionFrame &other)
+{
+ QStyleOptionFrame::operator=(other);
+
+ const QStyleOptionFrameV2 *f2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(&other);
+ features = f2 ? f2->features : FrameFeatures(QStyleOptionFrameV2::None);
+ version = Version;
+ return *this;
+}
+
+/*!
+ \enum QStyleOptionFrameV2::FrameFeature
+
+ This enum describes the different types of features a frame can have.
+
+ \value None Indicates a normal frame.
+ \value Flat Indicates a flat frame.
+*/
+
+/*!
+ \variable QStyleOptionFrameV2::features
+ \brief a bitwise OR of the features that describe this frame.
+
+ \sa FrameFeature
+*/
+
+/*!
+ \enum QStyleOptionFrameV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the
+ style option, and is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \class QStyleOptionFrameV3
+ \brief The QStyleOptionFrameV3 class is used to describe the
+ parameters necessary for drawing a frame in Qt 4.1 or above.
+
+ \since 4.5
+
+ QStyleOptionFrameV3 inherits QStyleOptionFrameV2
+
+ An instance of the QStyleOptionFrameV3 class has
+ \l{QStyleOption::type} {type} SO_Frame and
+ \l{QStyleOption::version} {version} 3. The type is used
+ internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles. The
+ version is used by QStyleOption subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast(),
+ you normally do not need to check it.
+
+ \sa QStyleOptionFrameV2, QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionFrameV3 object.
+*/
+QStyleOptionFrameV3::QStyleOptionFrameV3()
+ : QStyleOptionFrameV2(Version), frameShape(QFrame::NoFrame), unused(0)
+{
+}
+
+/*!
+ \fn QStyleOptionFrameV3::QStyleOptionFrameV3(const QStyleOptionFrameV3 &other)
+
+ Constructs a QStyleOptionFrameV3 copy of the \a other style option.
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionFrameV3::QStyleOptionFrameV3(int version)
+ : QStyleOptionFrameV2(version), frameShape(QFrame::NoFrame), unused(0)
+{
+}
+
+/*!
+ Constructs a QStyleOptionFrameV3 copy of the \a other style option
+ which can be either of the QStyleOptionFrameV3 or
+ QStyleOptionFrame types.
+
+ If the \a other style option's version is 1, the new style
+ option's \l FrameFeature value is set to
+ \l{QStyleOptionFrameV2::None}. If its version is 2 or lower,
+ \l{QStyleOptionFrameV3::frameShape} value is QFrame::NoFrame
+
+ \sa version
+*/
+QStyleOptionFrameV3::QStyleOptionFrameV3(const QStyleOptionFrame &other)
+{
+ operator=(other);
+}
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionFrameV3,
+ QStyleOptionFrameV2 or QStyleOptionFrame types.
+
+ If the \a other style option's version is 1, the new style
+ option's \l FrameFeature value is set to
+ \l{QStyleOptionFrameV2::None}. If its version is 2 or lower,
+ \l{QStyleOptionFrameV3::frameShape} value is QFrame::NoFrame
+*/
+QStyleOptionFrameV3 &QStyleOptionFrameV3::operator=(const QStyleOptionFrame &other)
+{
+ QStyleOptionFrameV2::operator=(other);
+
+ const QStyleOptionFrameV3 *f3 = qstyleoption_cast<const QStyleOptionFrameV3 *>(&other);
+ frameShape = f3 ? f3->frameShape : QFrame::NoFrame;
+ version = Version;
+ return *this;
+}
+
+
+/*!
+ \variable QStyleOptionFrameV3::frameShape
+ \brief This property holds the frame shape value of the frame.
+
+ \sa QFrame::frameShape
+*/
+
+/*!
+ \enum QStyleOptionFrameV3::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 3
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \class QStyleOptionViewItemV2
+ \brief The QStyleOptionViewItemV2 class is used to describe the
+ parameters necessary for drawing a frame in Qt 4.2 or above.
+ \since 4.2
+
+ QStyleOptionViewItemV2 inherits QStyleOptionViewItem.
+
+ An instance of the QStyleOptionViewItemV2 class has
+ \l{QStyleOption::type} {type} SO_ViewItem and
+ \l{QStyleOption::version} {version} 2. The type is used internally
+ by QStyleOption, its subclasses, and qstyleoption_cast() to
+ determine the type of style option. In general you do not need to
+ worry about this unless you want to create your own QStyleOption
+ subclass and your own styles. The version is used by QStyleOption
+ subclasses to implement extensions without breaking
+ compatibility. If you use qstyleoption_cast(), you normally do not
+ need to check it.
+
+ See QStyleOptionFrameV2's detailed description for a discussion
+ of how to handle "V2" classes.
+
+ \sa QStyleOptionViewItem, QStyleOption
+*/
+
+/*!
+ \enum QStyleOptionViewItemV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the
+ style option, and is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionViewItemV2::features
+ \brief a bitwise OR of the features that describe this view item
+
+ \sa ViewItemFeature
+*/
+
+/*!
+ Constructs a QStyleOptionViewItemV2 object.
+*/
+QStyleOptionViewItemV2::QStyleOptionViewItemV2()
+ : QStyleOptionViewItem(Version), features(None)
+{
+}
+
+/*!
+ \fn QStyleOptionViewItemV2::QStyleOptionViewItemV2(const QStyleOptionViewItemV2 &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ Constructs a QStyleOptionViewItemV2 copy of the \a other style option
+ which can be either of the QStyleOptionViewItemV2 or
+ QStyleOptionViewItem types.
+
+ If the \a other style option's version is 1, the new style option's \l
+ ViewItemFeature value is set to \l QStyleOptionViewItemV2::None. If its
+ version is 2, its \l ViewItemFeature value is simply copied to the
+ new style option.
+
+ \sa version
+*/
+QStyleOptionViewItemV2::QStyleOptionViewItemV2(const QStyleOptionViewItem &other)
+ : QStyleOptionViewItem(Version)
+{
+ (void)QStyleOptionViewItemV2::operator=(other);
+}
+
+/*!
+ \internal
+*/
+QStyleOptionViewItemV2::QStyleOptionViewItemV2(int version)
+ : QStyleOptionViewItem(version)
+{
+
+}
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionViewItemV2 or
+ QStyleOptionViewItem types.
+
+ If the \a{other} style option's version is 1, this style option's
+ \l ViewItemFeature value is set to \l QStyleOptionViewItemV2::None.
+ If its version is 2, its \l ViewItemFeature value is simply copied
+ to this style option.
+*/
+QStyleOptionViewItemV2 &QStyleOptionViewItemV2::operator=(const QStyleOptionViewItem &other)
+{
+ QStyleOptionViewItem::operator=(other);
+ const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(&other);
+ features = v2 ? v2->features : ViewItemFeatures(QStyleOptionViewItemV2::None);
+ return *this;
+}
+
+/*!
+ \enum QStyleOptionViewItemV2::ViewItemFeature
+
+ This enum describes the different types of features an item can have.
+
+ \value None Indicates a normal item.
+ \value WrapText Indicates an item with wrapped text.
+ \value Alternate Indicates that the item's background is rendered using alternateBase.
+ \value HasCheckIndicator Indicates that the item has a check state indicator.
+ \value HasDisplay Indicates that the item has a display role.
+ \value HasDecoration Indicates that the item has a decoration role.
+*/
+
+
+
+/*!
+ \class QStyleOptionViewItemV3
+ \brief The QStyleOptionViewItemV3 class is used to describe the
+ parameters necessary for drawing a frame in Qt 4.3 or above.
+ \since 4.3
+
+ QStyleOptionViewItemV3 inherits QStyleOptionViewItem.
+
+ An instance of the QStyleOptionViewItemV3 class has
+ \l{QStyleOption::type} {type} SO_ViewItem and \l{QStyleOption::version}
+ {version} 3. The type is used internally by QStyleOption, its subclasses,
+ and qstyleoption_cast() to determine the type of style option. In general
+ you do not need to worry about this unless you want to create your own
+ QStyleOption subclass and your own styles. The version is used by
+ QStyleOption subclasses to implement extensions without breaking
+ compatibility. If you use qstyleoption_cast(), you normally do not need to
+ check it.
+
+ See QStyleOptionFrameV2's detailed description for a discussion
+ of how to handle "V2" and other versioned classes.
+
+ \sa QStyleOptionViewItem, QStyleOption
+*/
+
+/*!
+ \enum QStyleOptionViewItemV3::StyleOptionVersion
+
+ This enum is used to hold information about the version of the
+ style option, and is defined for each QStyleOption subclass.
+
+ \value Version 3
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ Constructs a QStyleOptionViewItemV3 object.
+*/
+QStyleOptionViewItemV3::QStyleOptionViewItemV3()
+ : QStyleOptionViewItemV2(Version), widget(0)
+{
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+QStyleOptionViewItemV3::QStyleOptionViewItemV3(const QStyleOptionViewItem &other)
+ : QStyleOptionViewItemV2(Version), widget(0)
+{
+ (void)QStyleOptionViewItemV3::operator=(other);
+}
+
+/*!
+ \fn QStyleOptionViewItemV3::QStyleOptionViewItemV3(const QStyleOptionViewItemV3 &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be an instance of the QStyleOptionViewItemV2,
+ QStyleOptionViewItemV3 or QStyleOptionViewItem types.
+*/
+QStyleOptionViewItemV3 &QStyleOptionViewItemV3::operator = (const QStyleOptionViewItem &other)
+{
+ QStyleOptionViewItemV2::operator=(other);
+ const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*>(&other);
+ locale = v3 ? v3->locale : QLocale();
+ widget = v3 ? v3->widget : 0;
+ return *this;
+}
+
+/*!
+ \internal
+*/
+QStyleOptionViewItemV3::QStyleOptionViewItemV3(int version)
+ : QStyleOptionViewItemV2(version), widget(0)
+{
+}
+
+#ifndef QT_NO_ITEMVIEWS
+
+/*!
+ \class QStyleOptionViewItemV4
+ \brief The QStyleOptionViewItemV4 class is used to describe the
+ parameters necessary for drawing a frame in Qt 4.4 or above.
+ \since 4.4
+
+ QStyleOptionViewItemV4 inherits QStyleOptionViewItemV3.
+
+ An instance of the QStyleOptionViewItemV4 class has
+ \l{QStyleOption::type} {type} SO_ViewItem and
+ \l{QStyleOption::version} {version} 4. The type is used internally
+ by QStyleOption, its subclasses, and qstyleoption_cast() to
+ determine the type of style option. In general you do not need to
+ worry about this unless you want to create your own QStyleOption
+ subclass and your own styles. The version is used by QStyleOption
+ subclasses to implement extensions without breaking
+ compatibility. If you use qstyleoption_cast(), you normally do not
+ need to check it.
+
+ See QStyleOptionViewItemV3's detailed description for a discussion
+ of how to handle "V3" classes.
+
+ \sa QStyleOptionViewItem, QStyleOption
+*/
+
+/*!
+ \variable QStyleOptionViewItemV4::index
+
+ The model index that is to be drawn.
+*/
+
+/*!
+ \variable QStyleOptionViewItemV4::checkState
+
+ If this view item is checkable, i.e.,
+ ViewItemFeature::HasCheckIndicator is true, \c checkState is true
+ if the item is checked; otherwise, it is false.
+
+*/
+
+/*!
+ \variable QStyleOptionViewItemV4::icon
+
+ The icon (if any) to be drawn in the view item.
+*/
+
+
+/*!
+ \variable QStyleOptionViewItemV4::text
+
+ The text (if any) to be drawn in the view item.
+*/
+
+/*!
+ \variable QStyleOptionViewItemV4::backgroundBrush
+
+ The QBrush that should be used to paint the view items
+ background.
+*/
+
+/*!
+ \variable QStyleOptionViewItemV4::viewItemPosition
+
+ Gives the position of this view item relative to other items. See
+ the \l{QStyleOptionViewItemV4::}{ViewItemPosition} enum for the
+ details.
+*/
+
+/*!
+ \enum QStyleOptionViewItemV4::StyleOptionVersion
+
+ This enum is used to hold information about the version of the
+ style option, and is defined for each QStyleOption subclass.
+
+ \value Version 4
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \enum QStyleOptionViewItemV4::ViewItemPosition
+
+ This enum is used to represent the placement of the item on
+ a row. This can be used to draw items differently depending
+ on their placement, for example by putting rounded edges at
+ the beginning and end, and straight edges in between.
+
+ \value Invalid The ViewItemPosition is unknown and should be
+ disregarded.
+ \value Beginning The item appears at the beginning of the row.
+ \value Middle The item appears in the middle of the row.
+ \value End The item appears at the end of the row.
+ \value OnlyOne The item is the only one on the row, and is
+ therefore both at the beginning and the end.
+*/
+
+
+/*!
+ Constructs a QStyleOptionViewItemV4 object.
+*/
+QStyleOptionViewItemV4::QStyleOptionViewItemV4()
+: QStyleOptionViewItemV3(Version), checkState(Qt::Unchecked), viewItemPosition(QStyleOptionViewItemV4::Invalid)
+{
+}
+
+/*!
+ \fn QStyleOptionViewItemV4::QStyleOptionViewItemV4(const QStyleOptionViewItemV4 &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ Constructs a QStyleOptionViewItemV4 copy of the \a other style option
+ which can be either of the QStyleOptionViewItemV3 or
+ QStyleOptionViewItem types.
+
+ \sa version
+*/
+QStyleOptionViewItemV4::QStyleOptionViewItemV4(const QStyleOptionViewItem &other)
+ : QStyleOptionViewItemV3(Version)
+{
+ (void)QStyleOptionViewItemV4::operator=(other);
+}
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionViewItemV3 or
+ QStyleOptionViewItem types.
+*/
+QStyleOptionViewItemV4 &QStyleOptionViewItemV4::operator = (const QStyleOptionViewItem &other)
+{
+ QStyleOptionViewItemV3::operator=(other);
+ if (const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4*>(&other)) {
+ index = v4->index;
+ checkState = v4->checkState;
+ text = v4->text;
+ viewItemPosition = v4->viewItemPosition;
+ backgroundBrush = v4->backgroundBrush;
+ icon = v4->icon;
+ } else {
+ viewItemPosition = QStyleOptionViewItemV4::Invalid;
+ checkState = Qt::Unchecked;
+ }
+ return *this;
+}
+
+/*!
+ \internal
+*/
+QStyleOptionViewItemV4::QStyleOptionViewItemV4(int version)
+ : QStyleOptionViewItemV3(version)
+{
+}
+#endif // QT_NO_ITEMVIEWS
+
+/*!
+ \class QStyleOptionGroupBox
+ \brief The QStyleOptionGroupBox class describes the parameters for
+ drawing a group box.
+
+ \since 4.1
+
+ QStyleOptionButton contains all the information that QStyle
+ functions need the various graphical elements of a group box.
+
+ It holds the lineWidth and the midLineWidth for drawing the panel,
+ the group box's \l {text}{title} and the title's \l
+ {textAlignment}{alignment} and \l {textColor}{color}.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionComplex, QGroupBox
+*/
+
+/*!
+ \enum QStyleOptionGroupBox::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_GroupBox} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionGroupBox::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionGroupBox::lineWidth
+ \brief the line width for drawing the panel
+
+ The value of this variable is, currently, always 1.
+
+ \sa QFrame::lineWidth
+*/
+
+/*!
+ \variable QStyleOptionGroupBox::midLineWidth
+ \brief the mid-line width for drawing the panel
+
+ The mid-line width is usually used when drawing sunken or raised
+ group box frames. The value of this variable is, currently, always 0.
+
+ \sa QFrame::midLineWidth
+*/
+
+/*!
+ \variable QStyleOptionGroupBox::text
+ \brief the text of the group box
+
+ The default value is an empty string.
+
+ \sa QGroupBox::title
+*/
+
+/*!
+ \variable QStyleOptionGroupBox::textAlignment
+ \brief the alignment of the group box title
+
+ The default value is Qt::AlignLeft.
+
+ \sa QGroupBox::alignment
+*/
+
+/*!
+ \variable QStyleOptionGroupBox::features
+ \brief the features of the group box frame
+
+ The frame is flat by default.
+
+ \sa QStyleOptionFrameV2::FrameFeature
+*/
+
+/*!
+ \variable QStyleOptionGroupBox::textColor
+ \brief the color of the group box title
+
+ The default value is an invalid color with the RGB value (0, 0,
+ 0). An invalid color is a color that is not properly set up for
+ the underlying window system.
+*/
+
+/*!
+ Constructs a QStyleOptionGroupBox, initializing the members
+ variables to their default values.
+*/
+QStyleOptionGroupBox::QStyleOptionGroupBox()
+ : QStyleOptionComplex(Version, Type), features(QStyleOptionFrameV2::None),
+ textAlignment(Qt::AlignLeft), lineWidth(0), midLineWidth(0)
+{
+}
+
+/*!
+ \fn QStyleOptionGroupBox::QStyleOptionGroupBox(const QStyleOptionGroupBox &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionGroupBox::QStyleOptionGroupBox(int version)
+ : QStyleOptionComplex(version, Type), features(QStyleOptionFrameV2::None),
+ textAlignment(Qt::AlignLeft), lineWidth(0), midLineWidth(0)
+{
+}
+
+/*!
+ \class QStyleOptionHeader
+ \brief The QStyleOptionHeader class is used to describe the
+ parameters for drawing a header.
+
+ QStyleOptionHeader contains all the information that QStyle
+ functions need to draw the item views' header pane, header sort
+ arrow, and header label.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionHeader, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionHeader::QStyleOptionHeader()
+ : QStyleOption(QStyleOptionHeader::Version, SO_Header),
+ section(0), textAlignment(Qt::AlignLeft), iconAlignment(Qt::AlignLeft),
+ position(QStyleOptionHeader::Beginning),
+ selectedPosition(QStyleOptionHeader::NotAdjacent), sortIndicator(None),
+ orientation(Qt::Horizontal)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionHeader::QStyleOptionHeader(int version)
+ : QStyleOption(version, SO_Header),
+ section(0), textAlignment(Qt::AlignLeft), iconAlignment(Qt::AlignLeft),
+ position(QStyleOptionHeader::Beginning),
+ selectedPosition(QStyleOptionHeader::NotAdjacent), sortIndicator(None),
+ orientation(Qt::Horizontal)
+{
+}
+
+/*!
+ \variable QStyleOptionHeader::orientation
+ \brief the header's orientation (horizontal or vertical)
+
+ The default orientation is Qt::Horizontal
+*/
+
+/*!
+ \fn QStyleOptionHeader::QStyleOptionHeader(const QStyleOptionHeader &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionHeader::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Header} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionHeader::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionHeader::section
+ \brief which section of the header is being painted
+
+ The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionHeader::text
+ \brief the text of the header
+
+ The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionHeader::textAlignment
+ \brief the alignment flags for the text of the header
+
+ The default value is Qt::AlignLeft.
+*/
+
+/*!
+ \variable QStyleOptionHeader::icon
+ \brief the icon of the header
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+*/
+
+/*!
+ \variable QStyleOptionHeader::iconAlignment
+ \brief the alignment flags for the icon of the header
+
+ The default value is Qt::AlignLeft.
+*/
+
+/*!
+ \variable QStyleOptionHeader::position
+ \brief the section's position in relation to the other sections
+
+ The default value is QStyleOptionHeader::Beginning.
+*/
+
+/*!
+ \variable QStyleOptionHeader::selectedPosition
+ \brief the section's position in relation to the selected section
+
+ The default value is QStyleOptionHeader::NotAdjacent
+*/
+
+/*!
+ \variable QStyleOptionHeader::sortIndicator
+ \brief the direction the sort indicator should be drawn
+
+ The default value is QStyleOptionHeader::None.
+*/
+
+/*!
+ \enum QStyleOptionHeader::SectionPosition
+
+ This enum lets you know where the section's position is in relation to the other sections.
+
+ \value Beginning At the beginining of the header
+ \value Middle In the middle of the header
+ \value End At the end of the header
+ \value OnlyOneSection Only one header section
+
+ \sa position
+*/
+
+/*!
+ \enum QStyleOptionHeader::SelectedPosition
+
+ This enum lets you know where the section's position is in relation to the selected section.
+
+ \value NotAdjacent Not adjacent to the selected section
+ \value NextIsSelected The next section is selected
+ \value PreviousIsSelected The previous section is selected
+ \value NextAndPreviousAreSelected Both the next and previous section are selected
+
+ \sa selectedPosition
+*/
+
+/*!
+ \enum QStyleOptionHeader::SortIndicator
+
+ Indicates which direction the sort indicator should be drawn
+
+ \value None No sort indicator is needed
+ \value SortUp Draw an up indicator
+ \value SortDown Draw a down indicator
+
+ \sa sortIndicator
+*/
+
+/*!
+ \class QStyleOptionButton
+ \brief The QStyleOptionButton class is used to describe the
+ parameters for drawing buttons.
+
+ QStyleOptionButton contains all the information that QStyle
+ functions need to draw graphical elements like QPushButton,
+ QCheckBox, and QRadioButton.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionToolButton
+*/
+
+/*!
+ \enum QStyleOptionButton::ButtonFeature
+
+ This enum describes the different types of features a push button can have.
+
+ \value None Indicates a normal push button.
+ \value Flat Indicates a flat push button.
+ \value HasMenu Indicates that the button has a drop down menu.
+ \value DefaultButton Indicates that the button is a default button.
+ \value AutoDefaultButton Indicates that the button is an auto default button.
+ \value CommandLinkButton Indicates that the button is a Windows Vista type command link.
+
+ \sa features
+*/
+
+/*!
+ Constructs a QStyleOptionButton, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionButton::QStyleOptionButton()
+ : QStyleOption(QStyleOptionButton::Version, SO_Button), features(None)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionButton::QStyleOptionButton(int version)
+ : QStyleOption(version, SO_Button), features(None)
+{
+}
+
+/*!
+ \fn QStyleOptionButton::QStyleOptionButton(const QStyleOptionButton &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionButton::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Button} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionButton::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionButton::features
+ \brief a bitwise OR of the features that describe this button
+
+ \sa ButtonFeature
+*/
+
+/*!
+ \variable QStyleOptionButton::text
+ \brief the text of the button
+
+ The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionButton::icon
+ \brief the icon of the button
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+
+ \sa iconSize
+*/
+
+/*!
+ \variable QStyleOptionButton::iconSize
+ \brief the size of the icon for the button
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+*/
+
+
+#ifndef QT_NO_TOOLBAR
+/*!
+ \class QStyleOptionToolBar
+ \brief The QStyleOptionToolBar class is used to describe the
+ parameters for drawing a toolbar.
+
+ \since 4.1
+
+ QStyleOptionToolBar contains all the information that QStyle
+ functions need to draw QToolBar.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ The QStyleOptionToolBar class holds the lineWidth and the
+ midLineWidth for drawing the widget. It also stores information
+ about which \l {toolBarArea}{area} the toolbar should be located
+ in, whether it is movable or not, which position the toolbar line
+ should have (positionOfLine), and the toolbar's position within
+ the line (positionWithinLine).
+
+ In addition, the class provides a couple of enums: The
+ ToolBarFeature enum is used to describe whether a toolbar is
+ movable or not, and the ToolBarPosition enum is used to describe
+ the position of a toolbar line, as well as the toolbar's position
+ within the line.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionToolBar, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionToolBar::QStyleOptionToolBar()
+ : QStyleOption(Version, SO_ToolBar), positionOfLine(OnlyOne), positionWithinLine(OnlyOne),
+ toolBarArea(Qt::TopToolBarArea), features(None), lineWidth(0), midLineWidth(0)
+{
+}
+
+/*!
+ \fn QStyleOptionToolBar::QStyleOptionToolBar(const QStyleOptionToolBar &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionToolBar::QStyleOptionToolBar(int version)
+: QStyleOption(version, SO_ToolBar), positionOfLine(OnlyOne), positionWithinLine(OnlyOne),
+ toolBarArea(Qt::TopToolBarArea), features(None), lineWidth(0), midLineWidth(0)
+{
+
+}
+
+/*!
+ \enum QStyleOptionToolBar::ToolBarPosition
+
+ \image qstyleoptiontoolbar-position.png
+
+ This enum is used to describe the position of a toolbar line, as
+ well as the toolbar's position within the line.
+
+ The order of the positions within a line starts at the top of a
+ vertical line, and from the left within a horizontal line. The
+ order of the positions for the lines is always from the the
+ parent widget's boundary edges.
+
+ \value Beginning The toolbar is located at the beginning of the line,
+ or the toolbar line is the first of several lines. There can
+ only be one toolbar (and only one line) with this position.
+ \value Middle The toolbar is located in the middle of the line,
+ or the toolbar line is in the middle of several lines. There can
+ several toolbars (and lines) with this position.
+ \value End The toolbar is located at the end of the line,
+ or the toolbar line is the last of several lines. There can
+ only be one toolbar (and only one line) with this position.
+ \value OnlyOne There is only one toolbar or line. This is the default value
+ of the positionOfLine and positionWithinLine variables.
+
+ \sa positionWithinLine, positionOfLine
+*/
+
+/*!
+ \enum QStyleOptionToolBar::ToolBarFeature
+
+ This enum is used to describe whether a toolbar is movable or not.
+
+ \value None The toolbar cannot be moved. The default value.
+ \value Movable The toolbar is movable, and a handle will appear when
+ holding the cursor over the toolbar's boundary.
+
+ \sa features, QToolBar::isMovable()
+*/
+
+/*!
+ \variable QStyleOptionToolBar::positionOfLine
+
+ This variable holds the position of the toolbar line.
+
+ The default value is QStyleOptionToolBar::OnlyOne.
+*/
+
+/*!
+ \variable QStyleOptionToolBar::positionWithinLine
+
+ This variable holds the position of the toolbar within a line.
+
+ The default value is QStyleOptionToolBar::OnlyOne.
+*/
+
+/*!
+ \variable QStyleOptionToolBar::toolBarArea
+
+ This variable holds the location for drawing the toolbar.
+
+ The default value is Qt::TopToolBarArea.
+
+ \sa Qt::ToolBarArea
+*/
+
+/*!
+ \variable QStyleOptionToolBar::features
+
+ This variable holds whether the toolbar is movable or not.
+
+ The default value is \l None.
+*/
+
+/*!
+ \variable QStyleOptionToolBar::lineWidth
+
+ This variable holds the line width for drawing the toolbar.
+
+ The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionToolBar::midLineWidth
+
+ This variable holds the mid-line width for drawing the toolbar.
+
+ The default value is 0.
+*/
+
+/*!
+ \enum QStyleOptionToolBar::StyleOptionType
+
+ This enum is used to hold information about the type of the style
+ option, and is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ToolBar} for
+ this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionToolBar::StyleOptionVersion
+
+ This enum is used to hold information about the version of the
+ style option, and is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+#endif
+
+#ifndef QT_NO_TABBAR
+/*!
+ \class QStyleOptionTab
+ \brief The QStyleOptionTab class is used to describe the
+ parameters for drawing a tab bar.
+
+ The QStyleOptionTab class is used for drawing several built-in Qt
+ widgets including \l QTabBar and the panel for \l QTabWidget. Note
+ that to describe the parameters necessary for drawing a frame in
+ Qt 4.1 or above, you must use the QStyleOptionFrameV2 subclass.
+
+ An instance of the QStyleOptiontabV2 class has
+ \l{QStyleOption::type} {type} \l SO_Tab and
+ \l{QStyleOption::version} {version} 1. The type is used internally
+ by QStyleOption, its subclasses, and qstyleoption_cast() to
+ determine the type of style option. In general you do not need to
+ worry about this unless you want to create your own QStyleOption
+ subclass and your own styles. The version is used by QStyleOption
+ subclasses to implement extensions without breaking
+ compatibility. If you use qstyleoption_cast(), you normally do not
+ need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionTab and QStyleOptionTabV2.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionTabV2, QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionTab object, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionTab::QStyleOptionTab()
+ : QStyleOption(QStyleOptionTab::Version, SO_Tab),
+ shape(QTabBar::RoundedNorth),
+ row(0),
+ position(Beginning),
+ selectedPosition(NotAdjacent), cornerWidgets(QStyleOptionTab::NoCornerWidgets)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionTab::QStyleOptionTab(int version)
+ : QStyleOption(version, SO_Tab),
+ shape(QTabBar::RoundedNorth),
+ row(0),
+ position(Beginning),
+ selectedPosition(NotAdjacent), cornerWidgets(QStyleOptionTab::NoCornerWidgets)
+{
+}
+
+/*!
+ \fn QStyleOptionTab::QStyleOptionTab(const QStyleOptionTab &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionTab::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Tab} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionTab::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \enum QStyleOptionTab::TabPosition
+
+ This enum describes the position of the tab.
+
+ \value Beginning The tab is the first tab in the tab bar.
+ \value Middle The tab is neither the first nor the last tab in the tab bar.
+ \value End The tab is the last tab in the tab bar.
+ \value OnlyOneTab The tab is both the first and the last tab in the tab bar.
+
+ \sa position
+*/
+
+/*!
+ \enum QStyleOptionTab::CornerWidget
+
+ These flags indicate the corner widgets in a tab.
+
+ \value NoCornerWidgets There are no corner widgets
+ \value LeftCornerWidget Left corner widget
+ \value RightCornerWidget Right corner widget
+
+ \sa cornerWidgets
+*/
+
+/*! \enum QStyleOptionTab::SelectedPosition
+
+ This enum describes the position of the selected tab. Some styles
+ need to draw a tab differently depending on whether or not it is
+ adjacent to the selected tab.
+
+ \value NotAdjacent The tab is not adjacent to a selected tab (or is the selected tab).
+ \value NextIsSelected The next tab (typically the tab on the right) is selected.
+ \value PreviousIsSelected The previous tab (typically the tab on the left) is selected.
+
+ \sa selectedPosition
+*/
+
+/*!
+ \variable QStyleOptionTab::selectedPosition
+ \brief the position of the selected tab in relation to this tab
+
+ The default value is NotAdjacent, i.e. the tab is not adjacent to
+ a selected tab nor is it the selected tab.
+*/
+
+/*!
+ \variable QStyleOptionTab::cornerWidgets
+ \brief an OR combination of CornerWidget values indicating the
+ corner widgets of the tab bar
+
+ The default value is NoCornerWidgets.
+
+ \sa CornerWidget
+*/
+
+
+/*!
+ \variable QStyleOptionTab::shape
+ \brief the tab shape used to draw the tab; by default
+ QTabBar::RoundedNorth
+
+ \sa QTabBar::Shape
+*/
+
+/*!
+ \variable QStyleOptionTab::text
+ \brief the text of the tab
+
+ The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionTab::icon
+ \brief the icon for the tab
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+*/
+
+/*!
+ \variable QStyleOptionTab::row
+ \brief which row the tab is currently in
+
+ The default value is 0, indicating the front row. Currently this
+ property can only be 0.
+*/
+
+/*!
+ \variable QStyleOptionTab::position
+ \brief the position of the tab in the tab bar
+
+ The default value is \l Beginning, i.e. the tab is the first tab
+ in the tab bar.
+*/
+
+/*!
+ \class QStyleOptionTabV2
+ \brief The QStyleOptionTabV2 class is used to describe the
+ parameters necessary for drawing a tabs in Qt 4.1 or above.
+
+ \since 4.1
+
+ An instance of the QStyleOptionTabV2 class has
+ \l{QStyleOption::type} {type} \l SO_Tab and
+ \l{QStyleOption::version} {version} 2. The type is used internally
+ by QStyleOption, its subclasses, and qstyleoption_cast() to
+ determine the type of style option. In general you do not need to
+ worry about this unless you want to create your own QStyleOption
+ subclass and your own styles. The version is used by QStyleOption
+ subclasses to implement extensions without breaking
+ compatibility. If you use qstyleoption_cast(), you normally do not
+ need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionTab and QStyleOptionTabV2. One way to achieve this is
+ to use the QStyleOptionTabV2 copy constructor. For example:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 3
+
+ In the example above: If \c tabOption's version is 1, the extra
+ member (\l iconSize) will be set to an invalid size for \c tabV2.
+ If \c tabOption's version is 2, the constructor will simply copy
+ the \c tab's iconSize.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionTab, QStyleOption
+*/
+
+/*!
+ \enum QStyleOptionTabV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionTabV2::iconSize
+ \brief the size for the icons
+
+ The default value is QSize(-1, -1), i.e. an invalid size; use
+ QStyle::pixelMetric() to find the default icon size for tab bars.
+
+ \sa QTabBar::iconSize()
+*/
+
+/*!
+ Constructs a QStyleOptionTabV2.
+*/
+QStyleOptionTabV2::QStyleOptionTabV2()
+ : QStyleOptionTab(Version)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionTabV2::QStyleOptionTabV2(int version)
+ : QStyleOptionTab(version)
+{
+}
+
+/*!
+ \fn QStyleOptionTabV2::QStyleOptionTabV2(const QStyleOptionTabV2 &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ Constructs a QStyleOptionTabV2 copy of the \a other style option
+ which can be either of the QStyleOptionTabV2 or QStyleOptionTab
+ types.
+
+ If the other style option's version is 1, the new style option's
+ \c iconSize is set to an invalid value. If its version is 2, its
+ \c iconSize value is simply copied to the new style option.
+*/
+QStyleOptionTabV2::QStyleOptionTabV2(const QStyleOptionTab &other)
+ : QStyleOptionTab(Version)
+{
+ if (const QStyleOptionTabV2 *tab = qstyleoption_cast<const QStyleOptionTabV2 *>(&other)) {
+ *this = *tab;
+ } else {
+ *((QStyleOptionTab *)this) = other;
+ version = Version;
+ }
+}
+
+/*!
+ Assigns the \a other style option to this QStyleOptionTabV2. The
+ \a other style option can be either of the QStyleOptionTabV2 or
+ QStyleOptionTab types.
+
+ If the other style option's version is 1, this style option's \c
+ iconSize is set to an invalid size. If its version is 2, its \c
+ iconSize value is simply copied to this style option.
+*/
+QStyleOptionTabV2 &QStyleOptionTabV2::operator=(const QStyleOptionTab &other)
+{
+ QStyleOptionTab::operator=(other);
+
+ if (const QStyleOptionTabV2 *tab = qstyleoption_cast<const QStyleOptionTabV2 *>(&other))
+ iconSize = tab->iconSize;
+ else
+ iconSize = QSize();
+ return *this;
+}
+
+/*!
+ \class QStyleOptionTabV3
+ \brief The QStyleOptionTabV3 class is used to describe the
+ parameters necessary for drawing a tabs in Qt 4.5 or above.
+
+ \since 4.5
+
+ An instance of the QStyleOptionTabV3 class has
+ \l{QStyleOption::type} {type} \l SO_Tab and
+ \l{QStyleOption::version} {version} 3. The type is used internally
+ by QStyleOption, its subclasses, and qstyleoption_cast() to
+ determine the type of style option. In general you do not need to
+ worry about this unless you want to create your own QStyleOption
+ subclass and your own styles. The version is used by QStyleOption
+ subclasses to implement extensions without breaking
+ compatibility. If you use qstyleoption_cast(), you normally do not
+ need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionTab, QStyleOptionTabV2 and QStyleOptionTabV3.
+ One way to achieve this is to use the QStyleOptionTabV3 copy
+ constructor. For example:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 3
+
+ In the example above: If \c tabOption's version is 1, the extra
+ member (\l{QStyleOptionTabV2::iconSize}{iconSize}) will be set to
+ an invalid size for \c tabV2. If \c tabOption's version is 2, the
+ constructor will simply copy the \c tab's iconSize.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionTab, QStyleOption
+*/
+
+/*!
+ \enum QStyleOptionTabV3::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 3
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionTabV3::documentMode
+ \brief whether the tabbar is in document mode.
+
+ The default value is false;
+*/
+
+/*!
+ \variable QStyleOptionTabV3::leftButtonSize
+ \brief the size for the left widget on the tab.
+
+ The default value is QSize(-1, -1), i.e. an invalid size;
+*/
+
+/*!
+ \variable QStyleOptionTabV3::rightButtonSize
+ \brief the size for the right widget on the tab.
+
+ The default value is QSize(-1, -1), i.e. an invalid size;
+*/
+
+/*!
+ Constructs a QStyleOptionTabV3.
+*/
+
+QStyleOptionTabV3::QStyleOptionTabV3()
+ : QStyleOptionTabV2(Version)
+ , documentMode(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionTabV3::QStyleOptionTabV3(int version)
+ : QStyleOptionTabV2(version)
+{
+}
+
+/*!
+ \fn QStyleOptionTabV3::QStyleOptionTabV3(const QStyleOptionTabV3 &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \fn QStyleOptionTabV3::QStyleOptionTabV3(const QStyleOptionTabV2 &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ Constructs a QStyleOptionTabV3 copy of the \a other style option
+ which can be either of the QStyleOptionTabV3, QStyleOptionTabV2
+ or QStyleOptionTab types.
+
+ If the other style option's version is 1 or 2, the new style option's
+ \c leftButtonSize and \c rightButtonSize is set to an invalid value. If
+ its version is 3, its \c leftButtonSize and \c rightButtonSize values
+ are simply copied to the new style option.
+*/
+QStyleOptionTabV3::QStyleOptionTabV3(const QStyleOptionTab &other)
+ : QStyleOptionTabV2(Version)
+{
+ if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(&other)) {
+ *this = *tab;
+ } else {
+ *((QStyleOptionTabV2 *)this) = other;
+ version = Version;
+ }
+}
+
+/*!
+ Assigns the \a other style option to this QStyleOptionTabV3. The
+ \a other style option can be either of the QStyleOptionTabV3,
+ QStyleOptionTabV2 or QStyleOptionTab types.
+
+ If the other style option's version is 1 or 2, the new style option's
+ \c leftButtonSize and \c rightButtonSize is set to an invalid value. If
+ its version is 3, its \c leftButtonSize and \c rightButtonSize values
+ are simply copied to the new style option.
+*/
+QStyleOptionTabV3 &QStyleOptionTabV3::operator=(const QStyleOptionTab &other)
+{
+ QStyleOptionTabV2::operator=(other);
+
+ if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(&other)) {
+ leftButtonSize = tab->leftButtonSize;
+ rightButtonSize = tab->rightButtonSize;
+ } else {
+ leftButtonSize = QSize();
+ rightButtonSize = QSize();
+ documentMode = false;
+ }
+ return *this;
+}
+
+#endif // QT_NO_TABBAR
+
+/*!
+ \class QStyleOptionProgressBar
+ \brief The QStyleOptionProgressBar class is used to describe the
+ parameters necessary for drawing a progress bar.
+
+ Since Qt 4.1, Qt uses the QStyleOptionProgressBarV2 subclass for
+ drawing QProgressBar.
+
+ An instance of the QStyleOptionProgressBar class has type
+ SO_ProgressBar and version 1.
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles. The
+ version is used by QStyleOption subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast(),
+ you normally do not need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionProgressBar and QStyleOptionProgressBarV2.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionProgressBarV2, QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionProgressBar, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionProgressBar::QStyleOptionProgressBar()
+ : QStyleOption(QStyleOptionProgressBar::Version, SO_ProgressBar),
+ minimum(0), maximum(0), progress(0), textAlignment(Qt::AlignLeft), textVisible(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionProgressBar::QStyleOptionProgressBar(int version)
+ : QStyleOption(version, SO_ProgressBar),
+ minimum(0), maximum(0), progress(0), textAlignment(Qt::AlignLeft), textVisible(false)
+{
+}
+
+/*!
+ \fn QStyleOptionProgressBar::QStyleOptionProgressBar(const QStyleOptionProgressBar &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionProgressBar::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ProgressBar} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionProgressBar::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionProgressBar::minimum
+ \brief the minimum value for the progress bar
+
+ This is the minimum value in the progress bar. The default value
+ is 0.
+
+ \sa QProgressBar::minimum
+*/
+
+/*!
+ \variable QStyleOptionProgressBar::maximum
+ \brief the maximum value for the progress bar
+
+ This is the maximum value in the progress bar. The default value
+ is 0.
+
+ \sa QProgressBar::maximum
+*/
+
+/*!
+ \variable QStyleOptionProgressBar::text
+ \brief the text for the progress bar
+
+ The progress bar text is usually just the progress expressed as a
+ string. An empty string indicates that the progress bar has not
+ started yet. The default value is an empty string.
+
+ \sa QProgressBar::text
+*/
+
+/*!
+ \variable QStyleOptionProgressBar::textVisible
+ \brief a flag indicating whether or not text is visible
+
+ If this flag is true then the text is visible. Otherwise, the text
+ is not visible. The default value is false.
+
+ \sa QProgressBar::textVisible
+*/
+
+
+/*!
+ \variable QStyleOptionProgressBar::textAlignment
+ \brief the text alignment for the text in the QProgressBar
+
+ This can be used as a guide on where the text should be in the
+ progress bar. The default value is Qt::AlignLeft.
+*/
+
+/*!
+ \variable QStyleOptionProgressBar::progress
+ \brief the current progress for the progress bar
+
+ The current progress. A value of QStyleOptionProgressBar::minimum
+ - 1 indicates that the progress hasn't started yet. The default
+ value is 0.
+
+ \sa QProgressBar::value
+*/
+
+/*!
+ \class QStyleOptionProgressBarV2
+ \brief The QStyleOptionProgressBarV2 class is used to describe the
+ parameters necessary for drawing a progress bar in Qt 4.1 or above.
+
+ \since 4.1
+
+ An instance of this class has \l{QStyleOption::type} {type}
+ SO_ProgressBar and \l{QStyleOption::version} {version} 2.
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles. The
+ version is used by QStyleOption subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast(),
+ you normally do not need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionProgressBar and QStyleOptionProgressBarV2. One way
+ to achieve this is to use the QStyleOptionProgressBarV2 copy
+ constructor. For example:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 2
+
+ In the example above: If the \c progressBarOption's version is 1,
+ the extra members (\l orientation, \l invertedAppearance, and \l
+ bottomToTop) are set to default values for \c progressBarV2. If
+ the \c progressBarOption's version is 2, the constructor will
+ simply copy the extra members to progressBarV2.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionProgressBar, QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionProgressBarV2, initializing he members
+ variables to their default values.
+*/
+
+QStyleOptionProgressBarV2::QStyleOptionProgressBarV2()
+ : QStyleOptionProgressBar(2),
+ orientation(Qt::Horizontal), invertedAppearance(false), bottomToTop(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionProgressBarV2::QStyleOptionProgressBarV2(int version)
+ : QStyleOptionProgressBar(version),
+ orientation(Qt::Horizontal), invertedAppearance(false), bottomToTop(false)
+{
+}
+
+/*!
+ Constructs a copy of the \a other style option which can be either
+ of the QStyleOptionProgressBar and QStyleOptionProgressBarV2
+ types.
+
+ If the \a{other} style option's version is 1, the extra members (\l
+ orientation, \l invertedAppearance, and \l bottomToTop) are set
+ to default values for the new style option. If \a{other}'s version
+ is 2, the extra members are simply copied.
+
+ \sa version
+*/
+QStyleOptionProgressBarV2::QStyleOptionProgressBarV2(const QStyleOptionProgressBar &other)
+ : QStyleOptionProgressBar(2), orientation(Qt::Horizontal), invertedAppearance(false), bottomToTop(false)
+{
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(&other);
+ if (pb2)
+ *this = *pb2;
+ else
+ *((QStyleOptionProgressBar *)this) = other;
+}
+
+/*!
+ Constructs a copy of the \a other style option.
+*/
+QStyleOptionProgressBarV2::QStyleOptionProgressBarV2(const QStyleOptionProgressBarV2 &other)
+ : QStyleOptionProgressBar(2), orientation(Qt::Horizontal), invertedAppearance(false), bottomToTop(false)
+{
+ *this = other;
+}
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionProgressBarV2
+ or QStyleOptionProgressBar types.
+
+ If the \a{other} style option's version is 1, the extra members
+ (\l orientation, \l invertedAppearance, and \l bottomToTop) are
+ set to default values for this style option. If \a{other}'s
+ version is 2, the extra members are simply copied to this style
+ option.
+*/
+QStyleOptionProgressBarV2 &QStyleOptionProgressBarV2::operator=(const QStyleOptionProgressBar &other)
+{
+ QStyleOptionProgressBar::operator=(other);
+
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(&other);
+ orientation = pb2 ? pb2->orientation : Qt::Horizontal;
+ invertedAppearance = pb2 ? pb2->invertedAppearance : false;
+ bottomToTop = pb2 ? pb2->bottomToTop : false;
+ return *this;
+}
+
+/*!
+ \variable QStyleOptionProgressBarV2::orientation
+ \brief the progress bar's orientation (horizontal or vertical);
+ the default orentation is Qt::Horizontal
+
+ \sa QProgressBar::orientation
+*/
+
+/*!
+ \variable QStyleOptionProgressBarV2::invertedAppearance
+ \brief whether the progress bar's appearance is inverted
+
+ The default value is false.
+
+ \sa QProgressBar::invertedAppearance
+*/
+
+/*!
+ \variable QStyleOptionProgressBarV2::bottomToTop
+ \brief whether the text reads from bottom to top when the progress
+ bar is vertical
+
+ The default value is false.
+
+ \sa QProgressBar::textDirection
+*/
+
+/*!
+ \enum QStyleOptionProgressBarV2::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ProgressBar} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionProgressBarV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+
+/*!
+ \class QStyleOptionMenuItem
+ \brief The QStyleOptionMenuItem class is used to describe the
+ parameter necessary for drawing a menu item.
+
+ QStyleOptionMenuItem contains all the information that QStyle
+ functions need to draw the menu items from \l QMenu. It is also
+ used for drawing other menu-related widgets.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionMenuItem, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionMenuItem::QStyleOptionMenuItem()
+ : QStyleOption(QStyleOptionMenuItem::Version, SO_MenuItem), menuItemType(Normal),
+ checkType(NotCheckable), checked(false), menuHasCheckableItems(true), maxIconWidth(0), tabWidth(0)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
+ : QStyleOption(version, SO_MenuItem), menuItemType(Normal),
+ checkType(NotCheckable), checked(false), menuHasCheckableItems(true), maxIconWidth(0), tabWidth(0)
+{
+}
+
+/*!
+ \fn QStyleOptionMenuItem::QStyleOptionMenuItem(const QStyleOptionMenuItem &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionMenuItem::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_MenuItem} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionMenuItem::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \enum QStyleOptionMenuItem::MenuItemType
+
+ This enum indicates the type of menu item that the structure describes.
+
+ \value Normal A normal menu item.
+ \value DefaultItem A menu item that is the default action as specified with \l QMenu::defaultAction().
+ \value Separator A menu separator.
+ \value SubMenu Indicates the menu item points to a sub-menu.
+ \value Scroller A popup menu scroller (currently only used on Mac OS X).
+ \value TearOff A tear-off handle for the menu.
+ \value Margin The margin of the menu.
+ \value EmptyArea The empty area of the menu.
+
+ \sa menuItemType
+*/
+
+/*!
+ \enum QStyleOptionMenuItem::CheckType
+
+ This enum is used to indicate whether or not a check mark should be
+ drawn for the item, or even if it should be drawn at all.
+
+ \value NotCheckable The item is not checkable.
+ \value Exclusive The item is an exclusive check item (like a radio button).
+ \value NonExclusive The item is a non-exclusive check item (like a check box).
+
+ \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusive
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::menuItemType
+ \brief the type of menu item
+
+ The default value is \l Normal.
+
+ \sa MenuItemType
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::checkType
+ \brief the type of checkmark of the menu item
+
+ The default value is \l NotCheckable.
+
+ \sa CheckType
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::checked
+ \brief whether the menu item is checked or not
+
+ The default value is false.
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::menuHasCheckableItems
+ \brief whether the menu as a whole has checkable items or not
+
+ The default value is true.
+
+ If this option is set to false, then the menu has no checkable
+ items. This makes it possible for GUI styles to save some
+ horizontal space that would normally be used for the check column.
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::menuRect
+ \brief the rectangle for the entire menu
+
+ The default value is a null rectangle, i.e. a rectangle with both
+ the width and the height set to 0.
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::text
+ \brief the text for the menu item
+
+ Note that the text format is something like this "Menu
+ text\bold{\\t}Shortcut".
+
+ If the menu item doesn't have a shortcut, it will just contain the
+ menu item's text. The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::icon
+ \brief the icon for the menu item
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::maxIconWidth
+ \brief the maximum icon width for the icon in the menu item
+
+ This can be used for drawing the icon into the correct place or
+ properly aligning items. The variable must be set regardless of
+ whether or not the menu item has an icon. The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionMenuItem::tabWidth
+ \brief the tab width for the menu item
+
+ The tab width is the distance between the text of the menu item
+ and the shortcut. The default value is 0.
+*/
+
+
+/*!
+ \variable QStyleOptionMenuItem::font
+ \brief the font used for the menu item text
+
+ This is the font that should be used for drawing the menu text
+ minus the shortcut. The shortcut is usually drawn using the
+ painter's font. By default, the application's default font is
+ used.
+*/
+
+/*!
+ \class QStyleOptionComplex
+ \brief The QStyleOptionComplex class is used to hold parameters that are
+ common to all complex controls.
+
+ This class is not used on its own. Instead it is used to derive
+ other complex control options, for example QStyleOptionSlider and
+ QStyleOptionSpinBox.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator).
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionComplex of the specified \a type and \a
+ version, initializing the member variables to their default
+ values. This constructor is usually called by subclasses.
+*/
+
+QStyleOptionComplex::QStyleOptionComplex(int version, int type)
+ : QStyleOption(version, type), subControls(QStyle::SC_All), activeSubControls(QStyle::SC_None)
+{
+}
+
+/*!
+ \fn QStyleOptionComplex::QStyleOptionComplex(const QStyleOptionComplex &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionComplex::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Complex} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionComplex::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionComplex::subControls
+
+ This variable holds a bitwise OR of the \l{QStyle::SubControl}
+ {sub-controls} to be drawn for the complex control.
+
+ The default value is QStyle::SC_All.
+
+ \sa QStyle::SubControl
+*/
+
+/*!
+ \variable QStyleOptionComplex::activeSubControls
+
+ This variable holds a bitwise OR of the \l{QStyle::SubControl}
+ {sub-controls} that are active for the complex control.
+
+ The default value is QStyle::SC_None.
+
+ \sa QStyle::SubControl
+*/
+
+#ifndef QT_NO_SLIDER
+/*!
+ \class QStyleOptionSlider
+ \brief The QStyleOptionSlider class is used to describe the
+ parameters needed for drawing a slider.
+
+ QStyleOptionSlider contains all the information that QStyle
+ functions need to draw QSlider and QScrollBar.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionComplex, QSlider, QScrollBar
+*/
+
+/*!
+ Constructs a QStyleOptionSlider, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionSlider::QStyleOptionSlider()
+ : QStyleOptionComplex(Version, SO_Slider), orientation(Qt::Horizontal), minimum(0), maximum(0),
+ tickPosition(QSlider::NoTicks), tickInterval(0), upsideDown(false),
+ sliderPosition(0), sliderValue(0), singleStep(0), pageStep(0), notchTarget(0.0),
+ dialWrapping(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionSlider::QStyleOptionSlider(int version)
+ : QStyleOptionComplex(version, SO_Slider), orientation(Qt::Horizontal), minimum(0), maximum(0),
+ tickPosition(QSlider::NoTicks), tickInterval(0), upsideDown(false),
+ sliderPosition(0), sliderValue(0), singleStep(0), pageStep(0), notchTarget(0.0),
+ dialWrapping(false)
+{
+}
+
+/*!
+ \fn QStyleOptionSlider::QStyleOptionSlider(const QStyleOptionSlider &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionSlider::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Slider} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionSlider::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionSlider::orientation
+ \brief the slider's orientation (horizontal or vertical)
+
+ The default orientation is Qt::Horizontal.
+
+ \sa Qt::Orientation
+*/
+
+/*!
+ \variable QStyleOptionSlider::minimum
+ \brief the minimum value for the slider
+
+ The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionSlider::maximum
+ \brief the maximum value for the slider
+
+ The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionSlider::tickPosition
+ \brief the position of the slider's tick marks, if any
+
+ The default value is QSlider::NoTicks.
+
+ \sa QSlider::TickPosition
+*/
+
+/*!
+ \variable QStyleOptionSlider::tickInterval
+ \brief the interval that should be drawn between tick marks
+
+ The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionSlider::notchTarget
+ \brief the number of pixel between notches
+
+ The default value is 0.0.
+
+ \sa QDial::notchTarget()
+*/
+
+/*!
+ \variable QStyleOptionSlider::dialWrapping
+ \brief whether the dial should wrap or not
+
+ The default value is false, i.e. the dial is not wrapped.
+
+ \sa QDial::wrapping()
+*/
+
+/*!
+ \variable QStyleOptionSlider::upsideDown
+ \brief the slider control orientation
+
+ Normally a slider increases as it moves up or to the right;
+ upsideDown indicates that it should do the opposite (increase as
+ it moves down or to the left). The default value is false,
+ i.e. the slider increases as it moves up or to the right.
+
+ \sa QStyle::sliderPositionFromValue(),
+ QStyle::sliderValueFromPosition(),
+ QAbstractSlider::invertedAppearance
+*/
+
+/*!
+ \variable QStyleOptionSlider::sliderPosition
+ \brief the position of the slider handle
+
+ If the slider has active feedback (i.e.,
+ QAbstractSlider::tracking is true), this value will be the same as
+ \l sliderValue. Otherwise, it will have the current position of
+ the handle. The default value is 0.
+
+ \sa QAbstractSlider::tracking, sliderValue
+*/
+
+/*!
+ \variable QStyleOptionSlider::sliderValue
+ \brief the value of the slider
+
+ If the slider has active feedback (i.e.,
+ QAbstractSlider::tracking is true), this value will be the same
+ as \l sliderPosition. Otherwise, it will have the value the
+ slider had before the mouse was pressed.
+
+ The default value is 0.
+
+ \sa QAbstractSlider::tracking sliderPosition
+*/
+
+/*!
+ \variable QStyleOptionSlider::singleStep
+ \brief the size of the single step of the slider
+
+ The default value is 0.
+
+ \sa QAbstractSlider::singleStep
+*/
+
+/*!
+ \variable QStyleOptionSlider::pageStep
+ \brief the size of the page step of the slider
+
+ The default value is 0.
+
+ \sa QAbstractSlider::pageStep
+*/
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_SPINBOX
+/*!
+ \class QStyleOptionSpinBox
+ \brief The QStyleOptionSpinBox class is used to describe the
+ parameters necessary for drawing a spin box.
+
+ QStyleOptionSpinBox contains all the information that QStyle
+ functions need to draw QSpinBox and QDateTimeEdit.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionComplex
+*/
+
+/*!
+ Constructs a QStyleOptionSpinBox, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionSpinBox::QStyleOptionSpinBox()
+ : QStyleOptionComplex(Version, SO_SpinBox), buttonSymbols(QAbstractSpinBox::UpDownArrows),
+ stepEnabled(QAbstractSpinBox::StepNone), frame(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionSpinBox::QStyleOptionSpinBox(int version)
+ : QStyleOptionComplex(version, SO_SpinBox), buttonSymbols(QAbstractSpinBox::UpDownArrows),
+ stepEnabled(QAbstractSpinBox::StepNone), frame(false)
+{
+}
+
+/*!
+ \fn QStyleOptionSpinBox::QStyleOptionSpinBox(const QStyleOptionSpinBox &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionSpinBox::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_SpinBox} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionSpinBox::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionSpinBox::buttonSymbols
+ \brief the type of button symbols to draw for the spin box
+
+ The default value is QAbstractSpinBox::UpDownArrows specufying
+ little arrows in the classic style.
+
+ \sa QAbstractSpinBox::ButtonSymbols
+*/
+
+/*!
+ \variable QStyleOptionSpinBox::stepEnabled
+ \brief which buttons of the spin box that are enabled
+
+ The default value is QAbstractSpinBox::StepNone.
+
+ \sa QAbstractSpinBox::StepEnabled
+*/
+
+/*!
+ \variable QStyleOptionSpinBox::frame
+ \brief whether the spin box has a frame
+
+ The default value is false, i.e. the spin box has no frame.
+*/
+#endif // QT_NO_SPINBOX
+
+/*!
+ \class QStyleOptionQ3ListViewItem
+ \brief The QStyleOptionQ3ListViewItem class is used to describe an
+ item drawn in a Q3ListView.
+
+ This class is used for drawing the compatibility Q3ListView's
+ items. \bold {It is not recommended for new classes}.
+
+ QStyleOptionQ3ListViewItem contains all the information that
+ QStyle functions need to draw the Q3ListView items.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionQ3ListView, Q3ListViewItem
+*/
+
+/*!
+ \enum QStyleOptionQ3ListViewItem::Q3ListViewItemFeature
+
+ This enum describes the features a list view item can have.
+
+ \value None A standard item.
+ \value Expandable The item has children that can be shown.
+ \value MultiLine The item is more than one line tall.
+ \value Visible The item is visible.
+ \value ParentControl The item's parent is a type of item control (Q3CheckListItem::Controller).
+
+ \sa features, Q3ListViewItem::isVisible(), Q3ListViewItem::multiLinesEnabled(),
+ Q3ListViewItem::isExpandable()
+*/
+
+/*!
+ Constructs a QStyleOptionQ3ListViewItem, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionQ3ListViewItem::QStyleOptionQ3ListViewItem()
+ : QStyleOption(Version, SO_Q3ListViewItem), features(None), height(0), totalHeight(0),
+ itemY(0), childCount(0)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionQ3ListViewItem::QStyleOptionQ3ListViewItem(int version)
+ : QStyleOption(version, SO_Q3ListViewItem), features(None), height(0), totalHeight(0),
+ itemY(0), childCount(0)
+{
+}
+
+/*!
+ \fn QStyleOptionQ3ListViewItem::QStyleOptionQ3ListViewItem(const QStyleOptionQ3ListViewItem &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionQ3ListViewItem::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Q3ListViewItem} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionQ3ListViewItem::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionQ3ListViewItem::features
+ \brief the features for this item
+
+ This variable is a bitwise OR of the features of the item. The deafult value is \l None.
+
+ \sa Q3ListViewItemFeature
+*/
+
+/*!
+ \variable QStyleOptionQ3ListViewItem::height
+ \brief the height of the item
+
+ This doesn't include the height of the item's children. The default height is 0.
+
+ \sa Q3ListViewItem::height()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListViewItem::totalHeight
+ \brief the total height of the item, including its children
+
+ The default total height is 0.
+
+ \sa Q3ListViewItem::totalHeight()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListViewItem::itemY
+ \brief the Y-coordinate for the item
+
+ The default value is 0.
+
+ \sa Q3ListViewItem::itemPos()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListViewItem::childCount
+ \brief the number of children the item has
+*/
+
+/*!
+ \class QStyleOptionQ3ListView
+ \brief The QStyleOptionQ3ListView class is used to describe the
+ parameters for drawing a Q3ListView.
+
+ This class is used for drawing the compatibility Q3ListView. \bold
+ {It is not recommended for new classes}.
+
+ QStyleOptionQ3ListView contains all the information that QStyle
+ functions need to draw Q3ListView.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOptionComplex, Q3ListView, QStyleOptionQ3ListViewItem
+*/
+
+/*!
+ Creates a QStyleOptionQ3ListView, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionQ3ListView::QStyleOptionQ3ListView()
+ : QStyleOptionComplex(Version, SO_Q3ListView), viewportBGRole(QPalette::Base),
+ sortColumn(0), itemMargin(0), treeStepSize(0), rootIsDecorated(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionQ3ListView::QStyleOptionQ3ListView(int version)
+ : QStyleOptionComplex(version, SO_Q3ListView), viewportBGRole(QPalette::Base),
+ sortColumn(0), itemMargin(0), treeStepSize(0), rootIsDecorated(false)
+{
+}
+
+/*!
+ \fn QStyleOptionQ3ListView::QStyleOptionQ3ListView(const QStyleOptionQ3ListView &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionQ3ListView::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Q3ListView} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionQ3ListView::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::items
+ \brief a list of items in the Q3ListView
+
+ This is a list of \l {QStyleOptionQ3ListViewItem}s. The first item
+ can be used for most of the calculation that are needed for
+ drawing a list view. Any additional items are the children of
+ this first item, which may be used for additional information.
+
+ \sa QStyleOptionQ3ListViewItem
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::viewportPalette
+ \brief the palette of Q3ListView's viewport
+
+ By default, the application's default palette is used.
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::viewportBGRole
+ \brief the background role of Q3ListView's viewport
+
+ The default value is QPalette::Base.
+
+ \sa QWidget::backgroundRole()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::sortColumn
+ \brief the sort column of the list view
+
+ The default value is 0.
+
+ \sa Q3ListView::sortColumn()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::itemMargin
+ \brief the margin for items in the list view
+
+ The default value is 0.
+
+ \sa Q3ListView::itemMargin()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::treeStepSize
+ \brief the number of pixel to offset children items from their
+ parents
+
+ The default value is 0.
+
+ \sa Q3ListView::treeStepSize()
+*/
+
+/*!
+ \variable QStyleOptionQ3ListView::rootIsDecorated
+ \brief whether root items are decorated
+
+ The default value is false.
+
+ \sa Q3ListView::rootIsDecorated()
+*/
+
+/*!
+ \class QStyleOptionQ3DockWindow
+ \brief The QStyleOptionQ3DockWindow class is used to describe the
+ parameters for drawing various parts of a Q3DockWindow.
+
+ This class is used for drawing the old Q3DockWindow and its
+ parts. \bold {It is not recommended for new classes}.
+
+ QStyleOptionQ3DockWindow contains all the information that QStyle
+ functions need to draw Q3DockWindow and its parts.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, Q3DockWindow
+*/
+
+/*!
+ Constructs a QStyleOptionQ3DockWindow, initializing the member
+ variables to their default values.
+*/
+
+QStyleOptionQ3DockWindow::QStyleOptionQ3DockWindow()
+ : QStyleOption(Version, SO_Q3DockWindow), docked(false), closeEnabled(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionQ3DockWindow::QStyleOptionQ3DockWindow(int version)
+ : QStyleOption(version, SO_Q3DockWindow), docked(false), closeEnabled(false)
+{
+}
+
+/*!
+ \fn QStyleOptionQ3DockWindow::QStyleOptionQ3DockWindow(const QStyleOptionQ3DockWindow &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionQ3DockWindow::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_Q3DockWindow} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionQ3DockWindow::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionQ3DockWindow::docked
+ \brief whether the dock window is currently docked
+
+ The default value is false.
+*/
+
+/*!
+ \variable QStyleOptionQ3DockWindow::closeEnabled
+ \brief whether the dock window has a close button
+
+ The default value is false.
+*/
+
+/*!
+ \class QStyleOptionDockWidget
+ \brief The QStyleOptionDockWidget class is used to describe the
+ parameters for drawing a dock widget.
+
+ QStyleOptionDockWidget contains all the information that QStyle
+ functions need to draw graphical elements like QDockWidget.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption
+*/
+
+/*!
+ Constructs a QStyleOptionDockWidget, initializing the member
+ variables to their default values.
+*/
+
+QStyleOptionDockWidget::QStyleOptionDockWidget()
+ : QStyleOption(Version, SO_DockWidget), closable(false),
+ movable(false), floatable(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionDockWidget::QStyleOptionDockWidget(int version)
+ : QStyleOption(version, SO_DockWidget), closable(false),
+ movable(false), floatable(false)
+{
+}
+
+QStyleOptionDockWidgetV2::QStyleOptionDockWidgetV2()
+ : QStyleOptionDockWidget(Version), verticalTitleBar(false)
+{
+}
+
+QStyleOptionDockWidgetV2::QStyleOptionDockWidgetV2(
+ const QStyleOptionDockWidget &other)
+ : QStyleOptionDockWidget(Version)
+{
+ (void)QStyleOptionDockWidgetV2::operator=(other);
+}
+
+QStyleOptionDockWidgetV2 &QStyleOptionDockWidgetV2::operator = (
+ const QStyleOptionDockWidget &other)
+{
+ QStyleOptionDockWidget::operator=(other);
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(&other);
+ verticalTitleBar = v2 ? v2->verticalTitleBar : false;
+ return *this;
+}
+
+QStyleOptionDockWidgetV2::QStyleOptionDockWidgetV2(int version)
+ : QStyleOptionDockWidget(version), verticalTitleBar(false)
+{
+}
+
+/*!
+ \fn QStyleOptionDockWidget::QStyleOptionDockWidget(const QStyleOptionDockWidget &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionDockWidget::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_DockWidget} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionDockWidget::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionDockWidget::title
+ \brief the title of the dock window
+
+ The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionDockWidget::closable
+ \brief whether the dock window is closable
+
+ The default value is true.
+*/
+
+/*!
+ \variable QStyleOptionDockWidget::movable
+ \brief whether the dock window is movable
+
+ The default value is false.
+*/
+
+/*!
+ \variable QStyleOptionDockWidget::floatable
+ \brief whether the dock window is floatable
+
+ The default value is true.
+*/
+
+/*!
+ \class QStyleOptionToolButton
+ \brief The QStyleOptionToolButton class is used to describe the
+ parameters for drawing a tool button.
+
+ QStyleOptionToolButton contains all the information that QStyle
+ functions need to draw QToolButton.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionComplex, QStyleOptionButton
+*/
+
+/*!
+ \enum QStyleOptionToolButton::ToolButtonFeature
+ Describes the various features that a tool button can have.
+
+ \value None A normal tool button.
+ \value Arrow The tool button is an arrow.
+ \value Menu The tool button has a menu.
+ \value PopupDelay There is a delay to showing the menu.
+ \value HasMenu The button has a popup menu.
+ \value MenuButtonPopup The button should display an arrow to
+ indicate that a menu is present.
+
+ \sa features, QToolButton::toolButtonStyle(), QToolButton::popupMode()
+*/
+
+/*!
+ Constructs a QStyleOptionToolButton, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionToolButton::QStyleOptionToolButton()
+ : QStyleOptionComplex(Version, SO_ToolButton), features(None), arrowType(Qt::DownArrow)
+ , toolButtonStyle(Qt::ToolButtonIconOnly)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionToolButton::QStyleOptionToolButton(int version)
+ : QStyleOptionComplex(version, SO_ToolButton), features(None), arrowType(Qt::DownArrow)
+ , toolButtonStyle(Qt::ToolButtonIconOnly)
+
+{
+}
+
+/*!
+ \fn QStyleOptionToolButton::QStyleOptionToolButton(const QStyleOptionToolButton &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionToolButton::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ToolButton} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionToolButton::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionToolButton::features
+ \brief an OR combination of the tool button's features
+
+ The default value is \l None.
+
+ \sa ToolButtonFeature
+*/
+
+/*!
+ \variable QStyleOptionToolButton::icon
+ \brief the icon for the tool button
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+
+ \sa iconSize
+*/
+
+/*!
+ \variable QStyleOptionToolButton::iconSize
+ \brief the size of the icon for the tool button
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+*/
+
+/*!
+ \variable QStyleOptionToolButton::text
+ \brief the text of the tool button
+
+ This value is only used if toolButtonStyle is
+ Qt::ToolButtonTextUnderIcon, Qt::ToolButtonTextBesideIcon, or
+ Qt::ToolButtonTextOnly. The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionToolButton::arrowType
+ \brief the direction of the arrow for the tool button
+
+ This value is only used if \l features includes \l Arrow. The
+ default value is Qt::DownArrow.
+*/
+
+/*!
+ \variable QStyleOptionToolButton::toolButtonStyle
+ \brief a Qt::ToolButtonStyle value describing the appearance of
+ the tool button
+
+ The default value is Qt::ToolButtonIconOnly.
+
+ \sa QToolButton::toolButtonStyle()
+*/
+
+/*!
+ \variable QStyleOptionToolButton::pos
+ \brief the position of the tool button
+
+ The default value is a null point, i.e. (0, 0)
+*/
+
+/*!
+ \variable QStyleOptionToolButton::font
+ \brief the font that is used for the text
+
+ This value is only used if toolButtonStyle is
+ Qt::ToolButtonTextUnderIcon, Qt::ToolButtonTextBesideIcon, or
+ Qt::ToolButtonTextOnly. By default, the application's default font
+ is used.
+*/
+
+/*!
+ \class QStyleOptionComboBox
+ \brief The QStyleOptionComboBox class is used to describe the
+ parameter for drawing a combobox.
+
+ QStyleOptionButton contains all the information that QStyle
+ functions need to draw QComboBox.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionComplex, QComboBox
+*/
+
+/*!
+ Creates a QStyleOptionComboBox, initializing the members variables
+ to their default values.
+*/
+
+QStyleOptionComboBox::QStyleOptionComboBox()
+ : QStyleOptionComplex(Version, SO_ComboBox), editable(false), frame(true)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionComboBox::QStyleOptionComboBox(int version)
+ : QStyleOptionComplex(version, SO_ComboBox), editable(false), frame(true)
+{
+}
+
+/*!
+ \fn QStyleOptionComboBox::QStyleOptionComboBox(const QStyleOptionComboBox &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionComboBox::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ComboBox} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionComboBox::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionComboBox::editable
+ \brief whether or not the combobox is editable or not
+
+ the default
+ value is false
+
+ \sa QComboBox::isEditable()
+*/
+
+
+/*!
+ \variable QStyleOptionComboBox::frame
+ \brief whether the combo box has a frame
+
+ The default value is true.
+*/
+
+/*!
+ \variable QStyleOptionComboBox::currentText
+ \brief the text for the current item of the combo box
+
+ The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionComboBox::currentIcon
+ \brief the icon for the current item of the combo box
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+*/
+
+/*!
+ \variable QStyleOptionComboBox::iconSize
+ \brief the icon size for the current item of the combo box
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+*/
+
+/*!
+ \variable QStyleOptionComboBox::popupRect
+ \brief the popup rectangle for the combobox
+
+ The default value is a null rectangle, i.e. a rectangle with both
+ the width and the height set to 0.
+
+ This variable is currently unused. You can safely ignore it.
+
+ \sa QStyle::SC_ComboBoxListBoxPopup
+*/
+
+/*!
+ \class QStyleOptionToolBox
+ \brief The QStyleOptionToolBox class is used to describe the
+ parameters needed for drawing a tool box.
+
+ QStyleOptionToolBox contains all the information that QStyle
+ functions need to draw QToolBox.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QToolBox
+*/
+
+/*!
+ Creates a QStyleOptionToolBox, initializing the members variables
+ to their default values.
+*/
+
+QStyleOptionToolBox::QStyleOptionToolBox()
+ : QStyleOption(Version, SO_ToolBox)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionToolBox::QStyleOptionToolBox(int version)
+ : QStyleOption(version, SO_ToolBox)
+{
+}
+
+/*!
+ \fn QStyleOptionToolBox::QStyleOptionToolBox(const QStyleOptionToolBox &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionToolBox::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ToolBox} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionToolBox::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionToolBox::icon
+ \brief the icon for the tool box tab
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+*/
+
+/*!
+ \variable QStyleOptionToolBox::text
+ \brief the text for the tool box tab
+
+ The default value is an empty string.
+*/
+
+/*!
+ \class QStyleOptionToolBoxV2
+ \brief The QStyleOptionToolBoxV2 class is used to describe the parameters necessary for drawing a frame in Qt 4.3 or above.
+
+ \since 4.3
+ QStyleOptionToolBoxV2 inherits QStyleOptionToolBox which is used for
+ drawing the tabs in a QToolBox.
+
+ An instance of the QStyleOptionToolBoxV2 class has
+ \l{QStyleOption::type} {type} SO_ToolBox and
+ \l{QStyleOption::version} {version} 2. The type is used
+ internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles. The
+ version is used by QStyleOption subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast(),
+ you normally do not need to check it.
+
+ If you create your own QStyle subclass, you should handle both
+ QStyleOptionToolBox and QStyleOptionToolBoxV2.
+
+ \sa QStyleOptionToolBox, QStyleOption
+*/
+
+/*!
+ Contsructs a QStyleOptionToolBoxV2 object.
+*/
+QStyleOptionToolBoxV2::QStyleOptionToolBoxV2()
+ : QStyleOptionToolBox(Version), position(Beginning), selectedPosition(NotAdjacent)
+{
+}
+
+/*!
+ \fn QStyleOptionToolBoxV2::QStyleOptionToolBoxV2(const QStyleOptionToolBoxV2 &other)
+
+ Constructs a QStyleOptionToolBoxV2 copy of the \a other style option.
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionToolBoxV2::QStyleOptionToolBoxV2(int version)
+ : QStyleOptionToolBox(version), position(Beginning), selectedPosition(NotAdjacent)
+{
+}
+
+/*!
+ Constructs a QStyleOptionToolBoxV2 copy of the \a other style option
+ which can be either of the QStyleOptionToolBoxV2 or
+ QStyleOptionToolBox types.
+
+ If the \a other style option's version is 1, the new style
+ option's \l{QStyleOptionTab::position} {position} value is set to
+ \l QStyleOptionToolBoxV2::Beginning and \l selectedPosition is set
+ to \l QStyleOptionToolBoxV2::NotAdjacent. If its version is 2, the
+ \l{QStyleOptionTab::position} {position} selectedPosition values
+ are simply copied to the new style option.
+
+ \sa version
+*/
+QStyleOptionToolBoxV2::QStyleOptionToolBoxV2(const QStyleOptionToolBox &other)
+{
+ QStyleOptionToolBox::operator=(other);
+
+ const QStyleOptionToolBoxV2 *f2 = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(&other);
+ position = f2 ? f2->position : Beginning;
+ selectedPosition = f2 ? f2->selectedPosition : NotAdjacent;
+ version = Version;
+}
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionToolBoxV2 or
+ QStyleOptionToolBox types.
+
+ If the \a{other} style option's version is 1, this style option's
+ \l{QStyleOptionTab::position} {position} and \l selectedPosition
+ values are set to \l QStyleOptionToolBoxV2::Beginning and \l
+ QStyleOptionToolBoxV2::NotAdjacent respectively. If its
+ \l{QStyleOption::version} {version} is 2, these values are simply
+ copied to this style option.
+*/
+QStyleOptionToolBoxV2 &QStyleOptionToolBoxV2::operator=(const QStyleOptionToolBox &other)
+{
+ QStyleOptionToolBox::operator=(other);
+
+ const QStyleOptionToolBoxV2 *f2 = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(&other);
+ position = f2 ? f2->position : Beginning;
+ selectedPosition = f2 ? f2->selectedPosition : NotAdjacent;
+ version = Version;
+ return *this;
+}
+
+
+/*!
+ \enum QStyleOptionToolBoxV2::SelectedPosition
+
+ This enum describes the position of the selected tab. Some styles
+ need to draw a tab differently depending on whether or not it is
+ adjacent to the selected tab.
+
+ \value NotAdjacent The tab is not adjacent to a selected tab (or is the selected tab).
+ \value NextIsSelected The next tab (typically the tab on the right) is selected.
+ \value PreviousIsSelected The previous tab (typically the tab on the left) is selected.
+
+ \sa selectedPosition
+*/
+
+/*!
+ \enum QStyleOptionToolBoxV2::StyleOptionVersion
+
+ This enum holds the version of this style option
+
+ \value Version 2
+*/
+
+/*!
+ \enum QStyleOptionToolBoxV2::TabPosition
+
+ This enum describes tab positions relative to other tabs.
+
+ \value Beginning The tab is the first (i.e., top-most) tab in
+ the toolbox.
+ \value Middle The tab is placed in the middle of the toolbox.
+ \value End The tab is placed at the bottom of the toolbox.
+ \value OnlyOneTab There is only one tab in the toolbox.
+*/
+
+/*!
+ \variable QStyleOptionToolBoxV2::selectedPosition
+ \brief the position of the selected tab in relation to this tab
+
+ The default value is NotAdjacent, i.e. the tab is not adjacent to
+ a selected tab nor is it the selected tab.
+*/
+
+#ifndef QT_NO_RUBBERBAND
+/*!
+ \class QStyleOptionRubberBand
+ \brief The QStyleOptionRubberBand class is used to describe the
+ parameters needed for drawing a rubber band.
+
+ QStyleOptionRubberBand contains all the information that
+ QStyle functions need to draw QRubberBand.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QRubberBand
+*/
+
+/*!
+ Creates a QStyleOptionRubberBand, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionRubberBand::QStyleOptionRubberBand()
+ : QStyleOption(Version, SO_RubberBand), shape(QRubberBand::Line), opaque(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionRubberBand::QStyleOptionRubberBand(int version)
+ : QStyleOption(version, SO_RubberBand), shape(QRubberBand::Line), opaque(false)
+{
+}
+
+/*!
+ \fn QStyleOptionRubberBand::QStyleOptionRubberBand(const QStyleOptionRubberBand &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionRubberBand::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_RubberBand} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionRubberBand::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionRubberBand::shape
+ \brief the shape of the rubber band
+
+ The default shape is QRubberBand::Line.
+*/
+
+/*!
+ \variable QStyleOptionRubberBand::opaque
+ \brief whether the rubber band is required to be drawn in an opaque style
+
+ The default value is true.
+*/
+#endif // QT_NO_RUBBERBAND
+
+/*!
+ \class QStyleOptionTitleBar
+ \brief The QStyleOptionTitleBar class is used to describe the
+ parameters for drawing a title bar.
+
+ QStyleOptionTitleBar contains all the information that QStyle
+ functions need to draw the title bar of a QMdiSubWindow.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionComplex, QMdiSubWindow
+*/
+
+/*!
+ Constructs a QStyleOptionTitleBar, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionTitleBar::QStyleOptionTitleBar()
+ : QStyleOptionComplex(Version, SO_TitleBar), titleBarState(0), titleBarFlags(0)
+{
+}
+
+/*!
+ \fn QStyleOptionTitleBar::QStyleOptionTitleBar(const QStyleOptionTitleBar &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionTitleBar::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_TitleBar} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionTitleBar::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionTitleBar::QStyleOptionTitleBar(int version)
+ : QStyleOptionComplex(version, SO_TitleBar), titleBarState(0), titleBarFlags(0)
+{
+}
+
+
+/*!
+ \variable QStyleOptionTitleBar::text
+ \brief the text of the title bar
+
+ The default value is an empty string.
+*/
+
+/*!
+ \variable QStyleOptionTitleBar::icon
+ \brief the icon for the title bar
+
+ The default value is an empty icon, i.e. an icon with neither a
+ pixmap nor a filename.
+*/
+
+/*!
+ \variable QStyleOptionTitleBar::titleBarState
+ \brief the state of the title bar
+
+ This is basically the window state of the underlying widget. The
+ default value is 0.
+
+ \sa QWidget::windowState()
+*/
+
+/*!
+ \variable QStyleOptionTitleBar::titleBarFlags
+ \brief the widget flags for the title bar
+
+ The default value is Qt::Widget.
+
+ \sa Qt::WindowFlags
+*/
+
+/*!
+ \class QStyleOptionViewItem
+ \brief The QStyleOptionViewItem class is used to describe the
+ parameters used to draw an item in a view widget.
+
+ QStyleOptionViewItem contains all the information that QStyle
+ functions need to draw the items for Qt's model/view classes.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, {model-view-programming.html}{Model/View
+ Programming}
+*/
+
+/*!
+ \enum QStyleOptionViewItem::Position
+
+ This enum describes the position of the item's decoration.
+
+ \value Left On the left of the text.
+ \value Right On the right of the text.
+ \value Top Above the text.
+ \value Bottom Below the text.
+
+ \sa decorationPosition
+*/
+
+/*!
+ \variable QStyleOptionViewItem::showDecorationSelected
+ \brief whether the decoration should be highlighted on selected
+ items
+
+ If this option is true, the branch and any decorations on selected items
+ should be highlighted, indicating that the item is selected; otherwise, no
+ highlighting is required. The default value is false.
+
+ \sa QStyle::SH_ItemView_ShowDecorationSelected, QAbstractItemView
+*/
+
+/*!
+ \variable QStyleOptionViewItem::textElideMode
+ \brief where ellipsis should be added for text that is too long to fit
+ into an item
+
+ The default value is Qt::ElideMiddle, i.e. the ellipsis appears in
+ the middle of the text.
+
+ \sa Qt::TextElideMode, QStyle::SH_ItemView_EllipsisLocation
+*/
+
+/*!
+ Constructs a QStyleOptionViewItem, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionViewItem::QStyleOptionViewItem()
+ : QStyleOption(Version, SO_ViewItem),
+ displayAlignment(Qt::AlignLeft), decorationAlignment(Qt::AlignLeft),
+ textElideMode(Qt::ElideMiddle), decorationPosition(Left),
+ showDecorationSelected(false)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionViewItem::QStyleOptionViewItem(int version)
+ : QStyleOption(version, SO_ViewItem),
+ displayAlignment(Qt::AlignLeft), decorationAlignment(Qt::AlignLeft),
+ textElideMode(Qt::ElideMiddle), decorationPosition(Left),
+ showDecorationSelected(false)
+{
+}
+
+/*!
+ \fn QStyleOptionViewItem::QStyleOptionViewItem(const QStyleOptionViewItem &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \enum QStyleOptionViewItem::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_ViewItem} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionViewItem::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionViewItem::displayAlignment
+ \brief the alignment of the display value for the item
+
+ The default value is Qt::AlignLeft.
+*/
+
+/*!
+ \variable QStyleOptionViewItem::decorationAlignment
+ \brief the alignment of the decoration for the item
+
+ The default value is Qt::AlignLeft.
+*/
+
+/*!
+ \variable QStyleOptionViewItem::decorationPosition
+ \brief the position of the decoration for the item
+
+ The default value is \l Left.
+
+ \sa Position
+*/
+
+/*!
+ \variable QStyleOptionViewItem::decorationSize
+ \brief the size of the decoration for the item
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+
+ \sa decorationAlignment, decorationPosition
+*/
+
+/*!
+ \variable QStyleOptionViewItem::font
+ \brief the font used for the item
+
+ By default, the application's default font is used.
+
+ \sa QFont
+*/
+
+/*!
+ \fn T qstyleoption_cast<T>(const QStyleOption *option)
+ \relates QStyleOption
+
+ Returns a T or 0 depending on the \l{QStyleOption::type}{type} and
+ \l{QStyleOption::version}{version} of the given \a option.
+
+ Example:
+
+ \snippet doc/src/snippets/qstyleoption/main.cpp 4
+
+ \sa QStyleOption::type, QStyleOption::version
+*/
+
+/*!
+ \fn T qstyleoption_cast<T>(QStyleOption *option)
+ \overload
+ \relates QStyleOption
+
+ Returns a T or 0 depending on the type of the given \a option.
+*/
+
+#ifndef QT_NO_TABWIDGET
+/*!
+ \class QStyleOptionTabWidgetFrame
+ \brief The QStyleOptionTabWidgetFrame class is used to describe the
+ parameters for drawing the frame around a tab widget.
+
+ QStyleOptionTabWidgetFrame contains all the information that
+ QStyle functions need to draw the frame around QTabWidget.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QTabWidget
+*/
+
+/*!
+ Constructs a QStyleOptionTabWidgetFrame, initializing the members
+ variables to their default values.
+*/
+QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame()
+ : QStyleOption(Version, SO_TabWidgetFrame), lineWidth(0), midLineWidth(0),
+ shape(QTabBar::RoundedNorth)
+{
+}
+
+/*!
+ \fn QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame(const QStyleOptionTabWidgetFrame &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \internal */
+QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame(int version)
+ : QStyleOption(version, SO_TabWidgetFrame), lineWidth(0), midLineWidth(0),
+ shape(QTabBar::RoundedNorth)
+{
+}
+
+/*!
+ \enum QStyleOptionTabWidgetFrame::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_TabWidgetFrame} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionTabWidgetFrame::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrame::lineWidth
+ \brief the line width for drawing the panel
+
+ The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrame::midLineWidth
+ \brief the mid-line width for drawing the panel
+
+ The mid line width is usually used in drawing sunken or raised
+ frames. The default value is 0.
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrame::shape
+ \brief the tab shape used to draw the tabs
+
+ The default value is QTabBar::RoundedNorth.
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrame::tabBarSize
+ \brief the size of the tab bar
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrame::rightCornerWidgetSize
+ \brief the size of the right-corner widget
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+*/
+
+/*! \variable QStyleOptionTabWidgetFrame::leftCornerWidgetSize
+ \brief the size of the left-corner widget
+
+ The default value is QSize(-1, -1), i.e. an invalid size.
+*/
+
+
+/*!
+
+ \class QStyleOptionTabWidgetFrameV2
+ \brief The QStyleOptionTabWidgetFrameV2 class is used to describe the
+ parameters for drawing the frame around a tab widget.
+
+ QStyleOptionTabWidgetFrameV2 contains all the information that
+ QStyle functions need to draw the frame around QTabWidget.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QTabWidget
+*/
+
+
+/*!
+ \variable QStyleOptionTabWidgetFrameV2::tabBarRect
+ \brief the rectangle containing all the tabs
+
+ The default value is a null rectangle, i.e. a rectangle with both
+ the width and the height set to 0.
+*/
+
+/*!
+ \variable QStyleOptionTabWidgetFrameV2::selectedTabRect
+ \brief the rectangle containing the selected tab
+
+ This rectangle is contained within the tabBarRect. The default
+ value is a null rectangle, i.e. a rectangle with both the width
+ and the height set to 0.
+*/
+
+
+/*!
+ Constructs a QStyleOptionTabWidgetFrameV2, initializing the members
+ variables to their default values.
+*/
+
+QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2()
+ : QStyleOptionTabWidgetFrame(Version)
+{
+}
+
+
+/*! \internal */
+QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(int version)
+ : QStyleOptionTabWidgetFrame(version)
+{
+}
+
+
+/*! \fn QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrameV2 &other)
+ Constructs a QStyleOptionTabWidgetFrameV2 copy of the \a other style option.
+
+ If the \a other style option's version is 1, the new style option's \l
+ selectedTabRect and tabBarRect will contain null rects
+
+ \sa version
+*/
+
+/*!
+ Constructs a QStyleOptionTabWidgetFrameV2 copy of the \a other style option.
+
+ If the \a other style option's version is 1, the new style option's \l
+ selectedTabRect and tabBarRect will contain null rects
+
+ \sa version
+*/
+QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other)
+{
+ QStyleOptionTabWidgetFrameV2::operator=(other);
+
+}
+
+
+/*!
+ Assigns the \a other style option to this style option. The \a
+ other style option can be either of the QStyleOptionFrameV2 or
+ QStyleOptionFrame types.
+
+ If the \a{other} style option's version is 1, this style option's
+ QStyleOptionFrameV2::FrameFeature value is set to
+ QStyleOptionFrameV2::None. If its version is 2, its
+ \l{QStyleOptionFrameV2::}{FrameFeature} value is simply copied to
+ this style option.
+*/
+QStyleOptionTabWidgetFrameV2 &QStyleOptionTabWidgetFrameV2::operator=(const QStyleOptionTabWidgetFrame &other)
+{
+ QStyleOptionTabWidgetFrame::operator=(other);
+ if (const QStyleOptionTabWidgetFrameV2 *f2 = qstyleoption_cast<const QStyleOptionTabWidgetFrameV2 *>(&other)) {
+ selectedTabRect = f2->selectedTabRect;
+ tabBarRect = f2->tabBarRect;
+ }
+ return *this;
+}
+
+
+/*!
+ \enum QStyleOptionTabWidgetFrameV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+
+#endif // QT_NO_TABWIDGET
+
+#ifndef QT_NO_TABBAR
+
+/*!
+ \class QStyleOptionTabBarBase
+ \brief The QStyleOptionTabBarBase class is used to describe
+ the base of a tab bar, i.e. the part that the tab bar usually
+ overlaps with.
+
+ QStyleOptionTabBarBase contains all the information that QStyle
+ functions need to draw the tab bar base. Note that this is only
+ drawn for a standalone QTabBar (one that isn't part of a
+ QTabWidget).
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QTabBar::drawBase()
+*/
+
+/*!
+ Construct a QStyleOptionTabBarBase, initializing the members
+ vaiables to their default values.
+*/
+QStyleOptionTabBarBase::QStyleOptionTabBarBase()
+ : QStyleOption(Version, SO_TabBarBase), shape(QTabBar::RoundedNorth)
+{
+}
+
+/*! \internal */
+QStyleOptionTabBarBase::QStyleOptionTabBarBase(int version)
+ : QStyleOption(version, SO_TabBarBase), shape(QTabBar::RoundedNorth)
+{
+}
+
+/*!
+ \fn QStyleOptionTabBarBase::QStyleOptionTabBarBase(const QStyleOptionTabBarBase &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ \enum QStyleOptionTabBarBase::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_TabBarBase} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionTabBarBase::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionTabBarBase::shape
+ \brief the shape of the tab bar
+
+ The default value is QTabBar::RoundedNorth.
+*/
+
+/*!
+ \variable QStyleOptionTabBarBase::tabBarRect
+ \brief the rectangle containing all the tabs
+
+ The default value is a null rectangle, i.e. a rectangle with both
+ the width and the height set to 0.
+*/
+
+/*!
+ \variable QStyleOptionTabBarBase::selectedTabRect
+ \brief the rectangle containing the selected tab
+
+ This rectangle is contained within the tabBarRect. The default
+ value is a null rectangle, i.e. a rectangle with both the width
+ and the height set to 0.
+*/
+
+
+/*!
+ \class QStyleOptionTabBarBaseV2
+ \brief The QStyleOptionTabBarBaseV2 class is used to describe
+ the base of a tab bar, i.e. the part that the tab bar usually
+ overlaps with.
+ \since 4.5
+
+ QStyleOptionTabBarBase contains all the information that QStyle
+ functions need to draw the tab bar base.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QTabBar::drawBase()
+*/
+
+/*!
+ \enum QStyleOptionTabBarBaseV2::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 2
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleOptionTabBarBaseV2::documentMode
+ \brief whether the tabbar is in document mode.
+
+ The default value is false;
+*/
+
+/*!
+ Construct a QStyleOptionTabBarBaseV2, initializing the members
+ vaiables to their default values.
+*/
+QStyleOptionTabBarBaseV2::QStyleOptionTabBarBaseV2()
+ : QStyleOptionTabBarBase(Version)
+ , documentMode(false)
+{
+}
+
+/*!
+ \fn QStyleOptionTabBarBaseV2::QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBaseV2 &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ Constructs a copy of \a other.
+*/
+QStyleOptionTabBarBaseV2::QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBase &other)
+ : QStyleOptionTabBarBase(Version)
+{
+ (void)QStyleOptionTabBarBaseV2::operator=(other);
+}
+
+/*!
+ Constructs a QStyleOptionTabBarBaseV2 copy of the \a other style option
+ which can be either of the QStyleOptionTabBarBaseV2, or QStyleOptionTabBarBase types.
+
+ If the other style option's version is not 1, the new style option's
+ \c documentMode is set to false. If its version is 2, its \c documentMode value
+ is simply copied to the new style option.
+*/
+QStyleOptionTabBarBaseV2 &QStyleOptionTabBarBaseV2::operator = (const QStyleOptionTabBarBase &other)
+{
+ QStyleOptionTabBarBase::operator=(other);
+ const QStyleOptionTabBarBaseV2 *v2 = qstyleoption_cast<const QStyleOptionTabBarBaseV2*>(&other);
+ documentMode = v2 ? v2->documentMode : false;
+ return *this;
+}
+
+/*! \internal */
+QStyleOptionTabBarBaseV2::QStyleOptionTabBarBaseV2(int version)
+ : QStyleOptionTabBarBase(version), documentMode(false)
+{
+}
+
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_SIZEGRIP
+/*!
+ \class QStyleOptionSizeGrip
+ \brief The QStyleOptionSizeGrip class is used to describe the
+ parameter for drawing a size grip.
+ \since 4.2
+
+ QStyleOptionButton contains all the information that QStyle
+ functions need to draw QSizeGrip.
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters used by the style functions.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QStyleOptionComplex, QSizeGrip
+*/
+
+/*!
+ Constructs a QStyleOptionSizeGrip.
+*/
+QStyleOptionSizeGrip::QStyleOptionSizeGrip()
+ : QStyleOptionComplex(Version, Type), corner(Qt::BottomRightCorner)
+{
+}
+
+/*!
+ \fn QStyleOptionSizeGrip::QStyleOptionSizeGrip(const QStyleOptionSizeGrip &other)
+
+ Constructs a copy of the \a other style option.
+*/
+
+/*!
+ \internal
+*/
+QStyleOptionSizeGrip::QStyleOptionSizeGrip(int version)
+ : QStyleOptionComplex(version, Type), corner(Qt::BottomRightCorner)
+{
+}
+
+/*!
+ \variable QStyleOptionSizeGrip::corner
+
+ The corner in which the size grip is located.
+*/
+
+/*!
+ \enum QStyleOptionSizeGrip::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l{SO_TabBarBase} for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionSizeGrip::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+#endif // QT_NO_SIZEGRIP
+
+/*!
+ \class QStyleOptionGraphicsItem
+ \brief The QStyleOptionGraphicsItem class is used to describe
+ the parameters needed to draw a QGraphicsItem.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ For performance reasons, the access to the member variables is
+ direct (i.e., using the \c . or \c -> operator). This low-level feel
+ makes the structures straightforward to use and emphasizes that
+ these are simply parameters.
+
+ For an example demonstrating how style options can be used, see
+ the \l {widgets/styles}{Styles} example.
+
+ \sa QStyleOption, QGraphicsItem::paint()
+*/
+
+/*!
+ \enum QStyleOptionGraphicsItem::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Type The type of style option provided (\l SO_GraphicsItem for this class).
+
+ The type is used internally by QStyleOption, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleOption subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleOptionGraphicsItem::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleOption subclass.
+
+ \value Version 1
+
+ The version is used by QStyleOption subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ Constructs a QStyleOptionGraphicsItem.
+*/
+QStyleOptionGraphicsItem::QStyleOptionGraphicsItem()
+ : QStyleOption(Version, Type), levelOfDetail(1)
+{
+}
+
+/*!
+ \internal
+*/
+QStyleOptionGraphicsItem::QStyleOptionGraphicsItem(int version)
+ : QStyleOption(version, Type), levelOfDetail(1)
+{
+}
+
+/*!
+ \since 4.6
+
+ Returns the level of detail from the \a worldTransform.
+
+ Its value represents the maximum value of the height and
+ width of a unity rectangle, mapped using the \a worldTransform
+ of the painter used to draw the item. By default, if no
+ transformations are applied, its value is 1. If zoomed out 1:2, the level
+ of detail will be 0.5, and if zoomed in 2:1, its value is 2.
+*/
+qreal QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &worldTransform)
+{
+ if (worldTransform.type() <= QTransform::TxTranslate)
+ return 1; // Translation only? The LOD is 1.
+
+ // Two unit vectors.
+ QLineF v1(0, 0, 1, 0);
+ QLineF v2(0, 0, 0, 1);
+ // LOD is the transformed area of a 1x1 rectangle.
+ return qSqrt(worldTransform.map(v1).length() * worldTransform.map(v2).length());
+}
+
+/*!
+ \fn QStyleOptionGraphicsItem::QStyleOptionGraphicsItem(const QStyleOptionGraphicsItem &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ \variable QStyleOptionGraphicsItem::exposedRect
+ \brief the exposed rectangle, in item coordinates
+
+ Make use of this rectangle to speed up item drawing when only parts of the
+ item are exposed. If the whole item is exposed, this rectangle will be the
+ same as QGraphicsItem::boundingRect().
+
+ This member is only initialized for items that have the
+ QGraphicsItem::ItemUsesExtendedStyleOption flag set.
+*/
+
+/*!
+ \variable QStyleOptionGraphicsItem::matrix
+ \brief the complete transformation matrix for the item
+ \obsolete
+
+ The QMatrix provided through this member does include information about
+ any perspective transformations applied to the view or item. To get the
+ correct transformation matrix, use QPainter::transform() on the painter
+ passed into the QGraphicsItem::paint() implementation.
+
+ This matrix is the combination of the item's scene matrix and the matrix
+ of the painter used for drawing the item. It is provided for convenience,
+ allowing anvanced level-of-detail metrics that can be used to speed up
+ item drawing.
+
+ To find the dimensions of an item in screen coordinates (i.e., pixels),
+ you can use the mapping functions of QMatrix, such as QMatrix::map().
+
+ This member is only initialized for items that have the
+ QGraphicsItem::ItemUsesExtendedStyleOption flag set.
+
+ \sa QStyleOptionGraphicsItem::levelOfDetailFromTransform()
+*/
+
+/*!
+ \variable QStyleOptionGraphicsItem::levelOfDetail
+ \obsolete
+
+ Use QStyleOptionGraphicsItem::levelOfDetailFromTransform()
+ together with QPainter::worldTransform() instead.
+*/
+
+/*!
+ \class QStyleHintReturn
+ \brief The QStyleHintReturn class provides style hints that return more
+ than basic data types.
+
+ \ingroup appearance
+
+ QStyleHintReturn and its subclasses are used to pass information
+ from a style back to the querying widget. This is most useful
+ when the return value from QStyle::styleHint() does not provide enough
+ detail; for example, when a mask is to be returned.
+
+ \omit
+ ### --Sam
+ \endomit
+*/
+
+/*!
+ \enum QStyleHintReturn::HintReturnType
+
+ \value SH_Default QStyleHintReturn
+ \value SH_Mask \l QStyle::SH_RubberBand_Mask QStyle::SH_FocusFrame_Mask
+ \value SH_Variant \l QStyle::SH_TextControl_FocusIndicatorTextCharFormat
+*/
+
+/*!
+ \enum QStyleHintReturn::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleHintReturn subclass.
+
+ \value Type The type of style option provided (\l SH_Default for
+ this class).
+
+ The type is used internally by QStyleHintReturn, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleHintReturn subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleHintReturn::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleHintReturn subclass.
+
+ \value Version 1
+
+ The version is used by QStyleHintReturn subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \variable QStyleHintReturn::type
+ \brief the type of the style hint container
+
+ \sa HintReturnType
+*/
+
+/*!
+ \variable QStyleHintReturn::version
+ \brief the version of the style hint return container
+
+ This value can be used by subclasses to implement extensions
+ without breaking compatibility. If you use qstyleoption_cast<T>(), you
+ normally do not need to check it.
+*/
+
+/*!
+ Constructs a QStyleHintReturn with version \a version and type \a
+ type.
+
+ The version has no special meaning for QStyleHintReturn; it can be
+ used by subclasses to distinguish between different version of
+ the same hint type.
+
+ \sa QStyleOption::version, QStyleOption::type
+*/
+
+QStyleHintReturn::QStyleHintReturn(int version, int type)
+ : version(version), type(type)
+{
+}
+
+/*!
+ \internal
+*/
+
+QStyleHintReturn::~QStyleHintReturn()
+{
+
+}
+
+/*!
+ \class QStyleHintReturnMask
+ \brief The QStyleHintReturnMask class provides style hints that return a QRegion.
+
+ \ingroup appearance
+
+ \omit
+ ### --Sam
+ \endomit
+*/
+
+/*!
+ \variable QStyleHintReturnMask::region
+ \brief the region for style hints that return a QRegion
+*/
+
+/*!
+ Constructs a QStyleHintReturnMask. The member variables are
+ initialized to default values.
+*/
+QStyleHintReturnMask::QStyleHintReturnMask() : QStyleHintReturn(Version, Type)
+{
+}
+
+/*!
+ \enum QStyleHintReturnMask::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleHintReturn subclass.
+
+ \value Type The type of style option provided (\l{SH_Mask} for
+ this class).
+
+ The type is used internally by QStyleHintReturn, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleHintReturn subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleHintReturnMask::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleHintReturn subclass.
+
+ \value Version 1
+
+ The version is used by QStyleHintReturn subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \class QStyleHintReturnVariant
+ \brief The QStyleHintReturnVariant class provides style hints that return a QVariant.
+ \since 4.3
+ \ingroup appearance
+*/
+
+/*!
+ \variable QStyleHintReturnVariant::variant
+ \brief the variant for style hints that return a QVariant
+*/
+
+/*!
+ Constructs a QStyleHintReturnVariant. The member variables are
+ initialized to default values.
+*/
+QStyleHintReturnVariant::QStyleHintReturnVariant() : QStyleHintReturn(Version, Type)
+{
+}
+
+/*!
+ \enum QStyleHintReturnVariant::StyleOptionType
+
+ This enum is used to hold information about the type of the style option, and
+ is defined for each QStyleHintReturn subclass.
+
+ \value Type The type of style option provided (\l{SH_Variant} for
+ this class).
+
+ The type is used internally by QStyleHintReturn, its subclasses, and
+ qstyleoption_cast() to determine the type of style option. In
+ general you do not need to worry about this unless you want to
+ create your own QStyleHintReturn subclass and your own styles.
+
+ \sa StyleOptionVersion
+*/
+
+/*!
+ \enum QStyleHintReturnVariant::StyleOptionVersion
+
+ This enum is used to hold information about the version of the style option, and
+ is defined for each QStyleHintReturn subclass.
+
+ \value Version 1
+
+ The version is used by QStyleHintReturn subclasses to implement
+ extensions without breaking compatibility. If you use
+ qstyleoption_cast(), you normally do not need to check it.
+
+ \sa StyleOptionType
+*/
+
+/*!
+ \fn T qstyleoption_cast<T>(const QStyleHintReturn *hint)
+ \relates QStyleHintReturn
+
+ Returns a T or 0 depending on the \l{QStyleHintReturn::type}{type}
+ and \l{QStyleHintReturn::version}{version} of \a hint.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_styles_qstyleoption.cpp 0
+
+ \sa QStyleHintReturn::type, QStyleHintReturn::version
+*/
+
+/*!
+ \fn T qstyleoption_cast<T>(QStyleHintReturn *hint)
+ \overload
+ \relates QStyleHintReturn
+
+ Returns a T or 0 depending on the type of \a hint.
+*/
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType)
+{
+#if !defined(QT_NO_DEBUG)
+ switch (optionType) {
+ case QStyleOption::SO_Default:
+ debug << "SO_Default"; break;
+ case QStyleOption::SO_FocusRect:
+ debug << "SO_FocusRect"; break;
+ case QStyleOption::SO_Button:
+ debug << "SO_Button"; break;
+ case QStyleOption::SO_Tab:
+ debug << "SO_Tab"; break;
+ case QStyleOption::SO_MenuItem:
+ debug << "SO_MenuItem"; break;
+ case QStyleOption::SO_Frame:
+ debug << "SO_Frame"; break;
+ case QStyleOption::SO_ProgressBar:
+ debug << "SO_ProgressBar"; break;
+ case QStyleOption::SO_ToolBox:
+ debug << "SO_ToolBox"; break;
+ case QStyleOption::SO_Header:
+ debug << "SO_Header"; break;
+ case QStyleOption::SO_Q3DockWindow:
+ debug << "SO_Q3DockWindow"; break;
+ case QStyleOption::SO_DockWidget:
+ debug << "SO_DockWidget"; break;
+ case QStyleOption::SO_Q3ListViewItem:
+ debug << "SO_Q3ListViewItem"; break;
+ case QStyleOption::SO_ViewItem:
+ debug << "SO_ViewItem"; break;
+ case QStyleOption::SO_TabWidgetFrame:
+ debug << "SO_TabWidgetFrame"; break;
+ case QStyleOption::SO_TabBarBase:
+ debug << "SO_TabBarBase"; break;
+ case QStyleOption::SO_RubberBand:
+ debug << "SO_RubberBand"; break;
+ case QStyleOption::SO_Complex:
+ debug << "SO_Complex"; break;
+ case QStyleOption::SO_Slider:
+ debug << "SO_Slider"; break;
+ case QStyleOption::SO_SpinBox:
+ debug << "SO_SpinBox"; break;
+ case QStyleOption::SO_ToolButton:
+ debug << "SO_ToolButton"; break;
+ case QStyleOption::SO_ComboBox:
+ debug << "SO_ComboBox"; break;
+ case QStyleOption::SO_Q3ListView:
+ debug << "SO_Q3ListView"; break;
+ case QStyleOption::SO_TitleBar:
+ debug << "SO_TitleBar"; break;
+ case QStyleOption::SO_CustomBase:
+ debug << "SO_CustomBase"; break;
+ case QStyleOption::SO_GroupBox:
+ debug << "SO_GroupBox"; break;
+ case QStyleOption::SO_ToolBar:
+ debug << "SO_ToolBar"; break;
+ case QStyleOption::SO_ComplexCustomBase:
+ debug << "SO_ComplexCustomBase"; break;
+ case QStyleOption::SO_SizeGrip:
+ debug << "SO_SizeGrip"; break;
+ case QStyleOption::SO_GraphicsItem:
+ debug << "SO_GraphicsItem"; break;
+ }
+#else
+ Q_UNUSED(optionType);
+#endif
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const QStyleOption &option)
+{
+#if !defined(QT_NO_DEBUG)
+ debug << "QStyleOption(";
+ debug << QStyleOption::OptionType(option.type);
+ debug << ',' << (option.direction == Qt::RightToLeft ? "RightToLeft" : "LeftToRight");
+ debug << ',' << option.state;
+ debug << ',' << option.rect;
+ debug << ')';
+#else
+ Q_UNUSED(option);
+#endif
+ return debug;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
new file mode 100644
index 0000000000..557a297f7a
--- /dev/null
+++ b/src/widgets/styles/qstyleoption.h
@@ -0,0 +1,970 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEOPTION_H
+#define QSTYLEOPTION_H
+
+#include <QtCore/qvariant.h>
+#include <QtWidgets/qabstractspinbox.h>
+#include <QtWidgets/qicon.h>
+#include <QtGui/qmatrix.h>
+#include <QtWidgets/qslider.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qtabbar.h>
+#include <QtWidgets/qtabwidget.h>
+#include <QtWidgets/qrubberband.h>
+#include <QtWidgets/qframe.h>
+#ifndef QT_NO_ITEMVIEWS
+# include <QtCore/qabstractitemmodel.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QDebug;
+
+class Q_GUI_EXPORT QStyleOption
+{
+public:
+ enum OptionType {
+ SO_Default, SO_FocusRect, SO_Button, SO_Tab, SO_MenuItem,
+ SO_Frame, SO_ProgressBar, SO_ToolBox, SO_Header, SO_Q3DockWindow,
+ SO_DockWidget, SO_Q3ListViewItem, SO_ViewItem, SO_TabWidgetFrame,
+ SO_TabBarBase, SO_RubberBand, SO_ToolBar, SO_GraphicsItem,
+
+ SO_Complex = 0xf0000, SO_Slider, SO_SpinBox, SO_ToolButton, SO_ComboBox,
+ SO_Q3ListView, SO_TitleBar, SO_GroupBox, SO_SizeGrip,
+
+ SO_CustomBase = 0xf00,
+ SO_ComplexCustomBase = 0xf000000
+ };
+
+ enum StyleOptionType { Type = SO_Default };
+ enum StyleOptionVersion { Version = 1 };
+
+ int version;
+ int type;
+ QStyle::State state;
+ Qt::LayoutDirection direction;
+ QRect rect;
+ QFontMetrics fontMetrics;
+ QPalette palette;
+
+ QStyleOption(int version = QStyleOption::Version, int type = SO_Default);
+ QStyleOption(const QStyleOption &other);
+ ~QStyleOption();
+
+ void init(const QWidget *w);
+ inline void initFrom(const QWidget *w) { init(w); }
+ QStyleOption &operator=(const QStyleOption &other);
+};
+
+class Q_GUI_EXPORT QStyleOptionFocusRect : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_FocusRect };
+ enum StyleOptionVersion { Version = 1 };
+
+ QColor backgroundColor;
+
+ QStyleOptionFocusRect();
+ QStyleOptionFocusRect(const QStyleOptionFocusRect &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionFocusRect(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionFrame : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Frame };
+ enum StyleOptionVersion { Version = 1 };
+
+ int lineWidth;
+ int midLineWidth;
+
+ QStyleOptionFrame();
+ QStyleOptionFrame(const QStyleOptionFrame &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionFrame(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionFrameV2 : public QStyleOptionFrame
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ enum FrameFeature {
+ None = 0x00,
+ Flat = 0x01
+ };
+ Q_DECLARE_FLAGS(FrameFeatures, FrameFeature)
+ FrameFeatures features;
+
+ QStyleOptionFrameV2();
+ QStyleOptionFrameV2(const QStyleOptionFrameV2 &other) : QStyleOptionFrame(Version) { *this = other; }
+ QStyleOptionFrameV2(const QStyleOptionFrame &other);
+ QStyleOptionFrameV2 &operator=(const QStyleOptionFrame &other);
+
+protected:
+ QStyleOptionFrameV2(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionFrameV2::FrameFeatures)
+
+
+class Q_GUI_EXPORT QStyleOptionFrameV3 : public QStyleOptionFrameV2
+{
+public:
+ enum StyleOptionVersion { Version = 3 };
+ QFrame::Shape frameShape : 4;
+ uint unused : 28;
+
+ QStyleOptionFrameV3();
+ QStyleOptionFrameV3(const QStyleOptionFrameV3 &other) : QStyleOptionFrameV2(Version) { *this = other; }
+ QStyleOptionFrameV3(const QStyleOptionFrame &other);
+ QStyleOptionFrameV3 &operator=(const QStyleOptionFrame &other);
+
+protected:
+ QStyleOptionFrameV3(int version);
+};
+
+
+#ifndef QT_NO_TABWIDGET
+class Q_GUI_EXPORT QStyleOptionTabWidgetFrame : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_TabWidgetFrame };
+ enum StyleOptionVersion { Version = 1 };
+
+ int lineWidth;
+ int midLineWidth;
+ QTabBar::Shape shape;
+ QSize tabBarSize;
+ QSize rightCornerWidgetSize;
+ QSize leftCornerWidgetSize;
+
+ QStyleOptionTabWidgetFrame();
+ inline QStyleOptionTabWidgetFrame(const QStyleOptionTabWidgetFrame &other)
+ : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTabWidgetFrame(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionTabWidgetFrameV2 : public QStyleOptionTabWidgetFrame
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+
+ QRect tabBarRect;
+ QRect selectedTabRect;
+
+ QStyleOptionTabWidgetFrameV2();
+ QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrameV2 &other) :
+ QStyleOptionTabWidgetFrame(Version) { *this = other; }
+ QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other);
+ QStyleOptionTabWidgetFrameV2 &operator=(const QStyleOptionTabWidgetFrame &other);
+
+protected:
+ QStyleOptionTabWidgetFrameV2(int version);
+};
+
+#endif
+
+
+#ifndef QT_NO_TABBAR
+class Q_GUI_EXPORT QStyleOptionTabBarBase : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_TabBarBase };
+ enum StyleOptionVersion { Version = 1 };
+
+ QTabBar::Shape shape;
+ QRect tabBarRect;
+ QRect selectedTabRect;
+
+ QStyleOptionTabBarBase();
+ QStyleOptionTabBarBase(const QStyleOptionTabBarBase &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTabBarBase(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionTabBarBaseV2 : public QStyleOptionTabBarBase
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ bool documentMode;
+ QStyleOptionTabBarBaseV2();
+ QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBaseV2 &other) : QStyleOptionTabBarBase(Version) { *this = other; }
+ QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBase &other);
+ QStyleOptionTabBarBaseV2 &operator=(const QStyleOptionTabBarBase &other);
+
+protected:
+ QStyleOptionTabBarBaseV2(int version);
+};
+
+#endif
+
+class Q_GUI_EXPORT QStyleOptionHeader : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Header };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum SectionPosition { Beginning, Middle, End, OnlyOneSection };
+ enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected,
+ NextAndPreviousAreSelected };
+ enum SortIndicator { None, SortUp, SortDown };
+
+ int section;
+ QString text;
+ Qt::Alignment textAlignment;
+ QIcon icon;
+ Qt::Alignment iconAlignment;
+ SectionPosition position;
+ SelectedPosition selectedPosition;
+ SortIndicator sortIndicator;
+ Qt::Orientation orientation;
+
+ QStyleOptionHeader();
+ QStyleOptionHeader(const QStyleOptionHeader &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionHeader(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionButton : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Button };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum ButtonFeature { None = 0x00, Flat = 0x01, HasMenu = 0x02, DefaultButton = 0x04,
+ AutoDefaultButton = 0x08, CommandLinkButton = 0x10 };
+ Q_DECLARE_FLAGS(ButtonFeatures, ButtonFeature)
+
+ ButtonFeatures features;
+ QString text;
+ QIcon icon;
+ QSize iconSize;
+
+ QStyleOptionButton();
+ QStyleOptionButton(const QStyleOptionButton &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionButton(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionButton::ButtonFeatures)
+
+#ifndef QT_NO_TABBAR
+class Q_GUI_EXPORT QStyleOptionTab : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Tab };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum TabPosition { Beginning, Middle, End, OnlyOneTab };
+ enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
+ enum CornerWidget { NoCornerWidgets = 0x00, LeftCornerWidget = 0x01,
+ RightCornerWidget = 0x02 };
+ Q_DECLARE_FLAGS(CornerWidgets, CornerWidget)
+
+ QTabBar::Shape shape;
+ QString text;
+ QIcon icon;
+ int row;
+ TabPosition position;
+ SelectedPosition selectedPosition;
+ CornerWidgets cornerWidgets;
+
+ QStyleOptionTab();
+ QStyleOptionTab(const QStyleOptionTab &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTab(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionTab::CornerWidgets)
+
+class Q_GUI_EXPORT QStyleOptionTabV2 : public QStyleOptionTab
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ QSize iconSize;
+ QStyleOptionTabV2();
+ QStyleOptionTabV2(const QStyleOptionTabV2 &other) : QStyleOptionTab(Version) { *this = other; }
+ QStyleOptionTabV2(const QStyleOptionTab &other);
+ QStyleOptionTabV2 &operator=(const QStyleOptionTab &other);
+
+protected:
+ QStyleOptionTabV2(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionTabV3 : public QStyleOptionTabV2
+{
+public:
+ enum StyleOptionVersion { Version = 3 };
+ bool documentMode;
+ QSize leftButtonSize;
+ QSize rightButtonSize;
+ QStyleOptionTabV3();
+ QStyleOptionTabV3(const QStyleOptionTabV3 &other) : QStyleOptionTabV2(Version) { *this = other; }
+ QStyleOptionTabV3(const QStyleOptionTabV2 &other) : QStyleOptionTabV2(Version) { *this = other; }
+ QStyleOptionTabV3(const QStyleOptionTab &other);
+ QStyleOptionTabV3 &operator=(const QStyleOptionTab &other);
+
+protected:
+ QStyleOptionTabV3(int version);
+};
+
+#endif
+
+
+#ifndef QT_NO_TOOLBAR
+
+class Q_GUI_EXPORT QStyleOptionToolBar : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ToolBar };
+ enum StyleOptionVersion { Version = 1 };
+ enum ToolBarPosition { Beginning, Middle, End, OnlyOne };
+ enum ToolBarFeature { None = 0x0, Movable = 0x1 };
+ Q_DECLARE_FLAGS(ToolBarFeatures, ToolBarFeature)
+ ToolBarPosition positionOfLine; // The toolbar line position
+ ToolBarPosition positionWithinLine; // The position within a toolbar
+ Qt::ToolBarArea toolBarArea; // The toolbar docking area
+ ToolBarFeatures features;
+ int lineWidth;
+ int midLineWidth;
+ QStyleOptionToolBar();
+ QStyleOptionToolBar(const QStyleOptionToolBar &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionToolBar(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolBar::ToolBarFeatures)
+
+#endif
+
+
+
+class Q_GUI_EXPORT QStyleOptionProgressBar : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ProgressBar };
+ enum StyleOptionVersion { Version = 1 };
+
+ int minimum;
+ int maximum;
+ int progress;
+ QString text;
+ Qt::Alignment textAlignment;
+ bool textVisible;
+
+ QStyleOptionProgressBar();
+ QStyleOptionProgressBar(const QStyleOptionProgressBar &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionProgressBar(int version);
+};
+
+// Adds style info for vertical progress bars
+class Q_GUI_EXPORT QStyleOptionProgressBarV2 : public QStyleOptionProgressBar
+{
+public:
+ enum StyleOptionType { Type = SO_ProgressBar };
+ enum StyleOptionVersion { Version = 2 };
+ Qt::Orientation orientation;
+ bool invertedAppearance;
+ bool bottomToTop;
+
+ QStyleOptionProgressBarV2();
+ QStyleOptionProgressBarV2(const QStyleOptionProgressBar &other);
+ QStyleOptionProgressBarV2(const QStyleOptionProgressBarV2 &other);
+ QStyleOptionProgressBarV2 &operator=(const QStyleOptionProgressBar &other);
+
+protected:
+ QStyleOptionProgressBarV2(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionMenuItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_MenuItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum MenuItemType { Normal, DefaultItem, Separator, SubMenu, Scroller, TearOff, Margin,
+ EmptyArea };
+ enum CheckType { NotCheckable, Exclusive, NonExclusive };
+
+ MenuItemType menuItemType;
+ CheckType checkType;
+ bool checked;
+ bool menuHasCheckableItems;
+ QRect menuRect;
+ QString text;
+ QIcon icon;
+ int maxIconWidth;
+ int tabWidth;
+ QFont font;
+
+ QStyleOptionMenuItem();
+ QStyleOptionMenuItem(const QStyleOptionMenuItem &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionMenuItem(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionQ3ListViewItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Q3ListViewItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum Q3ListViewItemFeature { None = 0x00, Expandable = 0x01, MultiLine = 0x02, Visible = 0x04,
+ ParentControl = 0x08 };
+ Q_DECLARE_FLAGS(Q3ListViewItemFeatures, Q3ListViewItemFeature)
+
+ Q3ListViewItemFeatures features;
+ int height;
+ int totalHeight;
+ int itemY;
+ int childCount;
+
+ QStyleOptionQ3ListViewItem();
+ QStyleOptionQ3ListViewItem(const QStyleOptionQ3ListViewItem &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionQ3ListViewItem(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionQ3ListViewItem::Q3ListViewItemFeatures)
+
+class Q_GUI_EXPORT QStyleOptionQ3DockWindow : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Q3DockWindow };
+ enum StyleOptionVersion { Version = 1 };
+
+ bool docked;
+ bool closeEnabled;
+
+ QStyleOptionQ3DockWindow();
+ QStyleOptionQ3DockWindow(const QStyleOptionQ3DockWindow &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionQ3DockWindow(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionDockWidget : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_DockWidget };
+ enum StyleOptionVersion { Version = 1 };
+
+ QString title;
+ bool closable;
+ bool movable;
+ bool floatable;
+
+ QStyleOptionDockWidget();
+ QStyleOptionDockWidget(const QStyleOptionDockWidget &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionDockWidget(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionDockWidgetV2 : public QStyleOptionDockWidget
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+
+ bool verticalTitleBar;
+
+ QStyleOptionDockWidgetV2();
+ QStyleOptionDockWidgetV2(const QStyleOptionDockWidgetV2 &other)
+ : QStyleOptionDockWidget(Version) { *this = other; }
+ QStyleOptionDockWidgetV2(const QStyleOptionDockWidget &other);
+ QStyleOptionDockWidgetV2 &operator = (const QStyleOptionDockWidget &other);
+
+protected:
+ QStyleOptionDockWidgetV2(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionViewItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ViewItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum Position { Left, Right, Top, Bottom };
+
+ Qt::Alignment displayAlignment;
+ Qt::Alignment decorationAlignment;
+ Qt::TextElideMode textElideMode;
+ Position decorationPosition;
+ QSize decorationSize;
+ QFont font;
+ bool showDecorationSelected;
+
+ QStyleOptionViewItem();
+ QStyleOptionViewItem(const QStyleOptionViewItem &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionViewItem(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionViewItemV2 : public QStyleOptionViewItem
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+
+ enum ViewItemFeature {
+ None = 0x00,
+ WrapText = 0x01,
+ Alternate = 0x02,
+ HasCheckIndicator = 0x04,
+ HasDisplay = 0x08,
+ HasDecoration = 0x10
+ };
+ Q_DECLARE_FLAGS(ViewItemFeatures, ViewItemFeature)
+
+ ViewItemFeatures features;
+
+ QStyleOptionViewItemV2();
+ QStyleOptionViewItemV2(const QStyleOptionViewItemV2 &other) : QStyleOptionViewItem(Version) { *this = other; }
+ QStyleOptionViewItemV2(const QStyleOptionViewItem &other);
+ QStyleOptionViewItemV2 &operator=(const QStyleOptionViewItem &other);
+
+protected:
+ QStyleOptionViewItemV2(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionViewItemV2::ViewItemFeatures)
+
+class Q_GUI_EXPORT QStyleOptionViewItemV3 : public QStyleOptionViewItemV2
+{
+public:
+ enum StyleOptionVersion { Version = 3 };
+
+ QLocale locale;
+ const QWidget *widget;
+
+ QStyleOptionViewItemV3();
+ QStyleOptionViewItemV3(const QStyleOptionViewItemV3 &other)
+ : QStyleOptionViewItemV2(Version) { *this = other; }
+ QStyleOptionViewItemV3(const QStyleOptionViewItem &other);
+ QStyleOptionViewItemV3 &operator = (const QStyleOptionViewItem &other);
+
+protected:
+ QStyleOptionViewItemV3(int version);
+};
+
+#ifndef QT_NO_ITEMVIEWS
+class Q_GUI_EXPORT QStyleOptionViewItemV4 : public QStyleOptionViewItemV3
+{
+public:
+ enum StyleOptionVersion { Version = 4 };
+ enum ViewItemPosition { Invalid, Beginning, Middle, End, OnlyOne };
+
+ QModelIndex index;
+ Qt::CheckState checkState;
+ QIcon icon;
+ QString text;
+ ViewItemPosition viewItemPosition;
+ QBrush backgroundBrush;
+
+ QStyleOptionViewItemV4();
+ QStyleOptionViewItemV4(const QStyleOptionViewItemV4 &other)
+ : QStyleOptionViewItemV3(Version) { *this = other; }
+ QStyleOptionViewItemV4(const QStyleOptionViewItem &other);
+ QStyleOptionViewItemV4 &operator = (const QStyleOptionViewItem &other);
+
+protected:
+ QStyleOptionViewItemV4(int version);
+};
+#endif
+
+class Q_GUI_EXPORT QStyleOptionToolBox : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ToolBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ QString text;
+ QIcon icon;
+
+ QStyleOptionToolBox();
+ QStyleOptionToolBox(const QStyleOptionToolBox &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionToolBox(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionToolBoxV2 : public QStyleOptionToolBox
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ enum TabPosition { Beginning, Middle, End, OnlyOneTab };
+ enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
+
+ TabPosition position;
+ SelectedPosition selectedPosition;
+
+ QStyleOptionToolBoxV2();
+ QStyleOptionToolBoxV2(const QStyleOptionToolBoxV2 &other) : QStyleOptionToolBox(Version) { *this = other; }
+ QStyleOptionToolBoxV2(const QStyleOptionToolBox &other);
+ QStyleOptionToolBoxV2 &operator=(const QStyleOptionToolBox &other);
+
+protected:
+ QStyleOptionToolBoxV2(int version);
+};
+
+#ifndef QT_NO_RUBBERBAND
+class Q_GUI_EXPORT QStyleOptionRubberBand : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_RubberBand };
+ enum StyleOptionVersion { Version = 1 };
+
+ QRubberBand::Shape shape;
+ bool opaque;
+
+ QStyleOptionRubberBand();
+ QStyleOptionRubberBand(const QStyleOptionRubberBand &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionRubberBand(int version);
+};
+#endif // QT_NO_RUBBERBAND
+
+// -------------------------- Complex style options -------------------------------
+class Q_GUI_EXPORT QStyleOptionComplex : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Complex };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyle::SubControls subControls;
+ QStyle::SubControls activeSubControls;
+
+ QStyleOptionComplex(int version = QStyleOptionComplex::Version, int type = SO_Complex);
+ QStyleOptionComplex(const QStyleOptionComplex &other) : QStyleOption(Version, Type) { *this = other; }
+};
+
+#ifndef QT_NO_SLIDER
+class Q_GUI_EXPORT QStyleOptionSlider : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_Slider };
+ enum StyleOptionVersion { Version = 1 };
+
+ Qt::Orientation orientation;
+ int minimum;
+ int maximum;
+ QSlider::TickPosition tickPosition;
+ int tickInterval;
+ bool upsideDown;
+ int sliderPosition;
+ int sliderValue;
+ int singleStep;
+ int pageStep;
+ qreal notchTarget;
+ bool dialWrapping;
+
+ QStyleOptionSlider();
+ QStyleOptionSlider(const QStyleOptionSlider &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionSlider(int version);
+};
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_SPINBOX
+class Q_GUI_EXPORT QStyleOptionSpinBox : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_SpinBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ QAbstractSpinBox::ButtonSymbols buttonSymbols;
+ QAbstractSpinBox::StepEnabled stepEnabled;
+ bool frame;
+
+ QStyleOptionSpinBox();
+ QStyleOptionSpinBox(const QStyleOptionSpinBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionSpinBox(int version);
+};
+#endif // QT_NO_SPINBOX
+
+class Q_GUI_EXPORT QStyleOptionQ3ListView : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_Q3ListView };
+ enum StyleOptionVersion { Version = 1 };
+
+ QList<QStyleOptionQ3ListViewItem> items;
+ QPalette viewportPalette;
+ QPalette::ColorRole viewportBGRole;
+ int sortColumn;
+ int itemMargin;
+ int treeStepSize;
+ bool rootIsDecorated;
+
+ QStyleOptionQ3ListView();
+ QStyleOptionQ3ListView(const QStyleOptionQ3ListView &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionQ3ListView(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionToolButton : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_ToolButton };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum ToolButtonFeature { None = 0x00, Arrow = 0x01, Menu = 0x04, MenuButtonPopup = Menu, PopupDelay = 0x08,
+ HasMenu = 0x10 };
+ Q_DECLARE_FLAGS(ToolButtonFeatures, ToolButtonFeature)
+
+ ToolButtonFeatures features;
+ QIcon icon;
+ QSize iconSize;
+ QString text;
+ Qt::ArrowType arrowType;
+ Qt::ToolButtonStyle toolButtonStyle;
+ QPoint pos;
+ QFont font;
+
+ QStyleOptionToolButton();
+ QStyleOptionToolButton(const QStyleOptionToolButton &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionToolButton(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolButton::ToolButtonFeatures)
+
+class Q_GUI_EXPORT QStyleOptionComboBox : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_ComboBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ bool editable;
+ QRect popupRect;
+ bool frame;
+ QString currentText;
+ QIcon currentIcon;
+ QSize iconSize;
+
+ QStyleOptionComboBox();
+ QStyleOptionComboBox(const QStyleOptionComboBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionComboBox(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionTitleBar : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_TitleBar };
+ enum StyleOptionVersion { Version = 1 };
+
+ QString text;
+ QIcon icon;
+ int titleBarState;
+ Qt::WindowFlags titleBarFlags;
+
+ QStyleOptionTitleBar();
+ QStyleOptionTitleBar(const QStyleOptionTitleBar &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTitleBar(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionGroupBox : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_GroupBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleOptionFrameV2::FrameFeatures features;
+ QString text;
+ Qt::Alignment textAlignment;
+ QColor textColor;
+ int lineWidth;
+ int midLineWidth;
+
+ QStyleOptionGroupBox();
+ QStyleOptionGroupBox(const QStyleOptionGroupBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+protected:
+ QStyleOptionGroupBox(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionSizeGrip : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_SizeGrip };
+ enum StyleOptionVersion { Version = 1 };
+
+ Qt::Corner corner;
+
+ QStyleOptionSizeGrip();
+ QStyleOptionSizeGrip(const QStyleOptionSizeGrip &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+protected:
+ QStyleOptionSizeGrip(int version);
+};
+
+class Q_GUI_EXPORT QStyleOptionGraphicsItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_GraphicsItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ QRectF exposedRect;
+ QMatrix matrix;
+ qreal levelOfDetail;
+
+ QStyleOptionGraphicsItem();
+ QStyleOptionGraphicsItem(const QStyleOptionGraphicsItem &other) : QStyleOption(Version, Type) { *this = other; }
+ static qreal levelOfDetailFromTransform(const QTransform &worldTransform);
+protected:
+ QStyleOptionGraphicsItem(int version);
+};
+
+template <typename T>
+T qstyleoption_cast(const QStyleOption *opt)
+{
+ if (opt && opt->version >= static_cast<T>(0)->Version && (opt->type == static_cast<T>(0)->Type
+ || int(static_cast<T>(0)->Type) == QStyleOption::SO_Default
+ || (int(static_cast<T>(0)->Type) == QStyleOption::SO_Complex
+ && opt->type > QStyleOption::SO_Complex)))
+ return static_cast<T>(opt);
+ return 0;
+}
+
+template <typename T>
+T qstyleoption_cast(QStyleOption *opt)
+{
+ if (opt && opt->version >= static_cast<T>(0)->Version && (opt->type == static_cast<T>(0)->Type
+ || int(static_cast<T>(0)->Type) == QStyleOption::SO_Default
+ || (int(static_cast<T>(0)->Type) == QStyleOption::SO_Complex
+ && opt->type > QStyleOption::SO_Complex)))
+ return static_cast<T>(opt);
+ return 0;
+}
+
+// -------------------------- QStyleHintReturn -------------------------------
+class Q_GUI_EXPORT QStyleHintReturn {
+public:
+ enum HintReturnType {
+ SH_Default=0xf000, SH_Mask, SH_Variant
+ };
+
+ enum StyleOptionType { Type = SH_Default };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleHintReturn(int version = QStyleOption::Version, int type = SH_Default);
+ ~QStyleHintReturn();
+
+ int version;
+ int type;
+};
+
+class Q_GUI_EXPORT QStyleHintReturnMask : public QStyleHintReturn {
+public:
+ enum StyleOptionType { Type = SH_Mask };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleHintReturnMask();
+
+ QRegion region;
+};
+
+class Q_GUI_EXPORT QStyleHintReturnVariant : public QStyleHintReturn {
+public:
+ enum StyleOptionType { Type = SH_Variant };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleHintReturnVariant();
+
+ QVariant variant;
+};
+
+template <typename T>
+T qstyleoption_cast(const QStyleHintReturn *hint)
+{
+ if (hint && hint->version <= static_cast<T>(0)->Version &&
+ (hint->type == static_cast<T>(0)->Type || int(static_cast<T>(0)->Type) == QStyleHintReturn::SH_Default))
+ return static_cast<T>(hint);
+ return 0;
+}
+
+template <typename T>
+T qstyleoption_cast(QStyleHintReturn *hint)
+{
+ if (hint && hint->version <= static_cast<T>(0)->Version &&
+ (hint->type == static_cast<T>(0)->Type || int(static_cast<T>(0)->Type) == QStyleHintReturn::SH_Default))
+ return static_cast<T>(hint);
+ return 0;
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType);
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QStyleOption &option);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEOPTION_H
diff --git a/src/widgets/styles/qstylepainter.cpp b/src/widgets/styles/qstylepainter.cpp
new file mode 100644
index 0000000000..180499d791
--- /dev/null
+++ b/src/widgets/styles/qstylepainter.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstylepainter.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QStylePainter
+
+ \brief The QStylePainter class is a convenience class for drawing QStyle
+ elements inside a widget.
+
+ \ingroup appearance
+ \ingroup painting
+
+ QStylePainter extends QPainter with a set of high-level \c
+ draw...() functions implemented on top of QStyle's API. The
+ advantage of using QStylePainter is that the parameter lists get
+ considerably shorter. Whereas a QStyle object must be able to
+ draw on any widget using any painter (because the application
+ normally has one QStyle object shared by all widget), a
+ QStylePainter is initialized with a widget, eliminating the need
+ to specify the QWidget, the QPainter, and the QStyle for every
+ function call.
+
+ Example using QStyle directly:
+
+ \snippet doc/src/snippets/styles/styles.cpp 1
+
+ Example using QStylePainter:
+
+ \snippet doc/src/snippets/styles/styles.cpp 0
+ \snippet doc/src/snippets/styles/styles.cpp 4
+ \snippet doc/src/snippets/styles/styles.cpp 6
+
+ \sa QStyle, QStyleOption
+*/
+
+/*!
+ \fn QStylePainter::QStylePainter()
+
+ Constructs a QStylePainter.
+*/
+
+/*!
+ \fn QStylePainter::QStylePainter(QWidget *widget)
+
+ Construct a QStylePainter using widget \a widget for its paint device.
+*/
+
+/*!
+ \fn QStylePainter::QStylePainter(QPaintDevice *pd, QWidget *widget)
+
+ Construct a QStylePainter using \a pd for its paint device, and
+ attributes from \a widget.
+*/
+
+
+/*!
+ \fn bool QStylePainter::begin(QWidget *widget)
+
+ Begin painting operations on the specified \a widget.
+ Returns true if the painter is ready to use; otherwise returns false.
+
+ This is automatically called by the constructor that takes a QWidget.
+*/
+
+/*!
+ \fn bool QStylePainter::begin(QPaintDevice *pd, QWidget *widget)
+ \overload
+
+ Begin painting operations on paint device \a pd as if it was \a
+ widget.
+
+ This is automatically called by the constructor that
+ takes a QPaintDevice and a QWidget.
+*/
+
+
+/*!
+ \fn void QStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &option)
+
+ Use the widget's style to draw a primitive element \a pe specified by QStyleOption \a option.
+
+ \sa QStyle::drawPrimitive()
+*/
+
+/*!
+ \fn void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &option)
+
+ Use the widget's style to draw a control element \a ce specified by QStyleOption \a option.
+
+ \sa QStyle::drawControl()
+*/
+
+/*!
+ \fn void QStylePainter::drawComplexControl(QStyle::ComplexControl cc,
+ const QStyleOptionComplex &option)
+
+ Use the widget's style to draw a complex control \a cc specified by the
+ QStyleOptionComplex \a option.
+
+ \sa QStyle::drawComplexControl()
+*/
+
+/*!
+ \fn void QStylePainter::drawItemText(const QRect &rect, int flags, const QPalette &pal,
+ bool enabled, const QString &text,
+ QPalette::ColorRole textRole = QPalette::NoRole)
+
+ Draws the \a text in rectangle \a rect and palette \a pal.
+ The text is aligned and wrapped according to \a
+ flags.
+
+ The pen color is specified with \a textRole. The \a enabled bool
+ indicates whether or not the item is enabled; when reimplementing
+ this bool should influence how the item is drawn.
+
+ \sa QStyle::drawItemText(), Qt::Alignment
+*/
+
+/*!
+ \fn void QStylePainter::drawItemPixmap(const QRect &rect, int flags, const QPixmap &pixmap)
+
+ Draws the \a pixmap in rectangle \a rect.
+ The pixmap is aligned according to \a flags.
+
+ \sa QStyle::drawItemPixmap(), Qt::Alignment
+*/
+
+/*!
+ \fn QStyle *QStylePainter::style() const
+
+ Return the current style used by the QStylePainter.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstylepainter.h b/src/widgets/styles/qstylepainter.h
new file mode 100644
index 0000000000..ccb591c0f9
--- /dev/null
+++ b/src/widgets/styles/qstylepainter.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEPAINTER_H
+#define QSTYLEPAINTER_H
+
+#include <QtGui/qpainter.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStylePainter : public QPainter
+{
+public:
+ inline QStylePainter() : QPainter(), widget(0), wstyle(0) {}
+ inline explicit QStylePainter(QWidget *w) { begin(w, w); }
+ inline QStylePainter(QPaintDevice *pd, QWidget *w) { begin(pd, w); }
+ inline bool begin(QWidget *w) { return begin(w, w); }
+ inline bool begin(QPaintDevice *pd, QWidget *w) {
+ Q_ASSERT_X(w, "QStylePainter::QStylePainter", "Widget must be non-zero");
+ widget = w;
+ wstyle = w->style();
+ return QPainter::begin(pd);
+ };
+ inline void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt);
+ inline void drawControl(QStyle::ControlElement ce, const QStyleOption &opt);
+ inline void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt);
+ inline void drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole);
+ inline void drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap);
+ inline QStyle *style() const { return wstyle; }
+
+private:
+ QWidget *widget;
+ QStyle *wstyle;
+ Q_DISABLE_COPY(QStylePainter)
+};
+
+void QStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt)
+{
+ wstyle->drawPrimitive(pe, &opt, this, widget);
+}
+
+void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &opt)
+{
+ wstyle->drawControl(ce, &opt, this, widget);
+}
+
+void QStylePainter::drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt)
+{
+ wstyle->drawComplexControl(cc, &opt, this, widget);
+}
+
+void QStylePainter::drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole)
+{
+ wstyle->drawItemText(this, r, flags, pal, enabled, text, textRole);
+}
+
+void QStylePainter::drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap)
+{
+ wstyle->drawItemPixmap(this, r, flags, pixmap);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEPAINTER_H
diff --git a/src/widgets/styles/qstyleplugin.cpp b/src/widgets/styles/qstyleplugin.cpp
new file mode 100644
index 0000000000..bb345c4bf1
--- /dev/null
+++ b/src/widgets/styles/qstyleplugin.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstyleplugin.h"
+#include "qstyle.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QStylePlugin
+ \brief The QStylePlugin class provides an abstract base for custom QStyle plugins.
+
+ \ingroup plugins
+
+ QStylePlugin is a simple plugin interface that makes it easy
+ to create custom styles that can be loaded dynamically into
+ applications using the QStyleFactory class.
+
+ Writing a style plugin is achieved by subclassing this base class,
+ reimplementing the pure virtual keys() and create() functions, and
+ exporting the class using the Q_EXPORT_PLUGIN2() macro. See \l
+ {How to Create Qt Plugins} for details.
+
+ \sa QStyleFactory, QStyle
+*/
+
+/*!
+ \fn QStringList QStylePlugin::keys() const
+
+ Returns the list of style keys this plugin supports.
+
+ These keys are usually the class names of the custom styles that
+ are implemented in the plugin.
+
+ \sa create()
+*/
+
+/*!
+ \fn QStyle *QStylePlugin::create(const QString& key)
+
+ Creates and returns a QStyle object for the given style \a key.
+ If a plugin cannot create a style, it should return 0 instead.
+
+ The style key is usually the class name of the required
+ style. Note that the keys are case insensitive. For example:
+
+ \snippet doc/src/snippets/qstyleplugin/main.cpp 0
+ \codeline
+ \snippet doc/src/snippets/qstyleplugin/main.cpp 1
+ \snippet doc/src/snippets/qstyleplugin/main.cpp 2
+
+ \sa keys()
+*/
+
+/*!
+ Constructs a style plugin with the given \a parent.
+
+ Note that this constructor is invoked automatically by the
+ Q_EXPORT_PLUGIN2() macro, so there is no need for calling it
+ explicitly.
+*/
+QStylePlugin::QStylePlugin(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Destroys the style plugin.
+
+ Note that Qt destroys a plugin automatically when it is no longer
+ used, so there is no need for calling the destructor explicitly.
+*/
+QStylePlugin::~QStylePlugin()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstyleplugin.h b/src/widgets/styles/qstyleplugin.h
new file mode 100644
index 0000000000..2dd8ccfcfd
--- /dev/null
+++ b/src/widgets/styles/qstyleplugin.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEPLUGIN_H
+#define QSTYLEPLUGIN_H
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyle;
+
+struct Q_GUI_EXPORT QStyleFactoryInterface : public QFactoryInterface
+{
+ virtual QStyle *create(const QString &key) = 0;
+};
+
+#define QStyleFactoryInterface_iid "com.trolltech.Qt.QStyleFactoryInterface"
+
+Q_DECLARE_INTERFACE(QStyleFactoryInterface, QStyleFactoryInterface_iid)
+
+class Q_GUI_EXPORT QStylePlugin : public QObject, public QStyleFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QStyleFactoryInterface:QFactoryInterface)
+public:
+ explicit QStylePlugin(QObject *parent = 0);
+ ~QStylePlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QStyle *create(const QString &key) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEPLUGIN_H
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
new file mode 100644
index 0000000000..357b43c2b4
--- /dev/null
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -0,0 +1,5900 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+#include "qstylesheetstyle_p.h"
+#include "private/qcssutil_p.h"
+#include <qdebug.h>
+#include <qapplication.h>
+#include <qmenu.h>
+#include <qmenubar.h>
+#include <qpainter.h>
+#include <qstyleoption.h>
+#include <qlineedit.h>
+#include <qwindowsstyle.h>
+#include <qcombobox.h>
+#include <qwindowsstyle.h>
+#include <qplastiquestyle.h>
+#include "private/qcssparser_p.h"
+#include "private/qmath_p.h"
+#include <qabstractscrollarea.h>
+#include "private/qabstractscrollarea_p.h"
+#include <qtooltip.h>
+#include <qshareddata.h>
+#include <qradiobutton.h>
+#include <qtoolbutton.h>
+#include <qscrollbar.h>
+#include <qstring.h>
+#include <qfile.h>
+#include <qcheckbox.h>
+#include <qstatusbar.h>
+#include <qheaderview.h>
+#include <qprogressbar.h>
+#include <private/qwindowsstyle_p.h>
+#include <qtabbar.h>
+#include <QMetaProperty>
+#include <qmainwindow.h>
+#include <qdockwidget.h>
+#include <qmdisubwindow.h>
+#include <qdialog.h>
+#include <private/qwidget_p.h>
+#include <QAbstractSpinBox>
+#include <QLabel>
+#include "qdrawutil.h"
+
+#include <limits.h>
+#include <QtWidgets/qtoolbar.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QCss;
+
+
+class QStyleSheetStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QStyleSheetStyle)
+public:
+ QStyleSheetStylePrivate() { }
+};
+
+
+static QStyleSheetStyleCaches *styleSheetCaches = 0;
+
+/* RECURSION_GUARD:
+ * the QStyleSheetStyle is a proxy. If used with others proxy style, we may end up with something like:
+ * QStyleSheetStyle -> ProxyStyle -> QStyleSheetStyle -> OriginalStyle
+ * Recursion may happen if the style call the widget()->style() again.
+ * Not to mention the performence penalty of having two lookup of rules.
+ *
+ * The first instance of QStyleSheetStyle will set globalStyleSheetStyle to itself. The second one
+ * will notice the globalStyleSheetStyle is not istelf and call its base style directly.
+ */
+static const QStyleSheetStyle *globalStyleSheetStyle = 0;
+class QStyleSheetStyleRecursionGuard
+{
+ public:
+ QStyleSheetStyleRecursionGuard(const QStyleSheetStyle *that)
+ : guarded(globalStyleSheetStyle == 0)
+ {
+ if (guarded) globalStyleSheetStyle = that;
+ }
+ ~QStyleSheetStyleRecursionGuard() { if (guarded) globalStyleSheetStyle = 0; }
+ bool guarded;
+};
+#define RECURSION_GUARD(RETURN) \
+ if (globalStyleSheetStyle != 0 && globalStyleSheetStyle != this) { RETURN; } \
+ QStyleSheetStyleRecursionGuard recursion_guard(this);
+
+#define ceil(x) ((int)(x) + ((x) > 0 && (x) != (int)(x)))
+
+enum PseudoElement {
+ PseudoElement_None,
+ PseudoElement_DownArrow,
+ PseudoElement_UpArrow,
+ PseudoElement_LeftArrow,
+ PseudoElement_RightArrow,
+ PseudoElement_Indicator,
+ PseudoElement_ExclusiveIndicator,
+ PseudoElement_PushButtonMenuIndicator,
+ PseudoElement_ComboBoxDropDown,
+ PseudoElement_ComboBoxArrow,
+ PseudoElement_Item,
+ PseudoElement_SpinBoxUpButton,
+ PseudoElement_SpinBoxUpArrow,
+ PseudoElement_SpinBoxDownButton,
+ PseudoElement_SpinBoxDownArrow,
+ PseudoElement_GroupBoxTitle,
+ PseudoElement_GroupBoxIndicator,
+ PseudoElement_ToolButtonMenu,
+ PseudoElement_ToolButtonMenuArrow,
+ PseudoElement_ToolButtonDownArrow,
+ PseudoElement_ToolBoxTab,
+ PseudoElement_ScrollBarSlider,
+ PseudoElement_ScrollBarAddPage,
+ PseudoElement_ScrollBarSubPage,
+ PseudoElement_ScrollBarAddLine,
+ PseudoElement_ScrollBarSubLine,
+ PseudoElement_ScrollBarFirst,
+ PseudoElement_ScrollBarLast,
+ PseudoElement_ScrollBarUpArrow,
+ PseudoElement_ScrollBarDownArrow,
+ PseudoElement_ScrollBarLeftArrow,
+ PseudoElement_ScrollBarRightArrow,
+ PseudoElement_SplitterHandle,
+ PseudoElement_ToolBarHandle,
+ PseudoElement_ToolBarSeparator,
+ PseudoElement_MenuScroller,
+ PseudoElement_MenuTearoff,
+ PseudoElement_MenuCheckMark,
+ PseudoElement_MenuSeparator,
+ PseudoElement_MenuIcon,
+ PseudoElement_MenuRightArrow,
+ PseudoElement_TreeViewBranch,
+ PseudoElement_HeaderViewSection,
+ PseudoElement_HeaderViewUpArrow,
+ PseudoElement_HeaderViewDownArrow,
+ PseudoElement_ProgressBarChunk,
+ PseudoElement_TabBarTab,
+ PseudoElement_TabBarScroller,
+ PseudoElement_TabBarTear,
+ PseudoElement_SliderGroove,
+ PseudoElement_SliderHandle,
+ PseudoElement_SliderAddPage,
+ PseudoElement_SliderSubPage,
+ PseudoElement_SliderTickmark,
+ PseudoElement_TabWidgetPane,
+ PseudoElement_TabWidgetTabBar,
+ PseudoElement_TabWidgetLeftCorner,
+ PseudoElement_TabWidgetRightCorner,
+ PseudoElement_DockWidgetTitle,
+ PseudoElement_DockWidgetCloseButton,
+ PseudoElement_DockWidgetFloatButton,
+ PseudoElement_DockWidgetSeparator,
+ PseudoElement_MdiCloseButton,
+ PseudoElement_MdiMinButton,
+ PseudoElement_MdiNormalButton,
+ PseudoElement_TitleBar,
+ PseudoElement_TitleBarCloseButton,
+ PseudoElement_TitleBarMinButton,
+ PseudoElement_TitleBarMaxButton,
+ PseudoElement_TitleBarShadeButton,
+ PseudoElement_TitleBarUnshadeButton,
+ PseudoElement_TitleBarNormalButton,
+ PseudoElement_TitleBarContextHelpButton,
+ PseudoElement_TitleBarSysMenu,
+ PseudoElement_ViewItem,
+ PseudoElement_ViewItemIcon,
+ PseudoElement_ViewItemText,
+ PseudoElement_ViewItemIndicator,
+ PseudoElement_ScrollAreaCorner,
+ PseudoElement_TabBarTabCloseButton,
+ NumPseudoElements
+};
+
+struct PseudoElementInfo {
+ QStyle::SubControl subControl;
+ const char *name;
+};
+
+static const PseudoElementInfo knownPseudoElements[NumPseudoElements] = {
+ { QStyle::SC_None, "" },
+ { QStyle::SC_None, "down-arrow" },
+ { QStyle::SC_None, "up-arrow" },
+ { QStyle::SC_None, "left-arrow" },
+ { QStyle::SC_None, "right-arrow" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "menu-indicator" },
+ { QStyle::SC_ComboBoxArrow, "drop-down" },
+ { QStyle::SC_ComboBoxArrow, "down-arrow" },
+ { QStyle::SC_None, "item" },
+ { QStyle::SC_SpinBoxUp, "up-button" },
+ { QStyle::SC_SpinBoxUp, "up-arrow" },
+ { QStyle::SC_SpinBoxDown, "down-button" },
+ { QStyle::SC_SpinBoxDown, "down-arrow" },
+ { QStyle::SC_GroupBoxLabel, "title" },
+ { QStyle::SC_GroupBoxCheckBox, "indicator" },
+ { QStyle::SC_ToolButtonMenu, "menu-button" },
+ { QStyle::SC_ToolButtonMenu, "menu-arrow" },
+ { QStyle::SC_None, "menu-indicator" },
+ { QStyle::SC_None, "tab" },
+ { QStyle::SC_ScrollBarSlider, "handle" },
+ { QStyle::SC_ScrollBarAddPage, "add-page" },
+ { QStyle::SC_ScrollBarSubPage, "sub-page" },
+ { QStyle::SC_ScrollBarAddLine, "add-line" },
+ { QStyle::SC_ScrollBarSubLine, "sub-line" },
+ { QStyle::SC_ScrollBarFirst, "first" },
+ { QStyle::SC_ScrollBarLast, "last" },
+ { QStyle::SC_ScrollBarSubLine, "up-arrow" },
+ { QStyle::SC_ScrollBarAddLine, "down-arrow" },
+ { QStyle::SC_ScrollBarSubLine, "left-arrow" },
+ { QStyle::SC_ScrollBarAddLine, "right-arrow" },
+ { QStyle::SC_None, "handle" },
+ { QStyle::SC_None, "handle" },
+ { QStyle::SC_None, "separator" },
+ { QStyle::SC_None, "scroller" },
+ { QStyle::SC_None, "tearoff" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "separator" },
+ { QStyle::SC_None, "icon" },
+ { QStyle::SC_None, "right-arrow" },
+ { QStyle::SC_None, "branch" },
+ { QStyle::SC_None, "section" },
+ { QStyle::SC_None, "down-arrow" },
+ { QStyle::SC_None, "up-arrow" },
+ { QStyle::SC_None, "chunk" },
+ { QStyle::SC_None, "tab" },
+ { QStyle::SC_None, "scroller" },
+ { QStyle::SC_None, "tear" },
+ { QStyle::SC_SliderGroove, "groove" },
+ { QStyle::SC_SliderHandle, "handle" },
+ { QStyle::SC_None, "add-page" },
+ { QStyle::SC_None, "sub-page"},
+ { QStyle::SC_SliderTickmarks, "tick-mark" },
+ { QStyle::SC_None, "pane" },
+ { QStyle::SC_None, "tab-bar" },
+ { QStyle::SC_None, "left-corner" },
+ { QStyle::SC_None, "right-corner" },
+ { QStyle::SC_None, "title" },
+ { QStyle::SC_None, "close-button" },
+ { QStyle::SC_None, "float-button" },
+ { QStyle::SC_None, "separator" },
+ { QStyle::SC_MdiCloseButton, "close-button" },
+ { QStyle::SC_MdiMinButton, "minimize-button" },
+ { QStyle::SC_MdiNormalButton, "normal-button" },
+ { QStyle::SC_TitleBarLabel, "title" },
+ { QStyle::SC_TitleBarCloseButton, "close-button" },
+ { QStyle::SC_TitleBarMinButton, "minimize-button" },
+ { QStyle::SC_TitleBarMaxButton, "maximize-button" },
+ { QStyle::SC_TitleBarShadeButton, "shade-button" },
+ { QStyle::SC_TitleBarUnshadeButton, "unshade-button" },
+ { QStyle::SC_TitleBarNormalButton, "normal-button" },
+ { QStyle::SC_TitleBarContextHelpButton, "contexthelp-button" },
+ { QStyle::SC_TitleBarSysMenu, "sys-menu" },
+ { QStyle::SC_None, "item" },
+ { QStyle::SC_None, "icon" },
+ { QStyle::SC_None, "text" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "corner" },
+ { QStyle::SC_None, "close-button" },
+};
+
+
+struct QStyleSheetBorderImageData : public QSharedData
+{
+ QStyleSheetBorderImageData()
+ : horizStretch(QCss::TileMode_Unknown), vertStretch(QCss::TileMode_Unknown)
+ {
+ for (int i = 0; i < 4; i++)
+ cuts[i] = -1;
+ }
+ int cuts[4];
+ QPixmap pixmap;
+ QImage image;
+ QCss::TileMode horizStretch, vertStretch;
+};
+
+struct QStyleSheetBackgroundData : public QSharedData
+{
+ QStyleSheetBackgroundData(const QBrush& b, const QPixmap& p, QCss::Repeat r,
+ Qt::Alignment a, QCss::Origin o, Attachment t, QCss::Origin c)
+ : brush(b), pixmap(p), repeat(r), position(a), origin(o), attachment(t), clip(c) { }
+
+ bool isTransparent() const {
+ if (brush.style() != Qt::NoBrush)
+ return !brush.isOpaque();
+ return pixmap.isNull() ? false : pixmap.hasAlpha();
+ }
+ QBrush brush;
+ QPixmap pixmap;
+ QCss::Repeat repeat;
+ Qt::Alignment position;
+ QCss::Origin origin;
+ QCss::Attachment attachment;
+ QCss::Origin clip;
+};
+
+struct QStyleSheetBorderData : public QSharedData
+{
+ QStyleSheetBorderData() : bi(0)
+ {
+ for (int i = 0; i < 4; i++) {
+ borders[i] = 0;
+ styles[i] = QCss::BorderStyle_None;
+ }
+ }
+
+ QStyleSheetBorderData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r) : bi(0)
+ {
+ for (int i = 0; i < 4; i++) {
+ borders[i] = b[i];
+ styles[i] = s[i];
+ colors[i] = c[i];
+ radii[i] = r[i];
+ }
+ }
+
+ int borders[4];
+ QBrush colors[4];
+ QCss::BorderStyle styles[4];
+ QSize radii[4]; // topleft, topright, bottomleft, bottomright
+
+ const QStyleSheetBorderImageData *borderImage() const
+ { return bi; }
+ bool hasBorderImage() const { return bi!=0; }
+
+ QSharedDataPointer<QStyleSheetBorderImageData> bi;
+
+ bool isOpaque() const
+ {
+ for (int i = 0; i < 4; i++) {
+ if (styles[i] == QCss::BorderStyle_Native || styles[i] == QCss::BorderStyle_None)
+ continue;
+ if (styles[i] >= QCss::BorderStyle_Dotted && styles[i] <= QCss::BorderStyle_DotDotDash
+ && styles[i] != BorderStyle_Solid)
+ return false;
+ if (!colors[i].isOpaque())
+ return false;
+ if (!radii[i].isEmpty())
+ return false;
+ }
+ if (bi != 0 && bi->pixmap.hasAlpha())
+ return false;
+ return true;
+ }
+};
+
+
+struct QStyleSheetOutlineData : public QStyleSheetBorderData
+{
+ QStyleSheetOutlineData()
+ {
+ for (int i = 0; i < 4; i++) {
+ offsets[i] = 0;
+ }
+ }
+
+ QStyleSheetOutlineData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r, int *o)
+ : QStyleSheetBorderData(b, c, s, r)
+ {
+ for (int i = 0; i < 4; i++) {
+ offsets[i] = o[i];
+ }
+ }
+
+ int offsets[4];
+};
+
+struct QStyleSheetBoxData : public QSharedData
+{
+ QStyleSheetBoxData(int *m, int *p, int s) : spacing(s)
+ {
+ for (int i = 0; i < 4; i++) {
+ margins[i] = m[i];
+ paddings[i] = p[i];
+ }
+ }
+
+ int margins[4];
+ int paddings[4];
+
+ int spacing;
+};
+
+struct QStyleSheetPaletteData : public QSharedData
+{
+ QStyleSheetPaletteData(const QBrush &fg, const QBrush &sfg, const QBrush &sbg,
+ const QBrush &abg)
+ : foreground(fg), selectionForeground(sfg), selectionBackground(sbg),
+ alternateBackground(abg) { }
+
+ QBrush foreground;
+ QBrush selectionForeground;
+ QBrush selectionBackground;
+ QBrush alternateBackground;
+};
+
+struct QStyleSheetGeometryData : public QSharedData
+{
+ QStyleSheetGeometryData(int w, int h, int minw, int minh, int maxw, int maxh)
+ : minWidth(minw), minHeight(minh), width(w), height(h), maxWidth(maxw), maxHeight(maxh) { }
+
+ int minWidth, minHeight, width, height, maxWidth, maxHeight;
+};
+
+struct QStyleSheetPositionData : public QSharedData
+{
+ QStyleSheetPositionData(int l, int t, int r, int b, Origin o, Qt::Alignment p, QCss::PositionMode m, Qt::Alignment a = 0)
+ : left(l), top(t), bottom(b), right(r), origin(o), position(p), mode(m), textAlignment(a) { }
+
+ int left, top, bottom, right;
+ Origin origin;
+ Qt::Alignment position;
+ QCss::PositionMode mode;
+ Qt::Alignment textAlignment;
+};
+
+struct QStyleSheetImageData : public QSharedData
+{
+ QStyleSheetImageData(const QIcon &i, Qt::Alignment a, const QSize &sz)
+ : icon(i), alignment(a), size(sz) { }
+
+ QIcon icon;
+ Qt::Alignment alignment;
+ QSize size;
+};
+
+class QRenderRule
+{
+public:
+ QRenderRule() : features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0) { }
+ QRenderRule(const QVector<QCss::Declaration> &, const QWidget *);
+ ~QRenderRule() { }
+
+ QRect borderRect(const QRect &r) const;
+ QRect outlineRect(const QRect &r) const;
+ QRect paddingRect(const QRect &r) const;
+ QRect contentsRect(const QRect &r) const;
+
+ enum { Margin = 1, Border = 2, Padding = 4, All=Margin|Border|Padding };
+ QRect boxRect(const QRect &r, int flags = All) const;
+ QSize boxSize(const QSize &s, int flags = All) const;
+ QRect originRect(const QRect &rect, Origin origin) const;
+
+ QPainterPath borderClip(QRect rect);
+ void drawBorder(QPainter *, const QRect&);
+ void drawOutline(QPainter *, const QRect&);
+ void drawBorderImage(QPainter *, const QRect&);
+ void drawBackground(QPainter *, const QRect&, const QPoint& = QPoint(0, 0));
+ void drawBackgroundImage(QPainter *, const QRect&, QPoint = QPoint(0, 0));
+ void drawFrame(QPainter *, const QRect&);
+ void drawImage(QPainter *p, const QRect &rect);
+ void drawRule(QPainter *, const QRect&);
+ void configurePalette(QPalette *, QPalette::ColorGroup, const QWidget *, bool);
+ void configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette::ColorRole br);
+
+ const QStyleSheetPaletteData *palette() const { return pal; }
+ const QStyleSheetBoxData *box() const { return b; }
+ const QStyleSheetBackgroundData *background() const { return bg; }
+ const QStyleSheetBorderData *border() const { return bd; }
+ const QStyleSheetOutlineData *outline() const { return ou; }
+ const QStyleSheetGeometryData *geometry() const { return geo; }
+ const QStyleSheetPositionData *position() const { return p; }
+
+ bool hasPalette() const { return pal != 0; }
+ bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); }
+ bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern
+ && bg->brush.style() <= Qt::ConicalGradientPattern; }
+
+ bool hasNativeBorder() const {
+ return bd == 0
+ || (!bd->hasBorderImage() && bd->styles[0] == BorderStyle_Native);
+ }
+
+ bool hasNativeOutline() const {
+ return (ou == 0
+ || (!ou->hasBorderImage() && ou->styles[0] == BorderStyle_Native));
+ }
+
+ bool baseStyleCanDraw() const {
+ if (!hasBackground() || (background()->brush.style() == Qt::NoBrush && bg->pixmap.isNull()))
+ return true;
+ if (bg && !bg->pixmap.isNull())
+ return false;
+ if (hasGradientBackground())
+ return features & StyleFeature_BackgroundGradient;
+ return features & StyleFeature_BackgroundColor;
+ }
+
+ bool hasBox() const { return b != 0; }
+ bool hasBorder() const { return bd != 0; }
+ bool hasOutline() const { return ou != 0; }
+ bool hasPosition() const { return p != 0; }
+ bool hasGeometry() const { return geo != 0; }
+ bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); }
+ bool hasImage() const { return img != 0; }
+
+ QSize minimumContentsSize() const
+ { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); }
+ QSize minimumSize() const
+ { return boxSize(minimumContentsSize()); }
+
+ QSize contentsSize() const
+ { return geo ? QSize(geo->width, geo->height)
+ : ((img && img->size.isValid()) ? img->size : QSize()); }
+ QSize contentsSize(const QSize &sz) const
+ {
+ QSize csz = contentsSize();
+ if (csz.width() == -1) csz.setWidth(sz.width());
+ if (csz.height() == -1) csz.setHeight(sz.height());
+ return csz;
+ }
+ bool hasContentsSize() const
+ { return (geo && (geo->width != -1 || geo->height != -1)) || (img && img->size.isValid()); }
+
+ QSize size() const { return boxSize(contentsSize()); }
+ QSize size(const QSize &sz) const { return boxSize(contentsSize(sz)); }
+ QSize adjustSize(const QSize &sz)
+ {
+ if (!geo)
+ return sz;
+ QSize csz = contentsSize();
+ if (csz.width() == -1) csz.setWidth(sz.width());
+ if (csz.height() == -1) csz.setHeight(sz.height());
+ if (geo->maxWidth != -1 && csz.width() > geo->maxWidth) csz.setWidth(geo->maxWidth);
+ if (geo->maxHeight != -1 && csz.height() > geo->maxHeight) csz.setHeight(geo->maxHeight);
+ csz=csz.expandedTo(QSize(geo->minWidth, geo->minHeight));
+ return csz;
+ }
+
+ int features;
+ QBrush defaultBackground;
+ QFont font;
+ bool hasFont;
+
+ QHash<QString, QVariant> styleHints;
+ bool hasStyleHint(const QString& sh) const { return styleHints.contains(sh); }
+ QVariant styleHint(const QString& sh) const { return styleHints.value(sh); }
+
+ void fixupBorder(int);
+
+ QSharedDataPointer<QStyleSheetPaletteData> pal;
+ QSharedDataPointer<QStyleSheetBoxData> b;
+ QSharedDataPointer<QStyleSheetBackgroundData> bg;
+ QSharedDataPointer<QStyleSheetBorderData> bd;
+ QSharedDataPointer<QStyleSheetOutlineData> ou;
+ QSharedDataPointer<QStyleSheetGeometryData> geo;
+ QSharedDataPointer<QStyleSheetPositionData> p;
+ QSharedDataPointer<QStyleSheetImageData> img;
+
+ // Shouldn't be here
+ void setClip(QPainter *p, const QRect &rect);
+ void unsetClip(QPainter *);
+ int clipset;
+ QPainterPath clipPath;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////
+static const char *knownStyleHints[] = {
+ "activate-on-singleclick",
+ "alignment",
+ "arrow-keys-navigate-into-children",
+ "backward-icon",
+ "button-layout",
+ "cd-icon",
+ "combobox-list-mousetracking",
+ "combobox-popup",
+ "computer-icon",
+ "desktop-icon",
+ "dialog-apply-icon",
+ "dialog-cancel-icon",
+ "dialog-close-icon",
+ "dialog-discard-icon",
+ "dialog-help-icon",
+ "dialog-no-icon",
+ "dialog-ok-icon",
+ "dialog-open-icon",
+ "dialog-reset-icon",
+ "dialog-save-icon",
+ "dialog-yes-icon",
+ "dialogbuttonbox-buttons-have-icons",
+ "directory-closed-icon",
+ "directory-icon",
+ "directory-link-icon",
+ "directory-open-icon",
+ "dither-disable-text",
+ "dockwidget-close-icon",
+ "downarrow-icon",
+ "dvd-icon",
+ "etch-disabled-text",
+ "file-icon",
+ "file-link-icon",
+ "filedialog-backward-icon", // unused
+ "filedialog-contentsview-icon",
+ "filedialog-detailedview-icon",
+ "filedialog-end-icon",
+ "filedialog-infoview-icon",
+ "filedialog-listview-icon",
+ "filedialog-new-directory-icon",
+ "filedialog-parent-directory-icon",
+ "filedialog-start-icon",
+ "floppy-icon",
+ "forward-icon",
+ "gridline-color",
+ "harddisk-icon",
+ "home-icon",
+ "icon-size",
+ "leftarrow-icon",
+ "lineedit-password-character",
+ "mdi-fill-space-on-maximize",
+ "menu-scrollable",
+ "menubar-altkey-navigation",
+ "menubar-separator",
+ "messagebox-critical-icon",
+ "messagebox-information-icon",
+ "messagebox-question-icon",
+ "messagebox-text-interaction-flags",
+ "messagebox-warning-icon",
+ "mouse-tracking",
+ "network-icon",
+ "opacity",
+ "paint-alternating-row-colors-for-empty-area",
+ "rightarrow-icon",
+ "scrollbar-contextmenu",
+ "scrollbar-leftclick-absolute-position",
+ "scrollbar-middleclick-absolute-position",
+ "scrollbar-roll-between-buttons",
+ "scrollbar-scroll-when-pointer-leaves-control",
+ "scrollview-frame-around-contents",
+ "show-decoration-selected",
+ "spinbox-click-autorepeat-rate",
+ "spincontrol-disable-on-bounds",
+ "tabbar-elide-mode",
+ "tabbar-prefer-no-arrows",
+ "titlebar-close-icon",
+ "titlebar-contexthelp-icon",
+ "titlebar-maximize-icon",
+ "titlebar-menu-icon",
+ "titlebar-minimize-icon",
+ "titlebar-normal-icon",
+ "titlebar-shade-icon",
+ "titlebar-unshade-icon",
+ "toolbutton-popup-delay",
+ "trash-icon",
+ "uparrow-icon"
+};
+
+static const int numKnownStyleHints = sizeof(knownStyleHints)/sizeof(knownStyleHints[0]);
+
+static QList<QVariant> subControlLayout(const QString& layout)
+{
+ QList<QVariant> buttons;
+ for (int i = 0; i < layout.count(); i++) {
+ int button = layout[i].toAscii();
+ switch (button) {
+ case 'm':
+ buttons.append(PseudoElement_MdiMinButton);
+ buttons.append(PseudoElement_TitleBarMinButton);
+ break;
+ case 'M':
+ buttons.append(PseudoElement_TitleBarMaxButton);
+ break;
+ case 'X':
+ buttons.append(PseudoElement_MdiCloseButton);
+ buttons.append(PseudoElement_TitleBarCloseButton);
+ break;
+ case 'N':
+ buttons.append(PseudoElement_MdiNormalButton);
+ buttons.append(PseudoElement_TitleBarNormalButton);
+ break;
+ case 'I':
+ buttons.append(PseudoElement_TitleBarSysMenu);
+ break;
+ case 'T':
+ buttons.append(PseudoElement_TitleBar);
+ break;
+ case 'H':
+ buttons.append(PseudoElement_TitleBarContextHelpButton);
+ break;
+ case 'S':
+ buttons.append(PseudoElement_TitleBarShadeButton);
+ break;
+ default:
+ buttons.append(button);
+ break;
+ }
+ }
+ return buttons;
+}
+
+namespace {
+ struct ButtonInfo {
+ QRenderRule rule;
+ int element;
+ int offset;
+ int where;
+ int width;
+ };
+}
+
+QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const
+{
+ QHash<QStyle::SubControl, QRect> layoutRects;
+ const bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ const bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ QRenderRule subRule = renderRule(w, tb);
+ QRect cr = subRule.contentsRect(tb->rect);
+ QList<QVariant> layout = subRule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("I(T)HSmMX"));
+
+ int offsets[3] = { 0, 0, 0 };
+ enum Where { Left, Right, Center, NoWhere } where = Left;
+ QList<ButtonInfo> infos;
+ for (int i = 0; i < layout.count(); i++) {
+ ButtonInfo info;
+ info.element = layout[i].toInt();
+ if (info.element == '(') {
+ where = Center;
+ } else if (info.element == ')') {
+ where = Right;
+ } else {
+ switch (info.element) {
+ case PseudoElement_TitleBar:
+ if (!(tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)))
+ continue;
+ break;
+ case PseudoElement_TitleBarContextHelpButton:
+ if (!(tb->titleBarFlags & Qt::WindowContextHelpButtonHint))
+ continue;
+ break;
+ case PseudoElement_TitleBarMinButton:
+ if (!(tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ continue;
+ if (isMinimized)
+ info.element = PseudoElement_TitleBarNormalButton;
+ break;
+ case PseudoElement_TitleBarMaxButton:
+ if (!(tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ continue;
+ if (isMaximized)
+ info.element = PseudoElement_TitleBarNormalButton;
+ break;
+ case PseudoElement_TitleBarShadeButton:
+ if (!(tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ continue;
+ if (isMinimized)
+ info.element = PseudoElement_TitleBarUnshadeButton;
+ break;
+ case PseudoElement_TitleBarCloseButton:
+ case PseudoElement_TitleBarSysMenu:
+ if (!(tb->titleBarFlags & Qt::WindowSystemMenuHint))
+ continue;
+ break;
+ default:
+ continue;
+ }
+ if (info.element == PseudoElement_TitleBar) {
+ info.width = tb->fontMetrics.width(tb->text) + 6;
+ subRule.geo = new QStyleSheetGeometryData(info.width, tb->fontMetrics.height(), -1, -1, -1, -1);
+ } else {
+ subRule = renderRule(w, tb, info.element);
+ info.width = subRule.size().width();
+ }
+ info.rule = subRule;
+ info.offset = offsets[where];
+ info.where = where;
+ infos.append(info);
+
+ offsets[where] += info.width;
+ }
+ }
+
+ for (int i = 0; i < infos.count(); i++) {
+ ButtonInfo info = infos[i];
+ QRect lr = cr;
+ switch (info.where) {
+ case Center: {
+ lr.setLeft(cr.left() + offsets[Left]);
+ lr.setRight(cr.right() - offsets[Right]);
+ QRect r(0, 0, offsets[Center], lr.height());
+ r.moveCenter(lr.center());
+ r.setLeft(r.left()+info.offset);
+ r.setWidth(info.width);
+ lr = r;
+ break; }
+ case Left:
+ lr.translate(info.offset, 0);
+ lr.setWidth(info.width);
+ break;
+ case Right:
+ lr.moveLeft(cr.right() + 1 - offsets[Right] + info.offset);
+ lr.setWidth(info.width);
+ break;
+ default:
+ break;
+ }
+ QStyle::SubControl control = knownPseudoElements[info.element].subControl;
+ layoutRects[control] = positionRect(w, info.rule, info.element, lr, tb->direction);
+ }
+
+ return layoutRects;
+}
+
+static QStyle::StandardPixmap subControlIcon(int pe)
+{
+ switch (pe) {
+ case PseudoElement_MdiCloseButton: return QStyle::SP_TitleBarCloseButton;
+ case PseudoElement_MdiMinButton: return QStyle::SP_TitleBarMinButton;
+ case PseudoElement_MdiNormalButton: return QStyle::SP_TitleBarNormalButton;
+ case PseudoElement_TitleBarCloseButton: return QStyle::SP_TitleBarCloseButton;
+ case PseudoElement_TitleBarMinButton: return QStyle::SP_TitleBarMinButton;
+ case PseudoElement_TitleBarMaxButton: return QStyle::SP_TitleBarMaxButton;
+ case PseudoElement_TitleBarShadeButton: return QStyle::SP_TitleBarShadeButton;
+ case PseudoElement_TitleBarUnshadeButton: return QStyle::SP_TitleBarUnshadeButton;
+ case PseudoElement_TitleBarNormalButton: return QStyle::SP_TitleBarNormalButton;
+ case PseudoElement_TitleBarContextHelpButton: return QStyle::SP_TitleBarContextHelpButton;
+ default: break;
+ }
+ return QStyle::SP_CustomBase;
+}
+
+QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QWidget *widget)
+: features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0)
+{
+ QPalette palette = QApplication::palette(); // ###: ideally widget's palette
+ ValueExtractor v(declarations, palette);
+ features = v.extractStyleFeatures();
+
+ int w = -1, h = -1, minw = -1, minh = -1, maxw = -1, maxh = -1;
+ if (v.extractGeometry(&w, &h, &minw, &minh, &maxw, &maxh))
+ geo = new QStyleSheetGeometryData(w, h, minw, minh, maxw, maxh);
+
+ int left = 0, top = 0, right = 0, bottom = 0;
+ Origin origin = Origin_Unknown;
+ Qt::Alignment position = 0;
+ QCss::PositionMode mode = PositionMode_Unknown;
+ Qt::Alignment textAlignment = 0;
+ if (v.extractPosition(&left, &top, &right, &bottom, &origin, &position, &mode, &textAlignment))
+ p = new QStyleSheetPositionData(left, top, right, bottom, origin, position, mode, textAlignment);
+
+ int margins[4], paddings[4], spacing = -1;
+ for (int i = 0; i < 4; i++)
+ margins[i] = paddings[i] = 0;
+ if (v.extractBox(margins, paddings, &spacing))
+ b = new QStyleSheetBoxData(margins, paddings, spacing);
+
+ int borders[4];
+ QBrush colors[4];
+ QCss::BorderStyle styles[4];
+ QSize radii[4];
+ for (int i = 0; i < 4; i++) {
+ borders[i] = 0;
+ styles[i] = BorderStyle_None;
+ }
+ if (v.extractBorder(borders, colors, styles, radii))
+ bd = new QStyleSheetBorderData(borders, colors, styles, radii);
+
+ int offsets[4];
+ for (int i = 0; i < 4; i++) {
+ borders[i] = offsets[i] = 0;
+ styles[i] = BorderStyle_None;
+ }
+ if (v.extractOutline(borders, colors, styles, radii, offsets))
+ ou = new QStyleSheetOutlineData(borders, colors, styles, radii, offsets);
+
+ QBrush brush;
+ QString uri;
+ Repeat repeat = Repeat_XY;
+ Qt::Alignment alignment = Qt::AlignTop | Qt::AlignLeft;
+ Attachment attachment = Attachment_Scroll;
+ origin = Origin_Padding;
+ Origin clip = Origin_Border;
+ if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
+ bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
+
+ QBrush sfg, fg;
+ QBrush sbg, abg;
+ if (v.extractPalette(&fg, &sfg, &sbg, &abg))
+ pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
+
+ QIcon icon;
+ alignment = Qt::AlignCenter;
+ QSize size;
+ if (v.extractImage(&icon, &alignment, &size))
+ img = new QStyleSheetImageData(icon, alignment, size);
+
+ int adj = -255;
+ hasFont = v.extractFont(&font, &adj);
+
+#ifndef QT_NO_TOOLTIP
+ if (widget && qstrcmp(widget->metaObject()->className(), "QTipLabel") == 0)
+ palette = QToolTip::palette();
+#endif
+
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration& decl = declarations.at(i);
+ if (decl.d->propertyId == BorderImage) {
+ QString uri;
+ QCss::TileMode horizStretch, vertStretch;
+ int cuts[4];
+
+ decl.borderImageValue(&uri, cuts, &horizStretch, &vertStretch);
+ if (uri.isEmpty() || uri == QLatin1String("none")) {
+ if (bd && bd->bi)
+ bd->bi->pixmap = QPixmap();
+ } else {
+ if (!bd)
+ bd = new QStyleSheetBorderData;
+ if (!bd->bi)
+ bd->bi = new QStyleSheetBorderImageData;
+
+ QStyleSheetBorderImageData *bi = bd->bi;
+ bi->pixmap = QPixmap(uri);
+ for (int i = 0; i < 4; i++)
+ bi->cuts[i] = cuts[i];
+ bi->horizStretch = horizStretch;
+ bi->vertStretch = vertStretch;
+ }
+ } else if (decl.d->propertyId == QtBackgroundRole) {
+ if (bg && bg->brush.style() != Qt::NoBrush)
+ continue;
+ int role = decl.d->values.at(0).variant.toInt();
+ if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
+ defaultBackground = palette.color((QPalette::ColorRole)(role-Value_FirstColorRole));
+ } else if (decl.d->property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive)) {
+ // intentionally left blank...
+ } else if (decl.d->propertyId == UnknownProperty) {
+ bool knownStyleHint = false;
+ for (int i = 0; i < numKnownStyleHints; i++) {
+ QLatin1String styleHint(knownStyleHints[i]);
+ if (decl.d->property.compare(styleHint) == 0) {
+ QString hintName = QString(styleHint);
+ QVariant hintValue;
+ if (hintName.endsWith(QLatin1String("alignment"))) {
+ hintValue = (int) decl.alignmentValue();
+ } else if (hintName.endsWith(QLatin1String("color"))) {
+ hintValue = (int) decl.colorValue().rgba();
+ } else if (hintName.endsWith(QLatin1String("size"))) {
+ hintValue = decl.sizeValue();
+ // ### Qt5
+// } else if (hintName.endsWith(QLatin1String("icon"))) {
+// hintValue = decl.iconValue();
+ } else if (hintName == QLatin1String("button-layout")
+ && decl.d->values.count() != 0 && decl.d->values.at(0).type == Value::String) {
+ hintValue = subControlLayout(decl.d->values.at(0).variant.toString());
+ } else {
+ int integer;
+ decl.intValue(&integer);
+ hintValue = integer;
+ }
+ styleHints[decl.d->property] = hintValue;
+ knownStyleHint = true;
+ break;
+ }
+ }
+ if (!knownStyleHint)
+ qDebug("Unknown property %s", qPrintable(decl.d->property));
+ }
+ }
+
+ if (widget) {
+ QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
+ if (!style)
+ style = qobject_cast<QStyleSheetStyle *>(widget->style());
+ if (style)
+ fixupBorder(style->nativeFrameWidth(widget));
+
+ }
+ if (hasBorder() && border()->hasBorderImage())
+ defaultBackground = QBrush();
+}
+
+QRect QRenderRule::borderRect(const QRect& r) const
+{
+ if (!hasBox())
+ return r;
+ const int* m = box()->margins;
+ return r.adjusted(m[LeftEdge], m[TopEdge], -m[RightEdge], -m[BottomEdge]);
+}
+
+QRect QRenderRule::outlineRect(const QRect& r) const
+{
+ QRect br = borderRect(r);
+ if (!hasOutline())
+ return br;
+ const int *b = outline()->borders;
+ return r.adjusted(b[LeftEdge], b[TopEdge], -b[RightEdge], -b[BottomEdge]);
+}
+
+QRect QRenderRule::paddingRect(const QRect& r) const
+{
+ QRect br = borderRect(r);
+ if (!hasBorder())
+ return br;
+ const int *b = border()->borders;
+ return br.adjusted(b[LeftEdge], b[TopEdge], -b[RightEdge], -b[BottomEdge]);
+}
+
+QRect QRenderRule::contentsRect(const QRect& r) const
+{
+ QRect pr = paddingRect(r);
+ if (!hasBox())
+ return pr;
+ const int *p = box()->paddings;
+ return pr.adjusted(p[LeftEdge], p[TopEdge], -p[RightEdge], -p[BottomEdge]);
+}
+
+QRect QRenderRule::boxRect(const QRect& cr, int flags) const
+{
+ QRect r = cr;
+ if (hasBox()) {
+ if (flags & Margin) {
+ const int *m = box()->margins;
+ r.adjust(-m[LeftEdge], -m[TopEdge], m[RightEdge], m[BottomEdge]);
+ }
+ if (flags & Padding) {
+ const int *p = box()->paddings;
+ r.adjust(-p[LeftEdge], -p[TopEdge], p[RightEdge], p[BottomEdge]);
+ }
+ }
+ if (hasBorder() && (flags & Border)) {
+ const int *b = border()->borders;
+ r.adjust(-b[LeftEdge], -b[TopEdge], b[RightEdge], b[BottomEdge]);
+ }
+ return r;
+}
+
+QSize QRenderRule::boxSize(const QSize &cs, int flags) const
+{
+ QSize bs = boxRect(QRect(QPoint(0, 0), cs), flags).size();
+ if (cs.width() < 0) bs.setWidth(-1);
+ if (cs.height() < 0) bs.setHeight(-1);
+ return bs;
+}
+
+void QRenderRule::fixupBorder(int nativeWidth)
+{
+ if (bd == 0)
+ return;
+
+ if (!bd->hasBorderImage() || bd->bi->pixmap.isNull()) {
+ bd->bi = 0;
+ // ignore the color, border of edges that have none border-style
+ QBrush color = pal ? pal->foreground : QBrush();
+ const bool hasRadius = bd->radii[0].isValid() || bd->radii[1].isValid()
+ || bd->radii[2].isValid() || bd->radii[3].isValid();
+ for (int i = 0; i < 4; i++) {
+ if ((bd->styles[i] == BorderStyle_Native) && hasRadius)
+ bd->styles[i] = BorderStyle_None;
+
+ switch (bd->styles[i]) {
+ case BorderStyle_None:
+ // border-style: none forces width to be 0
+ bd->colors[i] = QBrush();
+ bd->borders[i] = 0;
+ break;
+ case BorderStyle_Native:
+ if (bd->borders[i] == 0)
+ bd->borders[i] = nativeWidth;
+ // intentional fall through
+ default:
+ if (!bd->colors[i].style() != Qt::NoBrush) // auto-acquire 'color'
+ bd->colors[i] = color;
+ break;
+ }
+ }
+
+ return;
+ }
+
+ // inspect the border image
+ QStyleSheetBorderImageData *bi = bd->bi;
+ if (bi->cuts[0] == -1) {
+ for (int i = 0; i < 4; i++) // assume, cut = border
+ bi->cuts[i] = int(border()->borders[i]);
+ }
+}
+
+void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect)
+{
+ setClip(p, rect);
+ static const Qt::TileRule tileMode2TileRule[] = {
+ Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile };
+
+ const QStyleSheetBorderImageData *borderImageData = border()->borderImage();
+ const int *targetBorders = border()->borders;
+ const int *sourceBorders = borderImageData->cuts;
+ QMargins sourceMargins(sourceBorders[LeftEdge], sourceBorders[TopEdge],
+ sourceBorders[RightEdge], sourceBorders[BottomEdge]);
+ QMargins targetMargins(targetBorders[LeftEdge], targetBorders[TopEdge],
+ targetBorders[RightEdge], targetBorders[BottomEdge]);
+
+ bool wasSmoothPixmapTransform = p->renderHints() & QPainter::SmoothPixmapTransform;
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ qDrawBorderPixmap(p, rect, targetMargins, borderImageData->pixmap,
+ QRect(QPoint(), borderImageData->pixmap.size()), sourceMargins,
+ QTileRules(tileMode2TileRule[borderImageData->horizStretch], tileMode2TileRule[borderImageData->vertStretch]));
+ p->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothPixmapTransform);
+ unsetClip(p);
+}
+
+QRect QRenderRule::originRect(const QRect &rect, Origin origin) const
+{
+ switch (origin) {
+ case Origin_Padding:
+ return paddingRect(rect);
+ case Origin_Border:
+ return borderRect(rect);
+ case Origin_Content:
+ return contentsRect(rect);
+ case Origin_Margin:
+ default:
+ return rect;
+ }
+}
+
+void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off)
+{
+ if (!hasBackground())
+ return;
+
+ const QPixmap& bgp = background()->pixmap;
+ if (bgp.isNull())
+ return;
+
+ setClip(p, borderRect(rect));
+
+ if (background()->origin != background()->clip) {
+ p->save();
+ p->setClipRect(originRect(rect, background()->clip), Qt::IntersectClip);
+ }
+
+ if (background()->attachment == Attachment_Fixed)
+ off = QPoint(0, 0);
+
+ QRect r = originRect(rect, background()->origin);
+ QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r);
+ QRect inter = aligned.translated(-off).intersected(r);
+
+ switch (background()->repeat) {
+ case Repeat_Y:
+ p->drawTiledPixmap(inter.x(), r.y(), inter.width(), r.height(), bgp,
+ inter.x() - aligned.x() + off.x(),
+ bgp.height() - int(aligned.y() - r.y()) % bgp.height() + off.y());
+ break;
+ case Repeat_X:
+ p->drawTiledPixmap(r.x(), inter.y(), r.width(), inter.height(), bgp,
+ bgp.width() - int(aligned.x() - r.x())%bgp.width() + off.x(),
+ inter.y() - aligned.y() + off.y());
+ break;
+ case Repeat_XY:
+ p->drawTiledPixmap(r, bgp,
+ QPoint(bgp.width() - int(aligned.x() - r.x())% bgp.width() + off.x(),
+ bgp.height() - int(aligned.y() - r.y())%bgp.height() + off.y()));
+ break;
+ case Repeat_None:
+ default:
+ p->drawPixmap(inter.x(), inter.y(), bgp, inter.x() - aligned.x() + off.x(),
+ inter.y() - aligned.y() + off.y(), inter.width(), inter.height());
+ break;
+ }
+
+
+ if (background()->origin != background()->clip)
+ p->restore();
+
+ unsetClip(p);
+}
+
+void QRenderRule::drawOutline(QPainter *p, const QRect &rect)
+{
+ if (!hasOutline())
+ return;
+
+ bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
+ p->setRenderHint(QPainter::Antialiasing);
+ qDrawBorder(p, rect, ou->styles, ou->borders, ou->colors, ou->radii);
+ p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
+}
+
+void QRenderRule::drawBorder(QPainter *p, const QRect& rect)
+{
+ if (!hasBorder())
+ return;
+
+ if (border()->hasBorderImage()) {
+ drawBorderImage(p, rect);
+ return;
+ }
+
+ bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
+ p->setRenderHint(QPainter::Antialiasing);
+ qDrawBorder(p, rect, bd->styles, bd->borders, bd->colors, bd->radii);
+ p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
+}
+
+QPainterPath QRenderRule::borderClip(QRect r)
+{
+ if (!hasBorder())
+ return QPainterPath();
+
+ QSize tlr, trr, blr, brr;
+ qNormalizeRadii(r, bd->radii, &tlr, &trr, &blr, &brr);
+ if (tlr.isNull() && trr.isNull() && blr.isNull() && brr.isNull())
+ return QPainterPath();
+
+ const QRectF rect(r);
+ const int *borders = border()->borders;
+ QPainterPath path;
+ qreal curY = rect.y() + borders[TopEdge]/2.0;
+ path.moveTo(rect.x() + tlr.width(), curY);
+ path.lineTo(rect.right() - trr.width(), curY);
+ qreal curX = rect.right() - borders[RightEdge]/2.0;
+ path.arcTo(curX - 2*trr.width() + borders[RightEdge], curY,
+ trr.width()*2 - borders[RightEdge], trr.height()*2 - borders[TopEdge], 90, -90);
+
+ path.lineTo(curX, rect.bottom() - brr.height());
+ curY = rect.bottom() - borders[BottomEdge]/2.0;
+ path.arcTo(curX - 2*brr.width() + borders[RightEdge], curY - 2*brr.height() + borders[BottomEdge],
+ brr.width()*2 - borders[RightEdge], brr.height()*2 - borders[BottomEdge], 0, -90);
+
+ path.lineTo(rect.x() + blr.width(), curY);
+ curX = rect.left() + borders[LeftEdge]/2.0;
+ path.arcTo(curX, rect.bottom() - 2*blr.height() + borders[BottomEdge]/2,
+ blr.width()*2 - borders[LeftEdge], blr.height()*2 - borders[BottomEdge], 270, -90);
+
+ path.lineTo(curX, rect.top() + tlr.height());
+ path.arcTo(curX, rect.top() + borders[TopEdge]/2,
+ tlr.width()*2 - borders[LeftEdge], tlr.height()*2 - borders[TopEdge], 180, -90);
+
+ path.closeSubpath();
+ return path;
+}
+
+/*! \internal
+ Clip the painter to the border (in case we are using radius border)
+ */
+void QRenderRule::setClip(QPainter *p, const QRect &rect)
+{
+ if (clipset++)
+ return;
+ clipPath = borderClip(rect);
+ if (!clipPath.isEmpty()) {
+ p->save();
+ p->setClipPath(clipPath, Qt::IntersectClip);
+ }
+}
+
+void QRenderRule::unsetClip(QPainter *p)
+{
+ if (--clipset)
+ return;
+ if (!clipPath.isEmpty())
+ p->restore();
+}
+
+void QRenderRule::drawBackground(QPainter *p, const QRect& rect, const QPoint& off)
+{
+ QBrush brush = hasBackground() ? background()->brush : QBrush();
+ if (brush.style() == Qt::NoBrush)
+ brush = defaultBackground;
+
+ if (brush.style() != Qt::NoBrush) {
+ Origin origin = hasBackground() ? background()->clip : Origin_Border;
+ // ### fix for gradients
+ const QPainterPath &borderPath = borderClip(originRect(rect, origin));
+ if (!borderPath.isEmpty()) {
+ // Drawn intead of being used as clipping path for better visual quality
+ bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
+ p->setRenderHint(QPainter::Antialiasing);
+ p->fillPath(borderPath, brush);
+ p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
+ } else {
+ p->fillRect(originRect(rect, origin), brush);
+ }
+ }
+
+ drawBackgroundImage(p, rect, off);
+}
+
+void QRenderRule::drawFrame(QPainter *p, const QRect& rect)
+{
+ drawBackground(p, rect);
+ if (hasBorder())
+ drawBorder(p, borderRect(rect));
+}
+
+void QRenderRule::drawImage(QPainter *p, const QRect &rect)
+{
+ if (!hasImage())
+ return;
+ img->icon.paint(p, rect, img->alignment);
+}
+
+void QRenderRule::drawRule(QPainter *p, const QRect& rect)
+{
+ drawFrame(p, rect);
+ drawImage(p, contentsRect(rect));
+}
+
+// *shudder* , *horror*, *whoa* <-- what you might feel when you see the functions below
+void QRenderRule::configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette::ColorRole br)
+{
+ if (bg && bg->brush.style() != Qt::NoBrush) {
+ if (br != QPalette::NoRole)
+ p->setBrush(br, bg->brush);
+ p->setBrush(QPalette::Window, bg->brush);
+ if (bg->brush.style() == Qt::SolidPattern) {
+ p->setBrush(QPalette::Light, bg->brush.color().lighter(115));
+ p->setBrush(QPalette::Midlight, bg->brush.color().lighter(107));
+ p->setBrush(QPalette::Dark, bg->brush.color().darker(150));
+ p->setBrush(QPalette::Shadow, bg->brush.color().darker(300));
+ }
+ }
+
+ if (!hasPalette())
+ return;
+
+ if (pal->foreground.style() != Qt::NoBrush) {
+ if (fr != QPalette::NoRole)
+ p->setBrush(fr, pal->foreground);
+ p->setBrush(QPalette::WindowText, pal->foreground);
+ p->setBrush(QPalette::Text, pal->foreground);
+ }
+ if (pal->selectionBackground.style() != Qt::NoBrush)
+ p->setBrush(QPalette::Highlight, pal->selectionBackground);
+ if (pal->selectionForeground.style() != Qt::NoBrush)
+ p->setBrush(QPalette::HighlightedText, pal->selectionForeground);
+ if (pal->alternateBackground.style() != Qt::NoBrush)
+ p->setBrush(QPalette::AlternateBase, pal->alternateBackground);
+}
+
+void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const QWidget *w, bool embedded)
+{
+ if (bg && bg->brush.style() != Qt::NoBrush) {
+ p->setBrush(cg, QPalette::Base, bg->brush); // for windows, windowxp
+ p->setBrush(cg, QPalette::Button, bg->brush); // for plastique
+ p->setBrush(cg, w->backgroundRole(), bg->brush);
+ p->setBrush(cg, QPalette::Window, bg->brush);
+ }
+
+ if (embedded) {
+ /* For embedded widgets (ComboBox, SpinBox and ScrollArea) we want the embedded widget
+ * to be transparent when we have a transparent background or border image */
+ if ((hasBackground() && background()->isTransparent())
+ || (hasBorder() && border()->hasBorderImage() && !border()->borderImage()->pixmap.isNull()))
+ p->setBrush(cg, w->backgroundRole(), Qt::NoBrush);
+ }
+
+ if (!hasPalette())
+ return;
+
+ if (pal->foreground.style() != Qt::NoBrush) {
+ p->setBrush(cg, QPalette::ButtonText, pal->foreground);
+ p->setBrush(cg, w->foregroundRole(), pal->foreground);
+ p->setBrush(cg, QPalette::WindowText, pal->foreground);
+ p->setBrush(cg, QPalette::Text, pal->foreground);
+ }
+ if (pal->selectionBackground.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::Highlight, pal->selectionBackground);
+ if (pal->selectionForeground.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground);
+ if (pal->alternateBackground.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Style rules
+#define WIDGET(x) (static_cast<QWidget *>(x.ptr))
+
+static inline QWidget *parentWidget(const QWidget *w)
+{
+ if(qobject_cast<const QLabel *>(w) && qstrcmp(w->metaObject()->className(), "QTipLabel") == 0) {
+ QWidget *p = qvariant_cast<QWidget *>(w->property("_q_stylesheet_parent"));
+ if (p)
+ return p;
+ }
+ return w->parentWidget();
+}
+
+class QStyleSheetStyleSelector : public StyleSelector
+{
+public:
+ QStyleSheetStyleSelector() { }
+
+ QStringList nodeNames(NodePtr node) const
+ {
+ if (isNullNode(node))
+ return QStringList();
+ const QMetaObject *metaObject = WIDGET(node)->metaObject();
+#ifndef QT_NO_TOOLTIP
+ if (qstrcmp(metaObject->className(), "QTipLabel") == 0)
+ return QStringList(QLatin1String("QToolTip"));
+#endif
+ QStringList result;
+ do {
+ result += QString::fromLatin1(metaObject->className()).replace(QLatin1Char(':'), QLatin1Char('-'));
+ metaObject = metaObject->superClass();
+ } while (metaObject != 0);
+ return result;
+ }
+ QString attribute(NodePtr node, const QString& name) const
+ {
+ if (isNullNode(node))
+ return QString();
+
+ QHash<QString, QString> &cache = m_attributeCache[WIDGET(node)];
+ QHash<QString, QString>::const_iterator cacheIt = cache.constFind(name);
+ if (cacheIt != cache.constEnd())
+ return cacheIt.value();
+
+ QVariant value = WIDGET(node)->property(name.toLatin1());
+ if (!value.isValid()) {
+ if (name == QLatin1String("class")) {
+ QString className = QString::fromLatin1(WIDGET(node)->metaObject()->className());
+ if (className.contains(QLatin1Char(':')))
+ className.replace(QLatin1Char(':'), QLatin1Char('-'));
+ cache[name] = className;
+ return className;
+ } else if (name == QLatin1String("style")) {
+ QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(WIDGET(node)->style());
+ if (proxy) {
+ QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
+ cache[name] = styleName;
+ return styleName;
+ }
+ }
+ }
+ QString valueStr;
+ if(value.type() == QVariant::StringList || value.type() == QVariant::List)
+ valueStr = value.toStringList().join(QLatin1String(" "));
+ else
+ valueStr = value.toString();
+ cache[name] = valueStr;
+ return valueStr;
+ }
+ bool nodeNameEquals(NodePtr node, const QString& nodeName) const
+ {
+ if (isNullNode(node))
+ return false;
+ const QMetaObject *metaObject = WIDGET(node)->metaObject();
+#ifndef QT_NO_TOOLTIP
+ if (qstrcmp(metaObject->className(), "QTipLabel") == 0)
+ return nodeName == QLatin1String("QToolTip");
+#endif
+ do {
+ const ushort *uc = (const ushort *)nodeName.constData();
+ const ushort *e = uc + nodeName.length();
+ const uchar *c = (uchar *)metaObject->className();
+ while (*c && uc != e && (*uc == *c || (*c == ':' && *uc == '-'))) {
+ ++uc;
+ ++c;
+ }
+ if (uc == e && !*c)
+ return true;
+ metaObject = metaObject->superClass();
+ } while (metaObject != 0);
+ return false;
+ }
+ bool hasAttributes(NodePtr) const
+ { return true; }
+ QStringList nodeIds(NodePtr node) const
+ { return isNullNode(node) ? QStringList() : QStringList(WIDGET(node)->objectName()); }
+ bool isNullNode(NodePtr node) const
+ { return node.ptr == 0; }
+ NodePtr parentNode(NodePtr node) const
+ { NodePtr n; n.ptr = isNullNode(node) ? 0 : parentWidget(WIDGET(node)); return n; }
+ NodePtr previousSiblingNode(NodePtr) const
+ { NodePtr n; n.ptr = 0; return n; }
+ NodePtr duplicateNode(NodePtr node) const
+ { return node; }
+ void freeNode(NodePtr) const
+ { }
+
+private:
+ mutable QHash<const QWidget *, QHash<QString, QString> > m_attributeCache;
+};
+
+QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const
+{
+ QHash<const QWidget *, QVector<StyleRule> >::const_iterator cacheIt = styleSheetCaches->styleRulesCache.constFind(w);
+ if (cacheIt != styleSheetCaches->styleRulesCache.constEnd())
+ return cacheIt.value();
+
+ if (!initWidget(w)) {
+ return QVector<StyleRule>();
+ }
+
+ QStyleSheetStyleSelector styleSelector;
+
+ StyleSheet defaultSs;
+ QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCaches->styleSheetCache.constFind(baseStyle());
+ if (defaultCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
+ defaultSs = getDefaultStyleSheet();
+ QStyle *bs = baseStyle();
+ styleSheetCaches->styleSheetCache.insert(bs, defaultSs);
+ QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
+ } else {
+ defaultSs = defaultCacheIt.value();
+ }
+ styleSelector.styleSheets += defaultSs;
+
+ if (!qApp->styleSheet().isEmpty()) {
+ StyleSheet appSs;
+ QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCaches->styleSheetCache.constFind(qApp);
+ if (appCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
+ QString ss = qApp->styleSheet();
+ if (ss.startsWith(QLatin1String("file:///")))
+ ss.remove(0, 8);
+ parser.init(ss, qApp->styleSheet() != ss);
+ if (!parser.parse(&appSs))
+ qWarning("Could not parse application stylesheet");
+ appSs.origin = StyleSheetOrigin_Inline;
+ appSs.depth = 1;
+ styleSheetCaches->styleSheetCache.insert(qApp, appSs);
+ } else {
+ appSs = appCacheIt.value();
+ }
+ styleSelector.styleSheets += appSs;
+ }
+
+ QVector<QCss::StyleSheet> widgetSs;
+ for (const QWidget *wid = w; wid; wid = parentWidget(wid)) {
+ if (wid->styleSheet().isEmpty())
+ continue;
+ StyleSheet ss;
+ QHash<const void *, StyleSheet>::const_iterator widCacheIt = styleSheetCaches->styleSheetCache.constFind(wid);
+ if (widCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
+ parser.init(wid->styleSheet());
+ if (!parser.parse(&ss)) {
+ parser.init(QLatin1String("* {") + wid->styleSheet() + QLatin1Char('}'));
+ if (!parser.parse(&ss))
+ qWarning("Could not parse stylesheet of widget %p", wid);
+ }
+ ss.origin = StyleSheetOrigin_Inline;
+ styleSheetCaches->styleSheetCache.insert(wid, ss);
+ } else {
+ ss = widCacheIt.value();
+ }
+ widgetSs.append(ss);
+ }
+
+ for (int i = 0; i < widgetSs.count(); i++)
+ widgetSs[i].depth = widgetSs.count() - i + 2;
+
+ styleSelector.styleSheets += widgetSs;
+
+ StyleSelector::NodePtr n;
+ n.ptr = (void *)w;
+ QVector<QCss::StyleRule> rules = styleSelector.styleRulesForNode(n);
+ styleSheetCaches->styleRulesCache.insert(w, rules);
+ return rules;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Rendering rules
+static QVector<Declaration> declarations(const QVector<StyleRule> &styleRules, const QString &part, quint64 pseudoClass = PseudoClass_Unspecified)
+{
+ QVector<Declaration> decls;
+ for (int i = 0; i < styleRules.count(); i++) {
+ const Selector& selector = styleRules.at(i).selectors.at(0);
+ // Rules with pseudo elements don't cascade. This is an intentional
+ // diversion for CSS
+ if (part.compare(selector.pseudoElement(), Qt::CaseInsensitive) != 0)
+ continue;
+ quint64 negated = 0;
+ quint64 cssClass = selector.pseudoClass(&negated);
+ if ((pseudoClass == PseudoClass_Any) || (cssClass == PseudoClass_Unspecified)
+ || ((((cssClass & pseudoClass) == cssClass)) && ((negated & pseudoClass) == 0)))
+ decls += styleRules.at(i).declarations;
+ }
+ return decls;
+}
+
+int QStyleSheetStyle::nativeFrameWidth(const QWidget *w)
+{
+ QStyle *base = baseStyle();
+
+#ifndef QT_NO_SPINBOX
+ if (qobject_cast<const QAbstractSpinBox *>(w))
+ return base->pixelMetric(QStyle::PM_SpinBoxFrameWidth, 0, w);
+#endif
+
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox *>(w))
+ return base->pixelMetric(QStyle::PM_ComboBoxFrameWidth, 0, w);
+#endif
+
+#ifndef QT_NO_MENU
+ if (qobject_cast<const QMenu *>(w))
+ return base->pixelMetric(QStyle::PM_MenuPanelWidth, 0, w);
+#endif
+
+#ifndef QT_NO_MENUBAR
+ if (qobject_cast<const QMenuBar *>(w))
+ return base->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, w);
+#endif
+#ifndef QT_NO_FRAME
+ if (const QFrame *frame = qobject_cast<const QFrame *>(w)) {
+ if (frame->frameShape() == QFrame::NoFrame)
+ return 0;
+ }
+#endif
+
+ if (qstrcmp(w->metaObject()->className(), "QTipLabel") == 0)
+ return base->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, w);
+
+ return base->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, w);
+}
+
+static quint64 pseudoClass(QStyle::State state)
+{
+ quint64 pc = 0;
+ if (state & QStyle::State_Enabled) {
+ pc |= PseudoClass_Enabled;
+ if (state & QStyle::State_MouseOver)
+ pc |= PseudoClass_Hover;
+ } else {
+ pc |= PseudoClass_Disabled;
+ }
+ if (state & QStyle::State_Active)
+ pc |= PseudoClass_Active;
+ if (state & QStyle::State_Window)
+ pc |= PseudoClass_Window;
+ if (state & QStyle::State_Sunken)
+ pc |= PseudoClass_Pressed;
+ if (state & QStyle::State_HasFocus)
+ pc |= PseudoClass_Focus;
+ if (state & QStyle::State_On)
+ pc |= (PseudoClass_On | PseudoClass_Checked);
+ if (state & QStyle::State_Off)
+ pc |= (PseudoClass_Off | PseudoClass_Unchecked);
+ if (state & QStyle::State_NoChange)
+ pc |= PseudoClass_Indeterminate;
+ if (state & QStyle::State_Selected)
+ pc |= PseudoClass_Selected;
+ if (state & QStyle::State_Horizontal)
+ pc |= PseudoClass_Horizontal;
+ else
+ pc |= PseudoClass_Vertical;
+ if (state & (QStyle::State_Open | QStyle::State_On | QStyle::State_Sunken))
+ pc |= PseudoClass_Open;
+ else
+ pc |= PseudoClass_Closed;
+ if (state & QStyle::State_Children)
+ pc |= PseudoClass_Children;
+ if (state & QStyle::State_Sibling)
+ pc |= PseudoClass_Sibling;
+ if (state & QStyle::State_ReadOnly)
+ pc |= PseudoClass_ReadOnly;
+ if (state & QStyle::State_Item)
+ pc |= PseudoClass_Item;
+#ifdef QT_KEYPAD_NAVIGATION
+ if (state & QStyle::State_HasEditFocus)
+ pc |= PseudoClass_EditFocus;
+#endif
+ return pc;
+}
+
+static void qt_check_if_internal_widget(const QWidget **w, int *element)
+{
+#ifdef QT_NO_DOCKWIDGET
+ Q_UNUSED(w);
+ Q_UNUSED(element);
+#else
+ if (*w && qstrcmp((*w)->metaObject()->className(), "QDockWidgetTitleButton") == 0) {
+ if ((*w)->objectName() == QLatin1String("qt_dockwidget_closebutton")) {
+ *element = PseudoElement_DockWidgetCloseButton;
+ } else if ((*w)->objectName() == QLatin1String("qt_dockwidget_floatbutton")) {
+ *element = PseudoElement_DockWidgetFloatButton;
+ }
+ *w = (*w)->parentWidget();
+ }
+#endif
+}
+
+QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, int element, quint64 state) const
+{
+ qt_check_if_internal_widget(&w, &element);
+ QHash<quint64, QRenderRule> &cache = styleSheetCaches->renderRulesCache[w][element];
+ QHash<quint64, QRenderRule>::const_iterator cacheIt = cache.constFind(state);
+ if (cacheIt != cache.constEnd())
+ return cacheIt.value();
+
+ if (!initWidget(w))
+ return QRenderRule();
+
+ quint64 stateMask = 0;
+ const QVector<StyleRule> rules = styleRules(w);
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ quint64 negated = 0;
+ stateMask |= selector.pseudoClass(&negated);
+ stateMask |= negated;
+ }
+
+ cacheIt = cache.constFind(state & stateMask);
+ if (cacheIt != cache.constEnd()) {
+ const QRenderRule &newRule = cacheIt.value();
+ cache[state] = newRule;
+ return newRule;
+ }
+
+
+ const QString part = QLatin1String(knownPseudoElements[element].name);
+ QVector<Declaration> decls = declarations(rules, part, state);
+ QRenderRule newRule(decls, w);
+ cache[state] = newRule;
+ if ((state & stateMask) != state)
+ cache[state&stateMask] = newRule;
+ return newRule;
+}
+
+QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, const QStyleOption *opt, int pseudoElement) const
+{
+ quint64 extraClass = 0;
+ QStyle::State state = opt ? opt->state : QStyle::State(QStyle::State_None);
+
+ if (const QStyleOptionComplex *complex = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
+ if (pseudoElement != PseudoElement_None) {
+ // if not an active subcontrol, just pass enabled/disabled
+ QStyle::SubControl subControl = knownPseudoElements[pseudoElement].subControl;
+
+ if (!(complex->activeSubControls & subControl))
+ state &= (QStyle::State_Enabled | QStyle::State_Horizontal | QStyle::State_HasFocus);
+ }
+
+ switch (pseudoElement) {
+ case PseudoElement_ComboBoxDropDown:
+ case PseudoElement_ComboBoxArrow:
+ state |= (complex->state & (QStyle::State_On|QStyle::State_ReadOnly));
+ break;
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_SpinBoxDownButton:
+ case PseudoElement_SpinBoxUpArrow:
+ case PseudoElement_SpinBoxDownArrow:
+#ifndef QT_NO_SPINBOX
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ bool on = false;
+ bool up = pseudoElement == PseudoElement_SpinBoxUpButton
+ || pseudoElement == PseudoElement_SpinBoxUpArrow;
+ if ((sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) && up)
+ on = true;
+ else if ((sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) && !up)
+ on = true;
+ state |= (on ? QStyle::State_On : QStyle::State_Off);
+ }
+#endif // QT_NO_SPINBOX
+ break;
+ case PseudoElement_GroupBoxTitle:
+ state |= (complex->state & (QStyle::State_MouseOver | QStyle::State_Sunken));
+ break;
+ case PseudoElement_ToolButtonMenu:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_ToolButtonDownArrow:
+ state |= complex->state & QStyle::State_MouseOver;
+ if (complex->state & QStyle::State_Sunken ||
+ complex->activeSubControls & QStyle::SC_ToolButtonMenu)
+ state |= QStyle::State_Sunken;
+ break;
+ case PseudoElement_SliderGroove:
+ state |= complex->state & QStyle::State_MouseOver;
+ break;
+ default:
+ break;
+ }
+
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ // QStyle::State_On is set when the popup is being shown
+ // Propagate EditField Pressed state
+ if (pseudoElement == PseudoElement_None
+ && (complex->activeSubControls & QStyle::SC_ComboBoxEditField)
+ && (!(state & QStyle::State_MouseOver))) {
+ state |= QStyle::State_Sunken;
+ }
+
+ if (!combo->frame)
+ extraClass |= PseudoClass_Frameless;
+ if (!combo->editable)
+ extraClass |= PseudoClass_ReadOnly;
+ else
+ extraClass |= PseudoClass_Editable;
+#ifndef QT_NO_SPINBOX
+ } else if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ if (!spin->frame)
+ extraClass |= PseudoClass_Frameless;
+#endif // QT_NO_SPINBOX
+ } else if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ if (gb->features & QStyleOptionFrameV2::Flat)
+ extraClass |= PseudoClass_Flat;
+ if (gb->lineWidth == 0)
+ extraClass |= PseudoClass_Frameless;
+ } else if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ if (tb->titleBarState & Qt::WindowMinimized) {
+ extraClass |= PseudoClass_Minimized;
+ }
+ else if (tb->titleBarState & Qt::WindowMaximized)
+ extraClass |= PseudoClass_Maximized;
+ }
+ } else {
+ // handle simple style options
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ extraClass |= PseudoClass_Default;
+ if (mi->checkType == QStyleOptionMenuItem::Exclusive)
+ extraClass |= PseudoClass_Exclusive;
+ else if (mi->checkType == QStyleOptionMenuItem::NonExclusive)
+ extraClass |= PseudoClass_NonExclusive;
+ if (mi->checkType != QStyleOptionMenuItem::NotCheckable)
+ extraClass |= (mi->checked) ? (PseudoClass_On|PseudoClass_Checked)
+ : (PseudoClass_Off|PseudoClass_Unchecked);
+ } else if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ if (hdr->position == QStyleOptionHeader::OnlyOneSection)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (hdr->position == QStyleOptionHeader::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (hdr->position == QStyleOptionHeader::End)
+ extraClass |= PseudoClass_Last;
+ else if (hdr->position == QStyleOptionHeader::Middle)
+ extraClass |= PseudoClass_Middle;
+
+ if (hdr->selectedPosition == QStyleOptionHeader::NextAndPreviousAreSelected)
+ extraClass |= (PseudoClass_NextSelected | PseudoClass_PreviousSelected);
+ else if (hdr->selectedPosition == QStyleOptionHeader::NextIsSelected)
+ extraClass |= PseudoClass_NextSelected;
+ else if (hdr->selectedPosition == QStyleOptionHeader::PreviousIsSelected)
+ extraClass |= PseudoClass_PreviousSelected;
+#ifndef QT_NO_TABWIDGET
+ } else if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ extraClass |= PseudoClass_Top;
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ extraClass |= PseudoClass_Bottom;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ extraClass |= PseudoClass_Left;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ extraClass |= PseudoClass_Right;
+ break;
+ default:
+ break;
+ }
+#endif
+#ifndef QT_NO_TABBAR
+ } else if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ if (tab->position == QStyleOptionTab::OnlyOneTab)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (tab->position == QStyleOptionTab::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (tab->position == QStyleOptionTab::End)
+ extraClass |= PseudoClass_Last;
+ else if (tab->position == QStyleOptionTab::Middle)
+ extraClass |= PseudoClass_Middle;
+
+ if (tab->selectedPosition == QStyleOptionTab::NextIsSelected)
+ extraClass |= PseudoClass_NextSelected;
+ else if (tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
+ extraClass |= PseudoClass_PreviousSelected;
+
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ extraClass |= PseudoClass_Top;
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ extraClass |= PseudoClass_Bottom;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ extraClass |= PseudoClass_Left;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ extraClass |= PseudoClass_Right;
+ break;
+ default:
+ break;
+ }
+#endif // QT_NO_TABBAR
+ } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (btn->features & QStyleOptionButton::Flat)
+ extraClass |= PseudoClass_Flat;
+ if (btn->features & QStyleOptionButton::DefaultButton)
+ extraClass |= PseudoClass_Default;
+ } else if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (frm->lineWidth == 0)
+ extraClass |= PseudoClass_Frameless;
+ if (const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt)) {
+ if (frame2->features & QStyleOptionFrameV2::Flat)
+ extraClass |= PseudoClass_Flat;
+ }
+ }
+#ifndef QT_NO_TOOLBAR
+ else if (const QStyleOptionToolBar *tb = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ if (tb->toolBarArea == Qt::LeftToolBarArea)
+ extraClass |= PseudoClass_Left;
+ else if (tb->toolBarArea == Qt::RightToolBarArea)
+ extraClass |= PseudoClass_Right;
+ else if (tb->toolBarArea == Qt::TopToolBarArea)
+ extraClass |= PseudoClass_Top;
+ else if (tb->toolBarArea == Qt::BottomToolBarArea)
+ extraClass |= PseudoClass_Bottom;
+
+ if (tb->positionWithinLine == QStyleOptionToolBar::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (tb->positionWithinLine == QStyleOptionToolBar::Middle)
+ extraClass |= PseudoClass_Middle;
+ else if (tb->positionWithinLine == QStyleOptionToolBar::End)
+ extraClass |= PseudoClass_Last;
+ else if (tb->positionWithinLine == QStyleOptionToolBar::OnlyOne)
+ extraClass |= PseudoClass_OnlyOne;
+ }
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_TOOLBOX
+ else if (const QStyleOptionToolBoxV2 *tab = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(opt)) {
+ if (tab->position == QStyleOptionToolBoxV2::OnlyOneTab)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (tab->position == QStyleOptionToolBoxV2::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (tab->position == QStyleOptionToolBoxV2::End)
+ extraClass |= PseudoClass_Last;
+ else if (tab->position == QStyleOptionToolBoxV2::Middle)
+ extraClass |= PseudoClass_Middle;
+
+ if (tab->selectedPosition == QStyleOptionToolBoxV2::NextIsSelected)
+ extraClass |= PseudoClass_NextSelected;
+ else if (tab->selectedPosition == QStyleOptionToolBoxV2::PreviousIsSelected)
+ extraClass |= PseudoClass_PreviousSelected;
+ }
+#endif // QT_NO_TOOLBOX
+#ifndef QT_NO_DOCKWIDGET
+ else if (const QStyleOptionDockWidgetV2 *dw = qstyleoption_cast<const QStyleOptionDockWidgetV2 *>(opt)) {
+ if (dw->verticalTitleBar)
+ extraClass |= PseudoClass_Vertical;
+ else
+ extraClass |= PseudoClass_Horizontal;
+ if (dw->closable)
+ extraClass |= PseudoClass_Closable;
+ if (dw->floatable)
+ extraClass |= PseudoClass_Floatable;
+ if (dw->movable)
+ extraClass |= PseudoClass_Movable;
+ }
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_ITEMVIEWS
+ else if (const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
+ if (v2->features & QStyleOptionViewItemV2::Alternate)
+ extraClass |= PseudoClass_Alternate;
+ if (const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ if (v4->viewItemPosition == QStyleOptionViewItemV4::OnlyOne)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (v4->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (v4->viewItemPosition == QStyleOptionViewItemV4::End)
+ extraClass |= PseudoClass_Last;
+ else if (v4->viewItemPosition == QStyleOptionViewItemV4::Middle)
+ extraClass |= PseudoClass_Middle;
+ }
+ }
+#endif
+#ifndef QT_NO_LINEEDIT
+ // LineEdit sets Sunken flag to indicate Sunken frame (argh)
+ if (const QLineEdit *lineEdit = qobject_cast<const QLineEdit *>(w)) {
+ state &= ~QStyle::State_Sunken;
+ if (lineEdit->hasFrame()) {
+ extraClass &= ~PseudoClass_Frameless;
+ } else {
+ extraClass |= PseudoClass_Frameless;
+ }
+ } else
+#endif
+ if (const QFrame *frm = qobject_cast<const QFrame *>(w)) {
+ if (frm->lineWidth() == 0)
+ extraClass |= PseudoClass_Frameless;
+ }
+ }
+
+ return renderRule(w, pseudoElement, pseudoClass(state) | extraClass);
+}
+
+bool QStyleSheetStyle::hasStyleRule(const QWidget *w, int part) const
+{
+ QHash<int, bool> &cache = styleSheetCaches->hasStyleRuleCache[w];
+ QHash<int, bool>::const_iterator cacheIt = cache.constFind(part);
+ if (cacheIt != cache.constEnd())
+ return cacheIt.value();
+
+ if (!initWidget(w))
+ return false;
+
+
+ const QVector<StyleRule> &rules = styleRules(w);
+ if (part == PseudoElement_None) {
+ bool result = w && !rules.isEmpty();
+ cache[part] = result;
+ return result;
+ }
+
+ QString pseudoElement = QLatin1String(knownPseudoElements[part].name);
+ QVector<Declaration> declarations;
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ if (pseudoElement.compare(selector.pseudoElement(), Qt::CaseInsensitive) == 0) {
+ cache[part] = true;
+ return true;
+ }
+ }
+
+ cache[part] = false;
+ return false;
+}
+
+static Origin defaultOrigin(int pe)
+{
+ switch (pe) {
+ case PseudoElement_ScrollBarAddPage:
+ case PseudoElement_ScrollBarSubPage:
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_GroupBoxTitle:
+ case PseudoElement_GroupBoxIndicator: // never used
+ case PseudoElement_ToolButtonMenu:
+ case PseudoElement_SliderAddPage:
+ case PseudoElement_SliderSubPage:
+ return Origin_Border;
+
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_SpinBoxDownButton:
+ case PseudoElement_PushButtonMenuIndicator:
+ case PseudoElement_ComboBoxDropDown:
+ case PseudoElement_ToolButtonDownArrow:
+ case PseudoElement_MenuCheckMark:
+ case PseudoElement_MenuIcon:
+ case PseudoElement_MenuRightArrow:
+ return Origin_Padding;
+
+ case PseudoElement_Indicator:
+ case PseudoElement_ExclusiveIndicator:
+ case PseudoElement_ComboBoxArrow:
+ case PseudoElement_ScrollBarSlider:
+ case PseudoElement_ScrollBarUpArrow:
+ case PseudoElement_ScrollBarDownArrow:
+ case PseudoElement_ScrollBarLeftArrow:
+ case PseudoElement_ScrollBarRightArrow:
+ case PseudoElement_SpinBoxUpArrow:
+ case PseudoElement_SpinBoxDownArrow:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_HeaderViewUpArrow:
+ case PseudoElement_HeaderViewDownArrow:
+ case PseudoElement_SliderGroove:
+ case PseudoElement_SliderHandle:
+ return Origin_Content;
+
+ default:
+ return Origin_Margin;
+ }
+}
+
+static Qt::Alignment defaultPosition(int pe)
+{
+ switch (pe) {
+ case PseudoElement_Indicator:
+ case PseudoElement_ExclusiveIndicator:
+ case PseudoElement_MenuCheckMark:
+ case PseudoElement_MenuIcon:
+ return Qt::AlignLeft | Qt::AlignVCenter;
+
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_SpinBoxDownButton:
+ case PseudoElement_PushButtonMenuIndicator:
+ case PseudoElement_ToolButtonDownArrow:
+ return Qt::AlignRight | Qt::AlignBottom;
+
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_ComboBoxDropDown:
+ case PseudoElement_ToolButtonMenu:
+ case PseudoElement_DockWidgetCloseButton:
+ case PseudoElement_DockWidgetFloatButton:
+ return Qt::AlignRight | Qt::AlignTop;
+
+ case PseudoElement_ScrollBarUpArrow:
+ case PseudoElement_ScrollBarDownArrow:
+ case PseudoElement_ScrollBarLeftArrow:
+ case PseudoElement_ScrollBarRightArrow:
+ case PseudoElement_SpinBoxUpArrow:
+ case PseudoElement_SpinBoxDownArrow:
+ case PseudoElement_ComboBoxArrow:
+ case PseudoElement_DownArrow:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_SliderGroove:
+ return Qt::AlignCenter;
+
+ case PseudoElement_GroupBoxTitle:
+ case PseudoElement_GroupBoxIndicator: // never used
+ return Qt::AlignLeft | Qt::AlignTop;
+
+ case PseudoElement_HeaderViewUpArrow:
+ case PseudoElement_HeaderViewDownArrow:
+ case PseudoElement_MenuRightArrow:
+ return Qt::AlignRight | Qt::AlignVCenter;
+
+ default:
+ return 0;
+ }
+}
+
+QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rect, int pe) const
+{
+ QStyle *base = baseStyle();
+
+ switch (pe) {
+ case PseudoElement_Indicator:
+ case PseudoElement_MenuCheckMark:
+ if (sz.width() == -1)
+ sz.setWidth(base->pixelMetric(PM_IndicatorWidth, 0, w));
+ if (sz.height() == -1)
+ sz.setHeight(base->pixelMetric(PM_IndicatorHeight, 0, w));
+ break;
+
+ case PseudoElement_ExclusiveIndicator:
+ case PseudoElement_GroupBoxIndicator:
+ if (sz.width() == -1)
+ sz.setWidth(base->pixelMetric(PM_ExclusiveIndicatorWidth, 0, w));
+ if (sz.height() == -1)
+ sz.setHeight(base->pixelMetric(PM_ExclusiveIndicatorHeight, 0, w));
+ break;
+
+ case PseudoElement_PushButtonMenuIndicator: {
+ int pm = base->pixelMetric(PM_MenuButtonIndicator, 0, w);
+ if (sz.width() == -1)
+ sz.setWidth(pm);
+ if (sz.height() == -1)
+ sz.setHeight(pm);
+ }
+ break;
+
+ case PseudoElement_ComboBoxDropDown:
+ if (sz.width() == -1)
+ sz.setWidth(16);
+ break;
+
+ case PseudoElement_ComboBoxArrow:
+ case PseudoElement_DownArrow:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_ToolButtonDownArrow:
+ case PseudoElement_MenuRightArrow:
+ if (sz.width() == -1)
+ sz.setWidth(13);
+ if (sz.height() == -1)
+ sz.setHeight(13);
+ break;
+
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_SpinBoxDownButton:
+ if (sz.width() == -1)
+ sz.setWidth(16);
+ if (sz.height() == -1)
+ sz.setHeight(rect.height()/2);
+ break;
+
+ case PseudoElement_ToolButtonMenu:
+ if (sz.width() == -1)
+ sz.setWidth(base->pixelMetric(PM_MenuButtonIndicator, 0, w));
+ break;
+
+ case PseudoElement_HeaderViewUpArrow:
+ case PseudoElement_HeaderViewDownArrow: {
+ int pm = base->pixelMetric(PM_HeaderMargin, 0, w);
+ if (sz.width() == -1)
+ sz.setWidth(pm);
+ if (sz.height() == 1)
+ sz.setHeight(pm);
+ break;
+ }
+
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarSlider: {
+ int pm = pixelMetric(QStyle::PM_ScrollBarExtent, 0, w);
+ if (sz.width() == -1)
+ sz.setWidth(pm);
+ if (sz.height() == -1)
+ sz.setHeight(pm);
+ break;
+ }
+
+ case PseudoElement_DockWidgetCloseButton:
+ case PseudoElement_DockWidgetFloatButton: {
+ int iconSize = pixelMetric(PM_SmallIconSize, 0, w);
+ return QSize(iconSize, iconSize);
+ }
+
+ default:
+ break;
+ }
+
+ // expand to rectangle
+ if (sz.height() == -1)
+ sz.setHeight(rect.height());
+ if (sz.width() == -1)
+ sz.setWidth(rect.width());
+
+ return sz;
+}
+
+static PositionMode defaultPositionMode(int pe)
+{
+ switch (pe) {
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarAddPage:
+ case PseudoElement_ScrollBarSubPage:
+ case PseudoElement_ScrollBarSlider:
+ case PseudoElement_SliderGroove:
+ case PseudoElement_SliderHandle:
+ case PseudoElement_TabWidgetPane:
+ return PositionMode_Absolute;
+ default:
+ return PositionMode_Static;
+ }
+}
+
+QRect QStyleSheetStyle::positionRect(const QWidget *w, const QRenderRule &rule2, int pe,
+ const QRect &originRect, Qt::LayoutDirection dir) const
+{
+ const QStyleSheetPositionData *p = rule2.position();
+ PositionMode mode = (p && p->mode != PositionMode_Unknown) ? p->mode : defaultPositionMode(pe);
+ Qt::Alignment position = (p && p->position != 0) ? p->position : defaultPosition(pe);
+ QRect r;
+
+ if (mode != PositionMode_Absolute) {
+ QSize sz = defaultSize(w, rule2.size(), originRect, pe);
+ sz = sz.expandedTo(rule2.minimumContentsSize());
+ r = QStyle::alignedRect(dir, position, sz, originRect);
+ if (p) {
+ int left = p->left ? p->left : -p->right;
+ int top = p->top ? p->top : -p->bottom;
+ r.translate(dir == Qt::LeftToRight ? left : -left, top);
+ }
+ } else {
+ r = p ? originRect.adjusted(dir == Qt::LeftToRight ? p->left : p->right, p->top,
+ dir == Qt::LeftToRight ? -p->right : -p->left, -p->bottom)
+ : originRect;
+ if (rule2.hasContentsSize()) {
+ QSize sz = rule2.size().expandedTo(rule2.minimumContentsSize());
+ if (sz.width() == -1) sz.setWidth(r.width());
+ if (sz.height() == -1) sz.setHeight(r.height());
+ r = QStyle::alignedRect(dir, position, sz, r);
+ }
+ }
+ return r;
+}
+
+QRect QStyleSheetStyle::positionRect(const QWidget *w, const QRenderRule& rule1, const QRenderRule& rule2, int pe,
+ const QRect& rect, Qt::LayoutDirection dir) const
+{
+ const QStyleSheetPositionData *p = rule2.position();
+ Origin origin = (p && p->origin != Origin_Unknown) ? p->origin : defaultOrigin(pe);
+ QRect originRect = rule1.originRect(rect, origin);
+ return positionRect(w, rule2, pe, originRect, dir);
+}
+
+
+/** \internal
+ For widget that have an embedded widget (such as combobox) return that embedded widget.
+ otherwise return the widget itself
+ */
+static QWidget *embeddedWidget(QWidget *w)
+{
+#ifndef QT_NO_COMBOBOX
+ if (QComboBox *cmb = qobject_cast<QComboBox *>(w)) {
+ if (cmb->isEditable())
+ return cmb->lineEdit();
+ else
+ return cmb;
+ }
+#endif
+
+#ifndef QT_NO_SPINBOX
+ if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(w))
+ return sb->findChild<QLineEdit *>();
+#endif
+
+#ifndef QT_NO_SCROLLAREA
+ if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w))
+ return sa->viewport();
+#endif
+
+ return w;
+}
+
+/** \internal
+ in case w is an embedded widget, return the container widget
+ (i.e, the widget for which the rules actualy apply)
+ (exemple, if w is a lineedit embedded in a combobox, return the combobox)
+
+ if w is not embedded, return w itself
+*/
+static QWidget *containerWidget(const QWidget *w)
+{
+#ifndef QT_NO_LINEEDIT
+ if (qobject_cast<const QLineEdit *>(w)) {
+ //if the QLineEdit is an embeddedWidget, we need the rule of the real widget
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox *>(w->parentWidget()))
+ return w->parentWidget();
+#endif
+#ifndef QT_NO_SPINBOX
+ if (qobject_cast<const QAbstractSpinBox *>(w->parentWidget()))
+ return w->parentWidget();
+#endif
+ }
+#endif // QT_NO_LINEEDIT
+
+#ifndef QT_NO_SCROLLAREA
+ if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w->parentWidget())) {
+ if (sa->viewport() == w)
+ return w->parentWidget();
+ }
+#endif
+
+ return const_cast<QWidget *>(w);
+}
+
+/** \internal
+ returns true if the widget can NOT be styled directly
+ */
+static bool unstylable(const QWidget *w)
+{
+ if (w->windowType() == Qt::Desktop)
+ return true;
+
+ if (!w->styleSheet().isEmpty())
+ return false;
+
+ if (containerWidget(w) != w)
+ return true;
+
+#ifndef QT_NO_FRAME
+ // detect QComboBoxPrivateContainer
+ else if (qobject_cast<const QFrame *>(w)) {
+ if (0
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<const QComboBox *>(w->parentWidget())
+#endif
+ )
+ return true;
+ }
+#endif
+ return false;
+}
+
+static quint64 extendedPseudoClass(const QWidget *w)
+{
+ quint64 pc = w->isWindow() ? quint64(PseudoClass_Window) : 0;
+ if (const QAbstractSlider *slider = qobject_cast<const QAbstractSlider *>(w)) {
+ pc |= ((slider->orientation() == Qt::Vertical) ? PseudoClass_Vertical : PseudoClass_Horizontal);
+ } else
+#ifndef QT_NO_COMBOBOX
+ if (const QComboBox *combo = qobject_cast<const QComboBox *>(w)) {
+ if (combo->isEditable())
+ pc |= (combo->isEditable() ? PseudoClass_Editable : PseudoClass_ReadOnly);
+ } else
+#endif
+#ifndef QT_NO_LINEEDIT
+ if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(w)) {
+ pc |= (edit->isReadOnly() ? PseudoClass_ReadOnly : PseudoClass_Editable);
+ } else
+#endif
+ { } // required for the above ifdef'ery to work
+ return pc;
+}
+
+// sets up the geometry of the widget. We set a dynamic property when
+// we modify the min/max size of the widget. The min/max size is restored
+// to their original value when a new stylesheet that does not contain
+// the CSS properties is set and when the widget has this dynamic property set.
+// This way we don't trample on users who had setup a min/max size in code and
+// don't use stylesheets at all.
+void QStyleSheetStyle::setGeometry(QWidget *w)
+{
+ QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Enabled | extendedPseudoClass(w));
+ const QStyleSheetGeometryData *geo = rule.geometry();
+ if (w->property("_q_stylesheet_minw").toBool()
+ && ((!rule.hasGeometry() || geo->minWidth == -1))) {
+ w->setMinimumWidth(0);
+ w->setProperty("_q_stylesheet_minw", QVariant());
+ }
+ if (w->property("_q_stylesheet_minh").toBool()
+ && ((!rule.hasGeometry() || geo->minHeight == -1))) {
+ w->setMinimumHeight(0);
+ w->setProperty("_q_stylesheet_minh", QVariant());
+ }
+ if (w->property("_q_stylesheet_maxw").toBool()
+ && ((!rule.hasGeometry() || geo->maxWidth == -1))) {
+ w->setMaximumWidth(QWIDGETSIZE_MAX);
+ w->setProperty("_q_stylesheet_maxw", QVariant());
+ }
+ if (w->property("_q_stylesheet_maxh").toBool()
+ && ((!rule.hasGeometry() || geo->maxHeight == -1))) {
+ w->setMaximumHeight(QWIDGETSIZE_MAX);
+ w->setProperty("_q_stylesheet_maxh", QVariant());
+ }
+
+
+ if (rule.hasGeometry()) {
+ if (geo->minWidth != -1) {
+ w->setProperty("_q_stylesheet_minw", true);
+ w->setMinimumWidth(rule.boxSize(QSize(qMax(geo->width, geo->minWidth), 0)).width());
+ }
+ if (geo->minHeight != -1) {
+ w->setProperty("_q_stylesheet_minh", true);
+ w->setMinimumHeight(rule.boxSize(QSize(0, qMax(geo->height, geo->minHeight))).height());
+ }
+ if (geo->maxWidth != -1) {
+ w->setProperty("_q_stylesheet_maxw", true);
+ w->setMaximumWidth(rule.boxSize(QSize(qMin(geo->width == -1 ? QWIDGETSIZE_MAX : geo->width,
+ geo->maxWidth == -1 ? QWIDGETSIZE_MAX : geo->maxWidth), 0)).width());
+ }
+ if (geo->maxHeight != -1) {
+ w->setProperty("_q_stylesheet_maxh", true);
+ w->setMaximumHeight(rule.boxSize(QSize(0, qMin(geo->height == -1 ? QWIDGETSIZE_MAX : geo->height,
+ geo->maxHeight == -1 ? QWIDGETSIZE_MAX : geo->maxHeight))).height());
+ }
+ }
+}
+
+void QStyleSheetStyle::setProperties(QWidget *w)
+{
+ QHash<QString, QVariant> propertyHash;
+ QVector<Declaration> decls = declarations(styleRules(w), QString());
+
+ // run through the declarations in order
+ for (int i = 0; i < decls.count(); i++) {
+ const Declaration &decl = decls.at(i);
+ QString property = decl.d->property;
+ if (!property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive))
+ continue;
+ property.remove(0, 10); // strip "qproperty-"
+ const QVariant value = w->property(property.toLatin1());
+ const QMetaObject *metaObject = w->metaObject();
+ int index = metaObject->indexOfProperty(property.toLatin1());
+ if (index == -1) {
+ qWarning() << w << " does not have a property named " << property;
+ continue;
+ }
+ QMetaProperty metaProperty = metaObject->property(index);
+ if (!metaProperty.isWritable() || !metaProperty.isDesignable()) {
+ qWarning() << w << " cannot design property named " << property;
+ continue;
+ }
+ QVariant v;
+ switch (value.type()) {
+ // ### Qt 5
+// case QVariant::Icon: v = decl.iconValue(); break;
+ case QVariant::Image: v = QImage(decl.uriValue()); break;
+ case QVariant::Pixmap: v = QPixmap(decl.uriValue()); break;
+ case QVariant::Rect: v = decl.rectValue(); break;
+ case QVariant::Size: v = decl.sizeValue(); break;
+ case QVariant::Color: v = decl.colorValue(); break;
+ case QVariant::Brush: v = decl.brushValue(); break;
+#ifndef QT_NO_SHORTCUT
+ case QVariant::KeySequence: v = QKeySequence(decl.d->values.at(0).variant.toString()); break;
+#endif
+ default: v = decl.d->values.at(0).variant; break;
+ }
+ propertyHash[property] = v;
+ }
+ // apply the values
+ const QList<QString> properties = propertyHash.keys();
+ for (int i = 0; i < properties.count(); i++) {
+ const QString &property = properties.at(i);
+ w->setProperty(property.toLatin1(), propertyHash[property]);
+ }
+}
+
+void QStyleSheetStyle::setPalette(QWidget *w)
+{
+ struct RuleRoleMap {
+ int state;
+ QPalette::ColorGroup group;
+ } map[3] = {
+ { int(PseudoClass_Active | PseudoClass_Enabled), QPalette::Active },
+ { PseudoClass_Disabled, QPalette::Disabled },
+ { PseudoClass_Enabled, QPalette::Inactive }
+ };
+
+ QPalette p = w->palette();
+ QWidget *ew = embeddedWidget(w);
+
+ for (int i = 0; i < 3; i++) {
+ QRenderRule rule = renderRule(w, PseudoElement_None, map[i].state | extendedPseudoClass(w));
+ if (i == 0) {
+ if (!w->property("_q_styleSheetWidgetFont").isValid()) {
+ saveWidgetFont(w, w->font());
+ }
+ updateStyleSheetFont(w);
+ if (ew != w)
+ updateStyleSheetFont(ew);
+ }
+
+ rule.configurePalette(&p, map[i].group, ew, ew != w);
+ }
+
+ styleSheetCaches->customPaletteWidgets.insert(w, w->palette());
+ w->setPalette(p);
+ if (ew != w)
+ ew->setPalette(p);
+}
+
+void QStyleSheetStyle::unsetPalette(QWidget *w)
+{
+ if (styleSheetCaches->customPaletteWidgets.contains(w)) {
+ QPalette p = styleSheetCaches->customPaletteWidgets.value(w);
+ w->setPalette(p);
+ QWidget *ew = embeddedWidget(w);
+ if (ew != w)
+ ew->setPalette(p);
+ styleSheetCaches->customPaletteWidgets.remove(w);
+ }
+ QVariant oldFont = w->property("_q_styleSheetWidgetFont");
+ if (oldFont.isValid()) {
+ w->setFont(qvariant_cast<QFont>(oldFont));
+ }
+ if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
+ embeddedWidget(w)->setAutoFillBackground(true);
+ styleSheetCaches->autoFillDisabledWidgets.remove(w);
+ }
+}
+
+static void updateWidgets(const QList<const QWidget *>& widgets)
+{
+ if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
+ for (int i = 0; i < widgets.size(); ++i) {
+ const QWidget *widget = widgets.at(i);
+ styleSheetCaches->styleRulesCache.remove(widget);
+ styleSheetCaches->hasStyleRuleCache.remove(widget);
+ styleSheetCaches->renderRulesCache.remove(widget);
+ }
+ }
+ for (int i = 0; i < widgets.size(); ++i) {
+ QWidget *widget = const_cast<QWidget *>(widgets.at(i));
+ if (widget == 0)
+ continue;
+ widget->style()->polish(widget);
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &event);
+ widget->update();
+ widget->updateGeometry();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// The stylesheet style
+int QStyleSheetStyle::numinstances = 0;
+
+QStyleSheetStyle::QStyleSheetStyle(QStyle *base)
+ : QWindowsStyle(*new QStyleSheetStylePrivate), base(base), refcount(1)
+{
+ ++numinstances;
+ if (numinstances == 1) {
+ styleSheetCaches = new QStyleSheetStyleCaches;
+ }
+}
+
+QStyleSheetStyle::~QStyleSheetStyle()
+{
+ --numinstances;
+ if (numinstances == 0) {
+ delete styleSheetCaches;
+ }
+}
+QStyle *QStyleSheetStyle::baseStyle() const
+{
+ if (base)
+ return base;
+ if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style()))
+ return me->base;
+ return QApplication::style();
+}
+
+void QStyleSheetStyleCaches::widgetDestroyed(QObject *o)
+{
+ styleRulesCache.remove((const QWidget *)o);
+ hasStyleRuleCache.remove((const QWidget *)o);
+ renderRulesCache.remove((const QWidget *)o);
+ customPaletteWidgets.remove((const QWidget *)o);
+ styleSheetCache.remove((const QWidget *)o);
+ autoFillDisabledWidgets.remove((const QWidget *)o);
+}
+
+void QStyleSheetStyleCaches::styleDestroyed(QObject *o)
+{
+ styleSheetCache.remove(o);
+}
+
+/*!
+ * Make sure that the cache will be clean by connecting destroyed if needed.
+ * return false if the widget is not stylable;
+ */
+bool QStyleSheetStyle::initWidget(const QWidget *w) const
+{
+ if (!w)
+ return false;
+ if(w->testAttribute(Qt::WA_StyleSheet))
+ return true;
+
+ if(unstylable(w))
+ return false;
+
+ const_cast<QWidget *>(w)->setAttribute(Qt::WA_StyleSheet, true);
+ QObject::connect(w, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(widgetDestroyed(QObject*)), Qt::UniqueConnection);
+ return true;
+}
+
+void QStyleSheetStyle::polish(QWidget *w)
+{
+ baseStyle()->polish(w);
+ RECURSION_GUARD(return)
+
+ if (!initWidget(w))
+ return;
+
+ if (styleSheetCaches->styleRulesCache.contains(w)) {
+ // the widget accessed its style pointer before polish (or repolish)
+ // (exemple: the QAbstractSpinBox constructor ask for the stylehint)
+ styleSheetCaches->styleRulesCache.remove(w);
+ styleSheetCaches->hasStyleRuleCache.remove(w);
+ styleSheetCaches->renderRulesCache.remove(w);
+ }
+ setGeometry(w);
+ setProperties(w);
+ unsetPalette(w);
+ setPalette(w);
+
+ //set the WA_Hover attribute if one of the selector depends of the hover state
+ QVector<StyleRule> rules = styleRules(w);
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ quint64 negated = 0;
+ quint64 cssClass = selector.pseudoClass(&negated);
+ if ( cssClass & PseudoClass_Hover || negated & PseudoClass_Hover) {
+ w->setAttribute(Qt::WA_Hover);
+ embeddedWidget(w)->setAttribute(Qt::WA_Hover);
+ }
+ }
+
+
+#ifndef QT_NO_SCROLLAREA
+ if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
+ QRenderRule rule = renderRule(sa, PseudoElement_None, PseudoClass_Enabled);
+ if ((rule.hasBorder() && rule.border()->hasBorderImage())
+ || (rule.hasBackground() && !rule.background()->pixmap.isNull())) {
+ QObject::connect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()), Qt::UniqueConnection);
+ QObject::connect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()), Qt::UniqueConnection);
+ }
+ }
+#endif
+
+#ifndef QT_NO_PROGRESSBAR
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(w)) {
+ QWindowsStyle::polish(pb);
+ }
+#endif
+
+ QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
+ if (rule.hasDrawable() || rule.hasBox()) {
+ if (w->metaObject() == &QWidget::staticMetaObject
+#ifndef QT_NO_ITEMVIEWS
+ || qobject_cast<QHeaderView *>(w)
+#endif
+#ifndef QT_NO_TABBAR
+ || qobject_cast<QTabBar *>(w)
+#endif
+#ifndef QT_NO_FRAME
+ || qobject_cast<QFrame *>(w)
+#endif
+#ifndef QT_NO_MAINWINDOW
+ || qobject_cast<QMainWindow *>(w)
+#endif
+#ifndef QT_NO_MDIAREA
+ || qobject_cast<QMdiSubWindow *>(w)
+#endif
+#ifndef QT_NO_MENUBAR
+ || qobject_cast<QMenuBar *>(w)
+#endif
+ || qobject_cast<QDialog *>(w)) {
+ w->setAttribute(Qt::WA_StyledBackground, true);
+ }
+ QWidget *ew = embeddedWidget(w);
+ if (ew->autoFillBackground()) {
+ ew->setAutoFillBackground(false);
+ styleSheetCaches->autoFillDisabledWidgets.insert(w);
+ if (ew != w) { //eg. viewport of a scrollarea
+ //(in order to draw the background anyway in case we don't.)
+ ew->setAttribute(Qt::WA_StyledBackground, true);
+ }
+ }
+ if (!rule.hasBackground() || rule.background()->isTransparent() || rule.hasBox()
+ || (!rule.hasNativeBorder() && !rule.border()->isOpaque()))
+ w->setAttribute(Qt::WA_OpaquePaintEvent, false);
+ }
+}
+
+void QStyleSheetStyle::polish(QApplication *app)
+{
+ baseStyle()->polish(app);
+}
+
+void QStyleSheetStyle::polish(QPalette &pal)
+{
+ baseStyle()->polish(pal);
+}
+
+void QStyleSheetStyle::repolish(QWidget *w)
+{
+ QList<const QWidget *> children = w->findChildren<const QWidget *>(QString());
+ children.append(w);
+ styleSheetCaches->styleSheetCache.remove(w);
+ updateWidgets(children);
+}
+
+void QStyleSheetStyle::repolish(QApplication *app)
+{
+ Q_UNUSED(app);
+ const QList<const QWidget*> allWidgets = styleSheetCaches->styleRulesCache.keys();
+ styleSheetCaches->styleSheetCache.remove(qApp);
+ styleSheetCaches->styleRulesCache.clear();
+ styleSheetCaches->hasStyleRuleCache.clear();
+ styleSheetCaches->renderRulesCache.clear();
+ updateWidgets(allWidgets);
+}
+
+void QStyleSheetStyle::unpolish(QWidget *w)
+{
+ if (!w || !w->testAttribute(Qt::WA_StyleSheet)) {
+ baseStyle()->unpolish(w);
+ return;
+ }
+
+ styleSheetCaches->styleRulesCache.remove(w);
+ styleSheetCaches->hasStyleRuleCache.remove(w);
+ styleSheetCaches->renderRulesCache.remove(w);
+ styleSheetCaches->styleSheetCache.remove(w);
+ unsetPalette(w);
+ w->setProperty("_q_stylesheet_minw", QVariant());
+ w->setProperty("_q_stylesheet_minh", QVariant());
+ w->setProperty("_q_stylesheet_maxw", QVariant());
+ w->setProperty("_q_stylesheet_maxh", QVariant());
+ w->setAttribute(Qt::WA_StyleSheet, false);
+ QObject::disconnect(w, 0, this, 0);
+#ifndef QT_NO_SCROLLAREA
+ if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
+ QObject::disconnect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()));
+ QObject::disconnect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()));
+ }
+#endif
+#ifndef QT_NO_PROGRESSBAR
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(w))
+ QWindowsStyle::unpolish(pb);
+#endif
+ baseStyle()->unpolish(w);
+}
+
+void QStyleSheetStyle::unpolish(QApplication *app)
+{
+ baseStyle()->unpolish(app);
+ RECURSION_GUARD(return)
+ styleSheetCaches->styleRulesCache.clear();
+ styleSheetCaches->hasStyleRuleCache.clear();
+ styleSheetCaches->renderRulesCache.clear();
+ styleSheetCaches->styleSheetCache.remove(qApp);
+}
+
+#ifndef QT_NO_TABBAR
+inline static bool verticalTabs(QTabBar::Shape shape)
+{
+ return shape == QTabBar::RoundedWest
+ || shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularWest
+ || shape == QTabBar::TriangularEast;
+}
+#endif // QT_NO_TABBAR
+
+void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(baseStyle()->drawComplexControl(cc, opt, p, w); return)
+
+ QRenderRule rule = renderRule(w, opt);
+
+ switch (cc) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QStyleOptionComboBox cmbOpt(*cmb);
+ cmbOpt.rect = rule.borderRect(opt->rect);
+ if (rule.hasNativeBorder()) {
+ rule.drawBackgroundImage(p, cmbOpt.rect);
+ rule.configurePalette(&cmbOpt.palette, QPalette::ButtonText, QPalette::Button);
+ bool customDropDown = (opt->subControls & QStyle::SC_ComboBoxArrow)
+ && (hasStyleRule(w, PseudoElement_ComboBoxDropDown) || hasStyleRule(w, PseudoElement_ComboBoxArrow));
+ if (customDropDown)
+ cmbOpt.subControls &= ~QStyle::SC_ComboBoxArrow;
+ if (rule.baseStyleCanDraw()) {
+ baseStyle()->drawComplexControl(cc, &cmbOpt, p, w);
+ } else {
+ QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
+ }
+ if (!customDropDown)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+
+ if (opt->subControls & QStyle::SC_ComboBoxArrow) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ if (subRule.hasDrawable()) {
+ QRect r = subControlRect(CC_ComboBox, opt, SC_ComboBoxArrow, w);
+ subRule.drawRule(p, r);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_ComboBoxArrow);
+ r = positionRect(w, subRule, subRule2, PseudoElement_ComboBoxArrow, r, opt->direction);
+ subRule2.drawRule(p, r);
+ } else {
+ cmbOpt.subControls = QStyle::SC_ComboBoxArrow;
+ QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
+ }
+ }
+
+ return;
+ }
+ break;
+
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox spinOpt(*spin);
+ rule.configurePalette(&spinOpt.palette, QPalette::ButtonText, QPalette::Button);
+ rule.configurePalette(&spinOpt.palette, QPalette::Text, QPalette::Base);
+ spinOpt.rect = rule.borderRect(opt->rect);
+ bool customUp = true, customDown = true;
+ QRenderRule upRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ QRenderRule downRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
+ bool upRuleMatch = upRule.hasGeometry() || upRule.hasPosition();
+ bool downRuleMatch = downRule.hasGeometry() || downRule.hasPosition();
+ if (rule.hasNativeBorder() && !upRuleMatch && !downRuleMatch) {
+ rule.drawBackgroundImage(p, spinOpt.rect);
+ customUp = (opt->subControls & QStyle::SC_SpinBoxUp)
+ && (hasStyleRule(w, PseudoElement_SpinBoxUpButton) || hasStyleRule(w, PseudoElement_UpArrow));
+ if (customUp)
+ spinOpt.subControls &= ~QStyle::SC_SpinBoxUp;
+ customDown = (opt->subControls & QStyle::SC_SpinBoxDown)
+ && (hasStyleRule(w, PseudoElement_SpinBoxDownButton) || hasStyleRule(w, PseudoElement_DownArrow));
+ if (customDown)
+ spinOpt.subControls &= ~QStyle::SC_SpinBoxDown;
+ if (rule.baseStyleCanDraw()) {
+ baseStyle()->drawComplexControl(cc, &spinOpt, p, w);
+ } else {
+ QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
+ }
+ if (!customUp && !customDown)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+
+ if ((opt->subControls & QStyle::SC_SpinBoxUp) && customUp) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ if (subRule.hasDrawable()) {
+ QRect r = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w);
+ subRule.drawRule(p, r);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SpinBoxUpArrow);
+ r = positionRect(w, subRule, subRule2, PseudoElement_SpinBoxUpArrow, r, opt->direction);
+ subRule2.drawRule(p, r);
+ } else {
+ spinOpt.subControls = QStyle::SC_SpinBoxUp;
+ QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
+ }
+ }
+
+ if ((opt->subControls & QStyle::SC_SpinBoxDown) && customDown) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
+ if (subRule.hasDrawable()) {
+ QRect r = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w);
+ subRule.drawRule(p, r);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SpinBoxDownArrow);
+ r = positionRect(w, subRule, subRule2, PseudoElement_SpinBoxDownArrow, r, opt->direction);
+ subRule2.drawRule(p, r);
+ } else {
+ spinOpt.subControls = QStyle::SC_SpinBoxDown;
+ QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
+ }
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+
+ QRect labelRect, checkBoxRect, titleRect, frameRect;
+ bool hasTitle = (gb->subControls & QStyle::SC_GroupBoxCheckBox) || !gb->text.isEmpty();
+
+ if (!rule.hasDrawable() && (!hasTitle || !hasStyleRule(w, PseudoElement_GroupBoxTitle))
+ && !hasStyleRule(w, PseudoElement_Indicator) && !rule.hasBox() && !rule.hasFont && !rule.hasPalette()) {
+ // let the native style draw the combobox if there is no style for it.
+ break;
+ }
+ rule.drawBackground(p, opt->rect);
+
+ QRenderRule titleRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
+ bool clipSet = false;
+
+ if (hasTitle) {
+ labelRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, w);
+ //Some native style (such as mac) may return a too small rectangle (because they use smaller fonts), so we may need to expand it a little bit.
+ labelRect.setSize(labelRect.size().expandedTo(ParentStyle::subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, w).size()));
+ if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
+ checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, w);
+ titleRect = titleRule.boxRect(checkBoxRect.united(labelRect));
+ } else {
+ titleRect = titleRule.boxRect(labelRect);
+ }
+ if (!titleRule.hasBackground() || !titleRule.background()->isTransparent()) {
+ clipSet = true;
+ p->save();
+ p->setClipRegion(QRegion(opt->rect) - titleRect);
+ }
+ }
+
+ frameRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, w);
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*gb);
+ frame.features = gb->features;
+ frame.lineWidth = gb->lineWidth;
+ frame.midLineWidth = gb->midLineWidth;
+ frame.rect = frameRect;
+ drawPrimitive(PE_FrameGroupBox, &frame, p, w);
+
+ if (clipSet)
+ p->restore();
+
+ // draw background and frame of the title
+ if (hasTitle)
+ titleRule.drawRule(p, titleRect);
+
+ // draw the indicator
+ if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*gb);
+ box.rect = checkBoxRect;
+ drawPrimitive(PE_IndicatorCheckBox, &box, p, w);
+ }
+
+ // draw the text
+ if (!gb->text.isEmpty()) {
+ int alignment = int(Qt::AlignCenter | Qt::TextShowMnemonic);
+ if (!styleHint(QStyle::SH_UnderlineShortcut, opt, w)) {
+ alignment |= Qt::TextHideMnemonic;
+ }
+
+ QPalette pal = gb->palette;
+ if (gb->textColor.isValid())
+ pal.setColor(QPalette::WindowText, gb->textColor);
+ titleRule.configurePalette(&pal, QPalette::WindowText, QPalette::Window);
+ drawItemText(p, labelRect, alignment, pal, gb->state & State_Enabled,
+ gb->text, QPalette::WindowText);
+
+ if (gb->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*gb);
+ fropt.rect = labelRect;
+ drawPrimitive(PE_FrameFocusRect, &fropt, p, w);
+ }
+ }
+
+ return;
+ }
+ break;
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tool = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QStyleOptionToolButton toolOpt(*tool);
+ rule.configurePalette(&toolOpt.palette, QPalette::ButtonText, QPalette::Button);
+ toolOpt.font = rule.font.resolve(toolOpt.font);
+ toolOpt.rect = rule.borderRect(opt->rect);
+ bool customArrow = (tool->features & (QStyleOptionToolButton::HasMenu | QStyleOptionToolButton::MenuButtonPopup));
+ bool customDropDown = tool->features & QStyleOptionToolButton::MenuButtonPopup;
+ if (rule.hasNativeBorder()) {
+ if (tool->subControls & SC_ToolButton) {
+ //in some case (eg. the button is "auto raised") the style doesn't draw the background
+ //so we need to draw the background.
+ // use the same condition as in QCommonStyle
+ State bflags = tool->state & ~State_Sunken;
+ if (bflags & State_AutoRaise && (!(bflags & State_MouseOver) || !(bflags & State_Enabled)))
+ bflags &= ~State_Raised;
+ if (tool->state & State_Sunken && tool->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (!(bflags & (State_Sunken | State_On | State_Raised)))
+ rule.drawBackground(p, toolOpt.rect);
+ }
+ customArrow = customArrow && hasStyleRule(w, PseudoElement_ToolButtonDownArrow);
+ if (customArrow)
+ toolOpt.features &= ~QStyleOptionToolButton::HasMenu;
+ customDropDown = customDropDown && hasStyleRule(w, PseudoElement_ToolButtonMenu);
+ if (customDropDown)
+ toolOpt.subControls &= ~QStyle::SC_ToolButtonMenu;
+
+ if (rule.baseStyleCanDraw() && !(tool->features & QStyleOptionToolButton::Arrow)) {
+ baseStyle()->drawComplexControl(cc, &toolOpt, p, w);
+ } else {
+ QWindowsStyle::drawComplexControl(cc, &toolOpt, p, w);
+ }
+
+ if (!customArrow && !customDropDown)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ toolOpt.rect = rule.contentsRect(opt->rect);
+ if (rule.hasFont)
+ toolOpt.font = rule.font;
+ drawControl(CE_ToolButtonLabel, &toolOpt, p, w);
+ }
+
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
+ QRect r = subControlRect(CC_ToolButton, opt, QStyle::SC_ToolButtonMenu, w);
+ if (customDropDown) {
+ if (opt->subControls & QStyle::SC_ToolButtonMenu) {
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, r);
+ } else {
+ toolOpt.rect = r;
+ baseStyle()->drawPrimitive(PE_IndicatorButtonDropDown, &toolOpt, p, w);
+ }
+ }
+ }
+
+ if (customArrow) {
+ QRenderRule subRule2 = customDropDown ? renderRule(w, opt, PseudoElement_ToolButtonMenuArrow)
+ : renderRule(w, opt, PseudoElement_ToolButtonDownArrow);
+ QRect r2 = customDropDown
+ ? positionRect(w, subRule, subRule2, PseudoElement_ToolButtonMenuArrow, r, opt->direction)
+ : positionRect(w, rule, subRule2, PseudoElement_ToolButtonDownArrow, opt->rect, opt->direction);
+ if (subRule2.hasDrawable()) {
+ subRule2.drawRule(p, r2);
+ } else {
+ toolOpt.rect = r2;
+ baseStyle()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &toolOpt, p, w);
+ }
+ }
+
+ return;
+ }
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider sbOpt(*sb);
+ if (!rule.hasDrawable()) {
+ sbOpt.rect = rule.borderRect(opt->rect);
+ rule.drawBackgroundImage(p, opt->rect);
+ baseStyle()->drawComplexControl(cc, &sbOpt, p, w);
+ } else {
+ rule.drawRule(p, opt->rect);
+ QWindowsStyle::drawComplexControl(cc, opt, p, w);
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ rule.drawRule(p, opt->rect);
+
+ QRenderRule grooveSubRule = renderRule(w, opt, PseudoElement_SliderGroove);
+ QRenderRule handleSubRule = renderRule(w, opt, PseudoElement_SliderHandle);
+ if (!grooveSubRule.hasDrawable()) {
+ QStyleOptionSlider slOpt(*slider);
+ bool handleHasRule = handleSubRule.hasDrawable();
+ // If the style specifies a different handler rule, draw the groove without the handler.
+ if (handleHasRule)
+ slOpt.subControls &= ~SC_SliderHandle;
+ baseStyle()->drawComplexControl(cc, &slOpt, p, w);
+ if (!handleHasRule)
+ return;
+ }
+
+ QRect gr = subControlRect(cc, opt, SC_SliderGroove, w);
+ if (slider->subControls & SC_SliderGroove) {
+ grooveSubRule.drawRule(p, gr);
+ }
+
+ if (slider->subControls & SC_SliderHandle) {
+ QRect hr = subControlRect(cc, opt, SC_SliderHandle, w);
+
+ QRenderRule subRule1 = renderRule(w, opt, PseudoElement_SliderSubPage);
+ if (subRule1.hasDrawable()) {
+ QRect r(gr.topLeft(),
+ slider->orientation == Qt::Horizontal
+ ? QPoint(hr.x()+hr.width()/2, gr.y()+gr.height() - 1)
+ : QPoint(gr.x()+gr.width() - 1, hr.y()+hr.height()/2));
+ subRule1.drawRule(p, r);
+ }
+
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderAddPage);
+ if (subRule2.hasDrawable()) {
+ QRect r(slider->orientation == Qt::Horizontal
+ ? QPoint(hr.x()+hr.width()/2+1, gr.y())
+ : QPoint(gr.x(), hr.y()+hr.height()/2+1),
+ gr.bottomRight());
+ subRule2.drawRule(p, r);
+ }
+
+ handleSubRule.drawRule(p, handleSubRule.boxRect(hr, Margin));
+ }
+
+ if (slider->subControls & SC_SliderTickmarks) {
+ // TODO...
+ }
+
+ return;
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+ case CC_MdiControls:
+ if (hasStyleRule(w, PseudoElement_MdiCloseButton)
+ || hasStyleRule(w, PseudoElement_MdiNormalButton)
+ || hasStyleRule(w, PseudoElement_MdiMinButton)) {
+ QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("mNX"));
+
+ QStyleOptionComplex optCopy(*opt);
+ optCopy.subControls = 0;
+ for (int i = 0; i < layout.count(); i++) {
+ int layoutButton = layout[i].toInt();
+ if (layoutButton < PseudoElement_MdiCloseButton
+ || layoutButton > PseudoElement_MdiNormalButton)
+ continue;
+ QStyle::SubControl control = knownPseudoElements[layoutButton].subControl;
+ if (!(opt->subControls & control))
+ continue;
+ QRenderRule subRule = renderRule(w, opt, layoutButton);
+ if (subRule.hasDrawable()) {
+ QRect rect = subRule.boxRect(subControlRect(CC_MdiControls, opt, control, w), Margin);
+ subRule.drawRule(p, rect);
+ QIcon icon = standardIcon(subControlIcon(layoutButton), opt);
+ icon.paint(p, subRule.contentsRect(rect), Qt::AlignCenter);
+ } else {
+ optCopy.subControls |= control;
+ }
+ }
+
+ if (optCopy.subControls)
+ baseStyle()->drawComplexControl(CC_MdiControls, &optCopy, p, w);
+ return;
+ }
+ break;
+
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (!subRule.hasDrawable() && !subRule.hasBox() && !subRule.hasBorder())
+ break;
+ subRule.drawRule(p, opt->rect);
+ QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
+
+ QRect ir;
+ ir = layout[SC_TitleBarLabel];
+ if (ir.isValid()) {
+ if (subRule.hasPalette())
+ p->setPen(subRule.palette()->foreground.color());
+ p->fillRect(ir, Qt::white);
+ p->drawText(ir.x(), ir.y(), ir.width(), ir.height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+
+ QPixmap pm;
+
+ ir = layout[SC_TitleBarSysMenu];
+ if (ir.isValid()) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarSysMenu);
+ subSubRule.drawRule(p, ir);
+ ir = subSubRule.contentsRect(ir);
+ if (!tb->icon.isNull()) {
+ tb->icon.paint(p, ir);
+ } else {
+ int iconSize = pixelMetric(PM_SmallIconSize, tb, w);
+ pm = standardIcon(SP_TitleBarMenuButton, 0, w).pixmap(iconSize, iconSize);
+ drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ }
+ }
+
+ ir = layout[SC_TitleBarCloseButton];
+ if (ir.isValid()) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarCloseButton);
+ subSubRule.drawRule(p, ir);
+
+ QSize sz = subSubRule.contentsRect(ir).size();
+ if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool)
+ pm = standardIcon(SP_DockWidgetCloseButton, 0, w).pixmap(sz);
+ else
+ pm = standardIcon(SP_TitleBarCloseButton, 0, w).pixmap(sz);
+ drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ }
+
+ int pes[] = {
+ PseudoElement_TitleBarMaxButton,
+ PseudoElement_TitleBarMinButton,
+ PseudoElement_TitleBarNormalButton,
+ PseudoElement_TitleBarShadeButton,
+ PseudoElement_TitleBarUnshadeButton,
+ PseudoElement_TitleBarContextHelpButton
+ };
+
+ for (unsigned int i = 0; i < sizeof(pes)/sizeof(int); i++) {
+ int pe = pes[i];
+ QStyle::SubControl sc = knownPseudoElements[pe].subControl;
+ ir = layout[sc];
+ if (!ir.isValid())
+ continue;
+ QRenderRule subSubRule = renderRule(w, opt, pe);
+ subSubRule.drawRule(p, ir);
+ pm = standardIcon(subControlIcon(pe), 0, w).pixmap(subSubRule.contentsRect(ir).size());
+ drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ }
+
+ return;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+ baseStyle()->drawComplexControl(cc, opt, p, w);
+}
+
+void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(baseStyle()->drawControl(ce, opt, p, w); return)
+
+ QRenderRule rule = renderRule(w, opt);
+ int pe1 = PseudoElement_None, pe2 = PseudoElement_None;
+ bool fallback = false;
+
+ switch (ce) {
+ case CE_ToolButtonLabel:
+ if (const QStyleOptionToolButton *btn = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ if (rule.hasBox() || btn->features & QStyleOptionToolButton::Arrow) {
+ QCommonStyle::drawControl(ce, opt, p, w);
+ } else {
+ QStyleOptionToolButton butOpt(*btn);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ baseStyle()->drawControl(ce, &butOpt, p, w);
+ }
+ return;
+ }
+ break;
+
+ case CE_FocusFrame:
+ if (!rule.hasNativeBorder()) {
+ rule.drawBorder(p, opt->rect);
+ return;
+ }
+ break;
+
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
+ ((btn->features & QStyleOptionButton::HasMenu) && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator))) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ }
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton btnOpt(*btn);
+ btnOpt.rect = rule.borderRect(opt->rect);
+ if (rule.hasNativeBorder()) {
+ rule.drawBackgroundImage(p, btnOpt.rect);
+ rule.configurePalette(&btnOpt.palette, QPalette::ButtonText, QPalette::Button);
+ bool customMenu = (btn->features & QStyleOptionButton::HasMenu
+ && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator));
+ if (customMenu)
+ btnOpt.features &= ~QStyleOptionButton::HasMenu;
+ if (rule.baseStyleCanDraw()) {
+ baseStyle()->drawControl(ce, &btnOpt, p, w);
+ } else {
+ QWindowsStyle::drawControl(ce, &btnOpt, p, w);
+ }
+ if (!customMenu)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_PushButtonMenuIndicator);
+ QRect ir = positionRect(w, rule, subRule, PseudoElement_PushButtonMenuIndicator, opt->rect, opt->direction);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, ir);
+ } else {
+ btnOpt.rect = ir;
+ baseStyle()->drawPrimitive(PE_IndicatorArrowDown, &btnOpt, p, w);
+ }
+ }
+ }
+ return;
+
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton butOpt(*button);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ if (rule.hasPosition() && rule.position()->textAlignment != 0) {
+ Qt::Alignment textAlignment = rule.position()->textAlignment;
+ QRect textRect = button->rect;
+ uint tf = Qt::TextShowMnemonic;
+ const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft;
+ tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter;
+ if (!styleHint(SH_UnderlineShortcut, button, w))
+ tf |= Qt::TextHideMnemonic;
+ if (!button->icon.isNull()) {
+ //Group both icon and text
+ QRect iconRect;
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+ QIcon::State state = QIcon::Off;
+ if (button->state & State_On)
+ state = QIcon::On;
+
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int labelWidth = pixmap.width();
+ int labelHeight = pixmap.height();
+ int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
+ int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
+ if (!button->text.isEmpty())
+ labelWidth += (textWidth + iconSpacing);
+
+ //Determine label alignment:
+ if (textAlignment & Qt::AlignLeft) { /*left*/
+ iconRect = QRect(textRect.x(), textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+ } else if (textAlignment & Qt::AlignHCenter) { /* center */
+ iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
+ textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+ } else { /*right*/
+ iconRect = QRect(textRect.x() + textRect.width() - labelWidth,
+ textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+ }
+
+ iconRect = visualRect(button->direction, textRect, iconRect);
+
+ tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
+
+ if (button->direction == Qt::RightToLeft)
+ textRect.setRight(iconRect.left() - iconSpacing);
+ else
+ textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
+
+ if (button->state & (State_On | State_Sunken))
+ iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w),
+ pixelMetric(PM_ButtonShiftVertical, opt, w));
+ p->drawPixmap(iconRect, pixmap);
+ } else {
+ tf |= textAlignment;
+ }
+ if (button->state & (State_On | State_Sunken))
+ textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w),
+ pixelMetric(PM_ButtonShiftVertical, opt, w));
+
+ if (button->features & QStyleOptionButton::HasMenu) {
+ int indicatorSize = pixelMetric(PM_MenuButtonIndicator, button, w);
+ if (button->direction == Qt::LeftToRight)
+ textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
+ else
+ textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
+ }
+ drawItemText(p, textRect, tf, butOpt.palette, (button->state & State_Enabled),
+ button->text, QPalette::ButtonText);
+ } else {
+ ParentStyle::drawControl(ce, &butOpt, p, w);
+ }
+ }
+ return;
+
+ case CE_RadioButton:
+ case CE_CheckBox:
+ if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
+ rule.drawRule(p, opt->rect);
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton butOpt(*btn);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ baseStyle()->drawControl(ce, &butOpt, p, w);
+ return;
+ }
+ break;
+ case CE_RadioButtonLabel:
+ case CE_CheckBoxLabel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton butOpt(*btn);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ ParentStyle::drawControl(ce, &butOpt, p, w);
+ }
+ return;
+
+ case CE_Splitter:
+ pe1 = PseudoElement_SplitterHandle;
+ break;
+
+ case CE_ToolBar:
+ if (rule.hasBackground()) {
+ rule.drawBackground(p, opt->rect);
+ }
+ if (rule.hasBorder()) {
+ rule.drawBorder(p, rule.borderRect(opt->rect));
+ } else {
+#ifndef QT_NO_TOOLBAR
+ if (const QStyleOptionToolBar *tb = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ QStyleOptionToolBar newTb(*tb);
+ newTb.rect = rule.borderRect(opt->rect);
+ baseStyle()->drawControl(ce, &newTb, p, w);
+ }
+#endif // QT_NO_TOOLBAR
+ }
+ return;
+
+ case CE_MenuEmptyArea:
+ case CE_MenuBarEmptyArea:
+ if (rule.hasDrawable()) {
+ // Drawn by PE_Widget
+ return;
+ }
+ break;
+
+ case CE_MenuTearoff:
+ case CE_MenuScroller:
+ if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ QStyleOptionMenuItem mi(*m);
+ int pe = ce == CE_MenuTearoff ? PseudoElement_MenuTearoff : PseudoElement_MenuScroller;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ mi.rect = subRule.contentsRect(opt->rect);
+ rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ } else {
+ baseStyle()->drawControl(ce, &mi, p, w);
+ }
+ }
+ return;
+
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ QStyleOptionMenuItem mi(*m);
+
+ int pseudo = (mi.menuItemType == QStyleOptionMenuItem::Separator) ? PseudoElement_MenuSeparator : PseudoElement_Item;
+ QRenderRule subRule = renderRule(w, opt, pseudo);
+ mi.rect = subRule.contentsRect(opt->rect);
+ rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ rule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
+ subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ subRule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font.resolve(p->font()));
+
+ // We fall back to drawing with the style sheet code whenever at least one of the
+ // items are styled in an incompatible way, such as having a background image.
+ QRenderRule allRules = renderRule(w, PseudoElement_Item, PseudoClass_Any);
+
+ if ((pseudo == PseudoElement_MenuSeparator) && subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ } else if ((pseudo == PseudoElement_Item)
+ && (allRules.hasBox() || allRules.hasBorder()
+ || (allRules.background() && !allRules.background()->pixmap.isNull()))) {
+ subRule.drawRule(p, opt->rect);
+ if (subRule.hasBackground()) {
+ mi.palette.setBrush(QPalette::Highlight, Qt::NoBrush);
+ mi.palette.setBrush(QPalette::Button, Qt::NoBrush);
+ } else {
+ mi.palette.setBrush(QPalette::Highlight, mi.palette.brush(QPalette::Button));
+ }
+ mi.palette.setBrush(QPalette::HighlightedText, mi.palette.brush(QPalette::ButtonText));
+
+ bool checkable = mi.checkType != QStyleOptionMenuItem::NotCheckable;
+ bool checked = checkable ? mi.checked : false;
+
+ bool dis = !(opt->state & QStyle::State_Enabled),
+ act = opt->state & QStyle::State_Selected;
+
+ if (!mi.icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
+ else
+ pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRenderRule iconRule = renderRule(w, opt, PseudoElement_MenuIcon);
+ if (!iconRule.hasGeometry()) {
+ iconRule.geo = new QStyleSheetGeometryData(pixw, pixh, pixw, pixh, -1, -1);
+ } else {
+ iconRule.geo->width = pixw;
+ iconRule.geo->height = pixh;
+ }
+ QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction);
+ iconRule.drawRule(p, iconRect);
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(iconRect.center());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ if (subSubRule.hasDrawable() || checked) {
+ QStyleOptionMenuItem newMi = mi;
+ newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+ }
+
+ QRect textRect = subRule.contentsRect(opt->rect);
+ textRect.setWidth(textRect.width() - mi.tabWidth);
+ QString s = mi.text;
+ p->setPen(mi.palette.buttonText().color());
+ if (!s.isEmpty()) {
+ int text_flags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, &mi, w))
+ text_flags |= Qt::TextHideMnemonic;
+ int t = s.indexOf(QLatin1Char('\t'));
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(opt->direction, mi.rect,
+ QRect(textRect.topRight(), QPoint(mi.rect.right(), textRect.bottom())));
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ p->drawText(textRect, text_flags, s.left(t));
+ }
+
+ if (mi.menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ PrimitiveElement arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_MenuRightArrow);
+ mi.rect = positionRect(w, subRule, subRule2, PseudoElement_MenuRightArrow, opt->rect, mi.direction);
+ drawPrimitive(arrow, &mi, p, w);
+ }
+ } else if (hasStyleRule(w, PseudoElement_MenuCheckMark) || hasStyleRule(w, PseudoElement_MenuRightArrow)) {
+ QWindowsStyle::drawControl(ce, &mi, p, w);
+ if (mi.checkType != QStyleOptionMenuItem::NotCheckable && !mi.checked) {
+ // We have a style defined, but QWindowsStyle won't draw anything if not checked.
+ // So we mimick what QWindowsStyle would do.
+ int checkcol = qMax<int>(mi.maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
+ QRect vCheckRect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x(), mi.rect.y(), checkcol, mi.rect.height()));
+ if (mi.state.testFlag(State_Enabled) && mi.state.testFlag(State_Selected)) {
+ qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &mi.palette.brush(QPalette::Button));
+ } else {
+ QBrush fill(mi.palette.light().color(), Qt::Dense4Pattern);
+ qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &fill);
+ }
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ if (subSubRule.hasDrawable()) {
+ QStyleOptionMenuItem newMi(mi);
+ newMi.rect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x() + QWindowsStylePrivate::windowsItemFrame,
+ mi.rect.y() + QWindowsStylePrivate::windowsItemFrame,
+ checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
+ mi.rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+ }
+ } else {
+ if (rule.hasDrawable() && !subRule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
+ mi.palette.setColor(QPalette::Window, Qt::transparent);
+ mi.palette.setColor(QPalette::Button, Qt::transparent);
+ }
+ if (rule.baseStyleCanDraw() && subRule.baseStyleCanDraw()) {
+ baseStyle()->drawControl(ce, &mi, p, w);
+ } else {
+ ParentStyle::drawControl(ce, &mi, p, w);
+ }
+ }
+
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+
+ return;
+ }
+ return;
+
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ QStyleOptionMenuItem mi(*m);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_Item);
+ mi.rect = subRule.contentsRect(opt->rect);
+ rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ QCommonStyle::drawControl(ce, &mi, p, w);
+ } else {
+ if (rule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
+ // So that the menu bar background is not hidden by the items
+ mi.palette.setColor(QPalette::Window, Qt::transparent);
+ mi.palette.setColor(QPalette::Button, Qt::transparent);
+ }
+ baseStyle()->drawControl(ce, &mi, p, w);
+ }
+ }
+ return;
+
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ if (!rule.hasBox())
+ break;
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QRect editRect = subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, w);
+ p->save();
+ p->setClipRect(editRect);
+ if (!cb->currentIcon.isNull()) {
+ int spacing = rule.hasBox() ? rule.box()->spacing : -1;
+ if (spacing == -1)
+ spacing = 6;
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width());
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-spacing - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + spacing, 0);
+ }
+ if (!cb->currentText.isEmpty() && !cb->editable) {
+ QPalette styledPalette(cb->palette);
+ rule.configurePalette(&styledPalette, QPalette::Text, QPalette::Base);
+ drawItemText(p, editRect.adjusted(0, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, styledPalette,
+ cb->state & State_Enabled, cb->currentText, QPalette::Text);
+ }
+ p->restore();
+ return;
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+
+ case CE_Header:
+ if (hasStyleRule(w, PseudoElement_HeaderViewUpArrow)
+ || hasStyleRule(w, PseudoElement_HeaderViewDownArrow)) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ if(hasStyleRule(w, PseudoElement_HeaderViewSection)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (!subRule.hasNativeBorder() || !subRule.baseStyleCanDraw()
+ || subRule.hasBackground() || subRule.hasPalette()) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ }
+ break;
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (subRule.hasNativeBorder()) {
+ QStyleOptionHeader hdr(*header);
+ subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
+
+ if (subRule.baseStyleCanDraw()) {
+ baseStyle()->drawControl(CE_HeaderSection, &hdr, p, w);
+ } else {
+ QWindowsStyle::drawControl(CE_HeaderSection, &hdr, p, w);
+ }
+ } else {
+ subRule.drawRule(p, opt->rect);
+ }
+ return;
+ }
+ break;
+
+ case CE_HeaderLabel:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QStyleOptionHeader hdr(*header);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font.resolve(p->font()));
+ baseStyle()->drawControl(ce, &hdr, p, w);
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+ return;
+ }
+ break;
+
+ case CE_HeaderEmptyArea:
+ if (rule.hasDrawable()) {
+ return;
+ }
+ break;
+
+ case CE_ProgressBar:
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ return;
+
+ case CE_ProgressBarGroove:
+ if (!rule.hasNativeBorder()) {
+ rule.drawRule(p, rule.boxRect(opt->rect, Margin));
+ return;
+ }
+ break;
+
+ case CE_ProgressBarContents: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
+ if (subRule.hasDrawable()) {
+ if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ p->save();
+ p->setClipRect(pb->rect);
+
+ qint64 minimum = qint64(pb->minimum);
+ qint64 maximum = qint64(pb->maximum);
+ qint64 progress = qint64(pb->progress);
+ bool vertical = (pb->orientation == Qt::Vertical);
+ bool inverted = pb->invertedAppearance;
+
+ QTransform m;
+ QRect rect = pb->rect;
+ if (vertical) {
+ rect = QRect(rect.y(), rect.x(), rect.height(), rect.width());
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ const bool indeterminate = pb->minimum == pb->maximum;
+ qreal fillRatio = indeterminate ? 0.50 : qreal(progress - minimum)/(maximum - minimum);
+ int fillWidth = int(rect.width() * fillRatio);
+ int chunkWidth = fillWidth;
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ chunkWidth = (opt->state & QStyle::State_Horizontal) ? sz.width() : sz.height();
+ }
+
+ QRect r = rect;
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ Q_D(const QWindowsStyle);
+ int chunkCount = fillWidth/chunkWidth;
+ int offset = (d->animateStep*8%rect.width());
+ int x = reverse ? r.left() + r.width() - offset - chunkWidth : r.x() + offset;
+ while (chunkCount > 0) {
+ r.setRect(x, rect.y(), chunkWidth, rect.height());
+ r = m.mapRect(QRectF(r)).toRect();
+ subRule.drawRule(p, r);
+ x += reverse ? -chunkWidth : chunkWidth;
+ if (reverse ? x < rect.left() : x > rect.right())
+ break;
+ --chunkCount;
+ }
+
+ r = rect;
+ x = reverse ? r.right() - (r.left() - x - chunkWidth)
+ : r.left() + (x - r.right() - chunkWidth);
+ while (chunkCount > 0) {
+ r.setRect(x, rect.y(), chunkWidth, rect.height());
+ r = m.mapRect(QRectF(r)).toRect();
+ subRule.drawRule(p, r);
+ x += reverse ? -chunkWidth : chunkWidth;
+ --chunkCount;
+ };
+ } else {
+ int x = reverse ? r.left() + r.width() - chunkWidth : r.x();
+
+ for (int i = 0; i < ceil(qreal(fillWidth)/chunkWidth); ++i) {
+ r.setRect(x, rect.y(), chunkWidth, rect.height());
+ r = m.mapRect(QRectF(r)).toRect();
+ subRule.drawRule(p, r);
+ x += reverse ? -chunkWidth : chunkWidth;
+ }
+ }
+
+ p->restore();
+ return;
+ }
+ }
+ }
+ break;
+
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) {
+ drawItemText(p, pb->rect, pb->textAlignment | Qt::TextSingleLine, pb->palette,
+ pb->state & State_Enabled, pb->text, QPalette::Text);
+ } else {
+ QStyleOptionProgressBarV2 pbCopy(*pb);
+ rule.configurePalette(&pbCopy.palette, QPalette::HighlightedText, QPalette::Highlight);
+ baseStyle()->drawControl(ce, &pbCopy, p, w);
+ }
+ return;
+ }
+ break;
+
+ case CE_SizeGrip:
+ if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt)) {
+ if (rule.hasDrawable()) {
+ rule.drawFrame(p, opt->rect);
+ p->save();
+ switch (sgOpt->corner) {
+ case Qt::BottomRightCorner: break;
+ case Qt::BottomLeftCorner: p->rotate(90); break;
+ case Qt::TopLeftCorner: p->rotate(180); break;
+ case Qt::TopRightCorner: p->rotate(270); break;
+ default: break;
+ }
+ rule.drawImage(p, opt->rect);
+ p->restore();
+ } else {
+ QStyleOptionSizeGrip sg(*sgOpt);
+ sg.rect = rule.contentsRect(opt->rect);
+ baseStyle()->drawControl(CE_SizeGrip, &sg, p, w);
+ }
+ return;
+ }
+ break;
+
+ case CE_ToolBoxTab:
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ return;
+
+ case CE_ToolBoxTabShape: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolBoxTab);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ return;
+ }
+ }
+ break;
+
+ case CE_ToolBoxTabLabel:
+ if (const QStyleOptionToolBox *box = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
+ QStyleOptionToolBox boxCopy(*box);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolBoxTab);
+ subRule.configurePalette(&boxCopy.palette, QPalette::ButtonText, QPalette::Button);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font);
+ boxCopy.rect = subRule.contentsRect(opt->rect);
+ QWindowsStyle::drawControl(ce, &boxCopy, p , w);
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+ return;
+ }
+ break;
+
+ case CE_ScrollBarAddPage:
+ pe1 = PseudoElement_ScrollBarAddPage;
+ break;
+
+ case CE_ScrollBarSubPage:
+ pe1 = PseudoElement_ScrollBarSubPage;
+ break;
+
+ case CE_ScrollBarAddLine:
+ pe1 = PseudoElement_ScrollBarAddLine;
+ pe2 = (opt->state & QStyle::State_Horizontal) ? PseudoElement_ScrollBarRightArrow : PseudoElement_ScrollBarDownArrow;
+ fallback = true;
+ break;
+
+ case CE_ScrollBarSubLine:
+ pe1 = PseudoElement_ScrollBarSubLine;
+ pe2 = (opt->state & QStyle::State_Horizontal) ? PseudoElement_ScrollBarLeftArrow : PseudoElement_ScrollBarUpArrow;
+ fallback = true;
+ break;
+
+ case CE_ScrollBarFirst:
+ pe1 = PseudoElement_ScrollBarFirst;
+ break;
+
+ case CE_ScrollBarLast:
+ pe1 = PseudoElement_ScrollBarLast;
+ break;
+
+ case CE_ScrollBarSlider:
+ pe1 = PseudoElement_ScrollBarSlider;
+ fallback = true;
+ break;
+
+#ifndef QT_NO_ITEMVIEWS
+ case CE_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
+ if (subRule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
+ QStyleOptionViewItemV4 optCopy(*vopt);
+ subRule.configurePalette(&optCopy.palette, vopt->state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text,
+ vopt->state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base);
+ QWindowsStyle::drawControl(ce, &optCopy, p, w);
+ } else {
+ QStyleOptionViewItemV4 voptCopy(*vopt);
+ subRule.configurePalette(&voptCopy.palette, QPalette::Text, QPalette::NoRole);
+ baseStyle()->drawControl(ce, &voptCopy, p, w);
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_ITEMVIEWS
+
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTab:
+ if (hasStyleRule(w, PseudoElement_TabBarTab)) {
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ break;
+
+ case CE_TabBarTabLabel:
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ QStyleOptionTabV3 tabCopy(*tab);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, opt->rect, opt->direction);
+ if (ce == CE_TabBarTabShape && subRule.hasDrawable()) {
+ subRule.drawRule(p, r);
+ return;
+ }
+ subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Window);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ tabCopy.rect = ce == CE_TabBarTabShape ? subRule.borderRect(r)
+ : subRule.contentsRect(r);
+ QWindowsStyle::drawControl(ce, &tabCopy, p, w);
+ } else {
+ baseStyle()->drawControl(ce, &tabCopy, p, w);
+ }
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+
+ return;
+ }
+ break;
+#endif // QT_NO_TABBAR
+
+ case CE_ColumnViewGrip:
+ if (rule.hasDrawable()) {
+ rule.drawRule(p, opt->rect);
+ return;
+ }
+ break;
+
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidgetV2 *dwOpt = qstyleoption_cast<const QStyleOptionDockWidgetV2 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
+ if (!subRule.hasDrawable() && !subRule.hasPosition())
+ break;
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ } else {
+ QStyleOptionDockWidgetV2 dwCopy(*dwOpt);
+ dwCopy.title = QString();
+ baseStyle()->drawControl(ce, &dwCopy, p, w);
+ }
+
+ if (!dwOpt->title.isEmpty()) {
+ QRect r = opt->rect;
+ if (dwOpt->verticalTitleBar) {
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ p->save();
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ Qt::Alignment alignment = 0;
+ if (subRule.hasPosition())
+ alignment = subRule.position()->textAlignment;
+ if (alignment == 0)
+ alignment = Qt::AlignLeft;
+ drawItemText(p, subRule.contentsRect(opt->rect),
+ alignment | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, dwOpt->title,
+ QPalette::WindowText);
+
+ if (dwOpt->verticalTitleBar)
+ p->restore();
+ }
+
+ return;
+ }
+ break;
+ case CE_ShapedFrame:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (rule.hasNativeBorder()) {
+ QStyleOptionFrameV3 frmOpt(*frm);
+ rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
+ frmOpt.rect = rule.borderRect(frmOpt.rect);
+ baseStyle()->drawControl(ce, &frmOpt, p, w);
+ }
+ // else, borders are already drawn in PE_Widget
+ }
+ return;
+
+
+ default:
+ break;
+ }
+
+ if (pe1 != PseudoElement_None) {
+ QRenderRule subRule = renderRule(w, opt, pe1);
+ if (subRule.bg != 0 || subRule.hasDrawable()) {
+ //We test subRule.bg directly because hasBackground() would return false for background:none.
+ //But we still don't want the default drawning in that case (example for QScrollBar::add-page) (task 198926)
+ subRule.drawRule(p, opt->rect);
+ } else if (fallback) {
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ pe2 = PseudoElement_None;
+ } else {
+ baseStyle()->drawControl(ce, opt, p, w);
+ }
+ if (pe2 != PseudoElement_None) {
+ QRenderRule subSubRule = renderRule(w, opt, pe2);
+ QRect r = positionRect(w, subRule, subSubRule, pe2, opt->rect, opt->direction);
+ subSubRule.drawRule(p, r);
+ }
+ return;
+ }
+
+ baseStyle()->drawControl(ce, opt, p, w);
+}
+
+void QStyleSheetStyle::drawItemPixmap(QPainter *p, const QRect &rect, int alignment, const
+ QPixmap &pixmap) const
+{
+ baseStyle()->drawItemPixmap(p, rect, alignment, pixmap);
+}
+
+void QStyleSheetStyle::drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ baseStyle()->drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
+}
+
+void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(baseStyle()->drawPrimitive(pe, opt, p, w); return)
+
+ int pseudoElement = PseudoElement_None;
+ QRenderRule rule = renderRule(w, opt);
+ QRect rect = opt->rect;
+
+ switch (pe) {
+
+ case PE_FrameStatusBar: {
+ QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_Item);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ return;
+ }
+ break;
+ }
+
+ case PE_IndicatorArrowDown:
+ pseudoElement = PseudoElement_DownArrow;
+ break;
+
+ case PE_IndicatorArrowUp:
+ pseudoElement = PseudoElement_UpArrow;
+ break;
+
+ case PE_IndicatorRadioButton:
+ pseudoElement = PseudoElement_ExclusiveIndicator;
+ break;
+
+ case PE_IndicatorViewItemCheck:
+ pseudoElement = PseudoElement_ViewItemIndicator;
+ break;
+
+ case PE_IndicatorCheckBox:
+ pseudoElement = PseudoElement_Indicator;
+ break;
+
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ pseudoElement = hdr->sortIndicator == QStyleOptionHeader::SortUp
+ ? PseudoElement_HeaderViewUpArrow
+ : PseudoElement_HeaderViewDownArrow;
+ }
+ break;
+
+ case PE_PanelButtonTool:
+ case PE_PanelButtonCommand:
+ if (qobject_cast<const QAbstractButton *>(w) && rule.hasBackground() && rule.hasNativeBorder()) {
+ //the window style will draw the borders
+ ParentStyle::drawPrimitive(pe, opt, p, w);
+ if (!rule.background()->pixmap.isNull() || rule.hasImage()) {
+ rule.drawRule(p, rule.boxRect(opt->rect, QRenderRule::Margin).adjusted(1,1,-1,-1));
+ }
+ return;
+ }
+ if (!rule.hasNativeBorder()) {
+ rule.drawRule(p, rule.boxRect(opt->rect, QRenderRule::Margin));
+ return;
+ }
+ break;
+
+ case PE_IndicatorButtonDropDown: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
+ if (!subRule.hasNativeBorder()) {
+ rule.drawBorder(p, opt->rect);
+ return;
+ }
+ break;
+ }
+
+ case PE_FrameDefaultButton:
+ if (rule.hasNativeBorder()) {
+ if (rule.baseStyleCanDraw())
+ break;
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ }
+ return;
+
+ case PE_FrameWindow:
+ case PE_FrameDockWidget:
+ case PE_Frame:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (rule.hasNativeBorder()) {
+ QStyleOptionFrameV2 frmOpt(*frm);
+ rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
+ if (!qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) //if it comes from CE_ShapedFrame, the margins are already sustracted
+ frmOpt.rect = rule.borderRect(frmOpt.rect);
+ baseStyle()->drawPrimitive(pe, &frmOpt, p, w);
+ } else {
+ rule.drawBorder(p, rule.borderRect(opt->rect));
+ }
+ }
+ return;
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+#ifndef QT_NO_SPINBOX
+ if (w && qobject_cast<const QAbstractSpinBox *>(w->parentWidget())) {
+ QRenderRule spinboxRule = renderRule(w->parentWidget(), opt);
+ if (!spinboxRule.hasNativeBorder() || !spinboxRule.baseStyleCanDraw())
+ return;
+ rule = spinboxRule;
+ }
+#endif
+ if (rule.hasNativeBorder()) {
+ QStyleOptionFrame frmOpt(*frm);
+ rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
+ frmOpt.rect = rule.borderRect(frmOpt.rect);
+ if (rule.baseStyleCanDraw()) {
+ rule.drawBackgroundImage(p, opt->rect);
+ baseStyle()->drawPrimitive(pe, &frmOpt, p, w);
+ } else {
+ rule.drawBackground(p, opt->rect);
+ if (frmOpt.lineWidth > 0)
+ baseStyle()->drawPrimitive(PE_FrameLineEdit, &frmOpt, p, w);
+ }
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+ }
+ return;
+
+ case PE_Widget:
+ if (w && !rule.hasDrawable()) {
+ QWidget *container = containerWidget(w);
+ if (styleSheetCaches->autoFillDisabledWidgets.contains(container)
+ && (container == w || !renderRule(container, opt).hasBackground())) {
+ //we do not have a background, but we disabled the autofillbackground anyway. so fill the background now.
+ // (this may happen if we have rules like :focus)
+ p->fillRect(opt->rect, opt->palette.brush(w->backgroundRole()));
+ }
+ break;
+ }
+#ifndef QT_NO_SCROLLAREA
+ if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w)) {
+ const QAbstractScrollAreaPrivate *sap = sa->d_func();
+ rule.drawBackground(p, opt->rect, sap->contentsOffset());
+ if (rule.hasBorder()) {
+ QRect brect = rule.borderRect(opt->rect);
+ if (styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, opt, w)) {
+ QRect r = brect.adjusted(0, 0, sa->verticalScrollBar()->isVisible() ? -sa->verticalScrollBar()->width() : 0,
+ sa->horizontalScrollBar()->isVisible() ? -sa->horizontalScrollBar()->height() : 0);
+ brect = QStyle::visualRect(opt->direction, brect, r);
+ }
+ rule.drawBorder(p, brect);
+ }
+ break;
+ }
+#endif
+ //fall tghought
+ case PE_PanelMenu:
+ case PE_PanelStatusBar:
+ if(rule.hasDrawable()) {
+ rule.drawRule(p, opt->rect);
+ return;
+ }
+ break;
+
+ case PE_FrameMenu:
+ if (rule.hasDrawable()) {
+ // Drawn by PE_PanelMenu
+ return;
+ }
+ break;
+
+ case PE_PanelMenuBar:
+ if (rule.hasDrawable()) {
+ // Drawn by PE_Widget
+ return;
+ }
+ break;
+
+ case PE_IndicatorToolBarSeparator:
+ case PE_IndicatorToolBarHandle: {
+ PseudoElement ps = pe == PE_IndicatorToolBarHandle ? PseudoElement_ToolBarHandle : PseudoElement_ToolBarSeparator;
+ QRenderRule subRule = renderRule(w, opt, ps);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ return;
+ }
+ }
+ break;
+
+ case PE_IndicatorMenuCheckMark:
+ pseudoElement = PseudoElement_MenuCheckMark;
+ break;
+
+ case PE_IndicatorArrowLeft:
+ pseudoElement = PseudoElement_LeftArrow;
+ break;
+
+ case PE_IndicatorArrowRight:
+ pseudoElement = PseudoElement_RightArrow;
+ break;
+
+ case PE_IndicatorColumnViewArrow:
+ if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
+ bool reverse = (viewOpt->direction == Qt::RightToLeft);
+ pseudoElement = reverse ? PseudoElement_LeftArrow : PseudoElement_RightArrow;
+ } else {
+ pseudoElement = PseudoElement_RightArrow;
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ if (const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch);
+ if (subRule.hasDrawable()) {
+ if ((v2->state & QStyle::State_Selected) && v2->showDecorationSelected)
+ p->fillRect(v2->rect, v2->palette.highlight());
+ else if (v2->features & QStyleOptionViewItemV2::Alternate)
+ p->fillRect(v2->rect, v2->palette.alternateBase());
+ subRule.drawRule(p, opt->rect);
+ } else {
+ baseStyle()->drawPrimitive(pe, v2, p, w);
+ }
+ }
+ return;
+
+ case PE_PanelTipLabel:
+ if (!rule.hasDrawable())
+ break;
+
+ if (const QStyleOptionFrame *frmOpt = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (rule.hasNativeBorder()) {
+ rule.drawBackground(p, opt->rect);
+ QStyleOptionFrame optCopy(*frmOpt);
+ optCopy.rect = rule.borderRect(opt->rect);
+ optCopy.palette.setBrush(QPalette::Window, Qt::NoBrush); // oh dear
+ baseStyle()->drawPrimitive(pe, &optCopy, p, w);
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+ }
+ return;
+
+ case PE_FrameGroupBox:
+ if (rule.hasNativeBorder())
+ break;
+ rule.drawBorder(p, opt->rect);
+ return;
+
+#ifndef QT_NO_TABWIDGET
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *frm = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabWidgetPane);
+ if (subRule.hasNativeBorder()) {
+ subRule.drawBackground(p, opt->rect);
+ QStyleOptionTabWidgetFrameV2 frmCopy(*frm);
+ subRule.configurePalette(&frmCopy.palette, QPalette::WindowText, QPalette::Window);
+ baseStyle()->drawPrimitive(pe, &frmCopy, p, w);
+ } else {
+ subRule.drawRule(p, opt->rect);
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_TABWIDGET
+
+ case PE_IndicatorProgressChunk:
+ pseudoElement = PseudoElement_ProgressBarChunk;
+ break;
+
+ case PE_IndicatorTabTear:
+ pseudoElement = PseudoElement_TabBarTear;
+ break;
+
+ case PE_FrameFocusRect:
+ if (!rule.hasNativeOutline()) {
+ rule.drawOutline(p, opt->rect);
+ return;
+ }
+ break;
+
+ case PE_IndicatorDockWidgetResizeHandle:
+ pseudoElement = PseudoElement_DockWidgetSeparator;
+ break;
+
+ case PE_PanelItemViewItem:
+ pseudoElement = PseudoElement_ViewItem;
+ break;
+
+ case PE_PanelScrollAreaCorner:
+ pseudoElement = PseudoElement_ScrollAreaCorner;
+ break;
+
+ case PE_IndicatorSpinDown:
+ case PE_IndicatorSpinMinus:
+ pseudoElement = PseudoElement_SpinBoxDownArrow;
+ break;
+
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinPlus:
+ pseudoElement = PseudoElement_SpinBoxUpArrow;
+ break;
+#ifndef QT_NO_TABBAR
+ case PE_IndicatorTabClose:
+ if (w)
+ w = w->parentWidget(); //match on the QTabBar instead of the CloseButton
+ pseudoElement = PseudoElement_TabBarTabCloseButton;
+#endif
+
+ default:
+ break;
+ }
+
+ if (pseudoElement != PseudoElement_None) {
+ QRenderRule subRule = renderRule(w, opt, pseudoElement);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, rect);
+ } else {
+ baseStyle()->drawPrimitive(pe, opt, p, w);
+ }
+ } else {
+ baseStyle()->drawPrimitive(pe, opt, p, w);
+ }
+}
+
+QPixmap QStyleSheetStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap,
+ const QStyleOption *option) const
+{
+ return baseStyle()->generatedIconPixmap(iconMode, pixmap, option);
+}
+
+QStyle::SubControl QStyleSheetStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->hitTestComplexControl(cc, opt, pt, w))
+ switch (cc) {
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRenderRule rule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (rule.hasDrawable() || rule.hasBox() || rule.hasBorder()) {
+ QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
+ QRect r;
+ QStyle::SubControl sc = QStyle::SC_None;
+ uint ctrl = SC_TitleBarSysMenu;
+ while (ctrl <= SC_TitleBarLabel) {
+ r = layout[QStyle::SubControl(ctrl)];
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ return sc;
+ }
+ }
+ break;
+
+ case CC_MdiControls:
+ if (hasStyleRule(w, PseudoElement_MdiCloseButton)
+ || hasStyleRule(w, PseudoElement_MdiNormalButton)
+ || hasStyleRule(w, PseudoElement_MdiMinButton))
+ return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
+ break;
+
+ case CC_ScrollBar: {
+ QRenderRule rule = renderRule(w, opt);
+ if (!rule.hasDrawable() && !rule.hasBox())
+ break;
+ }
+ // intentionally falls through
+ case CC_SpinBox:
+ case CC_GroupBox:
+ case CC_ComboBox:
+ case CC_Slider:
+ case CC_ToolButton:
+ return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
+ default:
+ break;
+ }
+
+ return baseStyle()->hitTestComplexControl(cc, opt, pt, w);
+}
+
+QRect QStyleSheetStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const
+{
+ return baseStyle()->itemPixmapRect(rect, alignment, pixmap);
+}
+
+QRect QStyleSheetStyle::itemTextRect(const QFontMetrics &metrics, const QRect& rect, int alignment,
+ bool enabled, const QString& text) const
+{
+ return baseStyle()->itemTextRect(metrics, rect, alignment, enabled, text);
+}
+
+int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->pixelMetric(m, opt, w))
+
+ QRenderRule rule = renderRule(w, opt);
+ QRenderRule subRule;
+
+ switch (m) {
+ case PM_MenuButtonIndicator:
+#ifndef QT_NO_TOOLBUTTON
+ // QToolButton adds this directly to the width
+ if (qobject_cast<const QToolButton *>(w) && (rule.hasBox() || !rule.hasNativeBorder()))
+ return 0;
+#endif
+ subRule = renderRule(w, opt, PseudoElement_PushButtonMenuIndicator);
+ if (subRule.hasContentsSize())
+ return subRule.size().width();
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ case PM_ButtonMargin:
+ case PM_ButtonDefaultIndicator:
+ if (rule.hasBox())
+ return 0;
+ break;
+
+ case PM_DefaultFrameWidth:
+ if (!rule.hasNativeBorder())
+ return rule.border()->borders[LeftEdge];
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_IndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ case PM_IndicatorHeight:
+ subRule = renderRule(w, opt, PseudoElement_Indicator);
+ if (subRule.hasContentsSize()) {
+ return (m == PM_ExclusiveIndicatorWidth) || (m == PM_IndicatorWidth)
+ ? subRule.size().width() : subRule.size().height();
+ }
+ break;
+
+ case PM_DockWidgetFrameWidth:
+ case PM_ToolTipLabelFrameWidth: // border + margin + padding (support only one width)
+ if (!rule.hasDrawable())
+ break;
+
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->margins[LeftEdge] + rule.box()->paddings[LeftEdge]: 0);
+
+ case PM_ToolBarFrameWidth:
+ if (rule.hasBorder() || rule.hasBox())
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->paddings[LeftEdge]: 0);
+ break;
+
+ case PM_MenuPanelWidth:
+ case PM_MenuBarPanelWidth:
+ if (rule.hasBorder() || rule.hasBox())
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->margins[LeftEdge]: 0);
+ break;
+
+
+ case PM_MenuHMargin:
+ case PM_MenuBarHMargin:
+ if (rule.hasBox())
+ return rule.box()->paddings[LeftEdge];
+ break;
+
+ case PM_MenuVMargin:
+ case PM_MenuBarVMargin:
+ if (rule.hasBox())
+ return rule.box()->paddings[TopEdge];
+ break;
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ case PM_ToolBarItemMargin:
+ if (rule.hasBox())
+ return rule.box()->margins[TopEdge];
+ break;
+
+ case PM_ToolBarItemSpacing:
+ case PM_MenuBarItemSpacing:
+ if (rule.hasBox() && rule.box()->spacing != -1)
+ return rule.box()->spacing;
+ break;
+
+ case PM_MenuTearoffHeight:
+ case PM_MenuScrollerHeight: {
+ PseudoElement ps = m == PM_MenuTearoffHeight ? PseudoElement_MenuTearoff : PseudoElement_MenuScroller;
+ subRule = renderRule(w, opt, ps);
+ if (subRule.hasContentsSize())
+ return subRule.size().height();
+ break;
+ }
+
+ case PM_ToolBarExtensionExtent:
+ break;
+
+ case PM_SplitterWidth:
+ case PM_ToolBarSeparatorExtent:
+ case PM_ToolBarHandleExtent: {
+ PseudoElement ps;
+ if (m == PM_ToolBarHandleExtent) ps = PseudoElement_ToolBarHandle;
+ else if (m == PM_SplitterWidth) ps = PseudoElement_SplitterHandle;
+ else ps = PseudoElement_ToolBarSeparator;
+ subRule = renderRule(w, opt, ps);
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ return (opt && opt->state & QStyle::State_Horizontal) ? sz.width() : sz.height();
+ }
+ break;
+ }
+
+ case PM_RadioButtonLabelSpacing:
+ if (rule.hasBox() && rule.box()->spacing != -1)
+ return rule.box()->spacing;
+ break;
+ case PM_CheckBoxLabelSpacing:
+ if (qobject_cast<const QCheckBox *>(w)) {
+ if (rule.hasBox() && rule.box()->spacing != -1)
+ return rule.box()->spacing;
+ }
+ // assume group box
+ subRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
+ if (subRule.hasBox() && subRule.box()->spacing != -1)
+ return subRule.box()->spacing;
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case PM_ScrollBarExtent:
+ if (rule.hasContentsSize()) {
+ QSize sz = rule.size();
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+ return sb->orientation == Qt::Horizontal ? sz.height() : sz.width();
+ return sz.width() == -1 ? sz.height() : sz.width();
+ }
+ break;
+
+ case PM_ScrollBarSliderMin:
+ if (hasStyleRule(w, PseudoElement_ScrollBarSlider)) {
+ subRule = renderRule(w, opt, PseudoElement_ScrollBarSlider);
+ QSize msz = subRule.minimumSize();
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+ return sb->orientation == Qt::Horizontal ? msz.width() : msz.height();
+ return msz.width() == -1 ? msz.height() : msz.width();
+ }
+ break;
+
+ case PM_ScrollView_ScrollBarSpacing:
+ if(!rule.hasNativeBorder() || rule.hasBox())
+ return 0;
+ break;
+#endif // QT_NO_SCROLLBAR
+
+ case PM_ProgressBarChunkWidth:
+ subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ return (opt->state & QStyle::State_Horizontal)
+ ? sz.width() : sz.height();
+ }
+ break;
+
+#ifndef QT_NO_TABWIDGET
+ case PM_TabBarTabHSpace:
+ case PM_TabBarTabVSpace:
+ subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox() || subRule.hasBorder())
+ return 0;
+ break;
+
+ case PM_TabBarScrollButtonWidth: {
+ subRule = renderRule(w, opt, PseudoElement_TabBarScroller);
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ return sz.width() != -1 ? sz.width() : sz.height();
+ }
+ }
+ break;
+
+ case PM_TabBarTabShiftHorizontal:
+ case PM_TabBarTabShiftVertical:
+ subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox())
+ return 0;
+ break;
+
+ case PM_TabBarBaseOverlap: {
+ const QWidget *tabWidget = qobject_cast<const QTabWidget *>(w) ? w : w->parentWidget();
+ if (hasStyleRule(tabWidget, PseudoElement_TabWidgetPane)) {
+ return 0;
+ }
+ break;
+ }
+#endif // QT_NO_TABWIDGET
+
+ case PM_SliderThickness: // horizontal slider's height (sizeHint)
+ case PM_SliderLength: // minimum length of slider
+ if (rule.hasContentsSize()) {
+ bool horizontal = opt->state & QStyle::State_Horizontal;
+ if (m == PM_SliderThickness) {
+ QSize sz = rule.size();
+ return horizontal ? sz.height() : sz.width();
+ } else {
+ QSize msz = rule.minimumContentsSize();
+ return horizontal ? msz.width() : msz.height();
+ }
+ }
+ break;
+
+ case PM_SliderControlThickness: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderHandle);
+ if (!subRule.hasContentsSize())
+ break;
+ QSize size = subRule.size();
+ return (opt->state & QStyle::State_Horizontal) ? size.height() : size.width();
+ }
+
+ case PM_ToolBarIconSize:
+ case PM_ListViewIconSize:
+ case PM_IconViewIconSize:
+ case PM_TabBarIconSize:
+ case PM_MessageBoxIconSize:
+ case PM_ButtonIconSize:
+ case PM_SmallIconSize:
+ if (rule.hasStyleHint(QLatin1String("icon-size"))) {
+ return rule.styleHint(QLatin1String("icon-size")).toSize().width();
+ }
+ break;
+
+ case PM_DockWidgetTitleMargin: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
+ if (!subRule.hasBox())
+ break;
+ return (subRule.border() ? subRule.border()->borders[TopEdge] : 0)
+ + (subRule.hasBox() ? subRule.box()->margins[TopEdge] + subRule.box()->paddings[TopEdge]: 0);
+ }
+
+ case PM_DockWidgetSeparatorExtent: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetSeparator);
+ if (!subRule.hasContentsSize())
+ break;
+ QSize sz = subRule.size();
+ return qMax(sz.width(), sz.height());
+ }
+
+ case PM_TitleBarHeight: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (subRule.hasContentsSize())
+ return subRule.size().height();
+ else if (subRule.hasBox() || subRule.hasBorder()) {
+ QFontMetrics fm = opt ? opt->fontMetrics : w->fontMetrics();
+ return subRule.size(QSize(0, fm.height())).height();
+ }
+ break;
+ }
+
+ case PM_MdiSubWindowFrameWidth:
+ if (rule.hasBox() || rule.hasBorder()) {
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->paddings[LeftEdge]+rule.box()->margins[LeftEdge]: 0);
+ }
+ break;
+
+ case PM_MdiSubWindowMinimizedWidth: {
+ QRenderRule subRule = renderRule(w, PseudoElement_None, PseudoClass_Minimized);
+ int width = subRule.size().width();
+ if (width != -1)
+ return width;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return baseStyle()->pixelMetric(m, opt, w);
+}
+
+QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->sizeFromContents(ct, opt, csz, w))
+
+ QRenderRule rule = renderRule(w, opt);
+ QSize sz = rule.adjustSize(csz);
+
+ switch (ct) {
+ case CT_SpinBox: // ### hopelessly broken QAbstractSpinBox (part 1)
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ return csz;
+ return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ case CT_ToolButton:
+ if (rule.hasBox() || !rule.hasNativeBorder() || !rule.baseStyleCanDraw())
+ sz += QSize(3, 3); // ### broken QToolButton
+ //fall thought
+ case CT_ComboBox:
+ case CT_PushButton:
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ if(ct == CT_ComboBox) {
+ //add some space for the drop down.
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ QRect comboRect = positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown, opt->rect, opt->direction);
+ //+2 because there is hardcoded margins in QCommonStyle::drawControl(CE_ComboBoxLabel)
+ sz += QSize(comboRect.width() + 2, 0);
+ }
+ return rule.boxSize(sz);
+ }
+ sz = rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ return rule.boxSize(sz, Margin);
+
+ case CT_HeaderSection: {
+ if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder()) {
+ sz = subRule.adjustSize(csz);
+ if (!subRule.hasGeometry()) {
+ QSize nativeContentsSize;
+ bool nullIcon = hdr->icon.isNull();
+ int iconSize = nullIcon ? 0 : pixelMetric(QStyle::PM_SmallIconSize, hdr, w);
+ QSize txt = hdr->fontMetrics.size(0, hdr->text);
+ nativeContentsSize.setHeight(qMax(iconSize, txt.height()));
+ nativeContentsSize.setWidth(iconSize + txt.width());
+ sz = sz.expandedTo(nativeContentsSize);
+ }
+ return subRule.size(sz);
+ }
+ return subRule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ }
+ }
+ break;
+ case CT_GroupBox:
+ case CT_LineEdit:
+#ifndef QT_NO_SPINBOX
+ // ### hopelessly broken QAbstractSpinBox (part 2)
+ if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(w ? w->parentWidget() : 0)) {
+ QRenderRule rule = renderRule(spinBox, opt);
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ return csz;
+ return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ }
+#endif
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ return rule.boxSize(sz);
+ }
+ break;
+
+ case CT_CheckBox:
+ case CT_RadioButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ bool isRadio = (ct == CT_RadioButton);
+ int iw = pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth
+ : PM_IndicatorWidth, btn, w);
+ int ih = pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
+ : PM_IndicatorHeight, btn, w);
+
+ int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
+ : PM_CheckBoxLabelSpacing, btn, w);
+ sz.setWidth(sz.width() + iw + spacing);
+ sz.setHeight(qMax(sz.height(), ih));
+ return rule.boxSize(sz);
+ }
+ }
+ break;
+
+ case CT_Menu:
+ case CT_MenuBar: // already has everything!
+ case CT_ScrollBar:
+ if (rule.hasBox() || rule.hasBorder())
+ return sz;
+ break;
+
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ PseudoElement pe = (mi->menuItemType == QStyleOptionMenuItem::Separator)
+ ? PseudoElement_MenuSeparator : PseudoElement_Item;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ if ((pe == PseudoElement_MenuSeparator) && subRule.hasContentsSize()) {
+ return QSize(sz.width(), subRule.size().height());
+ } else if ((pe == PseudoElement_Item) && (subRule.hasBox() || subRule.hasBorder())) {
+ int width = csz.width();
+ if (mi->text.contains(QLatin1Char('\t')))
+ width += 12; //as in QCommonStyle
+ return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height())));
+ }
+ }
+ break;
+
+ case CT_Splitter:
+ case CT_MenuBarItem: {
+ PseudoElement pe = (ct == CT_Splitter) ? PseudoElement_SplitterHandle : PseudoElement_Item;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ if (subRule.hasBox() || subRule.hasBorder())
+ return subRule.boxSize(sz);
+ break;
+ }
+
+ case CT_ProgressBar:
+ case CT_SizeGrip:
+ return (rule.hasContentsSize())
+ ? rule.size(sz)
+ : rule.boxSize(baseStyle()->sizeFromContents(ct, opt, sz, w));
+ break;
+
+ case CT_Slider:
+ if (rule.hasBorder() || rule.hasBox() || rule.hasGeometry())
+ return rule.boxSize(sz);
+ break;
+
+#ifndef QT_NO_TABBAR
+ case CT_TabBarTab: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ int spaceForIcon = 0;
+ bool vertical = false;
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ if (!tab->icon.isNull())
+ spaceForIcon = 6 /* icon offset */ + 4 /* spacing */ + 2 /* magic */; // ###: hardcoded to match with common style
+ vertical = verticalTabs(tab->shape);
+ }
+ sz = csz + QSize(vertical ? 0 : spaceForIcon, vertical ? spaceForIcon : 0);
+ return subRule.boxSize(subRule.adjustSize(sz));
+ }
+#ifdef Q_WS_MAC
+ if (baseStyle()->inherits("QMacStyle")) {
+ //adjust the size after the call to the style because the mac style ignore the size arguments anyway.
+ //this might cause the (max-){width,height} property to include the native style border while they should not.
+ return subRule.adjustSize(baseStyle()->sizeFromContents(ct, opt, csz, w));
+ }
+#endif
+ sz = subRule.adjustSize(csz);
+ break;
+ }
+#endif // QT_NO_TABBAR
+
+ case CT_MdiControls:
+ if (const QStyleOptionComplex *ccOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
+ if (!hasStyleRule(w, PseudoElement_MdiCloseButton)
+ && !hasStyleRule(w, PseudoElement_MdiNormalButton)
+ && !hasStyleRule(w, PseudoElement_MdiMinButton))
+ break;
+
+ QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("mNX"));
+
+ int width = 0, height = 0;
+ for (int i = 0; i < layout.count(); i++) {
+ int layoutButton = layout[i].toInt();
+ if (layoutButton < PseudoElement_MdiCloseButton
+ || layoutButton > PseudoElement_MdiNormalButton)
+ continue;
+ QStyle::SubControl sc = knownPseudoElements[layoutButton].subControl;
+ if (!(ccOpt->subControls & sc))
+ continue;
+ QRenderRule subRule = renderRule(w, opt, layoutButton);
+ QSize sz = subRule.size();
+ width += sz.width();
+ height = qMax(height, sz.height());
+ }
+
+ return QSize(width, height);
+ }
+ break;
+
+#ifndef QT_NO_ITEMVIEWS
+ case CT_ItemViewItem: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
+ sz = baseStyle()->sizeFromContents(ct, opt, csz, w);
+ sz = subRule.adjustSize(sz);
+ if (subRule.hasBox() || subRule.hasBorder())
+ sz = subRule.boxSize(sz);
+ return sz;
+ }
+#endif // QT_NO_ITEMVIEWS
+
+ default:
+ break;
+ }
+
+ return baseStyle()->sizeFromContents(ct, opt, sz, w);
+}
+
+/*!
+ \internal
+*/
+static QLatin1String propertyNameForStandardPixmap(QStyle::StandardPixmap sp)
+{
+ switch (sp) {
+ case QStyle::SP_TitleBarMenuButton: return QLatin1String("titlebar-menu-icon");
+ case QStyle::SP_TitleBarMinButton: return QLatin1String("titlebar-minimize-icon");
+ case QStyle::SP_TitleBarMaxButton: return QLatin1String("titlebar-maximize-icon");
+ case QStyle::SP_TitleBarCloseButton: return QLatin1String("titlebar-close-icon");
+ case QStyle::SP_TitleBarNormalButton: return QLatin1String("titlebar-normal-icon");
+ case QStyle::SP_TitleBarShadeButton: return QLatin1String("titlebar-shade-icon");
+ case QStyle::SP_TitleBarUnshadeButton: return QLatin1String("titlebar-unshade-icon");
+ case QStyle::SP_TitleBarContextHelpButton: return QLatin1String("titlebar-contexthelp-icon");
+ case QStyle::SP_DockWidgetCloseButton: return QLatin1String("dockwidget-close-icon");
+ case QStyle::SP_MessageBoxInformation: return QLatin1String("messagebox-information-icon");
+ case QStyle::SP_MessageBoxWarning: return QLatin1String("messagebox-warning-icon");
+ case QStyle::SP_MessageBoxCritical: return QLatin1String("messagebox-critical-icon");
+ case QStyle::SP_MessageBoxQuestion: return QLatin1String("messagebox-question-icon");
+ case QStyle::SP_DesktopIcon: return QLatin1String("desktop-icon");
+ case QStyle::SP_TrashIcon: return QLatin1String("trash-icon");
+ case QStyle::SP_ComputerIcon: return QLatin1String("computer-icon");
+ case QStyle::SP_DriveFDIcon: return QLatin1String("floppy-icon");
+ case QStyle::SP_DriveHDIcon: return QLatin1String("harddisk-icon");
+ case QStyle::SP_DriveCDIcon: return QLatin1String("cd-icon");
+ case QStyle::SP_DriveDVDIcon: return QLatin1String("dvd-icon");
+ case QStyle::SP_DriveNetIcon: return QLatin1String("network-icon");
+ case QStyle::SP_DirOpenIcon: return QLatin1String("directory-open-icon");
+ case QStyle::SP_DirClosedIcon: return QLatin1String("directory-closed-icon");
+ case QStyle::SP_DirLinkIcon: return QLatin1String("directory-link-icon");
+ case QStyle::SP_FileIcon: return QLatin1String("file-icon");
+ case QStyle::SP_FileLinkIcon: return QLatin1String("file-link-icon");
+ case QStyle::SP_FileDialogStart: return QLatin1String("filedialog-start-icon");
+ case QStyle::SP_FileDialogEnd: return QLatin1String("filedialog-end-icon");
+ case QStyle::SP_FileDialogToParent: return QLatin1String("filedialog-parent-directory-icon");
+ case QStyle::SP_FileDialogNewFolder: return QLatin1String("filedialog-new-directory-icon");
+ case QStyle::SP_FileDialogDetailedView: return QLatin1String("filedialog-detailedview-icon");
+ case QStyle::SP_FileDialogInfoView: return QLatin1String("filedialog-infoview-icon");
+ case QStyle::SP_FileDialogContentsView: return QLatin1String("filedialog-contentsview-icon");
+ case QStyle::SP_FileDialogListView: return QLatin1String("filedialog-listview-icon");
+ case QStyle::SP_FileDialogBack: return QLatin1String("filedialog-backward-icon");
+ case QStyle::SP_DirIcon: return QLatin1String("directory-icon");
+ case QStyle::SP_DialogOkButton: return QLatin1String("dialog-ok-icon");
+ case QStyle::SP_DialogCancelButton: return QLatin1String("dialog-cancel-icon");
+ case QStyle::SP_DialogHelpButton: return QLatin1String("dialog-help-icon");
+ case QStyle::SP_DialogOpenButton: return QLatin1String("dialog-open-icon");
+ case QStyle::SP_DialogSaveButton: return QLatin1String("dialog-save-icon");
+ case QStyle::SP_DialogCloseButton: return QLatin1String("dialog-close-icon");
+ case QStyle::SP_DialogApplyButton: return QLatin1String("dialog-apply-icon");
+ case QStyle::SP_DialogResetButton: return QLatin1String("dialog-reset-icon");
+ case QStyle::SP_DialogDiscardButton: return QLatin1String("discard-icon");
+ case QStyle::SP_DialogYesButton: return QLatin1String("dialog-yes-icon");
+ case QStyle::SP_DialogNoButton: return QLatin1String("dialog-no-icon");
+ case QStyle::SP_ArrowUp: return QLatin1String("uparrow-icon");
+ case QStyle::SP_ArrowDown: return QLatin1String("downarrow-icon");
+ case QStyle::SP_ArrowLeft: return QLatin1String("leftarrow-icon");
+ case QStyle::SP_ArrowRight: return QLatin1String("rightarrow-icon");
+ case QStyle::SP_ArrowBack: return QLatin1String("backward-icon");
+ case QStyle::SP_ArrowForward: return QLatin1String("forward-icon");
+ case QStyle::SP_DirHomeIcon: return QLatin1String("home-icon");
+ default: return QLatin1String("");
+ }
+}
+
+QIcon QStyleSheetStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->standardIcon(standardIcon, opt, w))
+ QString s = propertyNameForStandardPixmap(standardIcon);
+ if (!s.isEmpty()) {
+ QRenderRule rule = renderRule(w, opt);
+ if (rule.hasStyleHint(s))
+ return qvariant_cast<QIcon>(rule.styleHint(s));
+ }
+ return baseStyle()->standardIcon(standardIcon, opt, w);
+}
+
+QPalette QStyleSheetStyle::standardPalette() const
+{
+ return baseStyle()->standardPalette();
+}
+
+QPixmap QStyleSheetStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->standardPixmap(standardPixmap, opt, w))
+ QString s = propertyNameForStandardPixmap(standardPixmap);
+ if (!s.isEmpty()) {
+ QRenderRule rule = renderRule(w, opt);
+ if (rule.hasStyleHint(s)) {
+ QIcon icon = qvariant_cast<QIcon>(rule.styleHint(s));
+ return icon.pixmap(16, 16); // ###: unhard-code this if someone complains
+ }
+ }
+ return baseStyle()->standardPixmap(standardPixmap, opt, w);
+}
+
+int QStyleSheetStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ return baseStyle()->layoutSpacing(control1, control2, orientation, option, widget);
+}
+
+int QStyleSheetStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1 ,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption * option ,
+ const QWidget * widget) const
+{
+ return baseStyle()->layoutSpacing(control1, control2, orientation, option, widget);
+}
+
+int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
+ QStyleHintReturn *shret) const
+{
+ RECURSION_GUARD(return baseStyle()->styleHint(sh, opt, w, shret))
+ // Prevent endless loop if somebody use isActiveWindow property as selector.
+ // QWidget::isActiveWindow uses this styleHint to determine if the window is active or not
+ if (sh == SH_Widget_ShareActivation)
+ return baseStyle()->styleHint(sh, opt, w, shret);
+
+ QRenderRule rule = renderRule(w, opt);
+ QString s;
+ switch (sh) {
+ case SH_LineEdit_PasswordCharacter: s = QLatin1String("lineedit-password-character"); break;
+ case SH_DitherDisabledText: s = QLatin1String("dither-disabled-text"); break;
+ case SH_EtchDisabledText: s = QLatin1String("etch-disabled-text"); break;
+ case SH_ItemView_ActivateItemOnSingleClick: s = QLatin1String("activate-on-singleclick"); break;
+ case SH_ItemView_ShowDecorationSelected: s = QLatin1String("show-decoration-selected"); break;
+ case SH_Table_GridLineColor: s = QLatin1String("gridline-color"); break;
+ case SH_DialogButtonLayout: s = QLatin1String("button-layout"); break;
+ case SH_ToolTipLabel_Opacity: s = QLatin1String("opacity"); break;
+ case SH_ComboBox_Popup: s = QLatin1String("combobox-popup"); break;
+ case SH_ComboBox_ListMouseTracking: s = QLatin1String("combobox-list-mousetracking"); break;
+ case SH_MenuBar_AltKeyNavigation: s = QLatin1String("menubar-altkey-navigation"); break;
+ case SH_Menu_Scrollable: s = QLatin1String("menu-scrollable"); break;
+ case SH_DrawMenuBarSeparator: s = QLatin1String("menubar-separator"); break;
+ case SH_MenuBar_MouseTracking: s = QLatin1String("mouse-tracking"); break;
+ case SH_SpinBox_ClickAutoRepeatRate: s = QLatin1String("spinbox-click-autorepeat-rate"); break;
+ case SH_SpinControls_DisableOnBounds: s = QLatin1String("spincontrol-disable-on-bounds"); break;
+ case SH_MessageBox_TextInteractionFlags: s = QLatin1String("messagebox-text-interaction-flags"); break;
+ case SH_ToolButton_PopupDelay: s = QLatin1String("toolbutton-popup-delay"); break;
+ case SH_ToolBox_SelectedPageTitleBold:
+ if (renderRule(w, opt, PseudoElement_ToolBoxTab).hasFont)
+ return 0;
+ break;
+ case SH_GroupBox_TextLabelColor:
+ if (rule.hasPalette() && rule.palette()->foreground.style() != Qt::NoBrush)
+ return rule.palette()->foreground.color().rgba();
+ break;
+ case SH_ScrollView_FrameOnlyAroundContents: s = QLatin1String("scrollview-frame-around-contents"); break;
+ case SH_ScrollBar_ContextMenu: s = QLatin1String("scrollbar-contextmenu"); break;
+ case SH_ScrollBar_LeftClickAbsolutePosition: s = QLatin1String("scrollbar-leftclick-absolute-position"); break;
+ case SH_ScrollBar_MiddleClickAbsolutePosition: s = QLatin1String("scrollbar-middleclick-absolute-position"); break;
+ case SH_ScrollBar_RollBetweenButtons: s = QLatin1String("scrollbar-roll-between-buttons"); break;
+ case SH_ScrollBar_ScrollWhenPointerLeavesControl: s = QLatin1String("scrollbar-scroll-when-pointer-leaves-control"); break;
+ case SH_TabBar_Alignment:
+#ifndef QT_NO_TABWIDGET
+ if (qobject_cast<const QTabWidget *>(w)) {
+ rule = renderRule(w, opt, PseudoElement_TabWidgetTabBar);
+ if (rule.hasPosition())
+ return rule.position()->position;
+ }
+#endif // QT_NO_TABWIDGET
+ s = QLatin1String("alignment");
+ break;
+#ifndef QT_NO_TABBAR
+ case SH_TabBar_CloseButtonPosition:
+ rule = renderRule(w, opt, PseudoElement_TabBarTabCloseButton);
+ if (rule.hasPosition()) {
+ Qt::Alignment align = rule.position()->position;
+ if (align & Qt::AlignLeft || align & Qt::AlignTop)
+ return QTabBar::LeftSide;
+ if (align & Qt::AlignRight || align & Qt::AlignBottom)
+ return QTabBar::RightSide;
+ }
+ break;
+#endif
+ case SH_TabBar_ElideMode: s = QLatin1String("tabbar-elide-mode"); break;
+ case SH_TabBar_PreferNoArrows: s = QLatin1String("tabbar-prefer-no-arrows"); break;
+ case SH_ComboBox_PopupFrameStyle:
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox *>(w)) {
+ QAbstractItemView *view = w->findChild<QAbstractItemView *>();
+ if (view) {
+ view->ensurePolished();
+ QRenderRule subRule = renderRule(view, PseudoElement_None);
+ if (subRule.hasBox() || !subRule.hasNativeBorder())
+ return QFrame::NoFrame;
+ }
+ }
+#endif // QT_NO_COMBOBOX
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons: s = QLatin1String("dialogbuttonbox-buttons-have-icons"); break;
+ case SH_Workspace_FillSpaceOnMaximize: s = QLatin1String("mdi-fill-space-on-maximize"); break;
+ case SH_TitleBar_NoBorder:
+ if (rule.hasBorder())
+ return !rule.border()->borders[LeftEdge];
+ break;
+ case SH_TitleBar_AutoRaise: { // plain absurd
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (subRule.hasDrawable())
+ return 1;
+ break;
+ }
+ case SH_ItemView_ArrowKeysNavigateIntoChildren: s = QLatin1String("arrow-keys-navigate-into-children"); break;
+ case SH_ItemView_PaintAlternatingRowColorsForEmptyArea: s = QLatin1String("paint-alternating-row-colors-for-empty-area"); break;
+ default: break;
+ }
+ if (!s.isEmpty() && rule.hasStyleHint(s)) {
+ return rule.styleHint(s).toInt();
+ }
+
+ return baseStyle()->styleHint(sh, opt, w, shret);
+}
+
+QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->subControlRect(cc, opt, sc, w))
+
+ QRenderRule rule = renderRule(w, opt);
+ switch (cc) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ switch (sc) {
+ case SC_ComboBoxFrame: return rule.borderRect(opt->rect);
+ case SC_ComboBoxEditField:
+ {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ QRect r = rule.contentsRect(opt->rect);
+ QRect r2 = positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown,
+ opt->rect, opt->direction);
+ if (subRule.hasPosition() && subRule.position()->position & Qt::AlignLeft) {
+ return visualRect(opt->direction, r, r.adjusted(r2.width(),0,0,0));
+ } else {
+ return visualRect(opt->direction, r, r.adjusted(0,0,-r2.width(),0));
+ }
+ }
+ case SC_ComboBoxArrow: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ return positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown, opt->rect, opt->direction);
+ }
+ case SC_ComboBoxListBoxPopup:
+ default:
+ return baseStyle()->subControlRect(cc, opt, sc, w);
+ }
+ }
+
+ QStyleOptionComboBox comboBox(*cb);
+ comboBox.rect = rule.borderRect(opt->rect);
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &comboBox, sc, w)
+ : QWindowsStyle::subControlRect(cc, &comboBox, sc, w);
+ }
+ break;
+
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QRenderRule upRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ QRenderRule downRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
+ bool ruleMatch = rule.hasBox() || !rule.hasNativeBorder();
+ bool upRuleMatch = upRule.hasGeometry() || upRule.hasPosition();
+ bool downRuleMatch = downRule.hasGeometry() || upRule.hasPosition();
+ if (ruleMatch || upRuleMatch || downRuleMatch) {
+ switch (sc) {
+ case SC_SpinBoxFrame:
+ return rule.borderRect(opt->rect);
+ case SC_SpinBoxEditField:
+ {
+ QRect r = rule.contentsRect(opt->rect);
+ // Use the widest button on each side to determine edit field size.
+ Qt::Alignment upAlign, downAlign;
+
+ upAlign = upRule.hasPosition() ? upRule.position()->position
+ : Qt::Alignment(Qt::AlignRight);
+ upAlign = resolveAlignment(opt->direction, upAlign);
+
+ downAlign = downRule.hasPosition() ? downRule.position()->position
+ : Qt::Alignment(Qt::AlignRight);
+ downAlign = resolveAlignment(opt->direction, downAlign);
+
+ int upSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width();
+ int downSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width();
+ int widestL = qMax((upAlign & Qt::AlignLeft) ? upSize : 0,
+ (downAlign & Qt::AlignLeft) ? downSize : 0);
+ int widestR = qMax((upAlign & Qt::AlignRight) ? upSize : 0,
+ (downAlign & Qt::AlignRight) ? downSize : 0);
+ r.setRight(r.right() - widestR);
+ r.setLeft(r.left() + widestL);
+ return r;
+ }
+ case SC_SpinBoxDown:
+ if (downRuleMatch)
+ return positionRect(w, rule, downRule, PseudoElement_SpinBoxDownButton,
+ opt->rect, opt->direction);
+ break;
+ case SC_SpinBoxUp:
+ if (upRuleMatch)
+ return positionRect(w, rule, upRule, PseudoElement_SpinBoxUpButton,
+ opt->rect, opt->direction);
+ break;
+ default:
+ break;
+ }
+
+ return baseStyle()->subControlRect(cc, opt, sc, w);
+ }
+
+ QStyleOptionSpinBox spinBox(*spin);
+ spinBox.rect = rule.borderRect(opt->rect);
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &spinBox, sc, w)
+ : QWindowsStyle::subControlRect(cc, &spinBox, sc, w);
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ switch (sc) {
+ case SC_GroupBoxFrame:
+ case SC_GroupBoxContents: {
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ return sc == SC_GroupBoxFrame ? rule.borderRect(opt->rect)
+ : rule.contentsRect(opt->rect);
+ }
+ QStyleOptionGroupBox groupBox(*gb);
+ groupBox.rect = rule.borderRect(opt->rect);
+ return baseStyle()->subControlRect(cc, &groupBox, sc, w);
+ }
+ default:
+ case SC_GroupBoxLabel:
+ case SC_GroupBoxCheckBox: {
+ QRenderRule indRule = renderRule(w, opt, PseudoElement_GroupBoxIndicator);
+ QRenderRule labelRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
+ if (!labelRule.hasPosition() && !labelRule.hasGeometry() && !labelRule.hasBox()
+ && !labelRule.hasBorder() && !indRule.hasContentsSize()) {
+ QStyleOptionGroupBox groupBox(*gb);
+ groupBox.rect = rule.borderRect(opt->rect);
+ return baseStyle()->subControlRect(cc, &groupBox, sc, w);
+ }
+ int tw = opt->fontMetrics.width(gb->text);
+ int th = opt->fontMetrics.height();
+ int spacing = pixelMetric(QStyle::PM_CheckBoxLabelSpacing, opt, w);
+ int iw = pixelMetric(QStyle::PM_IndicatorWidth, opt, w);
+ int ih = pixelMetric(QStyle::PM_IndicatorHeight, opt, w);
+
+ if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
+ tw = tw + iw + spacing;
+ th = qMax(th, ih);
+ }
+ if (!labelRule.hasGeometry()) {
+ labelRule.geo = new QStyleSheetGeometryData(tw, th, tw, th, -1, -1);
+ } else {
+ labelRule.geo->width = tw;
+ labelRule.geo->height = th;
+ }
+ if (!labelRule.hasPosition()) {
+ labelRule.p = new QStyleSheetPositionData(0, 0, 0, 0, defaultOrigin(PseudoElement_GroupBoxTitle),
+ gb->textAlignment, PositionMode_Static);
+ }
+ QRect r = positionRect(w, rule, labelRule, PseudoElement_GroupBoxTitle,
+ opt->rect, opt->direction);
+ if (gb->subControls & SC_GroupBoxCheckBox) {
+ r = labelRule.contentsRect(r);
+ if (sc == SC_GroupBoxLabel) {
+ r.setLeft(r.left() + iw + spacing);
+ r.setTop(r.center().y() - th/2);
+ } else {
+ r = QRect(r.left(), r.center().y() - ih/2, iw, ih);
+ }
+ return r;
+ } else {
+ return labelRule.contentsRect(r);
+ }
+ }
+ } // switch
+ }
+ break;
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ switch (sc) {
+ case SC_ToolButton: return rule.borderRect(opt->rect);
+ case SC_ToolButtonMenu: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
+ return positionRect(w, rule, subRule, PseudoElement_ToolButtonMenu, opt->rect, opt->direction);
+ }
+ default:
+ break;
+ }
+ }
+
+ QStyleOptionToolButton tool(*tb);
+ tool.rect = rule.borderRect(opt->rect);
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &tool, sc, w)
+ : QWindowsStyle::subControlRect(cc, &tool, sc, w);
+ }
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider styleOptionSlider(*sb);
+ styleOptionSlider.rect = rule.borderRect(opt->rect);
+ if (rule.hasDrawable() || rule.hasBox()) {
+ QRect grooveRect;
+ if (!rule.hasBox()) {
+ grooveRect = rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, sb, SC_ScrollBarGroove, w)
+ : QWindowsStyle::subControlRect(cc, sb, SC_ScrollBarGroove, w);
+ } else {
+ grooveRect = rule.contentsRect(opt->rect);
+ }
+
+ PseudoElement pe = PseudoElement_None;
+
+ switch (sc) {
+ case SC_ScrollBarGroove:
+ return grooveRect;
+ case SC_ScrollBarAddPage:
+ case SC_ScrollBarSubPage:
+ case SC_ScrollBarSlider: {
+ QRect contentRect = grooveRect;
+ if (hasStyleRule(w, PseudoElement_ScrollBarSlider)) {
+ QRenderRule sliderRule = renderRule(w, opt, PseudoElement_ScrollBarSlider);
+ Origin origin = sliderRule.hasPosition() ? sliderRule.position()->origin : defaultOrigin(PseudoElement_ScrollBarSlider);
+ contentRect = rule.originRect(opt->rect, origin);
+ }
+ int maxlen = (styleOptionSlider.orientation == Qt::Horizontal) ? contentRect.width() : contentRect.height();
+ int sliderlen;
+ if (sb->maximum != sb->minimum) {
+ uint range = sb->maximum - sb->minimum;
+ sliderlen = (qint64(sb->pageStep) * maxlen) / (range + sb->pageStep);
+
+ int slidermin = pixelMetric(PM_ScrollBarSliderMin, sb, w);
+ if (sliderlen < slidermin || range > INT_MAX / 2)
+ sliderlen = slidermin;
+ if (sliderlen > maxlen)
+ sliderlen = maxlen;
+ } else {
+ sliderlen = maxlen;
+ }
+
+ int sliderstart = (styleOptionSlider.orientation == Qt::Horizontal ? contentRect.left() : contentRect.top())
+ + sliderPositionFromValue(sb->minimum, sb->maximum, sb->sliderPosition,
+ maxlen - sliderlen, sb->upsideDown);
+
+ QRect sr = (sb->orientation == Qt::Horizontal)
+ ? QRect(sliderstart, contentRect.top(), sliderlen, contentRect.height())
+ : QRect(contentRect.left(), sliderstart, contentRect.width(), sliderlen);
+ if (sc == SC_ScrollBarSlider) {
+ return sr;
+ } else if (sc == SC_ScrollBarSubPage) {
+ return QRect(contentRect.topLeft(), sb->orientation == Qt::Horizontal ? sr.bottomLeft() : sr.topRight());
+ } else { // SC_ScrollBarAddPage
+ return QRect(sb->orientation == Qt::Horizontal ? sr.topRight() : sr.bottomLeft(), contentRect.bottomRight());
+ }
+ break;
+ }
+ case SC_ScrollBarAddLine: pe = PseudoElement_ScrollBarAddLine; break;
+ case SC_ScrollBarSubLine: pe = PseudoElement_ScrollBarSubLine; break;
+ case SC_ScrollBarFirst: pe = PseudoElement_ScrollBarFirst; break;
+ case SC_ScrollBarLast: pe = PseudoElement_ScrollBarLast; break;
+ default: break;
+ }
+ if (hasStyleRule(w,pe)) {
+ QRenderRule subRule = renderRule(w, opt, pe);
+ if (subRule.hasPosition() || subRule.hasGeometry() || subRule.hasBox()) {
+ const QStyleSheetPositionData *pos = subRule.position();
+ QRect originRect = grooveRect;
+ if (rule.hasBox()) {
+ Origin origin = (pos && pos->origin != Origin_Unknown) ? pos->origin : defaultOrigin(pe);
+ originRect = rule.originRect(opt->rect, origin);
+ }
+ return positionRect(w, subRule, pe, originRect, styleOptionSlider.direction);
+ }
+ }
+ }
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &styleOptionSlider, sc, w)
+ : QWindowsStyle::subControlRect(cc, &styleOptionSlider, sc, w);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderGroove);
+ if (!subRule.hasDrawable())
+ break;
+ subRule.img = 0;
+ QRect gr = positionRect(w, rule, subRule, PseudoElement_SliderGroove, opt->rect, opt->direction);
+ switch (sc) {
+ case SC_SliderGroove:
+ return gr;
+ case SC_SliderHandle: {
+ bool horizontal = slider->orientation & Qt::Horizontal;
+ QRect cr = subRule.contentsRect(gr);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderHandle);
+ int len = horizontal ? subRule2.size().width() : subRule2.size().height();
+ subRule2.img = 0;
+ subRule2.geo = 0;
+ cr = positionRect(w, subRule2, PseudoElement_SliderHandle, cr, opt->direction);
+ int thickness = horizontal ? cr.height() : cr.width();
+ int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
+ (horizontal ? cr.width() : cr.height()) - len, slider->upsideDown);
+ cr = horizontal ? QRect(cr.x() + sliderPos, cr.y(), len, thickness)
+ : QRect(cr.x(), cr.y() + sliderPos, thickness, len);
+ return subRule2.borderRect(cr);
+ break; }
+ case SC_SliderTickmarks:
+ // TODO...
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+ case CC_MdiControls:
+ if (hasStyleRule(w, PseudoElement_MdiCloseButton)
+ || hasStyleRule(w, PseudoElement_MdiNormalButton)
+ || hasStyleRule(w, PseudoElement_MdiMinButton)) {
+ QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("mNX"));
+
+ int x = 0, width = 0;
+ QRenderRule subRule;
+ for (int i = 0; i < layout.count(); i++) {
+ int layoutButton = layout[i].toInt();
+ if (layoutButton < PseudoElement_MdiCloseButton
+ || layoutButton > PseudoElement_MdiNormalButton)
+ continue;
+ QStyle::SubControl control = knownPseudoElements[layoutButton].subControl;
+ if (!(opt->subControls & control))
+ continue;
+ subRule = renderRule(w, opt, layoutButton);
+ width = subRule.size().width();
+ if (sc == control)
+ break;
+ x += width;
+ }
+
+ return subRule.borderRect(QRect(x, opt->rect.top(), width, opt->rect.height()));
+ }
+ break;
+
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (!subRule.hasDrawable() && !subRule.hasBox() && !subRule.hasBorder())
+ break;
+ QHash<QStyle::SubControl, QRect> layoutRects = titleBarLayout(w, tb);
+ return layoutRects.value(sc);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return baseStyle()->subControlRect(cc, opt, sc, w);
+}
+
+QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->subElementRect(se, opt, w))
+
+ QRenderRule rule = renderRule(w, opt);
+#ifndef QT_NO_TABBAR
+ int pe = PseudoElement_None;
+#endif
+
+ switch (se) {
+ case SE_PushButtonContents:
+ case SE_PushButtonFocusRect:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton btnOpt(*btn);
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
+ return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, &btnOpt, w)
+ : QWindowsStyle::subElementRect(se, &btnOpt, w);
+ }
+ break;
+
+ case SE_LineEditContents:
+ case SE_FrameContents:
+ case SE_ShapedFrameContents:
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
+ }
+ break;
+
+ case SE_CheckBoxIndicator:
+ case SE_RadioButtonIndicator:
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ PseudoElement pe = se == SE_CheckBoxIndicator ? PseudoElement_Indicator : PseudoElement_ExclusiveIndicator;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ return positionRect(w, rule, subRule, pe, opt->rect, opt->direction);
+ }
+ break;
+
+ case SE_CheckBoxContents:
+ case SE_RadioButtonContents:
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ bool isRadio = se == SE_RadioButtonContents;
+ QRect ir = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator,
+ opt, w);
+ ir = visualRect(opt->direction, opt->rect, ir);
+ int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, 0, w);
+ QRect cr = rule.contentsRect(opt->rect);
+ ir.setRect(ir.left() + ir.width() + spacing, cr.y(),
+ cr.width() - ir.width() - spacing, cr.height());
+ return visualRect(opt->direction, opt->rect, ir);
+ }
+ break;
+
+ case SE_ToolBoxTabContents:
+ if (w && hasStyleRule(w->parentWidget(), PseudoElement_ToolBoxTab)) {
+ QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_ToolBoxTab);
+ return visualRect(opt->direction, opt->rect, subRule.contentsRect(opt->rect));
+ }
+ break;
+
+ case SE_RadioButtonFocusRect:
+ case SE_RadioButtonClickRect: // focusrect | indicator
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ return opt->rect;
+ }
+ break;
+
+ case SE_CheckBoxFocusRect:
+ case SE_CheckBoxClickRect: // relies on indicator and contents
+ return ParentStyle::subElementRect(se, opt, w);
+
+#ifndef QT_NO_ITEMVIEWS
+ case SE_ViewItemCheckIndicator:
+ if (!qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ return subElementRect(SE_CheckBoxIndicator, opt, w);
+ }
+ // intentionally falls through
+ case SE_ItemViewItemText:
+ case SE_ItemViewItemDecoration:
+ case SE_ItemViewItemFocusRect:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
+ PseudoElement pe = PseudoElement_None;
+ if (se == SE_ItemViewItemText || se == SE_ItemViewItemFocusRect)
+ pe = PseudoElement_ViewItemText;
+ else if (se == SE_ItemViewItemDecoration && vopt->features & QStyleOptionViewItemV2::HasDecoration)
+ pe = PseudoElement_ViewItemIcon;
+ else if (se == SE_ItemViewItemCheckIndicator && vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)
+ pe = PseudoElement_ViewItemIndicator;
+ else
+ break;
+ if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder() || hasStyleRule(w, pe)) {
+ QRenderRule subRule2 = renderRule(w, opt, pe);
+ QStyleOptionViewItemV4 optCopy(*vopt);
+ optCopy.rect = subRule.contentsRect(vopt->rect);
+ QRect rect = ParentStyle::subElementRect(se, &optCopy, w);
+ return positionRect(w, subRule2, pe, rect, opt->direction);
+ }
+ }
+ break;
+#endif // QT_NO_ITEMVIEWS
+
+ case SE_HeaderArrow: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewUpArrow);
+ if (subRule.hasPosition() || subRule.hasGeometry())
+ return positionRect(w, rule, subRule, PseudoElement_HeaderViewUpArrow, opt->rect, opt->direction);
+ }
+ break;
+
+ case SE_HeaderLabel: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (subRule.hasBox() || !subRule.hasNativeBorder())
+ return subRule.contentsRect(opt->rect);
+ }
+ break;
+
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarLabel:
+ if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasPosition() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) {
+ if (se == SE_ProgressBarGroove)
+ return rule.borderRect(pb->rect);
+ else if (se == SE_ProgressBarContents)
+ return rule.contentsRect(pb->rect);
+
+ QSize sz = pb->fontMetrics.size(0, pb->text);
+ return QStyle::alignedRect(Qt::LeftToRight, rule.hasPosition() ? rule.position()->textAlignment : pb->textAlignment,
+ sz, pb->rect);
+ }
+ }
+ break;
+
+#ifndef QT_NO_TABBAR
+ case SE_TabWidgetLeftCorner:
+ pe = PseudoElement_TabWidgetLeftCorner;
+ // intentionally falls through
+ case SE_TabWidgetRightCorner:
+ if (pe == PseudoElement_None)
+ pe = PseudoElement_TabWidgetRightCorner;
+ // intentionally falls through
+ case SE_TabWidgetTabBar:
+ if (pe == PseudoElement_None)
+ pe = PseudoElement_TabWidgetTabBar;
+ // intentionally falls through
+ case SE_TabWidgetTabPane:
+ case SE_TabWidgetTabContents:
+ if (pe == PseudoElement_None)
+ pe = PseudoElement_TabWidgetPane;
+
+ if (hasStyleRule(w, pe)) {
+ QRect r = QWindowsStyle::subElementRect(pe == PseudoElement_TabWidgetPane ? SE_TabWidgetTabPane : se, opt, w);
+ QRenderRule subRule = renderRule(w, opt, pe);
+ r = positionRect(w, subRule, pe, r, opt->direction);
+ if (pe == PseudoElement_TabWidgetTabBar) {
+ Q_ASSERT(opt);
+ r = opt->rect.intersected(r);
+ }
+ if (se == SE_TabWidgetTabContents)
+ r = subRule.contentsRect(r);
+ return r;
+ }
+ break;
+
+ case SE_TabBarTearIndicator: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTear);
+ if (subRule.hasContentsSize()) {
+ QRect r;
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r.setRect(tab->rect.left(), tab->rect.top(), subRule.size().width(), opt->rect.height());
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), subRule.size().height());
+ break;
+ default:
+ break;
+ }
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ return r;
+ }
+ break;
+ }
+ case SE_TabBarTabText:
+ case SE_TabBarTabLeftButton:
+ case SE_TabBarTabRightButton: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ return ParentStyle::subElementRect(se, opt, w);
+ }
+ break;
+ }
+#endif // QT_NO_TABBAR
+
+ case SE_DockWidgetCloseButton:
+ case SE_DockWidgetFloatButton: {
+ PseudoElement pe = (se == SE_DockWidgetCloseButton) ? PseudoElement_DockWidgetCloseButton : PseudoElement_DockWidgetFloatButton;
+ QRenderRule subRule2 = renderRule(w, opt, pe);
+ if (!subRule2.hasPosition())
+ break;
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
+ return positionRect(w, subRule, subRule2, pe, opt->rect, opt->direction);
+ }
+
+#ifndef QT_NO_TOOLBAR
+ case SE_ToolBarHandle:
+ if (hasStyleRule(w, PseudoElement_ToolBarHandle))
+ return ParentStyle::subElementRect(se, opt, w);
+ break;
+#endif //QT_NO_TOOLBAR
+
+ default:
+ break;
+ }
+
+ return baseStyle()->subElementRect(se, opt, w);
+}
+
+bool QStyleSheetStyle::event(QEvent *e)
+{
+ return (baseStyle()->event(e) && e->isAccepted()) || ParentStyle::event(e);
+}
+
+void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
+{
+ QWidget *container = containerWidget(w);
+ QRenderRule rule = renderRule(container, PseudoElement_None,
+ PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
+ QFont font = rule.font.resolve(w->font());
+
+ if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
+ && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
+
+ font = font.resolve(static_cast<QWidget *>(w->parent())->font());
+ }
+
+ if (w->data->fnt == font)
+ return;
+
+#ifdef QT3_SUPPORT
+ QFont old = w->data->fnt;
+#endif
+ w->data->fnt = font;
+#if defined(Q_WS_X11)
+ // make sure the font set on this widget is associated with the correct screen
+ //w->data->fnt.x11SetScreen(w->d_func()->xinfo.screen());
+#endif
+
+ QEvent e(QEvent::FontChange);
+ QApplication::sendEvent(w, &e);
+#ifdef QT3_SUPPORT
+ w->fontChange(old);
+#endif
+}
+
+void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
+{
+ w->setProperty("_q_styleSheetWidgetFont", font);
+}
+
+void QStyleSheetStyle::clearWidgetFont(QWidget* w) const
+{
+ w->setProperty("_q_styleSheetWidgetFont", QVariant(QVariant::Invalid));
+}
+
+// Polish palette that should be used for a particular widget, with particular states
+// (eg. :focus, :hover, ...)
+// this is called by widgets that paint themself in their paint event
+// Returns true if there is a new palette in pal.
+bool QStyleSheetStyle::styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal)
+{
+ if (!w || !opt || !pal)
+ return false;
+
+ RECURSION_GUARD(return false)
+
+ w = containerWidget(w);
+
+ QRenderRule rule = renderRule(w, PseudoElement_None, pseudoClass(opt->state) | extendedPseudoClass(w));
+ if (!rule.hasPalette())
+ return false;
+
+ rule.configurePalette(pal, QPalette::NoRole, QPalette::NoRole);
+ return true;
+}
+
+Qt::Alignment QStyleSheetStyle::resolveAlignment(Qt::LayoutDirection layDir, Qt::Alignment src)
+{
+ if (layDir == Qt::LeftToRight || src & Qt::AlignAbsolute)
+ return src;
+
+ if (src & Qt::AlignLeft) {
+ src &= ~Qt::AlignLeft;
+ src |= Qt::AlignRight;
+ } else if (src & Qt::AlignRight) {
+ src &= ~Qt::AlignRight;
+ src |= Qt::AlignLeft;
+ }
+ src |= Qt::AlignAbsolute;
+ return src;
+}
+
+// Returns whether the given QWidget has a "natural" parent, meaning that
+// the parent contains this child as part of its normal operation.
+// An example is the QTabBar inside a QTabWidget.
+// This does not mean that any QTabBar which is a child of QTabWidget will
+// match, only the one that was created by the QTabWidget initialization
+// (and hence has the correct object name).
+bool QStyleSheetStyle::isNaturalChild(const QWidget *w)
+{
+ if (w->objectName().startsWith(QLatin1String("qt_")))
+ return true;
+
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qstylesheetstyle_p.cpp"
+
+#endif // QT_NO_STYLE_STYLESHEET
diff --git a/src/widgets/styles/qstylesheetstyle_default.cpp b/src/widgets/styles/qstylesheetstyle_default.cpp
new file mode 100644
index 0000000000..c9cfc435fa
--- /dev/null
+++ b/src/widgets/styles/qstylesheetstyle_default.cpp
@@ -0,0 +1,512 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* This is the default Qt style sheet.
+
+ IMPORTANT: This style sheet is primarily meant for defining feature
+ capablities of styles. Do NOT add default styling rules here. When in
+ doubt ask the stylesheet maintainer.
+
+ The stylesheet in here used to be in a CSS file, but was moved here to
+ avoid parsing overhead.
+*/
+
+#include "private/qcssparser_p.h"
+#include "qstylesheetstyle_p.h"
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+QT_BEGIN_NAMESPACE
+
+using namespace QCss;
+
+// This is the class name of the selector.
+// Use an empty string where you would use '*' in CSS.
+// Ex. QHeaderView
+
+#define SET_ELEMENT_NAME(x) \
+ bSelector.elementName = (x)
+
+// This acts as both pseudo state and sub control. The first parameter is the
+// string name, and the second is the PseudoClass_* constant.
+// The sub control specifier is always the first, and has the type
+// PseudoClass_Unknown.
+// If there is no PseudoClass_Unknown as the first pseudo, it is assumed to be
+// a pseudo state.
+// Ex. QComboBox::drop-down:enabled
+// ^ ^
+
+#define ADD_PSEUDO(x, y) \
+ pseudo.type = (y); \
+ pseudo.name = (x); \
+ bSelector.pseudos << pseudo
+
+// This is attributes. The third parameter is AttributeSelector::*
+// Ex. QComboBox[style="QWindowsXPStyle"]
+// ^ ^
+
+#define ADD_ATTRIBUTE_SELECTOR(x, y, z) \
+ attr.name = (x); \
+ attr.value = (y); \
+ attr.valueMatchCriterium = (z); \
+ bSelector.attributeSelectors << attr
+
+// Adds the current basic selector to the rule.
+// Several basic selectors behave as AND (space in CSS).
+
+#define ADD_BASIC_SELECTOR \
+ selector.basicSelectors << bSelector; \
+ bSelector.ids.clear(); \
+ bSelector.pseudos.clear(); \
+ bSelector.attributeSelectors.clear()
+
+// Adds the current selector to the rule.
+// Several selectors behave as OR (comma in CSS).
+
+#define ADD_SELECTOR \
+ styleRule.selectors << selector; \
+ selector.basicSelectors.clear()
+
+// Sets the name of a property.
+// Ex. background: red;
+// ^
+
+#define SET_PROPERTY(x, y) \
+ decl.d->property = (x); \
+ decl.d->propertyId = (y)
+
+// Adds a value to the current property.
+// The first parameter should be Value::KnownIdentifier if the value can be
+// found among the Value_* constants, in which case the second should be that
+// constant. Otherwise the first parameter is Value::Identifier and the second
+// is a string.
+// Adding more values is the same as seperating by spaces in CSS.
+// Ex. border: 2px solid black;
+// ^ ^ ^
+
+#define ADD_VALUE(x, y) \
+ value.type = (x); \
+ value.variant = (y); \
+ decl.d->values << value
+
+// Adds the current declaration to the rule.
+// Ex. border: 2px solid black;
+// \----------------------/
+
+#define ADD_DECLARATION \
+ styleRule.declarations << decl; \
+ decl.d.detach(); \
+ decl.d->values.clear()
+
+// Adds the rule to the stylesheet.
+// Use at the end of every CSS block.
+
+#define ADD_STYLE_RULE \
+ sheet.styleRules << styleRule; \
+ styleRule.selectors.clear(); \
+ styleRule.declarations.clear()
+
+StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const
+{
+ StyleSheet sheet;
+ StyleRule styleRule;
+ BasicSelector bSelector;
+ Selector selector;
+ Declaration decl;
+ QCss::Value value;
+ Pseudo pseudo;
+ AttributeSelector attr;
+
+ // pixmap based style doesn't support any features
+ bool styleIsPixmapBased = baseStyle()->inherits("QMacStyle")
+ || baseStyle()->inherits("QWindowsXPStyle")
+ || baseStyle()->inherits("QGtkStyle")
+ || baseStyle()->inherits("QS60Style");
+
+
+ /*QLineEdit {
+ -qt-background-role: base;
+ border: native;
+ -qt-style-features: background-color;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QLineEdit"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Base);
+ ADD_DECLARATION;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ SET_PROPERTY(QLatin1String("-qt-style-features"), QtStyleFeatures);
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-color"));
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QLineEdit:no-frame {
+ border: none;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QLineEdit"));
+ ADD_PSEUDO(QLatin1String("no-frame"), PseudoClass_Frameless);
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_None);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QFrame {
+ border: native;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QFrame"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QLabel, QToolBox {
+ background: none;
+ border-image: none;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QLabel"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_ELEMENT_NAME(QLatin1String("QToolBox"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("background"), Background);
+ ADD_VALUE(Value::KnownIdentifier, Value_None);
+ ADD_DECLARATION;
+
+ SET_PROPERTY(QLatin1String("border-image"), BorderImage);
+ ADD_VALUE(Value::KnownIdentifier, Value_None);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QGroupBox {
+ border: native;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QGroupBox"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+
+ /*QToolTip {
+ -qt-background-role: window;
+ border: native;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QToolTip"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Window);
+ ADD_DECLARATION;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QPushButton, QToolButton {
+ border-style: native;
+ -qt-style-features: background-color; //only for not pixmap based styles
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QPushButton"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_ELEMENT_NAME(QLatin1String("QToolButton"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border-style"), BorderStyles);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ if (!styleIsPixmapBased) {
+ SET_PROPERTY(QLatin1String("-qt-style-features"), QtStyleFeatures);
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-color"));
+ ADD_DECLARATION;
+ }
+
+
+ ADD_STYLE_RULE;
+ }
+
+
+ /*QComboBox {
+ border: native;
+ -qt-style-features: background-color background-gradient; //only for not pixmap based styles
+ -qt-background-role: base;
+ }*/
+
+ {
+ SET_ELEMENT_NAME(QLatin1String("QComboBox"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ if (!styleIsPixmapBased) {
+ SET_PROPERTY(QLatin1String("-qt-style-features"), QtStyleFeatures);
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-color"));
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-gradient"));
+ ADD_DECLARATION;
+ }
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Base);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QComboBox[style="QPlastiqueStyle"][readOnly="true"],
+ QComboBox[style="QCleanlooksStyle"][readOnly="true"]
+ {
+ -qt-background-role: button;
+ }*/
+ if (baseStyle()->inherits("QPlastiqueStyle") || baseStyle()->inherits("QCleanlooksStyle"))
+ {
+ SET_ELEMENT_NAME(QLatin1String("QComboBox"));
+ ADD_ATTRIBUTE_SELECTOR(QLatin1String("readOnly"), QLatin1String("true"), AttributeSelector::MatchEqual);
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Button);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QAbstractSpinBox {
+ border: native;
+ -qt-style-features: background-color;
+ -qt-background-role: base;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QAbstractSpinBox"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ SET_PROPERTY(QLatin1String("-qt-style-features"), QtStyleFeatures);
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-color"));
+ ADD_DECLARATION;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Base);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QMenu {
+ -qt-background-role: window;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QMenu"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Window);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+ /*QMenu::item {
+ -qt-style-features: background-color;
+ }*/
+ if (!styleIsPixmapBased) {
+ SET_ELEMENT_NAME(QLatin1String("QMenu"));
+ ADD_PSEUDO(QLatin1String("item"), PseudoClass_Unknown);
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-style-features"), QtStyleFeatures);
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-color"));
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QHeaderView {
+ -qt-background-role: window;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QHeaderView"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Window);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QTableCornerButton::section, QHeaderView::section {
+ -qt-background-role: button;
+ -qt-style-features: background-color; //if style is not pixmap based
+ border: native;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QTableCornerButton"));
+ ADD_PSEUDO(QLatin1String("section"), PseudoClass_Unknown);
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_ELEMENT_NAME(QLatin1String("QHeaderView"));
+ ADD_PSEUDO(QLatin1String("section"), PseudoClass_Unknown);
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Button);
+ ADD_DECLARATION;
+
+ if (!styleIsPixmapBased) {
+ SET_PROPERTY(QLatin1String("-qt-style-features"), QtStyleFeatures);
+ ADD_VALUE(Value::Identifier, QString::fromLatin1("background-color"));
+ ADD_DECLARATION;
+ }
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QProgressBar {
+ -qt-background-role: base;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QProgressBar"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Base);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QScrollBar {
+ -qt-background-role: window;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QScrollBar"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("-qt-background-role"), QtBackgroundRole);
+ ADD_VALUE(Value::KnownIdentifier, Value_Window);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ /*QDockWidget {
+ border: native;
+ }*/
+ {
+ SET_ELEMENT_NAME(QLatin1String("QDockWidget"));
+ ADD_BASIC_SELECTOR;
+ ADD_SELECTOR;
+
+ SET_PROPERTY(QLatin1String("border"), Border);
+ ADD_VALUE(Value::KnownIdentifier, Value_Native);
+ ADD_DECLARATION;
+
+ ADD_STYLE_RULE;
+ }
+
+ sheet.origin = StyleSheetOrigin_UserAgent;
+ sheet.buildIndexes();
+ return sheet;
+}
+
+#endif // #ifndef QT_NO_STYLE_STYLESHEET
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
new file mode 100644
index 0000000000..1d38627edf
--- /dev/null
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLESHEETSTYLE_P_H
+#define QSTYLESHEETSTYLE_P_H
+
+#include "QtWidgets/qwindowsstyle.h"
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+#include "QtWidgets/qstyleoption.h"
+#include "QtCore/qhash.h"
+#include "QtGui/qevent.h"
+#include "QtCore/qvector.h"
+#include "QtWidgets/qapplication.h"
+#include "private/qcssparser_p.h"
+#include "QtGui/qbrush.h"
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class QRenderRule;
+class QAbstractScrollArea;
+class QStyleSheetStylePrivate;
+class QStyleOptionTitleBar;
+
+class Q_AUTOTEST_EXPORT QStyleSheetStyle : public QWindowsStyle
+{
+ typedef QWindowsStyle ParentStyle;
+
+ Q_OBJECT
+public:
+ QStyleSheetStyle(QStyle *baseStyle);
+ ~QStyleSheetStyle();
+
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
+ void drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *option) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const;
+ QRect itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled,
+ const QString &text) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &pal);
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+ QPalette standardPalette() const;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = 0,
+ const QWidget *w = 0 ) const;
+ int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w = 0) const;
+
+ // These functions are called from QApplication/QWidget. Be careful.
+ QStyle *baseStyle() const;
+ void repolish(QWidget *widget);
+ void repolish(QApplication *app);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+ QStyle *base;
+ void ref() { ++refcount; }
+ void deref() { Q_ASSERT(refcount > 0); if (!--refcount) delete this; }
+
+ void updateStyleSheetFont(QWidget* w) const;
+ void saveWidgetFont(QWidget* w, const QFont& font) const;
+ void clearWidgetFont(QWidget* w) const;
+
+ bool styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ bool event(QEvent *e);
+
+private:
+ int refcount;
+
+ friend class QRenderRule;
+ int nativeFrameWidth(const QWidget *);
+ QRenderRule renderRule(const QWidget *, int, quint64 = 0) const;
+ QRenderRule renderRule(const QWidget *, const QStyleOption *, int = 0) const;
+ QSize defaultSize(const QWidget *, QSize, const QRect&, int) const;
+ QRect positionRect(const QWidget *, const QRenderRule&, const QRenderRule&, int,
+ const QRect&, Qt::LayoutDirection) const;
+ QRect positionRect(const QWidget *w, const QRenderRule &rule2, int pe,
+ const QRect &originRect, Qt::LayoutDirection dir) const;
+
+ mutable QCss::Parser parser;
+
+ void setPalette(QWidget *);
+ void unsetPalette(QWidget *);
+ void setProperties(QWidget *);
+ void setGeometry(QWidget *);
+ QVector<QCss::StyleRule> styleRules(const QWidget *w) const;
+ bool hasStyleRule(const QWidget *w, int part) const;
+
+ QHash<QStyle::SubControl, QRect> titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const;
+
+ QCss::StyleSheet getDefaultStyleSheet() const;
+
+ static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment);
+ static bool isNaturalChild(const QWidget *w);
+ bool initWidget(const QWidget *w) const;
+public:
+ static int numinstances;
+
+private:
+ Q_DISABLE_COPY(QStyleSheetStyle)
+ Q_DECLARE_PRIVATE(QStyleSheetStyle)
+};
+
+class QStyleSheetStyleCaches : public QObject
+{
+ Q_OBJECT
+public Q_SLOTS:
+ void widgetDestroyed(QObject *);
+ void styleDestroyed(QObject *);
+public:
+ QHash<const QWidget *, QVector<QCss::StyleRule> > styleRulesCache;
+ QHash<const QWidget *, QHash<int, bool> > hasStyleRuleCache;
+ typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
+ QHash<const QWidget *, QRenderRules> renderRulesCache;
+ QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered
+ QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
+ QSet<const QWidget *> autoFillDisabledWidgets;
+};
+
+
+QT_END_NAMESPACE
+#endif // QT_NO_STYLE_STYLESHEET
+#endif // QSTYLESHEETSTYLE_P_H
diff --git a/src/widgets/styles/qwindowscestyle.cpp b/src/widgets/styles/qwindowscestyle.cpp
new file mode 100644
index 0000000000..39174f9855
--- /dev/null
+++ b/src/widgets/styles/qwindowscestyle.cpp
@@ -0,0 +1,2429 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowscestyle.h"
+
+#if !defined(QT_NO_STYLE_WINDOWSCE) || defined(QT_PLUGIN)
+
+#include "qpainterpath.h"
+#include "qapplication.h"
+#include "qdockwidget.h"
+#include "qtoolbar.h"
+#include "qpaintengine.h"
+#include "qpainter.h"
+#include "qstyleoption.h"
+#include "qwindowscestyle_p.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 2; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 15; // right border on windows
+static const int windowsCheckMarkWidth = 14; // checkmarks width on windows
+
+static const int windowsCEitemViewCheckBoxSize = 14;
+static const int windowsCEFrameGroupBoxOffset = 9;
+static const int windowsCEIndicatorSize = 14;
+static const int windowsCEExclusiveIndicatorSize = 14;
+static const int windowsCESliderThickness = 24;
+static const int windowsCEIconSize = 16;
+
+static const QColor windowsCECheckBoxGradientColorBegin = QColor(222, 224, 214);
+static const QColor windowsCECheckBoxGradientColorEnd = QColor(255, 255, 255);
+
+enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
+
+QWindowsCEStyle::QWindowsCEStyle() : QWindowsStyle() {
+ qApp->setEffectEnabled(Qt::UI_FadeMenu, false);
+ qApp->setEffectEnabled(Qt::UI_AnimateMenu, false);
+}
+
+void QWindowsCEStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const {
+
+ bool doRestore = false;
+ QRect rect = option->rect;
+
+ switch (element) {
+ case PE_PanelButtonTool: {
+ if (
+#ifndef QT_NO_TOOLBAR
+ (widget && qobject_cast<QToolBar*>(widget->parentWidget())) ||
+#endif
+#ifndef QT_NO_DOCKWIDGET
+ (widget && widget->inherits("QDockWidgetTitleButton")) ||
+#endif
+ (option->state & (State_Sunken | State_On)))
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect.adjusted(0, 0, 0, 0),
+ option->palette, option->state & (State_Sunken | State_On),
+ &option->palette.button());
+ if (option->state & (State_On)){
+ QBrush fill = QBrush(option->palette.midlight().color(), Qt::Dense4Pattern);
+ painter->fillRect(option->rect.adjusted(windowsItemFrame , windowsItemFrame ,
+ -windowsItemFrame , -windowsItemFrame ), fill);
+ }
+ break; }
+ case PE_IndicatorButtonDropDown:
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect, option->palette,
+ option->state & (State_Sunken | State_On),
+ &option->palette.brush(QPalette::Button));
+ break;
+#ifndef QT_NO_TABBAR
+ case PE_IndicatorTabTear:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ bool rtl = tab->direction == Qt::RightToLeft;
+ QRect rect = tab->rect;
+ QPainterPath path;
+ rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
+ rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
+ path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
+ int count = 3;
+ for(int jags = 1; jags <= count; ++jags, rtl = !rtl)
+ path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
+
+ painter->setPen(QPen(tab->palette.light(), qreal(.8)));
+ painter->setBrush(tab->palette.background());
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->drawPath(path);
+ }
+ break;
+#endif //QT_NO_TABBAR
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarSeparator:
+ //nothing to draw on WindowsCE
+ break;
+ case PE_IndicatorToolBarHandle:
+ painter->save();
+ painter->translate(option->rect.x(), option->rect.y());
+ if (option->state & State_Horizontal) {
+ int x = option->rect.width() / 2 - 4;
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ x -= 2;
+ if (option->rect.height() > 4) {
+ QWindowsCEStylePrivate::drawWinCEButton(painter,x - 1, 0, 7, option->rect.height(),
+ option->palette, false, 0);
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, x, 1, 3, option->rect.height() - 1,
+ option->palette, false, 0);
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, x + 3, 1, 3, option->rect.height() - 1,
+ option->palette, false, 0);
+ painter->setPen(option->palette.button().color());
+ painter->drawLine(x + 4, 2, x + 4,option->rect.height() - 2);
+ }
+ } else {
+ if (option->rect.width() > 4) {
+ int y = option->rect.height() / 2 - 4;
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, 2, y, option->rect.width() - 2, 3,
+ option->palette, false, 0);
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, 2, y + 3, option->rect.width() - 2, 3,
+ option->palette, false, 0);
+ }
+ }
+ painter->restore();
+ break;
+
+#endif // QT_NO_TOOLBAR
+ case PE_FrameButtonTool: {
+#ifndef QT_NO_DOCKWIDGET
+ if (widget && widget->inherits("QDockWidgetTitleButton")) {
+ if (const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget->parent()))
+ if (dw->isFloating()){
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect.adjusted(1, 1, 0, 0),
+ option->palette, option->state & (State_Sunken | State_On),
+ &option->palette.button());
+ return;
+ }
+ }
+#endif // QT_NO_DOCKWIDGET
+ QBrush fill;
+ bool stippled;
+ bool panel = (element == PE_PanelButtonTool);
+ if ((!(option->state & State_Sunken ))
+ && (!(option->state & State_Enabled)
+ || ((option->state & State_Enabled ) && !(option->state & State_MouseOver)))
+ && (option->state & State_On)) {
+ fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ stippled = true;
+ } else {
+ fill = option->palette.brush(QPalette::Button);
+ stippled = false;
+ }
+ if (option->state & (State_Raised | State_Sunken | State_On)) {
+ if (option->state & State_AutoRaise) {
+ if(option->state & (State_Enabled | State_Sunken | State_On)){
+ if (panel)
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, option->rect, option->palette,
+ option->state & (State_Sunken | State_On), &fill);
+ else
+ qDrawShadeRect(painter, option->rect, option->palette,
+ option->state & (State_Sunken | State_On), 1);
+ }
+ if (stippled) {
+ painter->setPen(option->palette.button().color());
+ painter->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ }
+ } else {
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect, option->palette,
+ option->state & (State_Sunken | State_On), panel ? &fill : 0);
+ }
+ } else {
+ painter->fillRect(option->rect, fill);
+ }
+ break; }
+
+ case PE_PanelButtonBevel: {
+ QBrush fill;
+ bool panel = element != PE_FrameButtonBevel;
+ painter->setBrushOrigin(option->rect.topLeft());
+ if (!(option->state & State_Sunken) && (option->state & State_On))
+ fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = option->palette.brush(QPalette::Button);
+
+ if (option->state & (State_Raised | State_On | State_Sunken)) {
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect, option->palette,
+ option->state & (State_Sunken | State_On),
+ panel ? &fill : 0); ;
+ } else {
+ if (panel)
+ painter->fillRect(option->rect, fill);
+ else
+ painter->drawRect(option->rect);
+ }
+ break; }
+
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ QRect fr = frame->rect;
+ painter->setPen(frame->palette.shadow().color());
+ painter->drawRect(fr.x(), fr.y(), fr.x() + fr.width() - 1,
+ fr.y() + fr.height() - windowsCEFrameGroupBoxOffset);
+ }
+ break;
+
+ case PE_IndicatorCheckBox: {
+ QBrush fill;
+ if (option->state & State_NoChange)
+ fill = QBrush(option->palette.base().color(), Qt::Dense4Pattern);
+ else if (option->state & State_Sunken)
+ fill = option->palette.button();
+ else if (option->state & State_Enabled)
+ fill = option->palette.base();
+ else
+ fill = option->palette.background();
+ painter->save();
+ doRestore = true;
+ painter->fillRect(option->rect,fill);
+ painter->setPen(option->palette.dark().color());
+ painter->drawRect(option->rect);
+ painter->setPen(option->palette.shadow().color());
+ painter->drawLine(option->rect.x() + 1,option->rect.y() + 1,
+ option->rect.x() + option->rect.width() - 1, option->rect.y() + 1);
+ painter->drawLine(option->rect.x() + 1,option->rect.y() + 1,
+ option->rect.x() + 1, option->rect.y() + option->rect.height() - 1);
+ //fall through...
+ }
+ case PE_IndicatorViewItemCheck:
+ case PE_Q3CheckListIndicator: {
+ if (!doRestore) {
+ painter->save();
+ doRestore = true;
+ }
+ int arrowSize= 2;
+ if (element == PE_Q3CheckListIndicator || element == PE_IndicatorViewItemCheck) {
+ QLinearGradient linearGradient(QPoint(option->rect.x(),option->rect.y()), QPoint(option->rect.x()+option->rect.width(),
+ option->rect.y()+option->rect.height()));
+ linearGradient.setColorAt(0, windowsCECheckBoxGradientColorBegin);
+ linearGradient.setColorAt(1, windowsCECheckBoxGradientColorEnd);
+ painter->setBrush(linearGradient);
+ painter->setPen(Qt::NoPen);
+ if (option->state & State_NoChange)
+ painter->setBrush(option->palette.brush(QPalette::Button));
+ painter->setPen(option->palette.link().color());
+ painter->drawRect(option->rect.x(), option->rect.y(), windowsCEitemViewCheckBoxSize, windowsCEitemViewCheckBoxSize);
+ painter->setPen(option->palette.brightText().color());
+ arrowSize= 3;
+ }
+ if (!(option->state & State_Off)) {
+ QLineF lines[9];
+ int i, xx, yy;
+ xx = option->rect.x() + 4;
+ yy = option->rect.y() + 6;
+ for (i = 0; i < 4; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + arrowSize);
+ ++xx;
+ ++yy;
+ }
+ yy -= 2;
+ for (i = 4; i < 9; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + arrowSize);
+ ++xx;
+ --yy;
+ }
+ painter->drawLines(lines, 9);
+ }
+ if (doRestore)
+ painter->restore();
+
+ break; }
+ case PE_IndicatorRadioButton: {
+ QRect ir = option->rect;
+ painter->save();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(option->palette.light());
+ painter->drawEllipse(option->rect);
+ painter->setPen(option->palette.shadow().color());
+ painter->setBrush(option->palette.shadow().color());
+ painter->drawArc(option->rect, 0, 360 * 16);
+ painter->drawArc(option->rect.x() + 1, option->rect.y() + 1, option->rect.width() - 2,
+ option->rect.height() - 2, 40 * 16, 180 * 16);
+ painter->setPen(option->palette.light().color());
+ painter->drawPoint(option->rect.x() + 11, option->rect.y() + 3);
+ painter->drawPoint(option->rect.x() + 3,option->rect.y() + 3);
+ painter->setPen(option->palette.shadow().color());
+ painter->drawPoint(option->rect.x() +3,option->rect.y() + 12);
+ if (option->state & (State_Sunken | State_On)) {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(option->palette.text());
+ painter->drawEllipse(option->rect.x() +3,option->rect.y()+ 2,9,10);
+ }
+ painter->restore();
+ break; }
+ case PE_PanelMenuBar:
+ painter->save();
+ painter->setPen(option->palette.shadow().color());
+ painter->drawRect(option->rect);
+ painter->restore();
+ break;
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ QBrush fill;
+ State flags = option->state;
+ QPalette pal = option->palette;
+ QRect r = option->rect;
+ if (! (flags & State_Sunken) && (flags & State_On))
+ fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
+ else
+ fill = pal.brush(QPalette::Button);
+ if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
+ painter->setPen(pal.dark().color());
+ painter->setBrush(fill);
+ painter->drawRect(r.adjusted(0, 0, -1, -1));
+ } else if (flags & (State_Raised | State_Sunken | State_On | State_Sunken)) {
+ QWindowsCEStylePrivate::drawWinCEButton(painter, r, pal, flags & (State_Sunken | State_On),
+ &fill);
+ } else {
+ painter->fillRect(r, fill);
+ }
+
+ }
+ break;
+ case PE_FrameDefaultButton: {
+ painter->setPen(option->palette.shadow().color());
+ QRect rect = option->rect;
+ rect.adjust(0, 0, -1, -1);
+ painter->drawRect(rect);
+ break; }
+ case PE_IndicatorSpinPlus:
+ case PE_IndicatorSpinMinus: {
+ QRect r = option->rect;
+ int fw = pixelMetric(PM_DefaultFrameWidth, option, widget)+2;
+ QRect br = r.adjusted(fw, fw, -fw, -fw);
+ int offset = (option->state & State_Sunken) ? 1 : 0;
+ int step = (br.width() + 4) / 5;
+ painter->fillRect(br.x() + offset, br.y() + offset +br.height() / 2 - step / 2,
+ br.width(), step,
+ option->palette.buttonText());
+ if (element == PE_IndicatorSpinPlus)
+ painter->fillRect(br.x() + br.width() / 2 - step / 2 + offset, br.y() + offset+4,
+ step, br.height()-7,
+ option->palette.buttonText());
+ break; }
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinDown: {
+ painter->save();
+ QPoint points[7];
+ switch (element) {
+ case PE_IndicatorSpinUp:
+ points[0] = QPoint(-2, -4);
+ points[1] = QPoint(-2, 2);
+ points[2] = QPoint(-1, -3);
+ points[3] = QPoint(-1, 1);
+ points[4] = QPoint(0, -2);
+ points[5] = QPoint(0, 0);
+ points[6] = QPoint(1, -1);
+ break;
+ case PE_IndicatorSpinDown:
+ points[0] = QPoint(0, -4);
+ points[1] = QPoint(0, 2);
+ points[2] = QPoint(-1, -3);
+ points[3] = QPoint(-1, 1);
+ points[4] = QPoint(-2, -2);
+ points[5] = QPoint(-2, 0);
+ points[6] = QPoint(-3, -1);
+ break;
+ default:
+ break;
+ }
+ if (option->state & State_Sunken)
+ painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
+ pixelMetric(PM_ButtonShiftVertical));
+ if (option->state & State_Enabled) {
+ painter->translate(option->rect.x() + option->rect.width() / 2,
+ option->rect.y() + option->rect.height() / 2);
+ painter->setPen(option->palette.buttonText().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ } else {
+ painter->translate(option->rect.x() + option->rect.width() / 2 + 1,
+ option->rect.y() + option->rect.height() / 2 + 1);
+ painter->setPen(option->palette.light().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ painter->translate(-1, -1);
+ painter->setPen(option->palette.mid().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ }
+
+ painter->restore();
+ break; }
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft: {
+ painter->save();
+ QPoint points[9];
+ switch (element) {
+ case PE_IndicatorArrowUp:
+
+ points[0] = QPoint(-4, 2);
+ points[1] = QPoint(4, 2);
+ points[2] = QPoint(-3, 1);
+ points[3] = QPoint(3, 1);
+ points[4] = QPoint(-2, 0);
+ points[5] = QPoint(2, 0);
+ points[6] = QPoint(-1, -1);
+ points[7] = QPoint(1, -1);
+ points[8] = QPoint(0, -2);
+ break;
+ case PE_IndicatorArrowDown:
+
+ points[0] = QPoint(-4, -2);
+ points[1] = QPoint(4, -2);
+ points[2] = QPoint(-3, -1);
+ points[3] = QPoint(3, -1);
+ points[4] = QPoint(-2, 0);
+ points[5] = QPoint(2, 0);
+ points[6] = QPoint(-1, 1);
+ points[7] = QPoint(1, 1);
+ points[8] = QPoint(0, 2);
+ break;
+ case PE_IndicatorArrowRight:
+ points[0] = QPoint(-3, -4);
+ points[1] = QPoint(-3, 4);
+ points[2] = QPoint(-2, -3);
+ points[3] = QPoint(-2, 3);
+ points[4] = QPoint(-1, -2);
+ points[5] = QPoint(-1, 2);
+ points[6] = QPoint(0, -1);
+ points[7] = QPoint(0, 1);
+ points[8] = QPoint(1, 0);
+ break;
+ case PE_IndicatorArrowLeft:
+ points[0] = QPoint(1, -4);
+ points[1] = QPoint(1, 4);
+ points[2] = QPoint(0, -3);
+ points[3] = QPoint(0, 3);
+ points[4] = QPoint(-1, -2);
+ points[5] = QPoint(-1, 2);
+ points[6] = QPoint(-2, -1);
+ points[7] = QPoint(-2, 1);
+ points[8] = QPoint(-3, 0);
+ break;
+ default:
+ break;
+ }
+ if (option->state & State_Sunken)
+ painter->translate(pixelMetric(PM_ButtonShiftHorizontal),
+ pixelMetric(PM_ButtonShiftVertical));
+ if (option->state & State_Enabled) {
+ painter->translate(option->rect.x() + option->rect.width() / 2,
+ option->rect.y() + option->rect.height() / 2);
+ painter->setPen(option->palette.buttonText().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawLine(points[6], points[7]);
+ painter->drawPoint(points[8]);
+ } else {
+ painter->translate(option->rect.x() + option->rect.width() / 2 + 1,
+ option->rect.y() + option->rect.height() / 2 + 1);
+ painter->setPen(option->palette.light().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawLine(points[6], points[7]);
+ painter->drawPoint(points[8]);
+ painter->translate(-1, -1);
+ painter->setPen(option->palette.mid().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawLine(points[6], points[7]);
+ painter->drawPoint(points[8]);
+ }
+ painter->restore();
+ break; }
+
+ case PE_FrameWindow: {
+ QPalette popupPal = option->palette;
+ popupPal.setColor(QPalette::Light, option->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, option->palette.light().color());
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, option->rect, popupPal, option->state & State_Sunken);
+ break; }
+
+ case PE_Frame:
+ case PE_FrameMenu:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ QPalette popupPal = frame->palette;
+ QRect r = frame->rect;
+ qDrawPlainRect(painter, r, frame->palette.shadow().color(),1);
+ }
+ break;
+ case PE_FrameStatusBar:
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, option->rect, option->palette, true, 0);
+ break;
+
+ case PE_FrameTabWidget: {
+ QRect rect = option->rect;
+ QPalette pal = option->palette;
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect, option->palette, false, 0);
+ break; }
+ default:
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+void QWindowsCEStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const {
+ switch (element) {
+ #ifndef QT_NO_MENU
+ case CE_MenuTearoff: {
+ if(option->state & State_Selected) {
+ if(pixelMetric(PM_MenuPanelWidth, option, widget) > 1)
+ qDrawShadePanel(painter, option->rect.x(), option->rect.y(), option->rect.width(),
+ option->rect.height(), option->palette, false, 2,
+ &option->palette.brush(QPalette::Button));
+ else
+ qDrawShadePanel(painter, option->rect.x() + 1, option->rect.y() + 1, option->rect.width() - 2,
+ option->rect.height() - 2, option->palette, true, 1, &option->palette.brush(QPalette::Button));
+ } else {
+ painter->fillRect(option->rect, option->palette.brush(QPalette::Button));
+ }
+ painter->setPen(QPen(option->palette.dark().color(), 1, Qt::DashLine));
+ painter->drawLine(option->rect.x()+2, option->rect.y()+option->rect.height()/2-1, option->rect.x()+option->rect.width()-4,
+ option->rect.y()+option->rect.height()/2-1);
+ painter->setPen(QPen(option->palette.light().color(), 1, Qt::DashLine));
+ painter->drawLine(option->rect.x()+2, option->rect.y()+option->rect.height()/2, option->rect.x()+option->rect.width()-4,
+ option->rect.y()+option->rect.height()/2);
+ break; }
+
+
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ bool active = mbi->state & State_Selected;
+ bool hasFocus = mbi->state & State_HasFocus;
+ bool down = mbi->state & State_Sunken;
+ QStyleOptionMenuItem newMbi = *mbi;
+ if (active || hasFocus) {
+ QBrush b = mbi->palette.brush(QPalette::Highlight);
+ if (active && down) {
+ painter->fillRect(mbi->rect.adjusted(0, 1, 0, -1), b);
+ }
+ }
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ painter->save();
+ QFont f = painter->font();
+ f.setBold(true);
+ painter->setFont(f);
+ QPixmap pix = mbi->icon.pixmap(pixelMetric(PM_SmallIconSize),
+ (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
+ if (!pix.isNull())
+ drawItemPixmap(painter,mbi->rect, alignment, pix);
+ else
+ if (active && down)
+ drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled,
+ mbi->text, QPalette::Light);
+ else
+ drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled,
+ mbi->text, QPalette::ButtonText);
+ painter->restore();
+ }
+ break;
+
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ painter->setPen(option->palette.shadow().color());
+ if (widget && !widget->testAttribute(Qt::WA_NoSystemBackground)) {
+ painter->eraseRect(option->rect);
+ QRect r = option->rect;
+ painter->drawLine(r.x() + 1, r.y() + 1, r.x()+ 1, r.y()+ r.height() - 2);
+ painter->drawLine(r.x() - 2 + r.width(), r.y() + 1, r.x() - 2 + r.width(), r.y() + r.height() - 2);
+ painter->drawLine(r.x() + 1, r.y() +1, r.x() - 1 + r.width(), r.y() + 1);
+ painter->drawLine(r.x() + 1, r.y() + r.height()-2 , r.x() - 2 + r.width(), r.y() + r.height() - 2);
+ }
+ painter->restore();
+ break;
+
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax(menuitem->maxIconWidth, windowsCheckMarkWidth);
+ QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ painter->fillRect(menuitem->rect.adjusted(1, 1, 0, 0), fill);
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-1 + h / 2;
+ painter->setPen(menuitem->palette.shadow().color());
+ painter->drawLine(x + 4, yoff + 1, x + w - 8, yoff + 1);
+ return;
+ }
+
+ QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
+ menuitem->rect.y(), checkcol, menuitem->rect.height()));
+ if (checked) {
+ if (act && !dis) {
+ qDrawPlainRect(painter, vCheckRect,
+ menuitem->palette.button().color(), 1,
+ &menuitem->palette.brush(QPalette::Button));
+ } else {
+ QBrush fill(menuitem->palette.button().color(), Qt::Dense4Pattern);
+ qDrawPlainRect(painter, vCheckRect,menuitem->palette.button().color(), 1, &fill);
+ }
+ } else if (!act) {
+ painter->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button));
+ }
+ // On Windows Style, if we have a checkable item and an icon we
+ // draw the icon recessed to indicate an item is checked. If we
+ // have no icon, we draw a checkmark instead.
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ if (act && !dis && !checked)
+ qDrawPlainRect(painter, vCheckRect, menuitem->palette.button().color(), 1,
+ &menuitem->palette.brush(QPalette::Button));
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(menuitem->palette.text().color());
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checked) {
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+ newMi.rect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x()
+ + windowsItemFrame, menuitem->rect.y() + windowsItemFrame,
+ checkcol - 2 * windowsItemFrame, menuitem->rect.height() - 2*windowsItemFrame));
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, painter, widget);
+ }
+ painter->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ painter->setPen(discol);
+ }
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ painter->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act)
+ painter->setPen(discol);
+ painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ painter->setFont(font);
+ if (dis && !act)
+ painter->setPen(discol);
+ painter->drawText(vTextRect, text_flags, s.left(t));
+ painter->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorSpinDown : PE_IndicatorSpinUp;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ if (act)
+ newMI.palette.setColor(QPalette::ButtonText,
+ newMI.palette.highlightedText().color());
+ drawPrimitive(arrow, &newMI, painter, widget);
+ }
+ }
+ break;
+#endif // QT_NO_MENU
+ case CE_MenuVMargin:
+ painter->fillRect(option->rect, Qt::white);
+ break;
+ case CE_MenuEmptyArea:
+ QWindowsStyle::drawControl(element,option, painter, widget);
+ break;
+
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ drawControl(CE_TabBarTabShape, tab, painter, widget);
+ drawControl(CE_TabBarTabLabel, tab, painter, widget);
+ }
+ break;
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ bool rtlHorTabs = (tab->direction == Qt::RightToLeft
+ && (tab->shape == QTabBar::RoundedNorth
+ || tab->shape == QTabBar::RoundedSouth));
+ bool selected = tab->state & State_Selected;
+ bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning));
+ bool firstTab = ((!rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::End));
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool previousSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
+ bool nextSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition
+ == QStyleOptionTab::PreviousIsSelected));
+ int tabBarAlignment = styleHint(SH_TabBar_Alignment, tab, widget);
+ bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignRight);
+
+ bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignLeft);
+ QColor light = tab->palette.light().color();
+ QColor midlight = tab->palette.midlight().color();
+ QColor dark = tab->palette.dark().color();
+ QColor shadow = tab->palette.shadow().color();
+ QColor background = tab->palette.background().color();
+ int borderThinkness = pixelMetric(PM_TabBarBaseOverlap, tab, widget);
+ if (selected)
+ borderThinkness /= 2;
+ QRect r2(option->rect);
+ int x1 = r2.left();
+ int x2 = r2.right();
+ int y1 = r2.top();
+ int y2 = r2.bottom();
+ switch (tab->shape) {
+ default:
+ QCommonStyle::drawControl(element, tab, painter, widget);
+ break;
+ case QTabBar::RoundedNorth: {
+ if (!selected) {
+ y1 += 2;
+ x1 += firstTab ? borderThinkness : 0;
+ x2 -= lastTab ? borderThinkness : 0;
+ }
+
+ painter->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ painter->setPen(background);
+ painter->drawLine(x1, y2 - 1, x2, y2 - 1);
+ painter->drawLine(x1, y2 + 1, x2, y2 + 1);
+ painter->drawLine(x1, y2, x2, y2);
+ }
+ // Left
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ painter->setPen(dark);
+ painter->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ painter->drawPoint(x1 + 1, y1 + 1);
+ painter->setPen(midlight);
+ painter->drawLine(x1 + 1, y1 + 2, x1 + 1, y2 -
+ ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+
+ }
+ // Top
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ painter->setPen(dark);
+ painter->drawLine(beg, y1, end, y1);
+
+ painter->setPen(midlight);
+ painter->drawLine(beg, y1 + 1, end, y1 + 1);
+
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ painter->setPen(shadow);
+ painter->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ painter->drawPoint(x2 - 1, y1 + 1);
+ painter->setPen(dark);
+ painter->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ }
+ break; }
+ case QTabBar::RoundedSouth: {
+ if (!selected) {
+ y2 -= 2;
+ x1 += firstTab ? borderThinkness : 0;
+ x2 -= lastTab ? borderThinkness : 0;
+ }
+
+ painter->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ painter->setPen(background);
+ painter->drawLine(x1, y1 + 1, x2 - 1, y1 + 1);
+ painter->drawLine(x1, y1 - 1, x2 - 1, y1 - 1);
+ painter->drawLine(x1, y1, x2 - 1, y1);
+ }
+ // Left
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ painter->setPen(dark);
+ painter->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ painter->drawPoint(x1 + 1, y2 - 1);
+ painter->setPen(midlight);
+ painter->drawLine(x1 + 1, y2 - 2, x1 + 1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ }
+ // Bottom
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ painter->setPen(shadow);
+ painter->drawLine(beg, y2, end, y2);
+ painter->setPen(dark);
+ painter->drawLine(beg, y2 - 1, end, y2 - 1);
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ painter->setPen(shadow);
+ painter->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected &&
+ rightAligned ? 0 : borderThinkness));
+ painter->drawPoint(x2 - 1, y2 - 1);
+ painter->setPen(dark);
+ painter->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected &&
+ rightAligned ? 0 : borderThinkness));
+ }
+ break; }
+ case QTabBar::RoundedWest: {
+ if (!selected) {
+ x1 += 2;
+ y1 += firstTab ? borderThinkness : 0;
+ y2 -= lastTab ? borderThinkness : 0;
+ }
+
+ painter->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ painter->setPen(background);
+ painter->drawLine(x2 - 1, y1, x2 - 1, y2);
+ painter->drawLine(x2, y1, x2, y2);
+ }
+ // Top
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ painter->setPen(dark);
+ painter->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected &&
+ leftAligned ? 0 : borderThinkness), y1);
+ painter->drawPoint(x1 + 1, y1 + 1);
+ painter->setPen(midlight);
+ painter->drawLine(x1 + 2, y1 + 1, x2 - ((onlyOne || firstTab) && selected &&
+ leftAligned ? 0 : borderThinkness), y1 + 1);
+ }
+ // Left
+ {
+ int beg = y1 + (previousSelected ? 0 : 2);
+ int end = y2 - (nextSelected ? 0 : 2);
+ painter->setPen(dark);
+ painter->drawLine(x1, beg, x1, end);
+ painter->setPen(midlight);
+ painter->drawLine(x1 + 1, beg, x1 + 1, end);
+ }
+ // Bottom
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ painter->setPen(shadow);
+ painter->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected &&
+ rightAligned ? 0 : borderThinkness), y2);
+ painter->drawPoint(x1 + 2, y2 - 1);
+ painter->setPen(dark);
+ painter->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected &&
+ rightAligned ? 0 : borderThinkness), y2 - 1);
+ painter->drawPoint(x1 + 1, y2 - 1);
+ painter->drawPoint(x1 + 2, y2);
+ }
+ break; }
+ case QTabBar::RoundedEast: {
+ if (!selected) {
+ x2 -= 2;
+ y1 += firstTab ? borderThinkness : 0;
+ y2 -= lastTab ? borderThinkness : 0;
+ }
+
+ painter->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ painter->setPen(background);
+ painter->drawLine(x1 + 1, y1, x1 + 1, y2 - 1);
+ painter->drawLine(x1, y1, x1, y2 - 1);
+ }
+ // Top
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ painter->setPen(dark);
+ painter->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected &&
+ leftAligned ? 0 : borderThinkness), y1);
+ painter->drawPoint(x2 - 1, y1 + 1);
+ painter->setPen(midlight);
+ painter->drawLine(x2 - 3, y1 + 1, x1 + ((onlyOne || firstTab) &&
+ selected && leftAligned ? 0 : borderThinkness), y1 + 1);
+ painter->drawPoint(x2 - 1, y1);
+
+ }
+ // Right
+ {
+ int beg = y1 + (previousSelected ? 0 : 2);
+ int end = y2 - (nextSelected ? 0 : 2);
+ painter->setPen(shadow);
+ painter->drawLine(x2, beg, x2, end);
+ painter->setPen(dark);
+ painter->drawLine(x2 - 1, beg, x2 - 1, end);
+ }
+ // Bottom
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ painter->setPen(shadow);
+ painter->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) &&
+ selected && rightAligned ? 0 : borderThinkness), y2);
+ painter->drawPoint(x2 - 1, y2 - 1);
+ painter->setPen(dark);
+ painter->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) &&
+ selected && rightAligned ? 0 : borderThinkness), y2 - 1);
+ }
+ break; }
+ }
+ }
+ break;
+#endif // QT_NO_TABBAR
+
+ case CE_ToolBar: {
+ QRect rect = option->rect;
+ painter->setPen(QPen(option->palette.dark().color()));
+ painter->drawLine(rect.topRight().x()-1,
+ rect.topRight().y(),
+ rect.bottomRight().x()-1,
+ rect.bottomRight().y());
+ painter->drawLine(rect.bottomLeft().x(),
+ rect.bottomLeft().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ painter->setPen(QPen(option->palette.light().color()));
+ painter->drawLine(rect.topRight().x(),
+ rect.topRight().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ painter->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.topRight().x(),
+ rect.topRight().y());
+
+ break; }
+#ifndef QT_NO_SCROLLBAR
+ case CE_ScrollBarSubLine:
+ case CE_ScrollBarAddLine: {
+ if (option->state & State_Sunken) {
+ QStyleOption buttonOpt = *option;
+
+ drawPrimitive(PE_PanelButtonBevel, &buttonOpt, painter, widget);
+ } else {
+ QStyleOption buttonOpt = *option;
+ if (!(buttonOpt.state & State_Sunken))
+ buttonOpt.state |= State_Raised;
+ drawPrimitive(PE_PanelButtonBevel, &buttonOpt, painter, widget);
+ }
+ PrimitiveElement arrow;
+ if (option->state & State_Horizontal) {
+ if (element == CE_ScrollBarAddLine)
+ arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
+ else
+ arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ } else {
+ if (element == CE_ScrollBarAddLine)
+ arrow = PE_IndicatorArrowDown;
+ else
+ arrow = PE_IndicatorArrowUp;
+ }
+ drawPrimitive(arrow, option, painter, widget);
+ break; }
+ case CE_ScrollBarAddPage:
+ case CE_ScrollBarSubPage: {
+ QBrush br;
+ QBrush bg = painter->background();
+ Qt::BGMode bg_mode = painter->backgroundMode();
+ painter->setPen(Qt::NoPen);
+ painter->setBackgroundMode(Qt::OpaqueMode);
+
+ if (option->state & State_Sunken) {
+ br = QBrush(option->palette.shadow().color(), Qt::Dense4Pattern);
+ painter->setBackground(option->palette.dark().color());
+ painter->setBrush(br);
+ } else {
+ QPixmap pm = option->palette.brush(QPalette::Light).texture();
+ if (option->state & State_Enabled)
+ br = !pm.isNull() ? QBrush(pm) : QBrush(option->palette.button().color(), Qt::Dense4Pattern);
+ else
+ br = !pm.isNull() ? QBrush(pm) : QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ painter->setBackground(option->palette.base().color());
+ painter->setBrush(br);
+ }
+ painter->drawRect(option->rect);
+ painter->setBackground(bg);
+ painter->setBackgroundMode(bg_mode);
+ break; }
+ case CE_ScrollBarSlider:
+ if (!(option->state & State_Enabled)) {
+ QStyleOptionButton buttonOpt;
+ buttonOpt.QStyleOption::operator=(*option);
+ buttonOpt.state = State_Enabled | State_Raised;
+ drawPrimitive(PE_PanelButtonBevel, &buttonOpt, painter, widget);
+ QPixmap pm = option->palette.brush(QPalette::Light).texture();
+ QBrush br = !pm.isNull() ? QBrush(pm) : QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(br);
+ painter->setBackgroundMode(Qt::OpaqueMode);
+ painter->drawRect(option->rect.adjusted(2, 2, -2, -2));
+ } else {
+ QStyleOptionButton buttonOpt;
+ buttonOpt.QStyleOption::operator=(*option);
+ buttonOpt.state = State_Enabled | State_Raised;
+ drawPrimitive(PE_PanelButtonBevel, &buttonOpt, painter, widget);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ case CE_HeaderSection: {
+ QBrush fill;
+ if (option->state & State_On)
+ fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = option->palette.brush(QPalette::Button);
+
+ if (option->state & (State_Raised | State_Sunken)) {
+ QWindowsCEStylePrivate::drawWinCEButton(painter, option->rect, option->palette,
+ option->state & State_Sunken, &fill);
+ } else {
+ painter->fillRect(option->rect, fill);
+ }
+ break; }
+
+ case CE_DockWidgetTitle:
+ QWindowsStyle::drawControl(element,option, painter, widget);
+ break;
+
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ painter->save();
+ QFont f = painter->font();
+ f.setBold(true);
+ painter->setFont(f);
+ QRect ir = btn->rect;
+ uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ if (!styleHint(SH_UnderlineShortcut, btn, widget))
+ tf |= Qt::TextHideMnemonic;
+
+ if (btn->state & (State_On | State_Sunken))
+ ir.translate(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
+ pixelMetric(PM_ButtonShiftVertical, option, widget));
+ if (!btn->icon.isNull()) {
+ QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ if (mode == QIcon::Normal && btn->state & State_HasFocus)
+ mode = QIcon::Active;
+ QIcon::State state = QIcon::Off;
+ if (btn->state & State_On)
+ state = QIcon::On;
+ QPixmap pixmap = btn->icon.pixmap(btn->iconSize, mode, state);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ //Center the icon if there is no text
+
+ QPoint point;
+ if (btn->text.isEmpty()) {
+ point = QPoint(ir.x() + ir.width() / 2 - pixw / 2,
+ ir.y() + ir.height() / 2 - pixh / 2);
+ } else {
+ point = QPoint(ir.x() + 2, ir.y() + ir.height() / 2 - pixh / 2);
+ }
+ if (btn->direction == Qt::RightToLeft)
+ point.rx() += pixw;
+
+ if ((btn->state & (State_On | State_Sunken)) && btn->direction == Qt::RightToLeft)
+ point.rx() -= pixelMetric(PM_ButtonShiftHorizontal, option, widget) * 2;
+
+ painter->drawPixmap(visualPos(btn->direction, btn->rect, point), pixmap);
+
+ if (btn->direction == Qt::RightToLeft)
+ ir.translate(-4, 0);
+ else
+ ir.translate(pixw + 4, 0);
+ ir.setWidth(ir.width() - (pixw + 4));
+ // left-align text if there is
+ if (!btn->text.isEmpty())
+ tf |= Qt::AlignLeft;
+ } else {
+ tf |= Qt::AlignHCenter;
+ }
+ drawItemText(painter, ir, tf, btn->palette, (btn->state & State_Enabled),
+ btn->text, QPalette::ButtonText);
+ painter->restore();
+ }
+ break;
+ default:
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+void QWindowsCEStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const {
+ switch (control) {
+ #ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int thickness = pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = pixelMetric(PM_SliderLength, slider, widget);
+ int ticks = slider->tickPosition;
+ QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
+ QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
+
+ if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
+ int mid = thickness / 2;
+ if (ticks & QSlider::TicksAbove)
+ mid += len / 8;
+ if (ticks & QSlider::TicksBelow)
+ mid -= len / 8;
+
+ painter->setPen(slider->palette.shadow().color());
+ if (slider->orientation == Qt::Horizontal) {
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, groove.x(), groove.y() + mid - 2,
+ groove.width(), 4, option->palette, true);
+ painter->drawLine(groove.x() + 1, groove.y() + mid - 1,
+ groove.x() + groove.width() - 3, groove.y() + mid - 1);
+ } else {
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, groove.x() + mid - 2, groove.y(),
+ 4, groove.height(), option->palette, true);
+ painter->drawLine(groove.x() + mid - 1, groove.y() + 1,
+ groove.x() + mid - 1, groove.y() + groove.height() - 3);
+ }
+ }
+ if (slider->subControls & SC_SliderTickmarks) {
+ QStyleOptionSlider tmpSlider = *slider;
+ tmpSlider.subControls = SC_SliderTickmarks;
+ QCommonStyle::drawComplexControl(control, &tmpSlider, painter, widget);
+ }
+
+ if (slider->subControls & SC_SliderHandle) {
+ // 4444440
+ // 4333310
+ // 4322210
+ // 4322210
+ // 4322210
+ // 4322210
+ // *43210*
+ // **440**
+ // ***0***
+ const QColor c0 = slider->palette.shadow().color();
+ const QColor c1 = slider->palette.dark().color();
+ // const QColor c2 = g.button();
+ const QColor c3 = slider->palette.midlight().color();
+ const QColor c4 = slider->palette.dark().color();
+ QBrush handleBrush;
+
+ if (slider->state & State_Enabled) {
+ handleBrush = slider->palette.color(QPalette::Button);
+ } else {
+ handleBrush = QBrush(slider->palette.color(QPalette::Button),
+ Qt::Dense4Pattern);
+ }
+
+ int x = handle.x(), y = handle.y(),
+ wi = handle.width(), he = handle.height();
+
+ int x1 = x;
+ int x2 = x + wi - 1;
+ int y1 = y;
+ int y2 = y + he - 1;
+
+ Qt::Orientation orient = slider->orientation;
+ bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
+ bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+ drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
+ Qt::BGMode oldMode = painter->backgroundMode();
+ painter->setBackgroundMode(Qt::OpaqueMode);
+ QWindowsCEStylePrivate::drawWinCEButton(painter, QRect(x, y, wi, he), slider->palette, false,
+ &handleBrush);
+ painter->setBackgroundMode(oldMode);
+ QBrush fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 + 2, y1 + 2, x2 - x1 - 3, y2 - y1 - 3),fill);
+ return;
+ }
+ QSliderDirection dir;
+ if (orient == Qt::Horizontal)
+ if (tickAbove)
+ dir = SlUp;
+ else
+ dir = SlDown;
+ else
+ if (tickAbove)
+ dir = SlLeft;
+ else
+ dir = SlRight;
+ QPolygon a;
+ int d = 0;
+ switch (dir) {
+ case SlUp:
+ x2++;
+ y1 = y1 + wi / 2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1, y1, x1, y2, x2, y2, x2, y1, x1 + d, y1 - d);
+ break;
+ case SlDown:
+ x2++;
+ y2 = y2 - wi / 2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1, y1, x1, y2, x1 + d, y2+d, x2, y2, x2, y1);
+ break;
+ case SlLeft:
+ d = (he + 1) / 2 - 1;
+ x1 = x1 + he / 2;
+ a.setPoints(5, x1, y1, x1 - d, y1 + d, x1, y2, x2, y2, x2, y1);
+ y1--;
+ break;
+ case SlRight:
+ d = (he + 1) / 2 - 1;
+ x2 = x2 - he / 2;
+ a.setPoints(5, x1, y1, x1, y2, x2, y2, x2 + d, y1 + d, x2, y1);
+ y1--;
+ break;
+ }
+ QBrush oldBrush = painter->brush();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(handleBrush);
+ Qt::BGMode oldMode = painter->backgroundMode();
+ painter->setBackgroundMode(Qt::OpaqueMode);
+ painter->drawRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ painter->drawPolygon(a);
+ QBrush fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1, y1, x2 - x1 + 1, y2 - y1 + 1),fill);
+ painter->setBrush(oldBrush);
+ painter->setBackgroundMode(oldMode);
+
+ if (dir != SlUp) {
+ painter->setPen(c4);
+ painter->drawLine(x1, y1, x2, y1);
+ painter->setPen(c3);
+ painter->drawLine(x1, y1 + 1, x2, y1 + 1);
+ }
+ if (dir != SlLeft) {
+ painter->setPen(c3);
+ painter->drawLine(x1 + 1, y1 + 1, x1 + 1, y2);
+ painter->setPen(c4);
+ painter->drawLine(x1, y1, x1, y2);
+ }
+ if (dir != SlRight) {
+ painter->setPen(c0);
+ painter->drawLine(x2, y1, x2, y2);
+ painter->setPen(c1);
+ painter->drawLine(x2 - 1, y1 + 1, x2 - 1, y2 - 1);
+ }
+ if (dir != SlDown) {
+ painter->setPen(c0);
+ painter->drawLine(x1, y2, x2, y2);
+ painter->setPen(c1);
+ painter->drawLine(x1+1, y2 - 1, x2 - 1, y2 - 1);
+ }
+
+ switch (dir) {
+ case SlUp:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 + 3, y1 - d + 2, x2 - x1 - 4,y1), fill);
+ painter->setPen(c4);
+ painter->drawLine(x1, y1, x1 + d, y1 - d);
+ painter->setPen(c0);
+ d = wi - d - 1;
+ painter->drawLine(x2, y1, x2 - d, y1 - d);
+ d--;
+ painter->setPen(c3);
+ painter->drawLine(x1 + 1, y1, x1 + 1 + d-1, y1 - d + 1);
+ painter->setPen(c1);
+ painter->drawLine(x2 - 1, y1, x2-1 - d, y1 - d);
+ break;
+ case SlDown:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 + 3, y2 - d, x2 - x1 - 4,y2 - 8), fill);
+ painter->setPen(c4);
+ painter->drawLine(x1, y2, x1 + d, y2 + d);
+ painter->setPen(c0);
+ d = wi - d - 1;
+ painter->drawLine(x2, y2, x2 - d, y2 + d);
+ d--;
+ painter->setPen(c3);
+ painter->drawLine(x1 + 1, y2, x1 + 1 + d - 1, y2 + d - 1);
+ painter->setPen(c1);
+ painter->drawLine(x2 - 1, y2, x2 - 1 - d, y2 + d);
+ break;
+ case SlLeft:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 - d + 2, y1 + 2, x1,y2 - y1 - 3), fill);
+ painter->setPen(c4);
+ painter->drawLine(x1, y1, x1 - d, y1 + d);
+ painter->setPen(c0);
+ d = he - d - 1;
+ painter->drawLine(x1, y2, x1 - d, y2 - d);
+ d--;
+ painter->setPen(c3);
+ painter->drawLine(x1, y1 + 1, x1 - d + 1, y1 + 1 + d - 1);
+ painter->setPen(c1);
+ painter->drawLine(x1, y2 - 1, x1 - d, y2 - 1 - d);
+ break;
+ case SlRight:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x2 - d - 4, y1 + 2, x2 - 4, y2 - y1 - 3), fill);
+ painter->setPen(c4);
+ painter->drawLine(x2, y1, x2 + d, y1 + d);
+ painter->setPen(c0);
+ d = he - d - 1;
+ painter->drawLine(x2, y2, x2 + d, y2 - d);
+ d--;
+ painter->setPen(c3);
+ painter->drawLine(x2, y1 + 1, x2 + d - 1, y1 + 1 + d - 1);
+ painter->setPen(c1);
+ painter->drawLine(x2, y2 - 1, x2 + d, y2 - 1 - d);
+ break;
+ }
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+
+#ifndef QT_NO_TOOLBAR
+ bool flat = !(widget ? qobject_cast<QToolBar*>(widget->parentWidget()) : 0);
+#else
+ bool flat = true;
+#endif
+
+ button = subControlRect(control, toolbutton, SC_ToolButton, widget);
+ menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+
+ if (flat && (toolbutton->subControls & SC_ToolButtonMenu)) {
+ menuarea.setLeft(menuarea.left() - 4);
+ button.setRight(button.right() - 4);
+ }
+
+ State bflags = toolbutton->state;
+
+ if (bflags & State_AutoRaise)
+ if (!(bflags & State_MouseOver)) {
+ bflags &= ~State_Raised;
+ }
+ State mflags = bflags;
+
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ mflags |= State_Sunken;
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ tool.rect = button;
+ tool.state = bflags;
+ drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ tool.state = bflags;
+ drawPrimitive(PE_IndicatorButtonDropDown, &tool, painter, widget);
+
+ if (!flat) {
+
+ //connect buttons
+ painter->save();
+ painter->setPen(tool.palette.button().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y(), tool.rect.x() - 2, tool.rect.y() + tool.rect.height());
+ painter->drawLine(tool.rect.x() - 1, tool.rect.y(), tool.rect.x() - 1, tool.rect.y() + tool.rect.height());
+ painter->drawLine(tool.rect.x(), tool.rect.y(), tool.rect.x(), tool.rect.y() + tool.rect.height());
+ painter->drawLine(tool.rect.x() + 1, tool.rect.y(), tool.rect.x() + 1, tool.rect.y() + tool.rect.height());
+
+ if (tool.state & State_Sunken)
+ {
+ painter->setPen(tool.palette.midlight().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y() + tool.rect.height() - 2,
+ tool.rect.x() + 1, tool.rect.y() + tool.rect.height() -2 );
+ painter->setPen(tool.palette.shadow().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y() + 1,tool.rect.x() + 1, tool.rect.y() + 1);
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y(), tool.rect.x() + 1, tool.rect.y());
+ painter->setPen(tool.palette.light().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y() + tool.rect.height() - 1,
+ tool.rect.x() + 1, tool.rect.y() + tool.rect.height() - 1);
+ }
+ else
+ {
+ painter->setPen(tool.palette.dark().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y(),tool.rect.x() + 1, tool.rect.y());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y()+tool.rect.height() - 2,tool.rect.x() + 1,
+ tool.rect.y() + tool.rect.height() - 2);
+ painter->setPen(tool.palette.midlight().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y() + 1,tool.rect.x() + 1, tool.rect.y() + 1);
+ painter->setPen(tool.palette.shadow().color());
+ painter->drawLine(tool.rect.x() - 2, tool.rect.y() + tool.rect.height() - 1,
+ tool.rect.x() + 1, tool.rect.y() + tool.rect.height() - 1);
+ }
+ painter->restore();
+ }
+
+
+ if (!flat) {
+ tool.rect.adjust(-3,0,-3,0);
+ painter->save();
+ painter->setPen(tool.palette.button().color());
+ if (tool.state & State_Sunken)
+ painter->drawLine(tool.rect.x() + 2, tool.rect.y() + 10,
+ tool.rect.x() + tool.rect.width(), tool.rect.y() + 10);
+ else
+ painter->drawLine(tool.rect.x() + 1, tool.rect.y() + 9, tool.rect.x() +
+ tool.rect.width() - 1, tool.rect.y() + 9);
+ painter->restore();
+ } else {
+ tool.rect.adjust(-1,0,-1,0);
+ }
+
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ }
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect.adjust(3, 3, -3, -3);
+ if (toolbutton->features & QStyleOptionToolButton::Menu)
+ fr.rect.adjust(0, 0, -pixelMetric(QStyle::PM_MenuButtonIndicator,
+ toolbutton, widget), 0);
+ drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ int fw = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ drawControl(CE_ToolButtonLabel, &label, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ // Draw frame
+ painter->save();
+ QFont f = painter->font();
+ f.setBold(true);
+ painter->setFont(f);
+ QStyleOptionGroupBox groupBoxFont = *groupBox;
+ groupBoxFont.fontMetrics = QFontMetrics(f);
+ QRect textRect = subControlRect(CC_GroupBox, &groupBoxFont, SC_GroupBoxLabel, widget);
+ QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
+ if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*groupBox);
+ frame.features = groupBox->features;
+ frame.lineWidth = groupBox->lineWidth;
+ frame.midLineWidth = groupBox->midLineWidth;
+ frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
+ painter->save();
+
+ QRegion region(groupBox->rect);
+ if (!groupBox->text.isEmpty()) {
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ QRect finalRect = checkBoxRect.united(textRect);
+ if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)
+ finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
+ region -= finalRect;
+ }
+ painter->setClipRegion(region);
+ drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
+ painter->restore();
+ }
+
+ // Draw title
+ if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ QColor textColor = groupBox->textColor;
+ if (textColor.isValid())
+ painter->setPen(textColor);
+ int alignment = int(groupBox->textAlignment);
+ if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
+ groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
+ textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
+
+ if (groupBox->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*groupBox);
+ fropt.rect = textRect;
+ drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+ // Draw checkbox
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
+ }
+ painter->restore();
+ }
+ break;
+#endif //QT_NO_GROUPBOX
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ if ((cmb->subControls & SC_ComboBoxFrame) && cmb->frame)
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, option->rect, option->palette, true, &editBrush);
+ else
+ painter->fillRect(option->rect, editBrush);
+
+ if (cmb->subControls & SC_ComboBoxArrow) {
+ State flags = State_None;
+
+ QRect ar = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
+ if (cmb->activeSubControls == SC_ComboBoxArrow) {
+ painter->setPen(cmb->palette.dark().color());
+ painter->setBrush(cmb->palette.brush(QPalette::Button));
+ painter->drawRect(ar.adjusted(0, 0, -1, -1));
+ QWindowsCEStylePrivate::drawWinCEButton(painter, ar.adjusted(0, 0, -1, -1), option->palette, true,
+ &cmb->palette.brush(QPalette::Button));
+ } else {
+ // Make qDrawWinButton use the right colors for drawing the shade of the button
+
+ QWindowsCEStylePrivate::drawWinCEButton(painter, ar, option->palette, false,
+ &cmb->palette.brush(QPalette::Button));
+ }
+
+ ar.adjust(2, 2, -2, -2);
+ if (option->state & State_Enabled)
+ flags |= State_Enabled;
+
+ if (cmb->activeSubControls == SC_ComboBoxArrow)
+ flags |= State_Sunken;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar;
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
+ }
+ if (cmb->subControls & SC_ComboBoxEditField) {
+ QRect re = subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
+ if (cmb->state & State_HasFocus && !cmb->editable)
+ painter->fillRect(re.x(), re.y(), re.width(), re.height(),
+ cmb->palette.brush(QPalette::Highlight));
+ if (cmb->state & State_HasFocus) {
+ painter->setPen(cmb->palette.highlightedText().color());
+ painter->setBackground(cmb->palette.highlight());
+ } else {
+ painter->setPen(cmb->palette.text().color());
+ painter->setBackground(cmb->palette.background());
+ }
+ if (cmb->state & State_HasFocus && !cmb->editable) {
+ QStyleOptionFocusRect focus;
+ focus.QStyleOption::operator=(*cmb);
+ focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget);
+ focus.state |= State_FocusAtBorder;
+ focus.backgroundColor = cmb->palette.highlight().color();
+ drawPrimitive(PE_FrameFocusRect, &focus, painter, widget);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QStyleOptionSpinBox copy = *sb;
+ PrimitiveElement pe;
+
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ QRect r = subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
+ QWindowsCEStylePrivate::drawWinCEPanel(painter, r, option->palette, true);
+ }
+ QPalette shadePal(option->palette);
+ shadePal.setColor(QPalette::Button, option->palette.light().color());
+ shadePal.setColor(QPalette::Light, option->palette.button().color());
+
+ bool reverse = QApplication::layoutDirection() == Qt::RightToLeft;
+
+ if (sb->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+ if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ if (reverse)
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+ else
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+ copy.rect = subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
+ QWindowsCEStylePrivate::drawWinCEButton(painter, copy.rect, option->palette, copy.state & (State_Sunken | State_On),
+ &copy.palette.brush(QPalette::Button));
+ copy.rect.adjust(3, 0, -4, 0);
+ drawPrimitive(pe, &copy, painter, widget);
+ }
+ if (sb->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = sb->state;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ if (reverse)
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+ else
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+ copy.rect = subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+ QWindowsCEStylePrivate::drawWinCEButton(painter, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
+ &copy.palette.brush(QPalette::Button));
+
+ copy.rect.adjust(3, 0, -4, 0);
+ if (pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowDown) {
+ copy.rect = copy.rect.adjusted(1, 1, -1, -1);
+ drawPrimitive(pe, &copy, painter, widget);
+ }
+ else {
+ drawPrimitive(pe, &copy, painter, widget);
+ }
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ QRect r = subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
+ painter->save();
+ painter->setPen(option->palette.light().color());
+ painter->drawLine(r.x() + 1 + r.width(), r.y() - 2, r.x() + 1 + r.width(), r.y() + r.height() + 1);
+ painter->setPen(option->palette.midlight().color());
+ painter->drawLine(r.x() + r.width(), r.y() - 1, r.x() + r.width(), r.y() + r.height());
+ painter->restore();
+ }
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+void QWindowsCEStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const {
+ if (text.isEmpty())
+ return;
+ QPen savedPen;
+ if (textRole != QPalette::NoRole) {
+ savedPen = painter->pen();
+ painter->setPen(pal.color(textRole));
+ }
+ if (!enabled) {
+ QPen pen = painter->pen();
+ painter->setPen(pal.light().color());
+ //painter->drawText(rect.adjusted(1, 1, 1, 1), alignment, text);
+ painter->setPen(pen);
+ }
+ painter->drawText(rect, alignment, text);
+ if (textRole != QPalette::NoRole)
+ painter->setPen(savedPen);
+}
+
+
+QSize QWindowsCEStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const {
+ QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ switch (type) {
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ int w = newSize.width(),
+ h = newSize.height();
+ int defwidth = 0;
+ if (btn->features & QStyleOptionButton::AutoDefaultButton)
+ defwidth = 2 * pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
+ if (w < 75 + defwidth && btn->icon.isNull())
+ w = 75 + defwidth;
+ if (h < 23 + defwidth)
+ h = 23 + defwidth;
+ newSize = QSize(w+14, h);
+ }
+ break;
+
+ case CT_RadioButton:
+ case CT_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (type == CT_RadioButton);
+ QRect irect = visualRect(btn->direction, btn->rect,
+ subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget));
+ int h = pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
+ : PM_IndicatorHeight, btn, widget);
+ int margins = (!btn->icon.isNull() && btn->text.isEmpty()) ? 0 : 10;
+ newSize += QSize(irect.right() + margins, 4);
+ newSize.setHeight(qMax(newSize.height(), h));
+ }
+ break;
+ case CT_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int fw = cmb->frame ? pixelMetric(PM_ComboBoxFrameWidth, option, widget) * 2 : 0;
+ newSize = QSize(newSize.width() + fw -1, qMax(24, newSize.height() + fw-1));
+ }
+ break;
+#ifndef QT_NO_SPINBOX
+ case CT_SpinBox:
+ if (const QStyleOptionSpinBox *spnb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ int fw = spnb->frame ? pixelMetric(PM_SpinBoxFrameWidth, option, widget) * 2 : 0;
+ newSize = QSize(newSize.width() + fw - 5, newSize.height() + fw - 6);
+ }
+ break;
+#endif
+ case CT_LineEdit:
+ newSize += QSize(0,1);
+ break;
+ case CT_MenuBarItem:
+ newSize += QSize(5, 1);
+ break;
+ case CT_MenuItem:
+ newSize += QSize(0, -2);
+ break;
+ case CT_MenuBar:
+ newSize += QSize(0, -1);
+ break;
+ case CT_ToolButton:
+ if (const QStyleOptionToolButton *b = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ if (b->toolButtonStyle != Qt::ToolButtonIconOnly)
+ newSize = QSize(newSize.width() + 1, newSize.height() - 1);
+ else
+ newSize = QSize(newSize.width() + 1, newSize.height());
+ }
+ break;
+
+ default:
+ break;
+ }
+ return newSize;
+}
+
+QRect QWindowsCEStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const {
+ QRect rect = QWindowsStyle::subElementRect(element, option, widget);
+ switch (element) {
+#ifndef QT_NO_COMBOBOX
+ case SE_ComboBoxFocusRect:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int margin = cb->frame ? 3 : 0;
+ rect.setRect(margin, margin, option->rect.width() - 2*margin - 20, option->rect.height() - 2*margin);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ default:
+ break;
+ }
+ return rect;
+}
+
+QRect QWindowsCEStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const {
+ QRect rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ switch (control) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int tickOffset = pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int thickness = pixelMetric(PM_SliderControlThickness, slider, widget);
+
+ switch (subControl) {
+ case SC_SliderHandle: {
+ int sliderPos = 0;
+ int len = pixelMetric(PM_SliderLength, slider, widget);
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ slider->sliderPosition,
+ (horizontal ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown);
+ if (horizontal)
+ rect.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness);
+ else
+ rect.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len);
+ break; }
+ default:
+ break;
+ }
+ rect = visualRect(slider->direction, slider->rect, rect);
+ }
+ break;
+#endif //QT_NO_SLIDER
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int x = cb->rect.x(),
+ y = cb->rect.y(),
+ wi = cb->rect.width(),
+ he = cb->rect.height();
+ int xpos = x;
+ int margin = cb->frame ? 3 : 0;
+ int bmarg = cb->frame ? 2 : 0;
+ xpos += wi - (he - 2*bmarg) - bmarg;
+ switch (subControl) {
+ case SC_ComboBoxArrow:
+ rect.setRect(xpos, y + bmarg, he - 2*bmarg, he - 2*bmarg);
+ break;
+ case SC_ComboBoxEditField:
+ rect.setRect(x + margin, y + margin, wi - 2 * margin - (he - 2*bmarg), he - 2 * margin);
+ break;
+ case SC_ComboBoxListBoxPopup:
+ rect = cb->rect;
+ break;
+ case SC_ComboBoxFrame:
+ rect = cb->rect;
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(cb->direction, cb->rect, rect);
+ }
+#endif //QT_NO_COMBOBOX
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QSize bs;
+ int fw = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
+ bs.setWidth(qMax(18, (spinbox->rect.height() / 2 - fw + 1)));
+ // 1.6 -approximate golden mean
+ bs.setHeight(qMax(18, qMin((bs.height() * 8 / 5), (spinbox->rect.width() / 4))));
+ bs = bs.expandedTo(QApplication::globalStrut());
+ int y = fw;
+ int x, lx, rx;
+ x = spinbox->rect.width() - y - bs.width() * 2;
+ lx = fw;
+ rx = x - fw;
+ switch (subControl) {
+ case SC_SpinBoxUp:
+ rect = QRect(x + bs.width(), y, bs.width(), bs.height());
+ break;
+ case SC_SpinBoxDown:
+ rect = QRect(x, y , bs.width(), bs.height());
+ break;
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ rect = QRect(lx, fw, spinbox->rect.width() - 2*fw - 2, spinbox->rect.height() - 2*fw);
+ } else {
+ rect = QRect(lx, fw, rx-2, spinbox->rect.height() - 2*fw);
+ }
+ break;
+ case SC_SpinBoxFrame:
+ rect = spinbox->rect;
+ default:
+ break;
+ }
+ rect = visualRect(spinbox->direction, spinbox->rect, rect);
+ }
+ break;
+#endif // Qt_NO_SPINBOX
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox: {
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ switch (subControl) {
+ case SC_GroupBoxFrame:
+ // FALL THROUGH
+ case SC_GroupBoxContents: {
+ int topMargin = 0;
+ int topHeight = 0;
+ int bottomMargin = 0;
+ int noLabelMargin = 0;
+ QRect frameRect = groupBox->rect;
+ int verticalAlignment = styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
+ if (groupBox->text.size()) {
+ topHeight = groupBox->fontMetrics.height();
+ if (verticalAlignment & Qt::AlignVCenter)
+ topMargin = topHeight / 2;
+ else if (verticalAlignment & Qt::AlignTop)
+ topMargin = -topHeight/2;
+ }
+ else {
+ topHeight = groupBox->fontMetrics.height();
+ noLabelMargin = topHeight / 2;
+ if (verticalAlignment & Qt::AlignVCenter) {
+ topMargin = topHeight / 4 - 4;
+ bottomMargin = topHeight / 4 - 4;
+ }
+ else if (verticalAlignment & Qt::AlignTop) {
+ topMargin = topHeight/2 - 4;
+ bottomMargin = topHeight/2 - 4;
+ }
+ }
+
+ if (subControl == SC_GroupBoxFrame) {
+ frameRect.setTop(topMargin);
+ frameRect.setBottom(frameRect.height() + bottomMargin);
+ rect = frameRect;
+ break;
+ }
+
+ int frameWidth = 0;
+ if ((groupBox->features & QStyleOptionFrameV2::Flat) == 0)
+ frameWidth = pixelMetric(PM_DefaultFrameWidth, groupBox, widget);
+ rect = frameRect.adjusted(frameWidth, frameWidth + topHeight, -frameWidth, -frameWidth - noLabelMargin);
+ break;
+ }
+ case SC_GroupBoxCheckBox:
+ // FALL THROUGH
+ case SC_GroupBoxLabel: {
+ QFontMetrics fontMetrics = groupBox->fontMetrics;
+ int h = fontMetrics.height();
+ int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
+ int marg = (groupBox->features & QStyleOptionFrameV2::Flat) ? 0 : 8;
+ rect = groupBox->rect.adjusted(marg, 0, -marg, 0);
+ rect.setHeight(h);
+
+ int indicatorWidth = pixelMetric(PM_IndicatorWidth, option, widget);
+ int indicatorSpace = pixelMetric(PM_CheckBoxLabelSpacing, option, widget) - 1;
+ bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
+ int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
+
+ // Adjusted rect for label + indicatorWidth + indicatorSpace
+ QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment,
+ QSize(tw + checkBoxSize, h), rect);
+
+ // Adjust totalRect if checkbox is set
+ if (hasCheckBox) {
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ int left = 0;
+ // Adjust for check box
+ if (subControl == SC_GroupBoxCheckBox) {
+ int indicatorHeight = pixelMetric(PM_IndicatorHeight, option, widget);
+ left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
+ int top = totalRect.top() + (fontMetrics.height() - indicatorHeight) / 2;
+ totalRect.setRect(left, top, indicatorWidth, indicatorHeight);
+ // Adjust for label
+ } else {
+ left = ltr ? (totalRect.left() + checkBoxSize - 2) : totalRect.left();
+ totalRect.setRect(left, totalRect.top(),
+ totalRect.width() - checkBoxSize, totalRect.height());
+ }
+ }
+ rect = totalRect;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
+ }
+#endif // QT_NO_GROUPBOX
+ default:
+ break;
+ }
+ return rect;
+}
+
+QStyle::SubControl QWindowsCEStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const {
+ /*switch (control) {
+ default:
+ break;
+ }*/
+ return QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+
+QPalette QWindowsCEStyle::standardPalette() const {
+ QPalette palette (Qt::black,QColor(198, 195, 198), QColor(222, 223, 222 ),
+ QColor(132, 130, 132), QColor(198, 195, 198) , Qt::black, Qt::white, Qt::white, QColor(198, 195, 198));
+ palette.setColor(QPalette::Window, QColor(198, 195, 198));
+ palette.setColor(QPalette::Base, Qt::white);
+ palette.setColor(QPalette::Button, QColor(198, 195, 198));
+ palette.setColor(QPalette::Highlight, QColor(0, 0, 132));
+ palette.setColor(QPalette::Light, Qt::white);
+ palette.setColor(QPalette::Midlight, QColor(222, 223, 222 ));
+ palette.setColor(QPalette::Dark, QColor(132, 130, 132));
+ palette.setColor(QPalette::Mid, QColor(132, 130, 132));
+ palette.setColor(QPalette::Shadow, QColor(0, 0, 0));
+ palette.setColor(QPalette::BrightText, QColor(33, 162, 33)); //color for ItemView checked indicator (arrow)
+ palette.setColor(QPalette::Link, QColor(24,81,132)); // color for the box around the ItemView indicator
+
+ return palette;
+}
+
+void QWindowsCEStyle::polish(QApplication *app) {
+ QWindowsStyle::polish(app);
+}
+
+void QWindowsCEStyle::polish(QWidget *widget) {
+ QWindowsStyle::polish(widget);
+}
+
+void QWindowsCEStyle::polish(QPalette &palette) {
+ QWindowsStyle::polish(palette);
+}
+
+int QWindowsCEStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const {
+ int ret;
+
+ switch (pm) {
+ case PM_DefaultFrameWidth:
+ ret = 1;
+ break;
+
+ case PM_MenuBarHMargin:
+ ret = 2;
+ break;
+ case PM_MenuBarVMargin:
+ ret = 2;
+ break;
+ /*case PM_MenuBarItemSpacing:
+ ret = 2;
+ break;*/
+
+ case PM_MenuButtonIndicator:
+ ret = 10;
+ break;
+
+ case PM_SpinBoxFrameWidth:
+ ret = 2;
+ break;
+ case PM_ButtonDefaultIndicator:
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 1;
+ break;
+#ifndef QT_NO_TABBAR
+ case PM_TabBarTabShiftHorizontal:
+ ret = 0;
+ break;
+ case PM_TabBarTabShiftVertical:
+ ret = 6;
+ break;
+#endif
+ case PM_MaximumDragDistance:
+ ret = 60;
+ break;
+
+ case PM_IndicatorWidth:
+ ret = windowsCEIndicatorSize;
+ break;
+
+ case PM_IndicatorHeight:
+ ret = windowsCEIndicatorSize;
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ ret = windowsCEExclusiveIndicatorSize;
+ break;
+
+ case PM_ExclusiveIndicatorHeight:
+ ret = windowsCEExclusiveIndicatorSize;;
+ break;
+
+#ifndef QT_NO_SLIDER
+ case PM_SliderLength:
+ ret = 12;
+ break;
+ case PM_SliderThickness:
+ ret = windowsCESliderThickness;
+ break;
+
+ case PM_TabBarScrollButtonWidth:
+ ret = 18;
+ break;
+
+ // Returns the number of pixels to use for the business part of the
+ // slider (i.e., the non-tickmark portion). The remaining space is shared
+ // equally between the tickmark regions.
+ case PM_SliderControlThickness:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
+ int ticks = sl->tickPosition;
+ int n = 0;
+ if (ticks & QSlider::TicksAbove)
+ ++n;
+ if (ticks & QSlider::TicksBelow)
+ ++n;
+ if (!n) {
+ ret = space;
+ break;
+ }
+ int thick = 12;
+ if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
+ thick += pixelMetric(PM_SliderLength, sl, widget) / 4;
+
+ space -= thick;
+ if (space > 0)
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ } else {
+ ret = 0;
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_MENU
+
+ case PM_SmallIconSize:
+ ret = windowsCEIconSize;
+ break;
+ case PM_ButtonMargin:
+ ret = 6;
+ break;
+
+ case PM_LargeIconSize:
+ ret = 32;
+ break;
+
+ case PM_IconViewIconSize:
+ ret = pixelMetric(PM_LargeIconSize, opt, widget);
+ break;
+
+ case PM_ToolBarIconSize:
+ ret = windowsCEIconSize;
+ break;
+ case PM_DockWidgetTitleMargin:
+ ret = 2;
+ break;
+#if defined(Q_WS_WIN)
+// case PM_DockWidgetFrameWidth:
+// ret = GetSystemMetrics(SM_CXFRAME);
+// break;
+#else
+ case PM_DockWidgetFrameWidth:
+ ret = 4;
+ break;
+#endif // Q_WS_WIN
+ break;
+
+#endif // QT_NO_MENU
+
+ case PM_TitleBarHeight:
+ ret = 30;
+ break;
+ case PM_ScrollBarExtent:
+ ret = 19;
+ break;
+ case PM_SplitterWidth:
+ ret = qMax(4, QApplication::globalStrut().width());
+ break;
+
+#if defined(Q_WS_WIN)
+ case PM_MDIFrameWidth:
+ ret = 3;
+ break;
+#endif
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 0;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = 10;
+ break;
+ case PM_ButtonIconSize:
+ ret = 22;
+ break;
+ default:
+ ret = QWindowsStyle::pixelMetric(pm, opt, widget);
+ break;
+ }
+ return ret;
+}
+
+QPixmap QWindowsCEStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const {
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ /*switch (standardPixmap) {
+
+ default:
+ break;
+ }*/
+#endif //QT_NO_IMAGEFORMAT_XPM
+ return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+int QWindowsCEStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *returnData) const {
+ int ret;
+ switch (hint) {
+ case SH_TabBar_ElideMode:
+ ret = Qt::ElideMiddle;
+ break;
+ case SH_EtchDisabledText:
+ ret = false;
+ break;
+ case SH_RequestSoftwareInputPanel:
+ ret = RSIP_OnMouseClick;
+ break;
+ default:
+ ret = QWindowsStyle::styleHint(hint, opt, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+void QWindowsCEStylePrivate::drawWinShades(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill) {
+ if (w < 2 || h < 2) // can't do anything with that
+ return;
+ QPen oldPen = p->pen();
+ QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
+ p->setPen(c1);
+ p->drawPolyline(a, 3);
+ QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
+ p->setPen(c2);
+ p->drawPolyline(b, 3);
+ if (w > 4 && h > 4) {
+ QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ p->setPen(c3);
+ p->drawPolyline(c, 3);
+ QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
+ p->setPen(c4);
+ p->drawPolyline(d, 3);
+ if (fill)
+ p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
+ }
+ p->setPen(oldPen);
+}
+
+void QWindowsCEStylePrivate::drawWinCEShades(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill) {
+ if (w < 2 || h < 2) // can't do anything with that
+ return;
+ QPen oldPen = p->pen();
+ QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
+ p->setPen(c2);
+ p->drawPolyline(b, 3);
+ if (w > 4 && h > 4) {
+ QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ p->setPen(c3);
+ p->drawPolyline(c, 3);
+ QPoint d[5] = { QPoint(x, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y), QPoint(x, y), QPoint(x, y+h-2) };
+ p->setPen(c4);
+ p->drawPolyline(d, 5);
+ if (fill)
+ p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
+ }
+ QPoint a[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ p->setPen(c1);
+ p->drawPolyline(a, 3);
+ p->setPen(oldPen);
+}
+
+void QWindowsCEStylePrivate::drawWinCEShadesSunken(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill) {
+ if (w < 2 || h < 2) // can't do anything with that
+ return;
+ QPen oldPen = p->pen();
+
+ QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
+ p->setPen(c2);
+ p->drawPolyline(b, 3);
+ if (w > 4 && h > 4) {
+ QPoint d[3] = { QPoint(x, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y) };
+ p->setPen(c4);
+ p->drawPolyline(d, 3);
+ QPoint c[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
+ p->setPen(c3);
+ p->drawPolyline(c, 3);
+ if (fill)
+ p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
+ }
+ QPoint a[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ p->setPen(c1);
+ p->drawPolyline(a, 3);
+ p->setPen(oldPen);
+}
+
+
+void QWindowsCEStylePrivate::drawWinCEButton(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ const QBrush *fill) {
+ if (sunken)
+ drawWinCEShadesSunken(p, x, y, w, h,
+ pal.shadow().color(), pal.light().color(), pal.shadow().color(),
+ pal.midlight().color(), fill);
+ else
+ drawWinCEShades(p, x, y, w, h,
+ pal.midlight().color(), pal.shadow().color(), pal.button().color(),
+ pal.dark().color(), fill);
+}
+
+void QWindowsCEStylePrivate::drawWinCEPanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ const QBrush *fill) {
+ if (sunken)
+ drawWinShades(p, x, y, w, h,
+ pal.dark().color(), pal.light().color(), pal.shadow().color(),
+ pal.midlight().color(), fill);
+ else
+ drawWinShades(p, x, y, w, h,
+ pal.light().color(), pal.shadow().color(), pal.button().color(),
+ pal.midlight().color(), fill);
+}
+
+void QWindowsCEStylePrivate::drawWinCEButton(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken, const QBrush *fill) {
+ drawWinCEButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
+}
+
+void QWindowsCEStylePrivate::drawWinCEPanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken, const QBrush *fill) {
+ drawWinCEPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWSCE
diff --git a/src/widgets/styles/qwindowscestyle.h b/src/widgets/styles/qwindowscestyle.h
new file mode 100644
index 0000000000..c9e7ecadfb
--- /dev/null
+++ b/src/widgets/styles/qwindowscestyle.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCESTYLE_H
+#define QWINDOWSCESTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSCE)
+
+class Q_GUI_EXPORT QWindowsCEStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QWindowsCEStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ virtual void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ void polish(QWidget *widget);
+ void polish(QPalette &palette);
+ void polish(QApplication *app);
+ QPalette standardPalette() const;
+};
+
+#endif // QT_NO_STYLE_WINDOWSCE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOWSCESTYLE_H
diff --git a/src/widgets/styles/qwindowscestyle_p.h b/src/widgets/styles/qwindowscestyle_p.h
new file mode 100644
index 0000000000..d32ac99d52
--- /dev/null
+++ b/src/widgets/styles/qwindowscestyle_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCE_P_H
+#define QWINDOWSCE_P_H
+
+#include "qwindowscestyle.h"
+#include <private/qwindowsstyle_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QPainter;
+class QPalette;
+class QPoint;
+class QColor;
+class QBrush;
+class QRect;
+
+// Private class
+class QWindowsCEStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsCEStyle)
+public:
+ inline QWindowsCEStylePrivate()
+ { }
+
+
+static void drawWinCEButton(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+static void drawWinCEButton(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+static void drawWinCEPanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+static void drawWinCEPanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+static void drawWinShades(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill);
+
+static void drawWinCEShades(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill);
+
+static void drawWinCEShadesSunken(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill);
+
+
+
+
+};
+
+QT_END_NAMESPACE
+
+#endif //QWINDOWSCE_P_H
diff --git a/src/widgets/styles/qwindowsmobilestyle.cpp b/src/widgets/styles/qwindowsmobilestyle.cpp
new file mode 100644
index 0000000000..1e029a30e0
--- /dev/null
+++ b/src/widgets/styles/qwindowsmobilestyle.cpp
@@ -0,0 +1,7283 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsmobilestyle.h"
+#include "qwindowsmobilestyle_p.h"
+
+#if !defined(QT_NO_STYLE_WINDOWSMOBILE) || defined(QT_PLUGIN)
+
+#include "qpainterpath.h"
+#include "qapplication.h"
+#include "qdesktopwidget.h"
+#include "qwidget.h"
+#include "qdockwidget.h"
+#include "qframe.h"
+#include "qmenu.h"
+#include "qpaintengine.h"
+#include "qpainter.h"
+#include "qgroupbox.h"
+#include "qstyleoption.h"
+#include "qlistview.h"
+#include "qdrawutil.h"
+#include "qtoolbar.h"
+#include "qabstractscrollarea.h"
+#include "qabstractbutton.h"
+#include "qcombobox.h"
+#include "qabstractscrollarea.h"
+#include "qframe.h"
+#include "qscrollbar.h"
+#include "qabstractitemview.h"
+#include "qmenubar.h"
+#include "qtoolbutton.h"
+#include "qtextedit.h"
+#include "qdialog.h"
+#include "qdebug.h"
+#include "qtabwidget.h"
+
+#ifdef Q_WS_WINCE
+#include "qt_windows.h"
+#include "qguifunctions_wince.h"
+extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_windows_mobile_65(); //defined in qguifunctions_wince.cpp
+#endif // Q_WS_WINCE
+
+#include "qstylehelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static const int windowsItemFrame = 1; // menu item frame width
+
+static const int windowsMobileitemViewCheckBoxSize = 13;
+static const int windowsMobileFrameGroupBoxOffset = 9;
+static const int windowsMobileIndicatorSize = 14;
+static const int windowsMobileExclusiveIndicatorSize = 14;
+static const int windowsMobileSliderThickness = 6;
+static const int windowsMobileIconSize = 16;
+static const int PE_IndicatorArrowUpBig = 0xf000101;
+static const int PE_IndicatorArrowDownBig = 0xf000102;
+static const int PE_IndicatorArrowLeftBig = 0xf000103;
+static const int PE_IndicatorArrowRightBig = 0xf000104;
+
+/* XPM */
+static const char *const radiobutton_xpm[] = {
+ "30 30 2 1",
+ " c None",
+ ". c #000000",
+ " ........ ",
+ " .............. ",
+ " .... .... ",
+ " .... .... ",
+ " ... ... ",
+ " ... ... ",
+ " .. .. ",
+ " .. .. ",
+ " ... ... ",
+ " .. .. ",
+ " .. .. ",
+ ".. ..",
+ ".. ..",
+ ".. ..",
+ ".. ..",
+ ".. ..",
+ ".. ..",
+ ".. ..",
+ ".. ..",
+ " .. .. ",
+ " .. .. ",
+ " ... ... ",
+ " .. .. ",
+ " .. .. ",
+ " ... ... ",
+ " ... ... ",
+ " .... .... ",
+ " .... .... ",
+ " .............. ",
+ " ........ "};
+
+/* XPM */
+static const char * const radiobutton_low_xpm[] = {
+ "15 15 2 1",
+ " c None",
+ ". c #000000",
+ " ..... ",
+ " .. .. ",
+ " . . ",
+ " . . ",
+ " . . ",
+ ". .",
+ ". .",
+ ". .",
+ ". .",
+ ". .",
+ " . . ",
+ " . . ",
+ " . . ",
+ " .. .. ",
+ " ..... "};
+
+/* XPM */
+ static const char * const arrowleft_big_xpm[] = {
+ "9 17 2 1",
+ " c None",
+ ". c #000000",
+ " .",
+ " ..",
+ " ...",
+ " ....",
+ " .....",
+ " ......",
+ " .......",
+ " ........",
+ ".........",
+ " ........",
+ " .......",
+ " ......",
+ " .....",
+ " ....",
+ " ...",
+ " ..",
+ " ."};
+
+/* XPM */
+ static const char * const arrowleft_xpm[] = {
+ "8 15 2 1",
+ " c None",
+ ". c #000000",
+ " .",
+ " ..",
+ " ...",
+ " ....",
+ " .....",
+ " ......",
+ " .......",
+ "........",
+ " .......",
+ " ......",
+ " .....",
+ " ....",
+ " ...",
+ " ..",
+ " ."};
+
+
+
+/* XPM */
+static const char *const horlines_xpm[] = {
+ "2 2 2 1",
+ " c None",
+ ". c #000000",
+ " ",
+ ".."};
+
+/* XPM */
+static const char *const vertlines_xpm[] = {
+ "2 2 2 1",
+ " c None",
+ ". c #000000",
+ ". ",
+ ". "};
+
+/* XPM */
+static const char *const radiochecked_xpm[] = {
+ "18 18 2 1",
+ " c None",
+ ". c #000000",
+ " ...... ",
+ " .......... ",
+ " .............. ",
+ " .............. ",
+ " ................ ",
+ " ................ ",
+ "..................",
+ "..................",
+ "..................",
+ "..................",
+ "..................",
+ "..................",
+ " ................ ",
+ " ................ ",
+ " .............. ",
+ " .............. ",
+ " .......... ",
+ " ...... "};
+
+/* XPM */
+static const char * const radiochecked_low_xpm[] = {
+ "9 9 2 1",
+ " c None",
+ ". c #000000",
+ " ... ",
+ " ....... ",
+ " ....... ",
+ ".........",
+ ".........",
+ ".........",
+ " ....... ",
+ " ....... ",
+ " ... "};
+
+static const char *const arrowdown_xpm[] = {
+ "15 8 2 1",
+ " c None",
+ ". c #000000",
+ "...............",
+ " ............. ",
+ " ........... ",
+ " ......... ",
+ " ....... ",
+ " ..... ",
+ " ... ",
+ " . "};
+
+
+static const char *const arrowdown_big_xpm[] = {
+ "17 9 2 1",
+ " c None",
+ ". c #000000",
+ ".................",
+ " ............... ",
+ " ............. ",
+ " ........... ",
+ " ......... ",
+ " ....... ",
+ " ..... ",
+ " ... ",
+ " . "};
+
+
+/* XPM */
+static const char *const checkedlight_xpm[] = {
+ "24 24 2 1",
+ " c None",
+ ". c #000000",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " . ",
+ " .. ",
+ " ... ",
+ " .... ",
+ " ..... ",
+ " ...... ",
+ " . ...... ",
+ " .. ...... ",
+ " ... ...... ",
+ " .... ...... ",
+ " .......... ",
+ " ......... ",
+ " ....... ",
+ " ..... ",
+ " ... ",
+ " . ",
+ " ",
+ " ",
+ " "};
+
+
+/* XPM */
+static const char *const checkedbold_xpm[] = {
+ "26 26 2 1",
+ " c None",
+ ". c #000000",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " .. ",
+ " ... ",
+ " .... ",
+ " ..... ",
+ " .. ...... ",
+ " ... ....... ",
+ " .... ....... ",
+ " ..... ....... ",
+ " ...... ....... ",
+ " .............. ",
+ " ............ ",
+ " .......... ",
+ " ........ ",
+ " ...... ",
+ " .... ",
+ " .. ",
+ " ",
+ " ",
+ " ",
+ " "};
+
+/* XPM */
+static const char * const checkedbold_low_xpm[] = {
+ "9 8 2 1",
+ " c None",
+ ". c #000000",
+ " .",
+ " ..",
+ ". ...",
+ ".. ... ",
+ "... ... ",
+ " ..... ",
+ " ... ",
+ " . "};
+
+/* XPM */
+static const char * const checkedlight_low_xpm[] = {
+ "8 8 2 1",
+ " c None",
+ ". c #000000",
+ " .",
+ " ..",
+ " ...",
+ ". ... ",
+ ".. ... ",
+ "..... ",
+ " ... ",
+ " . "};
+
+/* XPM */
+static const char * const highlightedradiobutton_xpm[] = {
+ "30 30 3 1",
+ " c None",
+ ". c #000000",
+ "+ c #0078CC",
+ " ........ ",
+ " .............. ",
+ " ....++++++++.... ",
+ " ....++++++++++++.... ",
+ " ...++++ ++++... ",
+ " ...+++ +++... ",
+ " ..++ ++.. ",
+ " ..++ ++.. ",
+ " ...++ ++... ",
+ " ..++ ++.. ",
+ " ..++ ++.. ",
+ "..++ ++..",
+ "..++ ++..",
+ "..++ ++..",
+ "..++ ++..",
+ "..++ ++..",
+ "..++ ++..",
+ "..++ ++..",
+ "..++ ++..",
+ " ..++ ++.. ",
+ " ..++ ++.. ",
+ " ...++ ++... ",
+ " ..++ ++.. ",
+ " ..++ ++.. ",
+ " ...+++ +++... ",
+ " ...++++ ++++... ",
+ " ....++++++++++++.... ",
+ " ....++++++++.... ",
+ " .............. ",
+ " ........ "};
+
+/* XPM */
+static const char * const highlightedradiobutton_low_xpm[] = {
+ "15 15 3 1",
+ " c None",
+ ". c #000000",
+ "+ c #3192D6",
+ " ..... ",
+ " ..+++++.. ",
+ " .++ ++. ",
+ " .+ +. ",
+ " .+ +. ",
+ ".+ +.",
+ ".+ +.",
+ ".+ +.",
+ ".+ +.",
+ ".+ +.",
+ " .+ +. ",
+ " .+ +. ",
+ " .++ ++. ",
+ " ..+++++.. ",
+ " ..... "};
+
+/* XPM */
+static const char * const cross_big_xpm[] = {
+"28 28 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
+" ",
+" ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++..@@@..........@@@..++ ",
+" ++..@@@@........@@@@..++ ",
+" ++..@@@@@......@@@@@..++ ",
+" ++...@@@@@....@@@@@...++ ",
+" ++....@@@@@..@@@@@....++ ",
+" ++.....@@@@@@@@@@.....++ ",
+" ++......@@@@@@@@......++ ",
+" ++.......@@@@@@.......++ ",
+" ++.......@@@@@@.......++ ",
+" ++......@@@@@@@@......++ ",
+" ++.....@@@@@@@@@@.....++ ",
+" ++....@@@@@..@@@@@....++ ",
+" ++...@@@@@....@@@@@...++ ",
+" ++..@@@@@......@@@@@..++ ",
+" ++..@@@@........@@@@..++ ",
+" ++..@@@..........@@@..++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ",
+" "};
+
+/* XPM */
+static const char * const cross_small_xpm[] = {
+"14 14 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
+" ",
+" ++++++++++++ ",
+" +..........+ ",
+" +.@@....@@.+ ",
+" +.@@@..@@@.+ ",
+" +..@@@@@@..+ ",
+" +...@@@@...+ ",
+" +...@@@@...+ ",
+" +..@@@@@@..+ ",
+" +.@@@..@@@.+ ",
+" +.@@....@@.+ ",
+" +..........+ ",
+" ++++++++++++ ",
+" "};
+
+/* XPM */
+static const char * const max_big_xpm[] = {
+"28 28 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
+" ",
+" ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ",
+" "};
+
+/* XPM */
+static const char * const max_small_xpm[] = {
+"14 14 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
+" ",
+" ++++++++++++ ",
+" +..........+ ",
+" +..........+ ",
+" +.@@@@@@@@.+ ",
+" +.@@@@@@@@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@@@@@@@@.+ ",
+" +..........+ ",
+" +..........+ ",
+" ++++++++++++ ",
+" "};
+
+/* XPM */
+static const char * const normal_big_xpm[] = {
+"28 28 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
+" ",
+" ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@............@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ",
+" "};
+
+/* XPM */
+static const char * const normal_small_xpm[] = {
+"14 14 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
+" ",
+" ++++++++++++ ",
+" +..........+ ",
+" +.@@@@@@@@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@......@.+ ",
+" +.@@@@@@@@.+ ",
+" +..........+ ",
+" ++++++++++++ ",
+" "};
+
+
+/* XPM */
+static const char * const min_big_xpm[] = {
+"28 28 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
+" ",
+" ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++..@@@@@@@@@@@@@@@@..++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++....................++ ",
+" ++++++++++++++++++++++++ ",
+" ++++++++++++++++++++++++ ",
+" ",
+" "};
+
+/* XPM */
+static const char * const min_small_xpm[] = {
+"14 14 4 1",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
+" ",
+" ++++++++++++ ",
+" +..........+ ",
+" +..........+ ",
+" +..........+ ",
+" +..........+ ",
+" +..........+ ",
+" +..........+ ",
+" +..........+ ",
+" +.@@@@@@@@.+ ",
+" +..........+ ",
+" +..........+ ",
+" ++++++++++++ ",
+" "};
+
+#ifdef Q_WS_WINCE_WM
+
+static char * sbhandleup_xpm[] = {
+"26 41 45 1",
+" c None",
+". c #000000",
+"+ c #E7E7E7",
+"@ c #D6D7D6",
+"# c #949294",
+"$ c #737573",
+"% c #636563",
+"& c #636163",
+"* c #5A5D5A",
+"= c #5A595A",
+"- c #525552",
+"; c #525152",
+"> c #4A4D4A",
+", c #7B797B",
+"' c #CECFCE",
+") c #CED3CE",
+"! c #6B6D6B",
+"~ c #6B696B",
+"{ c #737173",
+"] c #7B7D7B",
+"^ c #848684",
+"/ c #848284",
+"( c #8C8A8C",
+"_ c #8C8E8C",
+": c #B5B2B5",
+"< c #FFFFFF",
+"[ c #949694",
+"} c #B5B6B5",
+"| c #9C9A9C",
+"1 c #ADAEAD",
+"2 c #9C9E9C",
+"3 c #BDBABD",
+"4 c #BDBEBD",
+"5 c #F7F3F7",
+"6 c #C6C3C6",
+"7 c #C6C7C6",
+"8 c #A5A2A5",
+"9 c #CECBCE",
+"0 c #FFFBFF",
+"a c #ADAAAD",
+"b c #A5A6A5",
+"c c #D6D3D6",
+"d c #B5BAB5",
+"e c #DEDFDE",
+"f c #DEDBDE",
+"..........................",
+"+@#$%%&&&**===---;;;;>=,'+",
+"+@#$%%&&&**===---;;;;>=$'+",
+")$!!~~%%&&&**===---;;;;>;'",
+"#{$]],,$${{{!!~~%%%&&&*-;]",
+"#{$]],,$${{{!!~~%%%&&&*-;]",
+",$^//]],,$${{{!!~~%%%&&*;*",
+",,(^^//]],$${!!!!!~~%%%&-*",
+",,(^^//]],$${!!!!!~~%%%&-*",
+"]]_((^^//]$!%%~!{{!!~~%%-*",
+"//#__((^^]{:<<:~!{{{!!~~=*",
+"//#__((^^]{:<<:~!{{{!!~~=&",
+"//###__(/$:<<<<:~{${{!!~*&",
+"^^[[##_^]:<<<<<<}!{$${{!*%",
+"^^[[##_^]:<<<<<<}!{$${{!*%",
+"((|[[#_/:<<<<<<<<}!$$${{&~",
+"((||[#^1<<<<1:<<<<}!$$$$&~",
+"((||[#^1<<<<1:<<<<}!$$$$&~",
+"__2|#(1<<<<}],}<<<<}{$,$%~",
+"##2|_1<<<<}^((]3<<<<}{$,~!",
+"##2|_1<<<<}^((]3<<<<}{$,~!",
+"##2#1<<<<3^###(/4<<<<}{,~{",
+"##2#1<<<<3^###(/4<<<<}{,~!",
+"[[2_5<<<4(#|[[#_/6<<<<,,!{",
+"[|2_5<<4_[||||[[_/7<<<,]{$",
+"[|2_5<<4_[||||[[_/7<<<,]{$",
+"||8_5<6#|2222|||[_/9<<,]{$",
+"228#06[28888222||[_/'<,/$,",
+"228#06[28888222||[_/'<,/$,",
+"22a|6[8bbbb88822||[(/c](,]",
+"881b8baaabbbb88222|[(^(_,]",
+"881b8baaabbbb88222|[(^(_,]",
+"88111111aaabbb88822|[###]/",
+"bb:::11111aaabbb8822||[[/^",
+"bb:::11111aaabbb8822||[[//",
+"bb:::::1111aaabbb8822||[/(",
+"3a1::::::1111aaabb8822|_^8",
+"da1::::::1111aaabb8822|_^8",
+"e1aaabbbb888822||[[##__((@",
+"+e4:aaabbbb88822||[[[#[b@+",
+"+e4:aaabbbb88822||[[[#[bf+"};
+
+static char * sbhandledown_xpm[] = {
+"26 40 46 1",
+" c None",
+". c #E7E7E7",
+"+ c #DEDFDE",
+"@ c #BDBEBD",
+"# c #B5B2B5",
+"$ c #ADAAAD",
+"% c #A5A6A5",
+"& c #A5A2A5",
+"* c #9C9E9C",
+"= c #9C9A9C",
+"- c #949694",
+"; c #949294",
+"> c #D6D7D6",
+", c #DEDBDE",
+"' c #D6DBD6",
+") c #ADAEAD",
+"! c #8C8E8C",
+"~ c #8C8A8C",
+"{ c #BDBABD",
+"] c #848684",
+"^ c #B5BAB5",
+"/ c #848284",
+"( c #848A84",
+"_ c #7B7D7B",
+": c #7B797B",
+"< c #C6C3C6",
+"[ c #D6D3D6",
+"} c #FFFBFF",
+"| c #CECFCE",
+"1 c #FFFFFF",
+"2 c #737573",
+"3 c #F7F3F7",
+"4 c #CECBCE",
+"5 c #737173",
+"6 c #C6C7C6",
+"7 c #6B6D6B",
+"8 c #B5B6B5",
+"9 c #6B696B",
+"0 c #636563",
+"a c #636163",
+"b c #5A5D5A",
+"c c #5A595A",
+"d c #525552",
+"e c #525152",
+"f c #4A4D4A",
+"g c #C6CBC6",
+".+@#$$$%%%%&&&**==---;-%>.",
+".+@#$$$%%%%&&&**==---;-%,.",
+"')$$$%%%%&&&&**==--;;!!~~>",
+"{$)######))))$$$%%&&**=!]&",
+"^$)######))))$$$%%&&**=!]&",
+"%%#####))))$$$%%%&&**==-/(",
+"%%###)))))$$$%%%&&**==--/]",
+"%%###)))))$$$%%%&&**==--//",
+"&&))))))$$$%%%&&&**=-;;;_/",
+"&&)%&%$$$%%%%&&***=-~]~!:_",
+"&&)%&%$$$%%%%&&***=-~]~!:_",
+"**$=<-&%%%%&&&**==-~/[_~:_",
+"**&;}<-*&&&&***==-!/|1:/2:",
+"**&;}<-*&&&&***==-!/|1:/2:",
+"==&!31<;=****===-!/411:_5:",
+"-=*!311@!-====--!/6111:_52",
+"-=*!311@!-====--!/6111:_52",
+"--*!3111@~;=--;!/<1111::75",
+";;*;)1111{];;;~/@111185:95",
+";;*;)1111{];;;~/@111185:97",
+";;*=!)11118]~~_{1111852:97",
+";;*=!)11118]~~_{1111852:97",
+"!!*=;~)11118_:81111852:207",
+"~~==-;])1111)#1111872222a9",
+"~~==-;])1111)#1111872222a9",
+"~~=--;!/#111111118722255a0",
+"]]--;;!]_#11111187522557b0",
+"]]--;;!]_#11111187522557b0",
+"//;;;!!~/2#1111#95255779ba",
+"//;!!~~]]_5#11#975557799cb",
+"//;!!~~]]_5#11#975557799ca",
+"__!~~]]//_27009755779900db",
+"::~]]//__:2257777799000adb",
+"::~]]//__:2257777799000adb",
+":2]//__::225557799000aabeb",
+";52__::225557799000aaabde_",
+";52__::225557799000aaabde_",
+"[2779900aaabbcccdddeeeefeg",
+".>;200aaabbcccdddeeeefc:|.",
+".>;200aaabbcccdddeeeefc2|."};
+
+static char * sbgripdown_xpm[] = {
+"26 34 39 1",
+" c None",
+". c #949294",
+"+ c #9C9E9C",
+"@ c #9C9A9C",
+"# c #949694",
+"$ c #8C8E8C",
+"% c #8C8A8C",
+"& c #848684",
+"* c #848284",
+"= c #7B7D7B",
+"- c #7B797B",
+"; c #6B696B",
+"> c #636563",
+", c #737573",
+"' c #636163",
+") c #737173",
+"! c #5A5D5A",
+"~ c #6B6D6B",
+"{ c #5A595A",
+"] c #B5B6B5",
+"^ c #BDBEBD",
+"/ c #ADAEAD",
+"( c #BDBABD",
+"_ c #525552",
+": c #313031",
+"< c #525152",
+"[ c #ADAAAD",
+"} c #BDBAB5",
+"| c #4A4D4A",
+"1 c #4A494A",
+"2 c #C6C3C6",
+"3 c #C6CBC6",
+"4 c #E7E7E7",
+"5 c #DEDFDE",
+"6 c #E7E3E7",
+"7 c #DEE3DE",
+"8 c #CECBCE",
+"9 c #8C928C",
+"0 c #CECFCE",
+"..+++@@@###...$$%&&**==-;>",
+"$.++@@@@##...$$%%&**==-->>",
+"$$+@@@@###..$$%%&&*==--,>>",
+"$$@@@@###..$$%%&&**==-,,>'",
+"%%@@@###..$$$%&&**==--,,''",
+"%%@@###..$$$%&&**==--,,)''",
+"%%@###...$$%%&&*==--,,))'!",
+"&&###...$$%%&&**==--,)))!!",
+"&&##...$$%%&&**==--,,))~!!",
+"&&#...$$%%&&**==--,,))~~!{",
+"**...$$%%&&**==--,,))~~;!{",
+"**..$$%%&&**===--,)))~~;{{",
+"**.$$%%&]^&===//,,))~~;;{{",
+"==$$%%&&]^*==-((,))~~;;>{_",
+"==$%%&&***::--,,::~~;;;>__",
+"==%%&&&**=::-,,)::~~;;>>__",
+"--%&&&**==--,,)))~~;;>>>__",
+"--&&&**==--,,)))~~;;>>>'_<",
+",-&&**==]^-,))[[~;;>>>''<<",
+",,&**==-]^-)))}};;>>>'''<<",
+",,**==--,,::)~~;::>>'''!<<",
+"))*==--,,)::~~;;::>'''!!<|",
+"))==--,,)))~~;;;>>'''!!!||",
+"))=--,,)))~~;;;>>'''!!!{||",
+"~~--,,)))~~;;;>>'''!!!{{||",
+"~~-,,)))~~;;>>>'''!!!{{{|1",
+";;,,)))~~;;>>>'''!!!{{{_1<",
+"~;,)))~~;;>>>'''!!!{{{__1'",
+"%>~))~~;;>>>'''!!!{{{__|1$",
+"2>>~~~;;>>>''!!!{{{{__<113",
+"4%'';;;>>>''!!!{{{{__<11%4",
+"45-!!'>>>''!!!{{{{_<|11)64",
+"447+!{{___<<<||||1111|+444",
+"444489~__<<<||||111>$04444"};
+
+static char * sbgripup_xpm[] = {
+"26 34 38 1",
+" c None",
+". c #E7E7E7",
+"+ c #D6DBD6",
+"@ c #C6C7C6",
+"# c #B5B6B5",
+"$ c #ADAEAD",
+"% c #ADAAAD",
+"& c #A5A6A5",
+"* c #A5A2A5",
+"= c #BDBEBD",
+"- c #DEDFDE",
+"; c #C6CBC6",
+"> c #9C9E9C",
+", c #E7E3E7",
+"' c #BDBABD",
+") c #B5B2B5",
+"! c #9C9A9C",
+"~ c #DEE3DE",
+"{ c #949694",
+"] c #D6D7D6",
+"^ c #949294",
+"/ c #DEDBDE",
+"( c #8C8E8C",
+"_ c #8C8A8C",
+": c #848684",
+"< c #D6D3CE",
+"[ c #CECBCE",
+"} c #D6D3D6",
+"| c #848284",
+"1 c #313031",
+"2 c #7B7D7B",
+"3 c #CECFCE",
+"4 c #CECBC6",
+"5 c #7B797B",
+"6 c #737573",
+"7 c #737173",
+"8 c #6B6D6B",
+"9 c #6B696B",
+"....+@#$$%%%%&&&***$=-....",
+"...;$$$$$%%%&&&&**>>>>@...",
+".,'$$)#'#####)))$$$%*!!$~.",
+".=$)#'''####))))$$$%%*!{'.",
+"]$$''''#####)))$$$%%%&*{^/",
+"=$#'''#####)))$$$$%%&&&!^#",
+"$$'''#####))))$$$%%%&&*>(!",
+"$$''#####))))$$$%%%&&&*>(^",
+"$$######))))$$$$%%&&&**>(_",
+"%$#####))))$$$$%%%&&***>__",
+"%$####))))$$$$%%%&&&**>>__",
+"%%###)))))$$$%%%&&&**>>>_:",
+"%%##))))<])$$%[[&&***>>!::",
+"%%#)))))<]$$%%}<&&**>>!!:|",
+"&%)))))$$$11%%&&11*>>>!!:|",
+"&&))))$$$$11%&&&11*>>!!{||",
+"&&)))$$$$$%%%&&&**>>!!!{|2",
+"&&))$$$$$%%%&&&**>>>!!{{|2",
+"*&)$$$$$3]%&&&4@*>>!!{{{22",
+"**$$$$$%3]%&&&<<>>!!!{{^25",
+"**$$$$%%%%11&**>11!!{{^^25",
+"**$$$%%%%&11***>11!!{{^^55",
+"**$$%%%%&&&***>>!!!{{^^(55",
+">>$%%%%&&&***>>>!!{{^^((56",
+">>%%%%&&&&***>>!!!{{^^((66",
+">>%%%&&&&***>>!!!{{^^((_67",
+"!>%%&&&&***>>>!!{{{^^(__67",
+"!!%&&&&***>>>!!!{{^^((_:77",
+"!!&&&&***>>>!!!{{^^((__:77",
+"!!&&&****>>!!!{{^^^(__::78",
+"{!&&****>>>!!{{{^^((_::|88",
+"{{&****>>>!!!{{^^((__:||88",
+"{{****>>>!!!{{^^^(__::|289",
+"{{***>>>!!!{{{^^((_::||289"};
+
+static char * sbgripmiddle_xpm[] = {
+"26 2 12 1",
+" c None",
+". c #949294",
+"+ c #A5A2A5",
+"@ c #9C9E9C",
+"# c #9C9A9C",
+"$ c #949694",
+"% c #8C8E8C",
+"& c #8C8A8C",
+"* c #848684",
+"= c #848284",
+"- c #7B7D7B",
+"; c #6B696B",
+"..++@@@###$$$..%%&&*==--;;",
+"..++@@@###$$$..%%&&*==--;;"};
+
+
+static char * listviewhighmiddle_xpm[] = {
+"8 46 197 2",
+" c None",
+". c #66759E",
+"+ c #6C789D",
+"@ c #6A789E",
+"# c #6B789E",
+"$ c #6A779D",
+"% c #6C789C",
+"& c #6F7D9B",
+"* c #6F7D9A",
+"= c #9DB6EE",
+"- c #9DB6ED",
+"; c #9CB6ED",
+"> c #A1B6EF",
+", c #A2B6F0",
+"' c #93AAE9",
+") c #95ABEA",
+"! c #94ABEA",
+"~ c #94A9E8",
+"{ c #8BA8EA",
+"] c #8BA7EA",
+"^ c #8AA7EA",
+"/ c #8EAAE8",
+"( c #8FAAE8",
+"_ c #88A2E7",
+": c #8CA3E8",
+"< c #8BA3E7",
+"[ c #8BA3E8",
+"} c #8BA2E7",
+"| c #8CA2E7",
+"1 c #8DA2E7",
+"2 c #87A1E8",
+"3 c #87A1E9",
+"4 c #86A0E8",
+"5 c #86A1E7",
+"6 c #87A2E7",
+"7 c #859EE9",
+"8 c #849DE9",
+"9 c #869EE9",
+"0 c #869FE9",
+"a c #7C9BEA",
+"b c #7C9CEA",
+"c c #7B9CEA",
+"d c #7C9BE9",
+"e c #7E9CE9",
+"f c #7B9AEA",
+"g c #7C99E9",
+"h c #7C9AEA",
+"i c #7B9AE8",
+"j c #7A9AEA",
+"k c #7996E1",
+"l c #7C96E4",
+"m c #7B96E3",
+"n c #7B95E3",
+"o c #7E95E5",
+"p c #7E95E6",
+"q c #7292E1",
+"r c #7490DF",
+"s c #7591E0",
+"t c #7590DF",
+"u c #7392E1",
+"v c #6D8CDE",
+"w c #6F8EDD",
+"x c #6E8DDD",
+"y c #6E8DDE",
+"z c #6F8EDE",
+"A c #6E8EDE",
+"B c #718EDD",
+"C c #728EDD",
+"D c #6B89E0",
+"E c #6C89DF",
+"F c #6D89E0",
+"G c #6D89DF",
+"H c #6C88DF",
+"I c #6D88DF",
+"J c #6D86DD",
+"K c #6086E0",
+"L c #6686E0",
+"M c #6586E0",
+"N c #6486E0",
+"O c #6485E0",
+"P c #6786DF",
+"Q c #5F85E0",
+"R c #6583DE",
+"S c #6683DE",
+"T c #6682DD",
+"U c #6086DF",
+"V c #5F86E0",
+"W c #567ED7",
+"X c #567ED8",
+"Y c #557DD7",
+"Z c #5A7FD8",
+"` c #6281DA",
+" . c #5379D9",
+".. c #5278D9",
+"+. c #547BD8",
+"@. c #4C73D7",
+"#. c #4B72D2",
+"$. c #4C73D4",
+"%. c #4C73D3",
+"&. c #4B72D4",
+"*. c #4F75D3",
+"=. c #5074D2",
+"-. c #4971D0",
+";. c #4871D0",
+">. c #335ECF",
+",. c #325ECB",
+"'. c #335ECD",
+"). c #335ECE",
+"!. c #325DCD",
+"~. c #2E59C9",
+"{. c #3059C9",
+"]. c #2F59C9",
+"^. c #2F59C8",
+"/. c #2B59CA",
+"(. c #3355C6",
+"_. c #3354C5",
+":. c #3156C7",
+"<. c #3056C7",
+"[. c #3355C7",
+"}. c #3355C5",
+"|. c #254EBF",
+"1. c #1F51C1",
+"2. c #234FC0",
+"3. c #234FBF",
+"4. c #2350C0",
+"5. c #1E50BE",
+"6. c #1D50C0",
+"7. c #264DBE",
+"8. c #264CBD",
+"9. c #254DBE",
+"0. c #244EBF",
+"a. c #254DBF",
+"b. c #234CBF",
+"c. c #244CC0",
+"d. c #244BC0",
+"e. c #234BC0",
+"f. c #234BBF",
+"g. c #234CBE",
+"h. c #2049B7",
+"i. c #2A49B5",
+"j. c #2749B5",
+"k. c #2749B6",
+"l. c #2D49B4",
+"m. c #2649B6",
+"n. c #2946B5",
+"o. c #2A48B6",
+"p. c #2947B5",
+"q. c #2946B6",
+"r. c #2848B6",
+"s. c #2549B5",
+"t. c #2648B6",
+"u. c #2744B5",
+"v. c #2744B4",
+"w. c #2744AF",
+"x. c #2543B4",
+"y. c #2543B2",
+"z. c #2442B2",
+"A. c #2442B3",
+"B. c #2442B5",
+"C. c #2543B3",
+"D. c #1F40B1",
+"E. c #1E40B1",
+"F. c #243EAE",
+"G. c #273BAC",
+"H. c #263DAC",
+"I. c #253CAB",
+"J. c #273CAB",
+"K. c #273CAC",
+"L. c #263BAA",
+"M. c #253CAE",
+"N. c #263BA6",
+"O. c #253BA5",
+"P. c #253AA5",
+"Q. c #253BA6",
+"R. c #253CA7",
+"S. c #263AA6",
+"T. c #243CA6",
+"U. c #253CA5",
+"V. c #273BA8",
+"W. c #2F4DA4",
+"X. c #2F4DA3",
+"Y. c #1B2F85",
+"Z. c #B5B5B6",
+"`. c #B5B5B5",
+" + c #B5B6B6",
+".+ c #B5B4B6",
+"++ c #C2C3C5",
+"@+ c #C0C3C3",
+"#+ c #C1C3C4",
+"$+ c #E3E3E3",
+"%+ c #E3E3E4",
+"&+ c #E4E3E4",
+"*+ c #E2E3E4",
+"=+ c #ECEEEB",
+"-+ c #EBEDEA",
+";+ c #EEF0ED",
+">+ c #EFF0EE",
+". + @ @ # # $ % ",
+"& & * & & & & & ",
+"= = - = = ; > , ",
+"' ) ! ! ! ) ' ~ ",
+"{ ] { { { ^ / ( ",
+"_ : < [ : } | 1 ",
+"2 2 2 3 2 4 5 6 ",
+"7 7 7 7 7 8 9 0 ",
+"a b a a a c d e ",
+"f g h h h h i j ",
+"k l m m m n o p ",
+"q q q q q q q q ",
+"r r s s s t q u ",
+"v w x y z A B C ",
+"D E F F G F H I ",
+"J K L M N O P Q ",
+"R R S S S T U V ",
+"W W X X X Y Z ` ",
+" . . . . ...+.W ",
+" . . . . ..... .",
+"@.#.$.$.%.&.*.=.",
+"-.-.;.-.-.-.-.-.",
+">.,.'.).).!.!.>.",
+"~.{.].^.].^././.",
+"(.(.(.(.(._.:.<.",
+"(.(.[.[.[.[.(.}.",
+"|.1.2.3.3.4.5.6.",
+"7.7.7.7.7.8.9.0.",
+"a.b.c.d.c.e.f.g.",
+"h.i.j.k.j.k.l.m.",
+"n.o.p.q.r.p.s.t.",
+"u.u.v.u.u.u.u.u.",
+"w.x.y.z.A.y.B.C.",
+"D.D.E.D.D.D.D.D.",
+"D.D.E.D.D.D.D.D.",
+"F.G.H.I.J.K.L.M.",
+"N.N.O.N.N.P.Q.R.",
+"N.N.S.N.N.N.N.N.",
+"T.N.T.T.T.U.N.V.",
+"W.W.X.W.W.W.W.W.",
+"W.W.W.W.W.W.W.W.",
+"Y.Y.Y.Y.Y.Y.Y.Y.",
+"Z.`. + +.+Z.`.`.",
+"++@+#+#+#+#+@+@+",
+"$+%+&+&+*+%+%+%+",
+"=+-+;+-+-+>+-+-+"};
+
+
+
+static char * listviewhighcornerleft_xpm[] = {
+"100 46 1475 2",
+" c None",
+". c #FBFBFC",
+"+ c #E8EAE7",
+"@ c #758DC3",
+"# c #42599E",
+"$ c #28418A",
+"% c #19418F",
+"& c #3F5695",
+"* c #415896",
+"= c #435A98",
+"- c #445C99",
+"; c #465E9B",
+"> c #48609B",
+", c #49629C",
+"' c #4A639D",
+") c #49639D",
+"! c #4A629D",
+"~ c #4B639D",
+"{ c #4B649D",
+"] c #4C659D",
+"^ c #4D669D",
+"/ c #4E689D",
+"( c #506A9D",
+"_ c #516A9D",
+": c #536B9C",
+"< c #546C9C",
+"[ c #566D9B",
+"} c #576D9B",
+"| c #586E9C",
+"1 c #5B6F9D",
+"2 c #61739D",
+"3 c #63749E",
+"4 c #64749E",
+"5 c #68769E",
+"6 c #6A779E",
+"7 c #6B789E",
+"8 c #66759E",
+"9 c #6C789D",
+"0 c #EEF0ED",
+"a c #D0D3DC",
+"b c #3E51A3",
+"c c #28428B",
+"d c #29428C",
+"e c #425996",
+"f c #455C99",
+"g c #485F9C",
+"h c #49619E",
+"i c #4A63A0",
+"j c #4B64A1",
+"k c #4B65A1",
+"l c #4C66A2",
+"m c #4D67A2",
+"n c #4F69A1",
+"o c #516AA1",
+"p c #536CA0",
+"q c #556DA1",
+"r c #576EA0",
+"s c #586F9F",
+"t c #586E9F",
+"u c #596F9E",
+"v c #5A6F9E",
+"w c #5C709E",
+"x c #5E719E",
+"y c #5F729F",
+"z c #62739F",
+"A c #63739E",
+"B c #64749D",
+"C c #65749E",
+"D c #69769D",
+"E c #6C799E",
+"F c #6D799F",
+"G c #707D9F",
+"H c #717F9E",
+"I c #6E7AA1",
+"J c #6C789E",
+"K c #6F7C9C",
+"L c #6F7D9B",
+"M c #2A4AA0",
+"N c #4971D0",
+"O c #4C72D8",
+"P c #5472C0",
+"Q c #5573BF",
+"R c #5774BF",
+"S c #5875BF",
+"T c #5976C1",
+"U c #5A76C1",
+"V c #5C78C2",
+"W c #5E7AC2",
+"X c #607CC3",
+"Y c #627EC3",
+"Z c #637FC4",
+"` c #6581C5",
+" . c #6682C6",
+".. c #6783C7",
+"+. c #6984C8",
+"@. c #6B85C9",
+"#. c #6D87CA",
+"$. c #6F89CB",
+"%. c #718CCD",
+"&. c #748ECF",
+"*. c #7690D0",
+"=. c #7992D2",
+"-. c #7A93D3",
+";. c #7C95D5",
+">. c #7F98D7",
+",. c #8099D8",
+"'. c #859CDB",
+"). c #8AA0DD",
+"!. c #8DA3DF",
+"~. c #8FA5E0",
+"{. c #90A5E0",
+"]. c #91A6E1",
+"^. c #91A5E1",
+"/. c #90A4E0",
+"(. c #8EA3DE",
+"_. c #92A6E2",
+":. c #8FA4DF",
+"<. c #90A5DE",
+"[. c #90A5DC",
+"}. c #90A6DB",
+"|. c #91A6E0",
+"1. c #93A7E2",
+"2. c #95AAE6",
+"3. c #99AEEA",
+"4. c #9AB2EA",
+"5. c #99B1E9",
+"6. c #99B1E7",
+"7. c #98AFE6",
+"8. c #93A8E2",
+"9. c #97ACE7",
+"0. c #9AB3EB",
+"a. c #9DB5ED",
+"b. c #9DB6EE",
+"c. c #375095",
+"d. c #4056AD",
+"e. c #506DCD",
+"f. c #4360CC",
+"g. c #345ED6",
+"h. c #335ECF",
+"i. c #355ED6",
+"j. c #355FD6",
+"k. c #365FD6",
+"l. c #355FD0",
+"m. c #3760D5",
+"n. c #3A63D4",
+"o. c #3C63D1",
+"p. c #3B63CD",
+"q. c #3B63C9",
+"r. c #3B62C9",
+"s. c #3D63C8",
+"t. c #4065C5",
+"u. c #4567C5",
+"v. c #496BC5",
+"w. c #4F70C7",
+"x. c #5273C8",
+"y. c #5475CA",
+"z. c #5777CB",
+"A. c #5879CD",
+"B. c #5A7BCE",
+"C. c #5D7DCF",
+"D. c #5F7ECF",
+"E. c #617FD0",
+"F. c #6381D1",
+"G. c #6583D2",
+"H. c #6785D2",
+"I. c #6886D3",
+"J. c #6A88D4",
+"K. c #6C89D5",
+"L. c #6E8BD6",
+"M. c #708CD7",
+"N. c #718DD8",
+"O. c #738EDA",
+"P. c #748FDB",
+"Q. c #7691DC",
+"R. c #7893DD",
+"S. c #7994DD",
+"T. c #7A96DE",
+"U. c #7B97DF",
+"V. c #7C98E0",
+"W. c #7E9AE2",
+"X. c #7F9BE3",
+"Y. c #829DE4",
+"Z. c #849FE5",
+"`. c #87A0E6",
+" + c #88A1E7",
+".+ c #89A2E6",
+"++ c #8CA3E7",
+"@+ c #8EA5E9",
+"#+ c #8EA6E9",
+"$+ c #8FA7E9",
+"%+ c #8FA8E8",
+"&+ c #8FA9E8",
+"*+ c #91A9E8",
+"=+ c #90A7E8",
+"-+ c #8FA8EA",
+";+ c #90AAEA",
+">+ c #93ABEA",
+",+ c #95ABEA",
+"'+ c #93ABE9",
+")+ c #94ABEA",
+"!+ c #90A9EA",
+"~+ c #93AAE9",
+"{+ c #273E7E",
+"]+ c #345ED5",
+"^+ c #3D60CE",
+"/+ c #3D60CF",
+"(+ c #345ECF",
+"_+ c #335ED0",
+":+ c #355FD3",
+"<+ c #3A60CE",
+"[+ c #3A5FCB",
+"}+ c #385FC9",
+"|+ c #3B60C8",
+"1+ c #3C63CB",
+"2+ c #3E64CB",
+"3+ c #4166CA",
+"4+ c #4568C9",
+"5+ c #4A6CC7",
+"6+ c #4F71C8",
+"7+ c #5172CA",
+"8+ c #5475CE",
+"9+ c #5678D3",
+"0+ c #597CD6",
+"a+ c #5C7ED7",
+"b+ c #5E7FD8",
+"c+ c #6181D9",
+"d+ c #6383DA",
+"e+ c #6585DA",
+"f+ c #6786DB",
+"g+ c #6988DC",
+"h+ c #6B8ADD",
+"i+ c #6D8BDE",
+"j+ c #6F8DDE",
+"k+ c #718EDF",
+"l+ c #728FE0",
+"m+ c #7390E1",
+"n+ c #7390E2",
+"o+ c #7491E3",
+"p+ c #7592E4",
+"q+ c #7693E4",
+"r+ c #7794E5",
+"s+ c #7894E5",
+"t+ c #7995E6",
+"u+ c #7B96E6",
+"v+ c #7C97E7",
+"w+ c #7D9AE8",
+"x+ c #7F9CE9",
+"y+ c #829DE9",
+"z+ c #849EE9",
+"A+ c #859EE9",
+"B+ c #87A0E7",
+"C+ c #8AA2E7",
+"D+ c #8BA3E8",
+"E+ c #89A2E7",
+"F+ c #8CA6EA",
+"G+ c #8BA6EA",
+"H+ c #8BA7EA",
+"I+ c #8CA3E8",
+"J+ c #8BA8EA",
+"K+ c #8CA7EA",
+"L+ c #8CA8EA",
+"M+ c #4659C7",
+"N+ c #355ECF",
+"O+ c #3660CF",
+"P+ c #3860CE",
+"Q+ c #3961CD",
+"R+ c #3B61CB",
+"S+ c #3B61CA",
+"T+ c #3D62CA",
+"U+ c #3D63CA",
+"V+ c #4165CB",
+"W+ c #456ACB",
+"X+ c #4B6FCD",
+"Y+ c #5174CE",
+"Z+ c #5275D1",
+"`+ c #5477D4",
+" @ c #5678D9",
+".@ c #587ADB",
+"+@ c #597BDB",
+"@@ c #5B7DDC",
+"#@ c #5E7FDC",
+"$@ c #6081DD",
+"%@ c #6283DE",
+"&@ c #6484DF",
+"*@ c #6787E0",
+"=@ c #6989E1",
+"-@ c #6B8BE1",
+";@ c #6D8DE2",
+">@ c #6F8EE3",
+",@ c #718FE4",
+"'@ c #7290E4",
+")@ c #7491E5",
+"!@ c #7692E6",
+"~@ c #7793E5",
+"{@ c #7894E6",
+"]@ c #7895E7",
+"^@ c #7996E8",
+"/@ c #7A97E8",
+"(@ c #7B98E9",
+"_@ c #7D99E8",
+":@ c #7F9AE8",
+"<@ c #7F9BE9",
+"[@ c #7F9CEA",
+"}@ c #859EE8",
+"|@ c #859FE8",
+"1@ c #85A0E9",
+"2@ c #869FE9",
+"3@ c #86A1E7",
+"4@ c #86A0E9",
+"5@ c #87A1E7",
+"6@ c #88A2E7",
+"7@ c #87A1E9",
+"8@ c #5A6FCA",
+"9@ c #365FCF",
+"0@ c #345ED0",
+"a@ c #385FCC",
+"b@ c #385FCE",
+"c@ c #3A61CC",
+"d@ c #3B62CD",
+"e@ c #3E64CD",
+"f@ c #4167CF",
+"g@ c #4469CF",
+"h@ c #486CD1",
+"i@ c #4D71D2",
+"j@ c #5175D4",
+"k@ c #5376D6",
+"l@ c #5578DA",
+"m@ c #5679DC",
+"n@ c #587BDD",
+"o@ c #5A7DDE",
+"p@ c #5D80DE",
+"q@ c #5F82DF",
+"r@ c #6284DF",
+"s@ c #6585E0",
+"t@ c #6787E1",
+"u@ c #6988E2",
+"v@ c #6B8AE2",
+"w@ c #6D8CE3",
+"x@ c #6E8DE3",
+"y@ c #708EE4",
+"z@ c #718FE3",
+"A@ c #7391E4",
+"B@ c #7592E5",
+"C@ c #7895E5",
+"D@ c #7996E6",
+"E@ c #7A97E6",
+"F@ c #7B98E7",
+"G@ c #7A98E8",
+"H@ c #7B99E9",
+"I@ c #7E9AE9",
+"J@ c #7D9AE9",
+"K@ c #7E9AEA",
+"L@ c #809CE9",
+"M@ c #819DE8",
+"N@ c #7F9BEA",
+"O@ c #819DE9",
+"P@ c #819CE9",
+"Q@ c #839EE9",
+"R@ c #839EE8",
+"S@ c #839DEA",
+"T@ c #859FE9",
+"U@ c #87A0E8",
+"V@ c #86A0E8",
+"W@ c #87A1E8",
+"X@ c #3760CF",
+"Y@ c #3A61CE",
+"Z@ c #3A62CD",
+"`@ c #3F66CE",
+" # c #4368D0",
+".# c #466CD2",
+"+# c #496DD5",
+"@# c #4E72D6",
+"## c #5175D8",
+"$# c #5276DA",
+"%# c #5578DC",
+"&# c #577ADC",
+"*# c #597CDD",
+"=# c #5B7DDD",
+"-# c #5D7FDE",
+";# c #5E81DE",
+"># c #6183DF",
+",# c #6386DF",
+"'# c #6687E0",
+")# c #6888E0",
+"!# c #6A89E1",
+"~# c #6C8AE1",
+"{# c #6E8CE2",
+"]# c #6F8DE2",
+"^# c #7390E4",
+"/# c #7390E3",
+"(# c #7491E4",
+"_# c #7693E5",
+":# c #7895E6",
+"<# c #7896E6",
+"[# c #7997E7",
+"}# c #7B97E7",
+"|# c #7B98E8",
+"1# c #7C98E8",
+"2# c #7E9BE9",
+"3# c #809CEA",
+"4# c #819CEA",
+"5# c #839DE9",
+"6# c #365FD0",
+"7# c #3660D0",
+"8# c #3961CF",
+"9# c #3B63CF",
+"0# c #3D64D0",
+"a# c #4067D0",
+"b# c #4469D2",
+"c# c #466BD3",
+"d# c #496ED5",
+"e# c #4C71D6",
+"f# c #4E72D8",
+"g# c #5074D9",
+"h# c #5376DB",
+"i# c #5578DB",
+"j# c #587ADC",
+"k# c #5B7CDC",
+"l# c #5D7EDD",
+"m# c #5F80DD",
+"n# c #6081DE",
+"o# c #6383DE",
+"p# c #6686DF",
+"q# c #6887E0",
+"r# c #6988E0",
+"s# c #6B89E1",
+"t# c #6C8AE0",
+"u# c #6E8CE1",
+"v# c #708EE2",
+"w# c #718FE2",
+"x# c #7290E3",
+"y# c #7391E2",
+"z# c #7492E1",
+"A# c #7592E2",
+"B# c #7691E3",
+"C# c #7591E3",
+"D# c #7692E3",
+"E# c #7693E3",
+"F# c #7793E4",
+"G# c #7893E4",
+"H# c #7994E5",
+"I# c #7D97E8",
+"J# c #7E98E8",
+"K# c #7D98E8",
+"L# c #7D99E9",
+"M# c #7D9BEA",
+"N# c #7D9CEA",
+"O# c #7E99E8",
+"P# c #7D9AEA",
+"Q# c #7C9BEA",
+"R# c #7C9CEA",
+"S# c #355FCF",
+"T# c #3860D0",
+"U# c #3A62D0",
+"V# c #3C64D1",
+"W# c #4167D1",
+"X# c #4369D3",
+"Y# c #466BD4",
+"Z# c #486DD5",
+"`# c #4A6ED7",
+" $ c #4C70D8",
+".$ c #5478D9",
+"+$ c #577BDA",
+"@$ c #597DDB",
+"#$ c #5B7EDB",
+"$$ c #5D7FDC",
+"%$ c #6182DE",
+"&$ c #6284DE",
+"*$ c #6485DF",
+"=$ c #6586DF",
+"-$ c #6787DF",
+";$ c #6888DF",
+">$ c #6A8ADF",
+",$ c #6C8BE0",
+"'$ c #6D8CE0",
+")$ c #6E8DE1",
+"!$ c #6F8DE1",
+"~$ c #708EE1",
+"{$ c #718FE0",
+"]$ c #728FE1",
+"^$ c #7390E0",
+"/$ c #738FE0",
+"($ c #7490E1",
+"_$ c #7590E1",
+":$ c #7591E1",
+"<$ c #7592E1",
+"[$ c #7692E2",
+"}$ c #7794E2",
+"|$ c #7894E3",
+"1$ c #7996E3",
+"2$ c #7A96E5",
+"3$ c #7B98E6",
+"4$ c #7B9AE8",
+"5$ c #7C99E8",
+"6$ c #7C96E5",
+"7$ c #7D97E7",
+"8$ c #7C99E9",
+"9$ c #7B9AE9",
+"0$ c #7B9AEA",
+"a$ c #5B6DCF",
+"b$ c #305EC8",
+"c$ c #335ECE",
+"d$ c #305ECA",
+"e$ c #345FCF",
+"f$ c #3761D0",
+"g$ c #3A62D1",
+"h$ c #3C64D2",
+"i$ c #4066D3",
+"j$ c #466BD5",
+"k$ c #486ED6",
+"l$ c #4A6ED6",
+"m$ c #4D71D8",
+"n$ c #4F72D9",
+"o$ c #5073D9",
+"p$ c #4F72D8",
+"q$ c #5074D8",
+"r$ c #5276D9",
+"s$ c #587ADA",
+"t$ c #5B7CDB",
+"u$ c #5D7EDC",
+"v$ c #5F7FDD",
+"w$ c #6081DC",
+"x$ c #6182DD",
+"y$ c #6283DD",
+"z$ c #6484DE",
+"A$ c #6585DD",
+"B$ c #6787DE",
+"C$ c #6988DF",
+"D$ c #6A89DE",
+"E$ c #6C8ADF",
+"F$ c #6D8BDF",
+"G$ c #6E8CE0",
+"H$ c #6F8DE0",
+"I$ c #718EE0",
+"J$ c #728FDF",
+"K$ c #728FDE",
+"L$ c #7290E0",
+"M$ c #7190E0",
+"N$ c #7291E0",
+"O$ c #7191E0",
+"P$ c #7392E1",
+"Q$ c #7493E1",
+"R$ c #7594E1",
+"S$ c #7594E2",
+"T$ c #7694E2",
+"U$ c #7695E2",
+"V$ c #7A96E4",
+"W$ c #7895E2",
+"X$ c #7A96E2",
+"Y$ c #7A96E3",
+"Z$ c #7B96E3",
+"`$ c #7996E1",
+" % c #7C96E4",
+".% c #305EC9",
+"+% c #315ECC",
+"@% c #325ECE",
+"#% c #3760D0",
+"$% c #3962D1",
+"%% c #3E66D3",
+"&% c #4268D4",
+"*% c #446BD5",
+"=% c #476CD6",
+"-% c #496ED7",
+";% c #4B6FD7",
+">% c #4C70D7",
+",% c #4E71D7",
+"'% c #5074D7",
+")% c #5276D8",
+"!% c #5376D8",
+"~% c #5779DA",
+"{% c #597ADA",
+"]% c #5A7BDB",
+"^% c #5B7CDA",
+"/% c #5D7EDB",
+"(% c #5E7FDB",
+"_% c #6182DB",
+":% c #6384DC",
+"<% c #6586DD",
+"[% c #6686DC",
+"}% c #6887DD",
+"|% c #6988DD",
+"1% c #6A8ADE",
+"2% c #6B8BDE",
+"3% c #6C8CDE",
+"4% c #6E8DDF",
+"5% c #6E8CDF",
+"6% c #6D8DDF",
+"7% c #6C8BDF",
+"8% c #6F8DDF",
+"9% c #718FDF",
+"0% c #7290DF",
+"a% c #7391E0",
+"b% c #7491E0",
+"c% c #7292E1",
+"d% c #3959C5",
+"e% c #345BC5",
+"f% c #315EC8",
+"g% c #355BC5",
+"h% c #325EC8",
+"i% c #315ECB",
+"j% c #345DCC",
+"k% c #335ECD",
+"l% c #345ECD",
+"m% c #355FCE",
+"n% c #3862D0",
+"o% c #3E66D2",
+"p% c #456BD5",
+"q% c #476CD5",
+"r% c #4B6ED7",
+"s% c #4B6FD6",
+"t% c #4B6FD5",
+"u% c #4D71D6",
+"v% c #5073D7",
+"w% c #5174D7",
+"x% c #5275D8",
+"y% c #5577D8",
+"z% c #5678D8",
+"A% c #5779D9",
+"B% c #587AD8",
+"C% c #597CD9",
+"D% c #5B7DD9",
+"E% c #5D7FDA",
+"F% c #5F80DB",
+"G% c #6182DC",
+"H% c #6484DC",
+"I% c #6585DC",
+"J% c #6787DD",
+"K% c #6988DE",
+"L% c #6B8ADE",
+"M% c #6B8ADF",
+"N% c #6989DE",
+"O% c #6B89DE",
+"P% c #6E8BDF",
+"Q% c #708CDE",
+"R% c #708DDF",
+"S% c #708FDF",
+"T% c #728EDF",
+"U% c #6F8EDD",
+"V% c #728EDD",
+"W% c #7390DF",
+"X% c #7490DF",
+"Y% c #335DC8",
+"Z% c #3759C5",
+"`% c #3859C5",
+" & c #335EC8",
+".& c #325DCA",
+"+& c #345CCB",
+"@& c #335DCC",
+"#& c #345DCD",
+"$& c #355FCD",
+"%& c #3861D0",
+"&& c #3B64D1",
+"*& c #3E65D2",
+"=& c #4168D3",
+"-& c #456AD5",
+";& c #4B6ED5",
+">& c #4C6FD4",
+",& c #4D70D5",
+"'& c #4F72D6",
+")& c #5173D6",
+"!& c #5375D7",
+"~& c #5476D8",
+"{& c #5577D7",
+"]& c #5477D8",
+"^& c #5677D8",
+"/& c #5879D9",
+"(& c #597AD9",
+"_& c #5C7DDA",
+":& c #6080DC",
+"<& c #6080DB",
+"[& c #6181DC",
+"}& c #6282DC",
+"|& c #6383DD",
+"1& c #6484DD",
+"2& c #6686DE",
+"3& c #6685DE",
+"4& c #6786DE",
+"5& c #6687DE",
+"6& c #6887DE",
+"7& c #6987DE",
+"8& c #6788DF",
+"9& c #6785DF",
+"0& c #6B89DF",
+"a& c #6C89DF",
+"b& c #6F8DDD",
+"c& c #6D8CDE",
+"d& c #445BBB",
+"e& c #3759BE",
+"f& c #375AC6",
+"g& c #355CC8",
+"h& c #345CCA",
+"i& c #355ECC",
+"j& c #365FCD",
+"k& c #3761CE",
+"l& c #3A63D0",
+"m& c #3D65D1",
+"n& c #466AD4",
+"o& c #476BD4",
+"p& c #486CD3",
+"q& c #4A6ED4",
+"r& c #4B6ED4",
+"s& c #4E71D6",
+"t& c #4F71D5",
+"u& c #5072D6",
+"v& c #5274D7",
+"w& c #5273D7",
+"x& c #5274D6",
+"y& c #5476D7",
+"z& c #5779D8",
+"A& c #587AD9",
+"B& c #5A7CDA",
+"C& c #5C7DDB",
+"D& c #5D7EDA",
+"E& c #6081DA",
+"F& c #6181DB",
+"G& c #6283DC",
+"H& c #6483DD",
+"I& c #6483DE",
+"J& c #6585DE",
+"K& c #6786DF",
+"L& c #6886DE",
+"M& c #6887DF",
+"N& c #6987DF",
+"O& c #6A88DF",
+"P& c #6786E0",
+"Q& c #6A86DE",
+"R& c #6B89E0",
+"S& c #365BC8",
+"T& c #365CC8",
+"U& c #375DCA",
+"V& c #375FCB",
+"W& c #3860CD",
+"X& c #3C63D0",
+"Y& c #4167D2",
+"Z& c #4268D2",
+"`& c #4368D2",
+" * c #4367D2",
+".* c #4568D2",
+"+* c #466AD2",
+"@* c #496CD3",
+"#* c #4A6DD3",
+"$* c #4A6DD4",
+"%* c #4D70D4",
+"&* c #4F72D5",
+"** c #4C70D4",
+"=* c #4E72D5",
+"-* c #5173D5",
+";* c #5375D6",
+">* c #597BDA",
+",* c #5B7DDA",
+"'* c #5C7EDB",
+")* c #5D7FDB",
+"!* c #5E80DB",
+"~* c #5E81DA",
+"{* c #5F81DB",
+"]* c #5F82DB",
+"^* c #6384DD",
+"/* c #6384DE",
+"(* c #6585DF",
+"_* c #6486E0",
+":* c #6583DD",
+"<* c #6386E0",
+"[* c #6686E0",
+"}* c #6B86DD",
+"|* c #6D86DD",
+"1* c #6086E0",
+"2* c #5573CD",
+"3* c #3959C3",
+"4* c #3959C4",
+"5* c #3759C0",
+"6* c #375BC7",
+"7* c #365CC7",
+"8* c #395FCC",
+"9* c #3B62CE",
+"0* c #3E64D0",
+"a* c #4066D1",
+"b* c #4166D1",
+"c* c #4064CF",
+"d* c #4065CF",
+"e* c #4266D0",
+"f* c #4468D1",
+"g* c #4569D1",
+"h* c #476BD2",
+"i* c #466AD1",
+"j* c #476AD2",
+"k* c #456AD1",
+"l* c #496DD2",
+"m* c #4A6FD3",
+"n* c #496ED2",
+"o* c #4B70D4",
+"p* c #4D71D4",
+"q* c #4E72D4",
+"r* c #5073D4",
+"s* c #5174D5",
+"t* c #5175D5",
+"u* c #5276D6",
+"v* c #5377D6",
+"w* c #5478D7",
+"x* c #5579D7",
+"y* c #567AD8",
+"z* c #577BD9",
+"A* c #597CD8",
+"B* c #5A7DD9",
+"C* c #5A7ED9",
+"D* c #5B7FDA",
+"E* c #5C80DA",
+"F* c #5D80DA",
+"G* c #5E81DB",
+"H* c #5D80DB",
+"I* c #6082DC",
+"J* c #6183DD",
+"K* c #6183DE",
+"L* c #6082DB",
+"M* c #6282DE",
+"N* c #6682DE",
+"O* c #6583DE",
+"P* c #3759BF",
+"Q* c #375AC2",
+"R* c #375AC1",
+"S* c #375AC4",
+"T* c #395DCA",
+"U* c #3A5ECA",
+"V* c #3C60CC",
+"W* c #3D61CD",
+"X* c #3D61CC",
+"Y* c #3C61CD",
+"Z* c #3E62CD",
+"`* c #3F64CE",
+" = c #4266CF",
+".= c #4468D0",
+"+= c #4267CF",
+"@= c #4166CE",
+"#= c #4065CE",
+"$= c #4166CD",
+"%= c #4267CE",
+"&= c #456AD0",
+"*= c #4368CE",
+"== c #4468CF",
+"-= c #4569D0",
+";= c #486BD1",
+">= c #4B6FD3",
+",= c #4C70D3",
+"'= c #4F73D4",
+")= c #5275D5",
+"!= c #5477D6",
+"~= c #577BD7",
+"{= c #587CD8",
+"]= c #577CD8",
+"^= c #597DD9",
+"/= c #5A7DDA",
+"(= c #597DDA",
+"_= c #587CDA",
+":= c #5A7EDA",
+"<= c #567BD8",
+"[= c #557AD9",
+"}= c #567BD9",
+"|= c #577CD9",
+"1= c #587DD9",
+"2= c #587ED9",
+"3= c #577ED8",
+"4= c #587DD8",
+"5= c #587ED8",
+"6= c #567ED7",
+"7= c #526ABD",
+"8= c #3759C1",
+"9= c #385BC7",
+"0= c #395CC8",
+"a= c #3B5DC9",
+"b= c #3B5ECA",
+"c= c #3A5FCA",
+"d= c #3B60CC",
+"e= c #3C61CC",
+"f= c #3D62CD",
+"g= c #3E63CD",
+"h= c #3C61CB",
+"i= c #3C61CA",
+"j= c #3D62CB",
+"k= c #3F64CC",
+"l= c #4065CD",
+"m= c #4669D0",
+"n= c #476AD0",
+"o= c #496BD1",
+"p= c #4A6DD2",
+"q= c #4B6ED2",
+"r= c #4D71D3",
+"s= c #4E73D4",
+"t= c #4F74D4",
+"u= c #5075D5",
+"v= c #5276D5",
+"w= c #5377D7",
+"x= c #5278D7",
+"y= c #5277D6",
+"z= c #5378D7",
+"A= c #5379D8",
+"B= c #5379D9",
+"C= c #5278D8",
+"D= c #5178D7",
+"E= c #3355C0",
+"F= c #3556C1",
+"G= c #395AC6",
+"H= c #385AC7",
+"I= c #395BC7",
+"J= c #395EC9",
+"K= c #395FCA",
+"L= c #3B60CA",
+"M= c #3B60CB",
+"N= c #375DC7",
+"O= c #385EC8",
+"P= c #395FC9",
+"Q= c #3A60CA",
+"R= c #3D63CC",
+"S= c #4367CF",
+"T= c #476BD1",
+"U= c #4A6ED2",
+"V= c #4B6FD2",
+"W= c #4C6FD2",
+"X= c #4D70D1",
+"Y= c #4E71D2",
+"Z= c #4E72D2",
+"`= c #4E74D4",
+" - c #4E75D5",
+".- c #4E75D4",
+"+- c #4F75D3",
+"@- c #5075D2",
+"#- c #5075D3",
+"$- c #5177D7",
+"%- c #5178D8",
+"&- c #4F75D5",
+"*- c #5076D5",
+"=- c #4F76D6",
+"-- c #5279D9",
+";- c #3C52B1",
+">- c #3656C3",
+",- c #3757C5",
+"'- c #3758C6",
+")- c #3759C6",
+"!- c #375BC6",
+"~- c #385CC7",
+"{- c #385DC8",
+"]- c #365CC6",
+"^- c #355BC6",
+"/- c #355CC6",
+"(- c #365DC7",
+"_- c #375EC8",
+":- c #375CC6",
+"<- c #385EC6",
+"[- c #3A5FC7",
+"}- c #3C60C8",
+"|- c #3D61C9",
+"1- c #3E62CA",
+"2- c #4063CC",
+"3- c #4165CE",
+"4- c #4268D0",
+"5- c #4269D1",
+"6- c #436AD2",
+"7- c #446AD2",
+"8- c #456BD2",
+"9- c #496CD1",
+"0- c #4C6CD0",
+"a- c #4D6CCF",
+"b- c #4E6DD0",
+"c- c #4F6ECF",
+"d- c #4E6FCF",
+"e- c #4C70CF",
+"f- c #4A71D0",
+"g- c #4F6FCF",
+"h- c #4B71D0",
+"i- c #4A72D1",
+"j- c #4B73D4",
+"k- c #4F70D0",
+"l- c #4C73D3",
+"m- c #4C73D6",
+"n- c #4B72D2",
+"o- c #4B71D1",
+"p- c #4C73D7",
+"q- c #3354C0",
+"r- c #3152BE",
+"s- c #3052BE",
+"t- c #3051BF",
+"u- c #2E4FBF",
+"v- c #2E4FBE",
+"w- c #2E50BF",
+"x- c #2F50BF",
+"y- c #3156C4",
+"z- c #2F56C5",
+"A- c #2E57C5",
+"B- c #2F57C5",
+"C- c #3057C6",
+"D- c #3258C6",
+"E- c #3459C7",
+"F- c #365AC7",
+"G- c #385BC8",
+"H- c #3B5DCA",
+"I- c #3B5DCB",
+"J- c #3C5ECC",
+"K- c #3C60CD",
+"L- c #3C62CE",
+"M- c #3D65D0",
+"N- c #3D66D1",
+"O- c #4166D2",
+"P- c #4667D2",
+"Q- c #4A67D1",
+"R- c #4C68D0",
+"S- c #4C69CF",
+"T- c #4D6BCE",
+"U- c #4E6DCD",
+"V- c #4E6ECE",
+"W- c #4E6DCE",
+"X- c #4970D0",
+"Y- c #4770D0",
+"Z- c #4B6BCE",
+"`- c #4A6CCE",
+" ; c #496DCF",
+".; c #476FD0",
+"+; c #4870D0",
+"@; c #486DCF",
+"#; c #242F79",
+"$; c #2F41AC",
+"%; c #2040B8",
+"&; c #2041B8",
+"*; c #2243B3",
+"=; c #2243B8",
+"-; c #2343B8",
+";; c #2444B8",
+">; c #2445B8",
+",; c #2445B6",
+"'; c #2445B7",
+"); c #2444B9",
+"!; c #2949BE",
+"~; c #2649BF",
+"{; c #234BBF",
+"]; c #224CBF",
+"^; c #224AC0",
+"/; c #244CC0",
+"(; c #254DC0",
+"_; c #254DC1",
+":; c #264DC2",
+"<; c #274EC3",
+"[; c #274CC3",
+"}; c #274DC4",
+"|; c #254DC5",
+"1; c #214EC5",
+"2; c #204FC6",
+"3; c #1F50C8",
+"4; c #2151C9",
+"5; c #2B53C8",
+"6; c #3154C7",
+"7; c #3255C6",
+"8; c #2F57C7",
+"9; c #2C58C9",
+"0; c #2D59CA",
+"a; c #2D58C9",
+"b; c #2E5BCC",
+"c; c #325ECC",
+"d; c #325ECB",
+"e; c #1F40B1",
+"f; c #1F40B2",
+"g; c #1F40B3",
+"h; c #2A44BD",
+"i; c #2845BE",
+"j; c #2745BE",
+"k; c #2646BF",
+"l; c #2546BE",
+"m; c #2347BF",
+"n; c #2147BF",
+"o; c #2048C0",
+"p; c #1D48C0",
+"q; c #1C48C0",
+"r; c #1B47C0",
+"s; c #1C48BF",
+"t; c #1E49BE",
+"u; c #214ABD",
+"v; c #244CBD",
+"w; c #264DBE",
+"x; c #254EC0",
+"y; c #214FC2",
+"z; c #1B51C5",
+"A; c #1C51C7",
+"B; c #2250C8",
+"C; c #2A52C8",
+"D; c #3254C6",
+"E; c #3355C5",
+"F; c #3154C8",
+"G; c #3355C6",
+"H; c #2F57C8",
+"I; c #2E58C9",
+"J; c #2E59C9",
+"K; c #3059C9",
+"L; c #2040B6",
+"M; c #2743BB",
+"N; c #2844BC",
+"O; c #2743BD",
+"P; c #2844BE",
+"Q; c #2844BD",
+"R; c #2346BE",
+"S; c #2047BF",
+"T; c #1E48C0",
+"U; c #1D47C0",
+"V; c #1D49BF",
+"W; c #1F49BF",
+"X; c #204ABE",
+"Y; c #254DBF",
+"Z; c #234EC0",
+"`; c #2050C1",
+" > c #1C51C3",
+".> c #1F51C6",
+"+> c #2651C8",
+"@> c #2D53C7",
+"#> c #3155C6",
+"$> c #3155C7",
+"%> c #3355C7",
+"&> c #3254C7",
+"*> c #1E40B1",
+"=> c #2141B8",
+"-> c #2442B9",
+";> c #2744BB",
+">> c #2945BB",
+",> c #2A45BB",
+"'> c #2944BA",
+")> c #2745BB",
+"!> c #2545BC",
+"~> c #2246BD",
+"{> c #2047BE",
+"]> c #1F47BD",
+"^> c #1D48BE",
+"/> c #1E49C0",
+"(> c #1F4AC0",
+"_> c #214BBF",
+":> c #244CBE",
+"<> c #254DBE",
+"[> c #244DBE",
+"}> c #224FBF",
+"|> c #2051C1",
+"1> c #2151C3",
+"2> c #2252C5",
+"3> c #2151C1",
+"4> c #2851C6",
+"5> c #2A50C6",
+"6> c #2E54C6",
+"7> c #1F51C2",
+"8> c #1D52C5",
+"9> c #2651C9",
+"0> c #2950C7",
+"a> c #2D40A5",
+"b> c #2040B0",
+"c> c #1F40B0",
+"d> c #223CAE",
+"e> c #233CAE",
+"f> c #253BAC",
+"g> c #253BAD",
+"h> c #233CB0",
+"i> c #213EB2",
+"j> c #1F3FB4",
+"k> c #1E40B6",
+"l> c #1F3FB7",
+"m> c #1E3EB8",
+"n> c #1F3FB8",
+"o> c #2040B7",
+"p> c #2141B6",
+"q> c #2140B7",
+"r> c #2241B6",
+"s> c #2342B5",
+"t> c #2442B6",
+"u> c #2543B5",
+"v> c #2643B4",
+"w> c #2544B6",
+"x> c #2346B8",
+"y> c #2247B9",
+"z> c #2048BC",
+"A> c #1F48BF",
+"B> c #2049C0",
+"C> c #214AC0",
+"D> c #224BBF",
+"E> c #234CBE",
+"F> c #244DBF",
+"G> c #234CBF",
+"H> c #264DC0",
+"I> c #274EBF",
+"J> c #264DBF",
+"K> c #254EBF",
+"L> c #2050C0",
+"M> c #1F51C1",
+"N> c #1E42A4",
+"O> c #263BA6",
+"P> c #253BA7",
+"Q> c #253CA7",
+"R> c #1E41A5",
+"S> c #1F40AF",
+"T> c #273AAC",
+"U> c #1E40B0",
+"V> c #1F40B5",
+"W> c #1F40B6",
+"X> c #1F40B8",
+"Y> c #1E40B8",
+"Z> c #1F3EB8",
+"`> c #203FB7",
+" , c #2240B6",
+"., c #2341B7",
+"+, c #2345B9",
+"@, c #2147BB",
+"#, c #2148BA",
+"$, c #2049BB",
+"%, c #2049BD",
+"&, c #2049BF",
+"*, c #224BBE",
+"=, c #244DBD",
+"-, c #244CBF",
+";, c #182969",
+">, c #273BAD",
+",, c #2739AB",
+"', c #263AAC",
+"), c #243CAE",
+"!, c #233DAE",
+"~, c #213EAF",
+"{, c #1F3FB0",
+"], c #2040B4",
+"^, c #1F3FB6",
+"/, c #1E3EB7",
+"(, c #2240B7",
+"_, c #2341B6",
+":, c #2543B4",
+"<, c #2644B3",
+"[, c #2544B5",
+"}, c #2545B5",
+"|, c #2547B6",
+"1, c #2548B7",
+"2, c #2349BA",
+"3, c #1F49BE",
+"4, c #2149BD",
+"5, c #2049BE",
+"6, c #214BBE",
+"7, c #2249BE",
+"8, c #234CBD",
+"9, c #2149BE",
+"0, c #1E49BF",
+"a, c #253BA9",
+"b, c #253BAB",
+"c, c #263AAB",
+"d, c #213DAF",
+"e, c #203EAF",
+"f, c #1D40AF",
+"g, c #1D40B0",
+"h, c #1E40B4",
+"i, c #2241B7",
+"j, c #2643B6",
+"k, c #2744B5",
+"l, c #2643B5",
+"m, c #2346B6",
+"n, c #2147B7",
+"o, c #2644B6",
+"p, c #2247B7",
+"q, c #2248B8",
+"r, c #2647B7",
+"s, c #2549B7",
+"t, c #2645B7",
+"u, c #2148B8",
+"v, c #2847B6",
+"w, c #2549B6",
+"x, c #2849B6",
+"y, c #2049B7",
+"z, c #2A49B5",
+"A, c #243BA4",
+"B, c #253BA5",
+"C, c #253BA6",
+"D, c #263AA7",
+"E, c #263AA8",
+"F, c #2739AA",
+"G, c #243CAD",
+"H, c #223DAE",
+"I, c #1F3EAF",
+"J, c #1E3FB0",
+"K, c #1D40B1",
+"L, c #1E3FB1",
+"M, c #1F3FB3",
+"N, c #1F3FB5",
+"O, c #2140B6",
+"P, c #2140B8",
+"Q, c #2744B4",
+"R, c #2746B6",
+"S, c #2947B6",
+"T, c #2946B5",
+"U, c #2A48B6",
+"V, c #3551A8",
+"W, c #1F399C",
+"X, c #143D9F",
+"Y, c #263BA5",
+"Z, c #273BA8",
+"`, c #273BAA",
+" ' c #263AAD",
+".' c #233CAD",
+"+' c #213DAE",
+"@' c #203FB2",
+"#' c #2342B6",
+"$' c #2443B6",
+"%' c #2543B6",
+"&' c #2644B5",
+"*' c #133D9E",
+"=' c #263BA7",
+"-' c #263BA9",
+";' c #273BA9",
+">' c #263AAA",
+",' c #2539AB",
+"'' c #2639AB",
+")' c #253AAC",
+"!' c #243BAD",
+"~' c #223DAF",
+"{' c #203FB0",
+"]' c #2040B1",
+"^' c #2140B3",
+"/' c #2543B1",
+"(' c #2744AF",
+"_' c #1A3CA0",
+":' c #1D3BA2",
+"<' c #233BA4",
+"[' c #263AA5",
+"}' c #253AA5",
+"|' c #263AA6",
+"1' c #263BA4",
+"2' c #243BA5",
+"3' c #263BA8",
+"4' c #223EAF",
+"5' c #3B4CA5",
+"6' c #1D379A",
+"7' c #1E389C",
+"8' c #1E399F",
+"9' c #1F3BA2",
+"0' c #1F3BA3",
+"a' c #213BA4",
+"b' c #233AA3",
+"c' c #243AA3",
+"d' c #2539A4",
+"e' c #253AA6",
+"f' c #243BA7",
+"g' c #253CAA",
+"h' c #253CAC",
+"i' c #253CAD",
+"j' c #253CAE",
+"k' c #243DAE",
+"l' c #213FAF",
+"m' c #223FAF",
+"n' c #2040AF",
+"o' c #253D93",
+"p' c #1D3894",
+"q' c #1F379A",
+"r' c #1E389B",
+"s' c #1D399C",
+"t' c #1C3A9D",
+"u' c #1B3A9D",
+"v' c #183B9E",
+"w' c #163C9E",
+"x' c #153C9E",
+"y' c #163B9D",
+"z' c #173B9D",
+"A' c #193A9D",
+"B' c #1C3A9E",
+"C' c #1F3AA1",
+"D' c #223AA4",
+"E' c #253BA8",
+"F' c #273BA7",
+"G' c #263CAB",
+"H' c #263CAC",
+"I' c #243EAE",
+"J' c #273BAC",
+"K' c #2A3795",
+"L' c #1F389B",
+"M' c #1D389B",
+"N' c #1C399C",
+"O' c #1B399C",
+"P' c #1A3A9D",
+"Q' c #1D399B",
+"R' c #1B399B",
+"S' c #1A3A9C",
+"T' c #1B3A9F",
+"U' c #1D3AA0",
+"V' c #203BA2",
+"W' c #203BA3",
+"X' c #2639A6",
+"Y' c #1B3692",
+"Z' c #1C3794",
+"`' c #1D3796",
+" ) c #1E3898",
+".) c #1E389A",
+"+) c #1F399B",
+"@) c #1A399C",
+"#) c #193A9E",
+"$) c #1A3BA0",
+"%) c #1C3BA2",
+"&) c #1D3CA3",
+"*) c #203CA4",
+"=) c #223BA5",
+"-) c #3C4699",
+";) c #2B4595",
+">) c #1C3793",
+",) c #1D3895",
+"') c #1E3897",
+")) c #1F3998",
+"!) c #1F3999",
+"~) c #1F399A",
+"{) c #1E399C",
+"]) c #1C3B9E",
+"^) c #1D3BA0",
+"/) c #1E3CA2",
+"() c #223CA5",
+"_) c #243CA6",
+":) c #596FA9",
+"<) c #3B4894",
+"[) c #314993",
+"}) c #29499F",
+"|) c #28489E",
+"1) c #2B4BA1",
+"2) c #2C4BA1",
+"3) c #2D4CA2",
+"4) c #2E4CA3",
+"5) c #2F4CA4",
+"6) c #2E4CA4",
+"7) c #2F4DA3",
+"8) c #2F4DA4",
+"9) c #D3D5D2",
+"0) c #3B4794",
+"a) c #314791",
+"b) c #304892",
+"c) c #304893",
+"d) c #2F4995",
+"e) c #2F4997",
+"f) c #2D4A9A",
+"g) c #2A4A9D",
+"h) c #294A9F",
+"i) c #284AA0",
+"j) c #294AA0",
+"k) c #2B4AA1",
+"l) c #2D4CA3",
+"m) c #C9CAC9",
+"n) c #455D9B",
+"o) c #242F78",
+"p) c #1B2F85",
+"q) c #C6C3C8",
+"r) c #B5B2B6",
+"s) c #B5B7B4",
+"t) c #B5B7B3",
+"u) c #B5B2B5",
+"v) c #B5B3B4",
+"w) c #B5B5B4",
+"x) c #B5B6B3",
+"y) c #B5B4B4",
+"z) c #B5B3B5",
+"A) c #B5B4B5",
+"B) c #B5B5B5",
+"C) c #B5B5B3",
+"D) c #B5B5B6",
+"E) c #BAC3BE",
+"F) c #B9C3BD",
+"G) c #C1C3C4",
+"H) c #BFC3C2",
+"I) c #B9C3BE",
+"J) c #BBC3BF",
+"K) c #BDC3C1",
+"L) c #C0C3C3",
+"M) c #BEC3C1",
+"N) c #C2C3C5",
+"O) c #E6E3E8",
+"P) c #E0E2DF",
+"Q) c #E1E1E1",
+"R) c #E2E1E3",
+"S) c #E4E1E6",
+"T) c #E4E2E7",
+"U) c #E4E2E6",
+"V) c #E3E3E4",
+"W) c #E2E3E3",
+"X) c #E1E3E2",
+"Y) c #E3E3E3",
+"Z) c #E3E3E2",
+"`) c #EBEDEA",
+" ! c #EAECE9",
+".! c #E9EBE8",
+"+! c #ECEEEB",
+". . + @ # $ $ $ $ $ $ $ % $ $ $ $ $ % $ $ $ $ $ $ % $ $ $ $ $ % $ $ $ $ $ $ $ $ $ % $ $ & * = - ; > , , ' ) ! ! ~ { ] ^ / ( _ : < [ } | | 1 2 3 3 4 4 4 4 4 4 4 5 6 4 4 4 5 6 7 8 9 4 5 6 7 8 9 6 7 8 9 ",
+"0 a b % $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ c d d d d $ $ $ $ $ c d e f g h i i i i j k l m n o p q r s t u v w x y z 4 A B C D 9 9 E 9 E F G H I F J K L L L L J K L L L L L L L L ",
+"@ % M N O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O P Q R S T U V W X Y Z ` ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.b.b.b.b.b.",
+"c.$ d.O e.f.g.g.g.h.g.g.g.g.g.h.h.g.g.g.g.g.h.h.g.g.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+@+$+%+&+*+=+$+-+;+>+,+'+)+!+;+>+,+~+,+>+,+~+,+",
+"$ {+N N f.f.f.f.h.h.h.g.f.f.h.h.h.h.g.f.f.h.h.h.h.]+^+/+(+h._+:+<+[+}+|+1+2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+A+B+.+C+D+E+D+F+G+H+C+I+F+G+J+K+L+H+F+G+J+K+L+H+J+H+J+H+",
+"{+{+N N M+M+h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.N+N+h.h.(+O+P+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@[@y+}@|@1@A+1@2@3@ +2@4@2@5@C+D+6@D+7@5@C+D+6@I+C+D+6@I+",
+"{+{+8@N M+M+h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.9@9@0@N+a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@z@A@B@q+r+C@D@E@F@G@H@_@I@J@K@<@L@M@N@O@P@Q@R@S@T@A+A+U@V@W@W@A+2@U@V@W@W@U@V@W@W@",
+"{+{+8@N f.M+h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.(+(+(+9@9@X@Y@Z@e@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#z@^#/#(#p+_#r+:#s+t+<#[#}#|#|#1#_@|#_@_@2#L@3#4#y+y+5#z+z+z+5#z+z+z+z+A+A+A+A+A+",
+"{+{+8@8@f.f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.(+6#7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#&@p#q#r#s#t#u#v#w#x#x#y#y#z#A#B#C#D#E#E#F#G#H#F#H#H#u+v+I#J#K#L#J@J@M#N#O#P#M#M#M#N#M#Q#Q#R#",
+"$ {+8@e.f.f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.S#l.7#T#U#V#W#X#Y#Z#`# $f#g###.$+$@$#$$$$@%$&$*$=$-$;$>$,$'$)$!$~$~${$]$^$/$($($_$_$:$<$_$<$[$}$|$|$1$2$2$3$}#4$5$6$7$8$8$9$8$8$8$0$8$",
+"$ {+a$e.f.f.h.h.h.h.h.h.h.h.h.b$h.c$c$c$c$c$d$c$c$c$c$c$c$c$c$c$c$e$e$7#f$g$h$i$X#j$k$l$m$n$o$p$q$r$l@s$t$u$v$w$x$y$z$A$B$C$D$E$F$G$G$H$I$J$J$K$K$J$L$L$L$L$L$M$N$O$P$Q$R$S$T$U$1$V$T$W$X$Y$1$V$Y$Z$`$ %",
+"$ $ a$a$f.f.b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$b$.%b$b$b$.%d$+%+%@%h.e$l.#%$%h$%%&%*%=%-%;%>%,%'%)%!% @ @~%{%]%^%/%(%w$_%:%<%[%}%|%D$1%2%3%4%5%4%4%6%5%5%4%4%4%5%7%5%8%9%L$0%a%a%a%P$b%P$P$z#z#z#P$c%c%c%",
+"$ $ 8@e.f.f.d%b$b$b$b$b$d%b$b$b$b$b$b$e%f%b$b$b$b$b$g%h%b$.%i%i%j%k%l%m%X@n%h$o%&%p%q%`#r%s%t%u%v%w%x%y% @z%A%B%C%D%E%F%G%:%H%I%[%J%}%K%|%D$K%D$D$L%M%M%M%M%M%D$N%O%i+P%j+Q%R%S%T%0%U%V%W%W%W%W%X%X%X%X%",
+"$ $ 8@8@f.f.d%d%b$b$b$b$d%d%b$b$b$h%Y%Z%Z%h%f%f%h%Y%`%`% &h%h%.&+&@&#&$&X@%&&&*&=&-&j$Z#+#;&>&,&'&)&)&!&~&{&]&^&/&(&^%_&(%:&<&[&}&|&1&A$A$2&3&4&4&5&B$6&7&B$7&8&9&6&7&0&a&a&i+i+i+b&a&a&j+U%c&U%j+U%c&U%",
+"$ $ 8@8@d&e&d%d%d%d%d%d%d%d%d%d%d%`%d%d%d%d%`%`%`%d%d%d%d%`%`%f&g&h&j%i&j&k&l&m&=&X#Y#n&o&p&q&r&>&s&t&t&u&v&w&x&y&{&z&A&B&C&D&(%(%F%F%E&F&}&}&|&G&|&H&1&I%I&A$1&}&z$z$J&K&L&M&N&O&0&P&Q&0&a&R&a&a&a&R&a&",
+"{+$ 8@8@e&e&d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%`%f&S&T&U&V&W&Y@X&Y&Z&`& *.*+*@*#*@*r&$*#*r&%*&***=*-*;*y&z%A%z&A&A&>*B&,*,*'*)*!*!*~*{*F&}&{*}&{*]*G%G%y$^*/*J&(*2&_*:*<*=$[*}*<*=$<*|*1*",
+"{+{+8@2*e&e&d%d%d%d%d%d%d%d%d%e&3*4*4*4*4*4*5*4*4*4*4*4*4*4*4*4*`%f&6*6*7*8*9*0*a*b*c*d*e*f*g*h*i*j*+*k*h*l*m*n*m*o*p*q*r*s*t*u*v*w*x*y*y*z*A*B*C*D*E*F*G*E*G*F*H*G*F*~*]*{*I*x$J*K*L*G%K*M*o#o#I&N*O*O*",
+"{+{+8@2*e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&P*e&e&e&e&e&e&P*P*e&e&e&P*P*5*Q*R*S*T*U*V*W*X*Y*Z*`*d* =.=+=@=#=$=%=g@&=*===-=i*;=l*>=,=q*'=s*)=k@!=x*~={=]=^=/=(=_=:=(=<=<=]=[=}=|=]=]=1=2=3=|=4=5=2=2=2=3=6=6=6=",
+"{+{+7=e.e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&P*P*8=9=0=a=b=U*c=d=e=f=e@#=g=h=i=i=j=k=k=l=%===m=n=o=p=q=,=r=s=t=u=v=v*w=x=x=y=z=z=A=z=A=B=C=B=D=C=B=x=B=B=B=B=B=B=B=B=B=B=B=B=B=B=",
+"{+{+7=7=e&e&e&e&E=E=e&e&e&e&E=E=E=e&e&e&e&E=E=E=e&e&e&e&E=E=e&e&e&e&E=E=E=F=d%G=G=H=I=J=K=L=M=R+}+N=O=P=Q=j=i=h=R=e@@=S=-=T=h@l*U=V=W=X=Y=Z=`= - - -.-+-@- -#-$-%-$-&-*-$-=-%-----C=$-%---------B=B=B=B=",
+"{+{+7=7=;-;-E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=>-,-'-)-!-6*~-{-{-]-^-/-/-(-_-:-N=<-[-}-|-1-2-3- =4-5-6-7-8-9-0-0-a-b-c-d-e-f-g-h-h-i-j-k-h-h-i-j-l-m-n-o-i-j-l-m-n-j-l-p-n-",
+"{+{+7=7=;-;-E=E=E=E=E=E=E=E=q-r-s-t-t-u-u-v-v-v-u-w-x-u-u-u-u-u-u-u-u-v-v-u-u-u-u-u-v-v-u-u-u-u-v-v-u-y-z-A-B-C-D-E-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-U-V-W-V-e-X-Y-Z-`- ;.;Y-N N +;@;.;Y-N N N N N N N ",
+"#;#;d&d&$;$;%;%;%;%;%;%;%;%;&;*;=;-;-;-;;;>;,;>;>;>;;;>;>;>;>;>;>;>;>;>;';);>;>;>;>;>;';>;>;>;>;>;';);!;~;{;];^;/;(;_;_;:;<;[;};};|;1;2;3;4;5;6;7;8;9;9;0;a;0;0;b;h.a;0;0;b;h.c;h.d;0;b;h.c;h.d;h.c;h.d;",
+"#;#;;-;-$;$;e;e;e;e;e;e;e;e;e;e;e;f;f;f;f;e;e;e;f;f;f;f;f;f;f;f;f;f;f;f;g;%;f;f;f;f;f;g;f;f;f;f;f;g;%;h;i;j;k;l;m;n;o;p;q;r;r;s;t;u;v;w;x;y;z;A;B;C;6;D;E;F;G;G;H;I;F;G;G;H;I;J;J;K;G;H;I;J;J;K;I;J;J;K;",
+"#;#;;-;-$;$;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;L;e;e;e;e;e;e;e;e;e;e;e;e;L;M;N;O;P;Q;i;i;k;R;S;T;U;q;q;V;W;X;{;Y;Z;`; >.>+>@>#>+>$>6;#>#>+>%>&>G;G;G;G;G;&>G;G;G;G;G;G;G;G;G;",
+"#;#;d.;-$;$;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;*>e;e;e;e;e;e;e;e;e;e;e;e;*>=>->;>>>,>'>'>)>!>~>{>]>^>^>V;V;/>(>_>:><>[>}>|>1>2>3>2>4>5>6>7>8>9>0>G;G;G;G;9>0>G;G;G;G;G;G;G;G;",
+"#;#;d.d.a>a>e;e;e;e;e;e;e;e;e;e;b>b>c>c>c>c>c>b>e;e;e;e;e;e;e;e;e;e;e;e;e;e;d>e>f>g>h>i>j>k>l>l>m>m>n>n>o>o>p>q>r>r>s>t>u>v>v>u>w>';x>y>z>t;A>B>C>D>E>E>F>G>F>H>H>I>F>Y;J>w;K>L>K>M>J>w;K>L>K>M>K>L>K>M>",
+"#;#;d.d.a>a>N>e;N>O>O>O>N>e;N>O>O>P>Q>R>S>R>Q>O>O>O>N>e;N>O>O>O>N>e;N>N>O>T>e;e;e;U>U>U>U>f;V>W>o>o>o>o>X>X>Y>Y>n>n>Z>Z>`> ,.,t>t>u>u>w>+,@,#,$,%,A>&,*,=,B>[>-,w;<>C>[>-,w;w;w;w;w;-,w;w;w;w;w;w;w;w;w;",
+"#;;,;-;-a>a>N>N>N>O>O>O>N>N>N>O>O>O>O>N>N>N>O>O>O>O>N>N>N>O>O>O>N>N>N>N>O>>,,,,,,,',g>),!,~,{,{,*>U>e;f;],o>%;o>^,^,/,/,l>q>(,_,t>u>:,<,v>[,},|,1,2,%,%,3,4,5,6,7,8,9,5,6,0,G>G>Y;G>6,0,G>G>Y;G>G>G>Y;G>",
+";,;,;-;-O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>P>a,b,',',c,c,f>),e>d,e,{,{,U>U>f,f,U>U>g,g,*>g;h,^,^,`>`>q>i,t>j,k,k,l,w>m,n,o,p,q,r,s,t,p,u,v,w,x,y,z,u,v,w,x,y,z,w,x,y,z,",
+";,;,b b O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>A,A,A,B,C,D,E,F,c,',g>G,!,H,~,e,{,I,J,J,K,K,U>f,f,J,L,M,N,L;O,i,P,.,l,Q,k,k,k,k,k,k,R,v,k,k,k,R,v,S,T,U,k,R,v,S,T,U,v,S,T,U,",
+";,;,b V,W,W,X,X,O>X,X,X,X,X,O>X,X,X,X,X,X,O>X,X,X,X,X,X,O>X,X,X,X,X,O>X,X,O>O>O>O>B,B,B,B,Y,O>O>Z,`,T>T> '',g>.'+'e,{,{,e,+'+'e,e,{,J,K,e;@'N,O,#'$'%'%'j,%'j,&'k,k,%'j,&'k,k,k,k,k,&'k,k,k,k,k,k,k,k,k,",
+";,;,b V,W,W,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,*'O>O>O>O>O>O>O>O>B,B,A,A,B,C,='-'`,;'>'>',''')'!'!'e>e>~'~'~,~,{'{,*>*>e;]']']']']']'^'/']']']'^'/':,(':,]'^'/':,(':,/':,(':,",
+";,;,V,V,W,W,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,_':'<'['}'|'|'O>O>O>O>O>O>O>Y,Y,1'1'B,B,2'2'C,3'-'>'c,)')'!'),4'{'e;]'e;*>*>e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;e;",
+";,;,5'5'W,W,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,W,6'6'6'7'8'9'0'a'b'c'd'd'}'}'O>O>O>O>O>O>O>O>Y,1'1'['['e'e'f'g'h'i'j'k'G,),!,l'j'm'n'b>b>),m'b>e;e;e;e;e;b>e;e;e;e;e;e;e;e;e;",
+";,;,b b o'o'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'W,q'q'q'r's't'u'v'w'x'y'z'A'B'C'D'2'2'B,B,O>O>O>O>O>O>O>O>O>O>O>Y,Y,C,C,='='='E'F'3'3'3'G'Z,='F'F'G'H'I'J'F'F'G'H'I'J'G'H'I'J'",
+";,;,b b K'K'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'W,W,W,W,W,L'L'q'r'M'N'O'P'u'N's'Q'R'S'A'T'U'C'V'9'0'W'D'}'X'|'O>O>B,B,O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>",
+";,;,b b K'K'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'p'Y'Y'Y'Z'`' ).)+)+)+)W,W,W,W,L'L'q'q'r'r's'M'N'P'@)A'#)$)%)&)*)=)B,|'|'O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>",
+"{+;,$ -);)K'p'p'o'p'p'p'p'p'o'p'p'p'p'p'p'o'p'p'p'p'p'p'o'p'p'p'p'p'o'o'p'p'p'p'p'p'p'p'p'p'>)>)Y'Y'>)Z',)')))!)~)+)W,W,W,W,W,W,W,W,W,W,W,L'L'{)s't'])^)/)])/)/)O>()])/)/)O>()O>_)O>/)O>()O>_)O>()O>_)O>",
+":);,;,;)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)[)M M M M M M M M M M M M M M M M M M })})|)|)})M M 1)2)3)4)5)6)6)6)7)7)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)",
+"9)#;;,;,$ -)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)<)0)a)a)a)b)c)d)e)f)g)h)i)i)j)j)M M M M M M M M M M M })})})})M k)k)M M k)l)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)8)",
+"+ 9)m)n)$ #;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;#;o)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)p)",
+"+ + 9)a m)q)r)s)r)s)r)s)r)s)r)r)s)r)s)r)s)r)r)s)r)s)r)s)r)s)r)s)r)s)r)s)r)t)u)v)w)x)x)w)y)z)A)A)B)B)B)B)w)w)C)C)w)w)B)B)B)B)B)w)w)w)w)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)D)B)B)B)B)B)D)B)B)B)D)B)",
+". + + 9)9)9)q)E)q)E)q)E)q)E)q)q)E)q)E)q)E)q)q)E)q)E)q)E)q)E)q)E)q)E)q)E)q)F)G)H)E)I)J)K)H)L)L)L)L)L)L)L)H)H)M)M)H)H)L)L)G)L)L)H)H)H)H)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)L)N)L)L)L)L)L)N)L)L)L)N)L)",
+". . 0 . + O)P)O)P)O)P)O)P)O)P)P)O)P)O)P)O)P)P)O)P)O)P)O)P)O)P)O)P)O)P)O)P)O)Q)R)S)T)U)V)W)X)W)W)V)V)V)V)V)V)V)V)Y)Y)Z)Z)Y)Z)Z)Y)Y)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)V)Y)V)V)V)V)V)Y)V)V)V)Y)V)",
+". . . 0 0 0 . 0 0 0 + 0 + 0 + 0 + 0 + 0 + 0 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 0 `) !+ + + .! !`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)`)+!`)`)`)`)`)+!`)`)`)+!`)"};
+
+
+static char * listviewhighcornerright_xpm[] = {
+"100 46 780 2",
+" c None",
+". c #6A779D",
+"+ c #6C789C",
+"@ c #6C789D",
+"# c #6B789D",
+"$ c #6A779E",
+"% c #66759E",
+"& c #64749E",
+"* c #63749E",
+"= c #61739D",
+"- c #576D9B",
+"; c #556C9C",
+"> c #4D679D",
+", c #4A649D",
+"' c #49629D",
+") c #465E9C",
+"! c #40579C",
+"~ c #3B5394",
+"{ c #2C4E97",
+"] c #314993",
+"^ c #2B4595",
+"/ c #1B4296",
+"( c #253D93",
+"_ c #19418F",
+": c #0F3C96",
+"< c #42599E",
+"[ c #758DC3",
+"} c #E8EAE7",
+"| c #EEF0ED",
+"1 c #FBFBFC",
+"2 c #6F7D9B",
+"3 c #6F7D9A",
+"4 c #6E7B9C",
+"5 c #67759E",
+"6 c #63739E",
+"7 c #62739D",
+"8 c #596F9C",
+"9 c #4A639D",
+"0 c #47609C",
+"a c #445B9F",
+"b c #3E5697",
+"c c #2E509A",
+"d c #2D509A",
+"e c #2D4F99",
+"f c #2D4F98",
+"g c #28418A",
+"h c #3E51A3",
+"i c #D0D3DC",
+"j c #A1B6EF",
+"k c #A2B6F0",
+"l c #A1B6F0",
+"m c #A3B6F0",
+"n c #A0B6EF",
+"o c #9DB6EE",
+"p c #9CB5EF",
+"q c #9CB2F0",
+"r c #9FB5EE",
+"s c #9CB4EB",
+"t c #9AB3EC",
+"u c #9AB0EC",
+"v c #9DB3EB",
+"w c #9BB4EC",
+"x c #9BB4EE",
+"y c #9BB1EF",
+"z c #9BB0F0",
+"A c #90ACF0",
+"B c #93ABEE",
+"C c #91A8EB",
+"D c #8BA3E8",
+"E c #88A1E7",
+"F c #809DE9",
+"G c #7A99E8",
+"H c #7491E5",
+"I c #698AE4",
+"J c #6184E3",
+"K c #507EDC",
+"L c #4E7CDB",
+"M c #4F7DDC",
+"N c #5479DA",
+"O c #567BDC",
+"P c #577CDD",
+"Q c #5074DA",
+"R c #5174DB",
+"S c #5175DC",
+"T c #5276DD",
+"U c #4D71DE",
+"V c #4C72D8",
+"W c #3A6CE0",
+"X c #2B49A6",
+"Y c #E0E2DF",
+"Z c #93AAE9",
+"` c #94A9E8",
+" . c #94AAE9",
+".. c #93A9E9",
+"+. c #92AAE9",
+"@. c #8DA9E8",
+"#. c #8CA7E9",
+"$. c #92ABE9",
+"%. c #8EAAE9",
+"&. c #8EA9E9",
+"*. c #8FAAE9",
+"=. c #8CA8E9",
+"-. c #8CA2E7",
+";. c #86A1E6",
+">. c #839EE9",
+",. c #7F9CE9",
+"'. c #7A97E8",
+"). c #7693E7",
+"!. c #6E8EE8",
+"~. c #678AE9",
+"{. c #5D84E3",
+"]. c #577CDF",
+"^. c #4E77DF",
+"/. c #4A70DB",
+"(. c #4870DB",
+"_. c #4870DC",
+":. c #4770E3",
+"<. c #496FDC",
+"[. c #486EDB",
+"}. c #466FE4",
+"|. c #466EE3",
+"1. c #4167D9",
+"2. c #4066D8",
+"3. c #3F66D8",
+"4. c #3D64D7",
+"5. c #3960DA",
+"6. c #476DD9",
+"7. c #446EE5",
+"8. c #305EC8",
+"9. c #8EAAE8",
+"0. c #8FAAE8",
+"a. c #91AAE9",
+"b. c #8FA9E8",
+"c. c #8BA8E8",
+"d. c #8AA7E9",
+"e. c #8BA5EA",
+"f. c #8AA7E8",
+"g. c #87A2E6",
+"h. c #859FE8",
+"i. c #7F9DE8",
+"j. c #7C9AE8",
+"k. c #7B95E7",
+"l. c #7090E8",
+"m. c #6B8BE9",
+"n. c #6386E6",
+"o. c #5881E1",
+"p. c #5479DE",
+"q. c #4D74DE",
+"r. c #476EDB",
+"s. c #446EE1",
+"t. c #446EE0",
+"u. c #446EDF",
+"v. c #446DE0",
+"w. c #426ADF",
+"x. c #3C64DA",
+"y. c #4360CC",
+"z. c #D3D5D2",
+"A. c #E6E3E8",
+"B. c #8DA2E7",
+"C. c #8CA6EA",
+"D. c #8DA3E9",
+"E. c #88A2E7",
+"F. c #87A1E7",
+"G. c #8AA1E7",
+"H. c #849EE9",
+"I. c #7D9AE9",
+"J. c #7B98E8",
+"K. c #7796E5",
+"L. c #7191E7",
+"M. c #688CE9",
+"N. c #6687E5",
+"O. c #5C83E1",
+"P. c #557BDE",
+"Q. c #4F76DE",
+"R. c #4C72DE",
+"S. c #456EDF",
+"T. c #426AD9",
+"U. c #4269D9",
+"V. c #4269D8",
+"W. c #3D64D9",
+"X. c #3A61DA",
+"Y. c #345ED6",
+"Z. c #335ECF",
+"`. c #C6C3C8",
+" + c #86A1E7",
+".+ c #87A2E7",
+"++ c #87A0E7",
+"@+ c #859EE8",
+"#+ c #849DE9",
+"$+ c #7E9BE9",
+"%+ c #7A99E9",
+"&+ c #7A95E5",
+"*+ c #7593E7",
+"=+ c #6F8EE9",
+"-+ c #668AE5",
+";+ c #6386E0",
+">+ c #5B82DF",
+",+ c #5379DE",
+"'+ c #5075DE",
+")+ c #4B6FDC",
+"!+ c #446AD7",
+"~+ c #4269D6",
+"{+ c #4269D5",
+"]+ c #3E65D7",
+"^+ c #C9CAC9",
+"/+ c #869EE9",
+"(+ c #859FE9",
+"_+ c #849FE9",
+":+ c #829DE8",
+"<+ c #819DE8",
+"[+ c #7B9AE9",
+"}+ c #7A96E6",
+"|+ c #7290E8",
+"1+ c #698CE6",
+"2+ c #6689E0",
+"3+ c #5D84E0",
+"4+ c #587FDF",
+"5+ c #5377DD",
+"6+ c #4B74DE",
+"7+ c #496BD8",
+"8+ c #7C9BE9",
+"9+ c #7E9CE9",
+"0+ c #7D9AEA",
+"a+ c #7D9BEA",
+"b+ c #7D98E8",
+"c+ c #7C98E8",
+"d+ c #7796E4",
+"e+ c #7592E6",
+"f+ c #7390E1",
+"g+ c #698DE0",
+"h+ c #6588DE",
+"i+ c #5E84E0",
+"j+ c #5880DF",
+"k+ c #5479DC",
+"l+ c #4F75DE",
+"m+ c #4A6FDB",
+"n+ c #436AD7",
+"o+ c #3F65D7",
+"p+ c #BAC3BE",
+"q+ c #7B9AE8",
+"r+ c #7B9AEA",
+"s+ c #7A9AEA",
+"t+ c #7B99E9",
+"u+ c #7D97E7",
+"v+ c #7D95E6",
+"w+ c #7D95E5",
+"x+ c #7C95E6",
+"y+ c #7493E3",
+"z+ c #7290DF",
+"A+ c #6C8DDE",
+"B+ c #6B89E1",
+"C+ c #6486DF",
+"D+ c #5D81DF",
+"E+ c #567DDE",
+"F+ c #4F73DE",
+"G+ c #496EDA",
+"H+ c #355ED6",
+"I+ c #345ED5",
+"J+ c #7E95E5",
+"K+ c #7C97E8",
+"L+ c #7C97E7",
+"M+ c #7B94E6",
+"N+ c #7A95E4",
+"O+ c #7695E5",
+"P+ c #7694E4",
+"Q+ c #7994E6",
+"R+ c #7995E4",
+"S+ c #7594E4",
+"T+ c #7391E2",
+"U+ c #6E8EDE",
+"V+ c #6B8ADE",
+"W+ c #6688DF",
+"X+ c #5F84E0",
+"Y+ c #5980E0",
+"Z+ c #4D72DD",
+"`+ c #456BD7",
+" @ c #4168D6",
+".@ c #3C64D7",
+"+@ c #335ED0",
+"@@ c #4659C7",
+"#@ c #7292E1",
+"$@ c #7392E1",
+"%@ c #7492E1",
+"&@ c #718FDF",
+"*@ c #6F8EDE",
+"=@ c #6D8BDE",
+"-@ c #6B88DF",
+";@ c #597FDF",
+">@ c #557ADD",
+",@ c #5176DC",
+"'@ c #4D74DD",
+")@ c #496DDA",
+"!@ c #3860D8",
+"~@ c #7391E0",
+"{@ c #7290DE",
+"]@ c #6D8EDD",
+"^@ c #6D8DDD",
+"/@ c #7190E0",
+"(@ c #6C8DDD",
+"_@ c #6B89DF",
+":@ c #6487E0",
+"<@ c #6085DF",
+"[@ c #5F81DE",
+"}@ c #567EDE",
+"|@ c #4F74D9",
+"1@ c #466BD7",
+"2@ c #4067D5",
+"3@ c #3C63D7",
+"4@ c #335ED3",
+"5@ c #335ED1",
+"6@ c #718EDD",
+"7@ c #728EDD",
+"8@ c #748EDD",
+"9@ c #708EDD",
+"0@ c #6F8DDD",
+"a@ c #6E8DDD",
+"b@ c #6C8ADE",
+"c@ c #6C89DF",
+"d@ c #6988DF",
+"e@ c #6387DF",
+"f@ c #6282DE",
+"g@ c #5681E0",
+"h@ c #577BDD",
+"i@ c #5277DB",
+"j@ c #4D73D8",
+"k@ c #4A70D8",
+"l@ c #436AD5",
+"m@ c #3F66D6",
+"n@ c #3C63D8",
+"o@ c #3960D8",
+"p@ c #3860D7",
+"q@ c #335ED2",
+"r@ c #345ED4",
+"s@ c #6C88DF",
+"t@ c #6D88DF",
+"u@ c #6B89DE",
+"v@ c #6888DF",
+"w@ c #6587E0",
+"x@ c #6989DF",
+"y@ c #6687E0",
+"z@ c #6287E0",
+"A@ c #6281DD",
+"B@ c #5881E0",
+"C@ c #557ADB",
+"D@ c #5176D9",
+"E@ c #4E75D7",
+"F@ c #4A6FD8",
+"G@ c #476BD6",
+"H@ c #4067D6",
+"I@ c #3C62D7",
+"J@ c #3C60D4",
+"K@ c #365ED1",
+"L@ c #345ED3",
+"M@ c #6786DF",
+"N@ c #5F85E0",
+"O@ c #5F86E0",
+"P@ c #6186DF",
+"Q@ c #6286E0",
+"R@ c #6284DF",
+"S@ c #6384DF",
+"T@ c #5B7FDE",
+"U@ c #577DDC",
+"V@ c #557BDA",
+"W@ c #5278D8",
+"X@ c #4E76D6",
+"Y@ c #4C72D7",
+"Z@ c #486DD8",
+"`@ c #4469D6",
+" # c #3F62D2",
+".# c #3C60CF",
+"+# c #345ECF",
+"@# c #6086DF",
+"## c #6085E0",
+"$# c #6285DF",
+"%# c #6383DD",
+"&# c #6481DC",
+"*# c #6380DD",
+"=# c #6183DE",
+"-# c #6083DD",
+";# c #6081DC",
+"># c #6080DD",
+",# c #6083DE",
+"'# c #6181DC",
+")# c #6280DD",
+"!# c #577EDB",
+"~# c #557CD7",
+"{# c #4F76D6",
+"]# c #4E74D7",
+"^# c #466CD7",
+"/# c #3B64D6",
+"(# c #4261CD",
+"_# c #375FCE",
+":# c #5A7FD8",
+"<# c #6281DA",
+"[# c #5F81D8",
+"}# c #5C80D8",
+"|# c #557DD7",
+"1# c #577ED8",
+"2# c #567ED7",
+"3# c #587DD8",
+"4# c #577DD8",
+"5# c #587ED8",
+"6# c #567DD8",
+"7# c #5379D9",
+"8# c #5177D7",
+"9# c #4D74D5",
+"0# c #486ED9",
+"a# c #4068D4",
+"b# c #3D65D2",
+"c# c #4361CC",
+"d# c #345ECE",
+"e# c #325DCF",
+"f# c #2C5AD1",
+"g# c #3959C5",
+"h# c #547BD8",
+"i# c #567DD7",
+"j# c #557BD8",
+"k# c #5279D9",
+"l# c #5278D9",
+"m# c #4D74D6",
+"n# c #4B71D8",
+"o# c #496CD8",
+"p# c #4669D7",
+"q# c #3D66D3",
+"r# c #3F62CF",
+"s# c #4260CC",
+"t# c #5379D8",
+"u# c #4E75D4",
+"v# c #4C73D7",
+"w# c #476CD7",
+"x# c #4869D0",
+"y# c #4067D2",
+"z# c #3D64D1",
+"A# c #4261CC",
+"B# c #395FCE",
+"C# c #4F75D3",
+"D# c #5074D2",
+"E# c #5174D1",
+"F# c #5175D1",
+"G# c #4F74D3",
+"H# c #4C73D5",
+"I# c #4C73D4",
+"J# c #4A72D1",
+"K# c #4B70CF",
+"L# c #506CCC",
+"M# c #4D6BCE",
+"N# c #4167D0",
+"O# c #3D65D1",
+"P# c #3F63CF",
+"Q# c #3B5FCD",
+"R# c #3159CD",
+"S# c #4971D0",
+"T# c #4870CF",
+"U# c #4C6FCF",
+"V# c #4E6CCE",
+"W# c #4E6BCE",
+"X# c #4769CF",
+"Y# c #3D66D0",
+"Z# c #3C65D1",
+"`# c #4062CE",
+" $ c #3D5FCD",
+".$ c #365FCF",
+"+$ c #325DCD",
+"@$ c #2D5AD0",
+"#$ c #3859C5",
+"$$ c #355FCF",
+"%$ c #355ECF",
+"&$ c #335ECE",
+"*$ c #305CCD",
+"=$ c #2B5ACE",
+"-$ c #3056C9",
+";$ c #2553C6",
+">$ c #2153C8",
+",$ c #1F4FC7",
+"'$ c #274CC5",
+")$ c #214AC7",
+"!$ c #1C48C8",
+"~$ c #1244C9",
+"{$ c #1043C9",
+"]$ c #1144C9",
+"^$ c #2A45BE",
+"/$ c #2744B5",
+"($ c #1D49C0",
+"_$ c #2B58DE",
+":$ c #002D94",
+"<$ c #2B59CA",
+"[$ c #2A59CA",
+"}$ c #2E57C8",
+"|$ c #3255C6",
+"1$ c #3355C5",
+"2$ c #1C52C8",
+"3$ c #1D50C7",
+"4$ c #234FC6",
+"5$ c #264CC5",
+"6$ c #1D48C7",
+"7$ c #1245C8",
+"8$ c #1F44C2",
+"9$ c #2945BE",
+"0$ c #2A45BD",
+"a$ c #2040BF",
+"b$ c #3156C7",
+"c$ c #3056C7",
+"d$ c #3354C5",
+"e$ c #3355C6",
+"f$ c #3255C5",
+"g$ c #3254C5",
+"h$ c #1952C7",
+"i$ c #1951C8",
+"j$ c #2050C7",
+"k$ c #274CC4",
+"l$ c #244CC6",
+"m$ c #1F49C7",
+"n$ c #1E47C5",
+"o$ c #2045C3",
+"p$ c #1C44BF",
+"q$ c #2045BE",
+"r$ c #2040B8",
+"s$ c #3254C6",
+"t$ c #3055C6",
+"u$ c #2A54C6",
+"v$ c #2353C7",
+"w$ c #3054C5",
+"x$ c #2F55C5",
+"y$ c #2A54C5",
+"z$ c #2553C5",
+"A$ c #2F54C5",
+"B$ c #3155C6",
+"C$ c #2A54C7",
+"D$ c #1A52C8",
+"E$ c #204FC2",
+"F$ c #264DC6",
+"G$ c #234BC5",
+"H$ c #1D48C1",
+"I$ c #1E48BF",
+"J$ c #2646BE",
+"K$ c #2B45BD",
+"L$ c #1E43BE",
+"M$ c #2643BF",
+"N$ c #2243BF",
+"O$ c #3049BC",
+"P$ c #1E50BE",
+"Q$ c #1D50C0",
+"R$ c #1D50BF",
+"S$ c #1852C1",
+"T$ c #1E51C0",
+"U$ c #214FBF",
+"V$ c #2050C0",
+"W$ c #244EBF",
+"X$ c #2151C0",
+"Y$ c #234FBF",
+"Z$ c #2350C0",
+"`$ c #2351C0",
+" % c #244FBF",
+".% c #2250C0",
+"+% c #2051C0",
+"@% c #1E50C0",
+"#% c #244DBE",
+"$% c #274DBF",
+"%% c #244CBF",
+"&% c #1C48C0",
+"*% c #2247BF",
+"=% c #2C44BD",
+"-% c #1C44BE",
+";% c #1444BF",
+">% c #1841BF",
+",% c #1F40BF",
+"'% c #254DBE",
+")% c #224FBE",
+"!% c #224FBF",
+"~% c #234EBF",
+"{% c #254CBD",
+"]% c #244DBD",
+"^% c #244CBD",
+"/% c #264DBE",
+"(% c #264DBD",
+"_% c #214BC0",
+":% c #1D48C0",
+"<% c #2347BF",
+"[% c #2B44BD",
+"}% c #2444BE",
+"|% c #0F42BF",
+"1% c #0641BF",
+"2% c #0F41BF",
+"3% c #1741BE",
+"4% c #1F40BD",
+"5% c #234BBF",
+"6% c #234CBE",
+"7% c #214BBE",
+"8% c #244CBE",
+"9% c #214ABE",
+"0% c #214ABF",
+"a% c #1F48C0",
+"b% c #2746BE",
+"c% c #1F43BE",
+"d% c #0941BE",
+"e% c #0342BA",
+"f% c #0242BC",
+"g% c #1241B8",
+"h% c #1F40B7",
+"i% c #2F41AC",
+"j% c #2644AE",
+"k% c #2D49B4",
+"l% c #2649B6",
+"m% c #2949B7",
+"n% c #2849B5",
+"o% c #2149B8",
+"p% c #1E49B9",
+"q% c #1F48B8",
+"r% c #1F49B9",
+"s% c #2545B6",
+"t% c #2744B7",
+"u% c #2844B7",
+"v% c #2043B8",
+"w% c #1241B7",
+"x% c #1340B8",
+"y% c #0D41B8",
+"z% c #1941B8",
+"A% c #1F40B8",
+"B% c #203FB8",
+"C% c #2549B5",
+"D% c #2648B6",
+"E% c #2547B7",
+"F% c #2248B7",
+"G% c #2048B7",
+"H% c #2346B6",
+"I% c #2146B6",
+"J% c #2247B7",
+"K% c #2148B7",
+"L% c #2743B4",
+"M% c #2643B5",
+"N% c #2542B6",
+"O% c #1D42B7",
+"P% c #0E42B8",
+"Q% c #0C41B8",
+"R% c #1341B8",
+"S% c #1740B8",
+"T% c #1C41B8",
+"U% c #1F40B1",
+"V% c #2644B5",
+"W% c #2544B5",
+"X% c #2544B4",
+"Y% c #2444B5",
+"Z% c #2444B4",
+"`% c #2744B4",
+" & c #2241B7",
+".& c #1D41B8",
+"+& c #0B42B8",
+"@& c #0942B8",
+"#& c #0C42B8",
+"$& c #0F41B8",
+"%& c #1641B8",
+"&& c #2442B5",
+"*& c #2543B3",
+"=& c #2342B2",
+"-& c #2341B4",
+";& c #2141B3",
+">& c #2141B5",
+",& c #2140B5",
+"'& c #2040B5",
+")& c #1C40B7",
+"!& c #1B41B3",
+"~& c #0142B6",
+"{& c #0E41B7",
+"]& c #1141B7",
+"^& c #1440B2",
+"/& c #113FB0",
+"(& c #1440B0",
+"_& c #213EAF",
+":& c #233DAE",
+"<& c #223EAF",
+"[& c #1E40B1",
+"}& c #173EAD",
+"|& c #1440AF",
+"1& c #0D40AF",
+"2& c #0941B0",
+"3& c #0D3FAE",
+"4& c #1B3CAC",
+"5& c #233CAD",
+"6& c #203FB0",
+"7& c #273BAD",
+"8& c #1D40B0",
+"9& c #2040B1",
+"0& c #1E40B0",
+"a& c #1C40B0",
+"b& c #1B3DAC",
+"c& c #143DAC",
+"d& c #193DAD",
+"e& c #1B3DAD",
+"f& c #173DAD",
+"g& c #153DAC",
+"h& c #1C3CAC",
+"i& c #243CAD",
+"j& c #213FB0",
+"k& c #263BAA",
+"l& c #253CAE",
+"m& c #273AAC",
+"n& c #273AAD",
+"o& c #253BAD",
+"p& c #1D3CAC",
+"q& c #243BAD",
+"r& c #1E3CAC",
+"s& c #263BAD",
+"t& c #1A3DAC",
+"u& c #143DAB",
+"v& c #163DAC",
+"w& c #1A3CAC",
+"x& c #1F3CAD",
+"y& c #263BAB",
+"z& c #263BA6",
+"A& c #1E42A4",
+"B& c #2D40A5",
+"C& c #253BA6",
+"D& c #253CA7",
+"E& c #263AA5",
+"F& c #253BA7",
+"G& c #1E3BA6",
+"H& c #193DA6",
+"I& c #173DA5",
+"J& c #143DA6",
+"K& c #1A3DA7",
+"L& c #133DA6",
+"M& c #123DA5",
+"N& c #1A3CA7",
+"O& c #243BA6",
+"P& c #263AA7",
+"Q& c #273BA7",
+"R& c #263AA6",
+"S& c #223BA6",
+"T& c #1D3BA6",
+"U& c #173CA6",
+"V& c #133DA5",
+"W& c #1B3DA6",
+"X& c #193DA5",
+"Y& c #123DA4",
+"Z& c #163CA5",
+"`& c #213CA6",
+" * c #273BA8",
+".* c #263BA7",
+"+* c #253BA5",
+"@* c #263BA5",
+"#* c #1C3BA6",
+"$* c #1B3BA9",
+"%* c #133BA8",
+"&* c #0A3BA7",
+"** c #083AA6",
+"=* c #123CA5",
+"-* c #0839A8",
+";* c #0239A6",
+">* c #123AA8",
+",* c #1F49C8",
+"'* c #2F4DA4",
+")* c #2E4DA3",
+"!* c #384CA4",
+"~* c #3C4DA7",
+"{* c #394EA7",
+"]* c #3B4CA5",
+"^* c #3C52B1",
+"/* c #3551A8",
+"(* c #3759BE",
+"_* c #4161C7",
+":* c #0033A8",
+"<* c #596FA9",
+"[* c #2F4DA3",
+"}* c #2D4BA5",
+"|* c #2E4CA4",
+"1* c #2C4AA5",
+"2* c #2D4BA4",
+"3* c #354DA4",
+"4* c #3A4BA4",
+"5* c #394DA6",
+"6* c #4056AD",
+"7* c #445BBB",
+"8* c #B5B7B4",
+"9* c #1B2F85",
+"0* c #242F79",
+"a* c #B5B5B5",
+"b* c #B5B2B6",
+"c* c #C0C3C3",
+"d* c #E3E3E4",
+"e* c #EBEDEA",
+". + @ + # $ % & # $ % & # $ % & # $ % & & * = - ; > , ' ) ! ~ { { { { { { { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / / / ( / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / _ _ / / : / < [ } | | | 1 1 ",
+"2 2 2 2 3 2 4 @ 3 2 4 @ 3 2 4 @ 3 2 4 @ # 5 6 7 8 ; > 9 0 a b c d e f { { { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ( ( ( ( ( ( ( ( ( / / / / / / / / / / / / / / / / / _ _ _ _ _ _ _ _ _ _ _ g g _ / / : : : h i } 1 | 1 ",
+"j k l m n o p q n o p q r s t u v w x y z A B C D E F G H I J K L M N O P O O Q R S T T T T T T T T T T T T T T T T T T U U U U U U U U U U U U U U U U U U U U U U U U U U U U V V V U U W X : [ Y | | ",
+"Z ` . ...+.@.#...+.@.#.Z $.%.&.Z $.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.6.7.8.: h Y } 1 ",
+"9.0.a.b.c.c.d.e.f.c.d.e.f.c.d.e.f.c.d.e.g.h.i.j.k.l.m.n.o.p.q.r.s.s.t.u.u.v.w.x.4.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.y.5.7.6.: / z.A.} ",
+"-.B.C.D.-.E.g.F.G.E.g.F.G.E.g.F.G.E.g.F.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.V.U.U.W.X.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Z.y.Y.7.7.: : `.z.} ",
+" +.+g.;.++F.@+#+++F.@+#+++F.@+#+++F.@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+{+{+4.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.Y.Y.5.5.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Z.Z.Z.y.y.5.7.7.: : ^+z.Y ",
+"/+(+_+#+H.H.>.:+H.H.>.:+H.H.>.:+H.H.>.<+[+}+*+|+1+2+3+4+5+6+7+{+{+4.4.4.4.4.4.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.Y.Y.Y.Y.Y.Y.Y.5.Y.Y.Y.Y.Y.Y.Y.Y.5.Y.Y.5.5.5.5.Y.Y.Y.Y.Y.Y.Z.Z.Z.Z.y.y.y.y.y.y.7.7.: : ^+i } ",
+"8+9+0+0+a+0+0+b+a+0+0+b+a+0+0+b+a+0+0+c+d+e+f+g+h+i+j+k+l+m+n+o+4.4.4.4.5.5.5.5.5.5.Y.Y.5.5.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.7.7.: : p+z.Y ",
+"q+r+r+s+t+u+v+w+t+u+v+w+t+u+v+w+t+u+x+&+y+z+A+B+C+D+E+5+F+G+~+4.4.4.4.5.5.5.5.5.H+Y.Y.Y.Y.Y.Y.Y.Y.I+Y.Z.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.7.7.: : `.z.A.",
+"J+v+K+L+M+N+O+P+Q+R+O+P+Q+R+O+P+Q+R+O+S+T+U+V+W+X+Y+P.T Z+`+ @4.4..@5.5.5.5.5.5.Y.Y.Y.I+I+I+I+I++@+@Z.Z.Y.Y.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.@@Z.7.7.: : p+z.Y ",
+"#@$@$@%@%@$@#@&@#@#@#@&@#@#@#@&@#@#@#@*@=@-@;+i+;@>@,@'@)@ @4.X.5.5.H+Y.Y.Y.!@Y.Y.I++@+@Z.Z.+@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.y.Z.6.6.: : `.z.A.",
+"#@$@~@~@~@{@]@^@/@{@]@^@/@{@]@^@/@{@]@(@_@:@<@[@}@k+|@V 1@2@3@5.5.5.Y.Y.I+4@I+5@+@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.y.Z.6.6.: : p+z.Y ",
+"6@7@8@9@0@a@b@c@a@a@b@c@a@a@b@c@a@a@b@d@e@<@f@g@h@i@j@k@l@m@n@o@o@p@Y.I+q@q@r@+@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.y.Z.6.6.: : `.z.A.",
+"s@t@u@_@_@v@w@w@x@v@w@w@x@v@y@y@x@v@:@z@A@B@P C@D@E@F@G@H@I@J@K@5@+@+@+@r@I+L@Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.@@Z.W W : : p+z.Y ",
+"M@N@O@P@C+Q@Q@R@C+;+Q@R@C+;+;+S@C+Q@Q@R@T@U@V@W@X@Y@Z@`@4. #.#+#Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.8.Z.Z.Z.Z.8.8.Z.Z.y.@@@@W W : : `.z.A.",
+"@#O@O@##$#%#&#*#=#-#;#>#,#-#;#>#,#-#'#)#!#~#W@{#]#k@^#H@/#(#_#Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.8.8.Z.Z.Z.Z.Z.Z.Z.8.8.8.8.8.8.8.8.8.8.8.Z.Z.y.y.@@W W : : p+z.Y ",
+":#<#[#}#|#1#2#3#4#5#1#4#4#1#1#4#4#1#1#6#7#8#9#V 0#`+a#b#c#d#e#Z.Z.Z.f#Z.Z.Z.f#f#f#f#f#f#f#f#f#f#g#g#g#g#g#8.8.8.8.8.8.8.8.8.g#g#g#g#8.g#8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.y.y.@@W W : : `.z.A.",
+"h#2#i#6#|#j#7#k#|#j#7#7#|#j#7#7#|#j#7#l#8#m#n#n#o#p#q#r#s#d#e#Z.Z.Z.f#f#f#f#Z.f#f#g#g#g#g#g#g#g#g#g#g#g#g#8.8.8.g#g#8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.y.y.y.y.8.8.8.y.y.@@W W : : p+z.Y ",
+"l#7#7#l#7#7#7#W@7#7#7#W@7#7#k#W@t#7#7#W@u#v#n#w#x#y#z#A#B#Z.e#f#f#Z.f#f#f#Z.Z.g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#8.8.8.g#g#g#g#8.8.g#g#g#g#g#g#8.8.g#8.8.y.8.8.y.y.8.y.y.y.y.@@W W : : `.z.A.",
+"C#D#E#F#G#H#I#J#G#H#I#J#G#H#I#J#G#H#I#J#K#L#M#N#O#P#s#Q#+#f#R#f#f#f#f#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#@@@@y.y.@@@@y.y.W W : : p+z.Y ",
+"S#S#S#S#S#T#S#U#S#T#S#U#S#T#S#U#S#T#S#U#V#W#X#Y#Z#`# $.$+$@$#$g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#@@@@@@@@@@@@@@@@@@y.y.W W : : `.z.A.",
+"+$Z..$$$%$+$&$*$%$+$&$*$%$+$&$*$%$+$&$*$=$-$;$>$,$'$)$!$~${$]$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$/$/$/$/$($($_$_$:$:$p+z.Y ",
+"<$<$<$<$<$[$}$|$<$[$}$|$<$[$}$|$<$[$}$|$1$2$3$4$5$)$6$7$8$9$0$a$a$a$a$a$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$/$/$/$^$^$^$/$/$/$/$/$/$/$/$/$/$/$/$/$/$($($_$_$:$:$`.z.A.",
+"b$c$c$c$d$e$e$f$g$|$|$1$d$e$e$1$d$e$e$1$h$i$j$k$l$m$n$o$p$9$q$a$a$a$a$a$a$a$a$^$a$a$^$^$^$^$^$^$a$r$r$r$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$^$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$($($_$_$:$:$p+z.Y ",
+"e$1$s$s$1$t$u$v$w$x$y$z$A$x$u$v$g$B$C$>$D$E$F$G$H$I$J$K$L$M$N$a$a$a$a$a$a$a$a$^$r$r$a$^$^$^$a$r$r$r$r$r$/$^$r$^$^$^$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$O$($_$_$:$:$`.z.A.",
+"P$Q$R$S$T$U$V$W$X$Y$Z$W$`$ %.%W$+%U$@%#%$%%%&%($*%=%-%;%>%>%,%r$r$r$r$r$a$a$a$/$/$/$r$r$r$r$r$r$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$O$($_$_$:$:$p+z.Y ",
+"'%W$)%!%~%{%'%]%~%^%'%]%~%^%'%]%~%^%/%(%_%&%:%<%[%}%|%1%2%3%4%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$r$/$/$r$r$r$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$/$r$/$/$/$/$/$O$($_$_$:$:$`.z.A.",
+"5%6%'%'%6%7%8%9%6%7%8%9%6%7%8%9%6%7%8%0%&%a%<%b%[%c%d%e%f%g%h%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$/$/$/$/$/$/$/$/$/$/$/$/$/$r$r$/$/$r$r$/$r$i%j%O$($_$_$:$:$p+z.Y ",
+"k%l%m%n%o%o%p%q%o%o%r%q%o%o%r%q%o%o%p%q%s%t%/$u%v%w%x%y%z%A%B%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$/$/$/$/$/$/$/$r$r$i%i%i%r$r$i%i%i%i%i%i%i%i%i%i%i%i%r$/$/$j%j%j%j%j%j%j%j%j%O$($_$_$:$:$`.z.A.",
+"C%D%E%F%G%H%I%J%K%H%I%J%K%H%I%J%K%H%I%J%L%M%N%O%P%Q%R%S%T%A%B%r$r$r$r$r$r$r$r$r$r$r$r$r$r$r$U%U%r$r$i%i%/$/$r$r$/$/$/$/$r$r$i%i%i%i%i%i%i%i%i%i%i%i%i%i%j%i%j%j%j%j%j%j%j%j%j%j%j%j%j%O$($_$_$:$:$p+z.Y ",
+"/$/$/$/$V%V%W%X%W%Y%Y%Z%W%W%Y%Z%W%W%W%`%`% &B%.&+&@&#&$&%&A%B%r$r$r$U%U%U%U%r$U%U%U%U%U%U%U%U%U%U%i%i%i%i%i%i%i%i%/$/$/$i%i%i%i%i%i%i%i%i%j%j%j%j%i%i%i%i%i%j%j%j%i%i%j%j%j%j%j%j%j%j%O$($_$_$:$:$`.z.A.",
+"&&*&=&-&=&;&>&,&=&;&>&,&=&;&>&,&=&;&>&'&)&!&~&{&]&^&/&(&_&:&<&U%U%U%U%U%U%U%U%U%U%U%U%U%i%i%U%U%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%O$($_$_$:$:$p+z.Y ",
+"U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%[&}&|&1&2&3&4&5&_&6&U%7&U%U%U%U%U%U%U%U%i%i%U%U%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%O$O$_$_$:$:$`.z.A.",
+"U%U%U%U%U%U%[&8&U%9&[&0&U%9&[&0&U%9&[&a&:&b&c&d&e&f&g&h&i&<&j&U%U%U%U%U%U%U%U%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%O$O$_$_$:$:$p+z.Y ",
+"k&l&m&7&7&n&o&p&7&n&q&r&s&s&q&r&s&n&o&p&t&u&u&g&v&w&x&q&n&m&y&7&7&U%U%7&z&7&z&U%A&B&i%i%B&B&i%i%B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&i%B&O$O$_$_$:$:$`.z.A.",
+"C&D&E&z&z&E&F&G&z&E&F&G&z&E&F&G&z&E&F&G&H&I&J&K&L&M&N&O&P&Q&z&z&z&z&z&z&z&z&z&z&z&z&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&O$O$_$_$:$:$p+z.Y ",
+"z&z&z&z&R&S&T&U&R&S&T&U&R&S&T&U&R&S&T&U&V&V&W&X&Y&Z&`&C&R&z&z&z&z&z&z&z&z&z&z&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&O$O$_$_$:$:$^+z.A.",
+"z& *.*+*@*#*$*%*@*#*$*%*@*#*$*%*@*#*$*%*&***=*-*;*>*k&P&+*z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&z&B&B&B&B&z&z&z&B&B&B&z&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&B&/$O$O$@@_$,*:$/ ^+z.Y ",
+"'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*'*)*'*!*~*{*]*^*^*^*/*/*/*/*/*/*/*^*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*^*/*/*/*/*/*h h ^*h h ^*^*h h ^*^*^*^*h ^*^*^*^*h ^*^*^*(*_*_*_*_*_$:*:$<*`.z.} ",
+"'*'*'*'*'*[*}*|*'*[*}*|*'*[*}*|*'*[*}*|*1*1*2*}*}*2*[*)*3*4*5*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*h h h h h h h h h h h h h h h h 6*7*_*_*_*_*^*:*:$: 8*z.Y } ",
+"9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*( <*8*^+z.Y } 1 ",
+"a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*8*b*8*b*8*b*8*b*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*b*8*8*8*8*b*8*`.z.A.Y | | ",
+"c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*p+`.p+`.p+`.p+`.`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+`.p+^+`.^+^+z.z.Y Y | | 1 ",
+"d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*d*A.Y A.Y A.Y A.Y Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y A.Y } } | | | | 1 1 ",
+"e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*} | } | } | } | | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | } | | | | 1 | | | 1 1 1 "};
+
+
+static char * tabmiddle_xpm[] = {
+"33 42 32 1",
+" c None",
+". c #CECFEF",
+"+ c #CECBE7",
+"@ c #C6C7E7",
+"# c #C6CBE7",
+"$ c #BDBEDE",
+"% c #BDC3DE",
+"& c #CECBEF",
+"* c #B5B6D6",
+"= c #ADAECE",
+"- c #ADB2CE",
+"; c #BDBAD6",
+"> c #B5BAD6",
+", c #C6C3DE",
+"' c #ADAAC6",
+") c #B5B2CE",
+"! c #B5B6CE",
+"~ c #A5A2BD",
+"{ c #A5A6BD",
+"] c #9C9EB5",
+"^ c #9CA2BD",
+"/ c #ADAEC6",
+"( c #C6C3E7",
+"_ c #9C9AB5",
+": c #A5A6C6",
+"< c #949AAD",
+"[ c #A5AAC6",
+"} c #9496AD",
+"| c #BDBADE",
+"1 c #BDBED6",
+"2 c #9CA2B5",
+"3 c #A5AABD",
+"..........................+@.#.#.",
+"........................$@%&#.#..",
+"......................**$$@@&#.#.",
+".....................=-;>,%+@.#..",
+"....................'')!$$@@&#.#.",
+"...................~{=)$$@@&#.#..",
+"..................]^'/;;(%&#.#...",
+"................._]:/*>,%&@.#.#..",
+".................<{[)!$%+@.#.#...",
+"................}~{=!$%@@.#......",
+"................]^/-|$@@.#.......",
+"................]'/*;@@&#........",
+"...............<~[)>,%&#.#.......",
+"...............]~=)$%+#.#........",
+"...............]'/;1@@.#.........",
+"...............~{)*,%&#..........",
+"...............2/-$$@#...........",
+"...............~[*>(@&#..........",
+"...............^=)$%+#...........",
+"...............{'*>(@.#..........",
+"...............^=)$%+#...........",
+"...............{'*>(@.#..........",
+"...............^=)$%+#...........",
+"...............{'*>(@.#..........",
+"...............^=)$%+#...........",
+"...............{'*>(@.#..........",
+"...............^=)$%+#...........",
+"...............{'*>@@.#..........",
+"...............^=!$%&#...........",
+"...............{/*;@@.#..........",
+"...............{)!$%&#...........",
+"..............]'/;1@@.#..........",
+"..............23)>,%&#...........",
+"..............~=-$$@@.#..........",
+".............]{/*;@@.#...........",
+"............<^[)>,%&#............",
+"............]{/!$%@@.#...........",
+"..........]^[-!$%@@.#............",
+".........]^3/!>$@@.#.............",
+".......<]^3/!>$@@&#..............",
+".....<]2{[/!>$%@&#.#.............",
+"}<<_]2{3/-!>$%@&#.#.............."};
+
+
+static char * tabselectedbeginn_xpm[] = {
+"33 39 28 1",
+" c None",
+". c #CECFEF",
+"+ c #EFF3EF",
+"@ c #FFFBFF",
+"# c #F7FBF7",
+"$ c #FFFFFF",
+"% c #EFEFEF",
+"& c #F7F7F7",
+"* c #DEDFDE",
+"= c #E7E7E7",
+"- c #D6D3D6",
+"; c #DEE3DE",
+"> c #EFEBEF",
+", c #F7F3F7",
+"' c #CECBCE",
+") c #CECFCE",
+"! c #D6D7D6",
+"~ c #DEDBDE",
+"{ c #E7EBE7",
+"] c #C6C7C6",
+"^ c #E7E3E7",
+"/ c #BDC3BD",
+"( c #CED3CE",
+"_ c #BDBABD",
+": c #C6C3C6",
+"< c #C6CBC6",
+"[ c #D6DBD6",
+"} c #BDBEBD",
+"..........................+@#$#$$",
+"........................%%&&@#$#$",
+"......................*==%%&&@#$$",
+"....................--*;>%,&@#$#$",
+"...................')!~={,+@#$#$$",
+"...................]-!^=%%&&@#$#$",
+"................../'(~;>%&&@#$#$$",
+"................._])!*={,&@#$#$$$",
+"................_])~*>%&&$#$$$$$$",
+"................:<![={&&@#$$$$$$$",
+"................:)!^=,+@#$$$$$$$$",
+"...............}'(*^%+@#$#$$$$$$$",
+"...............:<!*>%&&$#$$$$$$$$",
+".............../)!^{,&@#$$$$$$$$$",
+"...............](*^%+@#$$$$$$$$$$",
+"...............]!~=%&&$$$$$$$$$$$",
+"...............'(*=,+@#$$$$$$$$$$",
+"...............<!*>%&&$$$$$$$$$$$",
+"...............'-^=,+@#$$$$$$$$$$",
+"...............<!*>%&#$$$$$$$$$$$",
+"...............'-^=,+@#$$$$$$$$$$",
+"...............<!*>%&#$$$$$$$$$$$",
+"...............'-^=,+@#$$$$$$$$$$",
+"...............<!*>%&#$$$$$$$$$$$",
+"...............'-^=,+@#$$$$$$$$$$",
+"...............<!*>%&#$$$$$$$$$$$",
+"...............'!^=,&@#$$$$$$$$$$",
+"...............<~*>%&#$$$$$$$$$$$",
+"...............)!^{,&@#$$$$$$$$$$",
+"..............])~;%+@#$$$$$$$$$$$",
+"..............]-[={&&$#$$$$$$$$$$",
+".............])!^=,&@#$$$$$$$$$$$",
+"............:'-*^%+@#$$$$$$$$$$$$",
+"............])~*>%&&$#$$$$$$$$$$$",
+"...........:'!*={,&@#$$$$$$$$$$$$",
+"..........:'-~^=,+@#$$$$$$$$$$$$$",
+".......}]'-~^=%,&@#$$$$$$$$$$$$$$",
+".....}:])-~^=%,+@#$#$$$$$$$$$$$$$",
+"}}}:]')-!*^=%,&@#$#$$$$$$$$$$$$$$"};
+
+
+static char * tabselectedend_xpm[] = {
+"33 42 33 1",
+" c None",
+". c #FFFFFF",
+"+ c #CECBE7",
+"@ c #C6C7E7",
+"# c #CECFEF",
+"$ c #C6CBE7",
+"% c #BDBEDE",
+"& c #BDC3DE",
+"* c #CECBEF",
+"= c #B5B6D6",
+"- c #ADAECE",
+"; c #ADB2CE",
+"> c #BDBAD6",
+", c #B5BAD6",
+"' c #C6C3DE",
+") c #ADAAC6",
+"! c #B5B2CE",
+"~ c #B5B6CE",
+"{ c #A5A2BD",
+"] c #A5A6BD",
+"^ c #9C9EB5",
+"/ c #9CA2BD",
+"( c #ADAEC6",
+"_ c #C6C3E7",
+": c #9C9AB5",
+"< c #A5A6C6",
+"[ c #949AAD",
+"} c #A5AAC6",
+"| c #9496AD",
+"1 c #BDBADE",
+"2 c #BDBED6",
+"3 c #9CA2B5",
+"4 c #A5AABD",
+"..........................+@#$#$#",
+"........................%@&*$#$##",
+"......................==%%@@*$#$#",
+".....................-;>,'&+@#$##",
+"....................))!~%%@@*$#$#",
+"...................{]-!%%@@*$#$##",
+"..................^/)(>>_&*$#$###",
+".................:^<(=,'&*@#$#$##",
+".................[]}!~%&+@#$#$###",
+"................|{]-~%&@@#$######",
+"................^/(;1%@@#$#######",
+"................^)(=>@@*$########",
+"...............[{}!,'&*$#$#######",
+"...............^{-!%&+$#$########",
+"...............^)(>2@@#$#########",
+"...............{]!='&*$##########",
+"...............3(;%%@$###########",
+"...............{}=,_@*$##########",
+".............../-!%&+$###########",
+"...............])=,_@#$##########",
+".............../-!%&+$###########",
+"...............])=,_@#$##########",
+".............../-!%&+$###########",
+"...............])=,_@#$##########",
+".............../-!%&+$###########",
+"...............])=,_@#$##########",
+".............../-!%&+$###########",
+"...............])=,@@#$##########",
+".............../-~%&*$###########",
+"...............](=>@@#$##########",
+"...............]!~%&*$###########",
+"..............^)(>2@@#$##########",
+"..............34!,'&*$###########",
+"..............{-;%%@@#$##########",
+".............^](=>@@#$###########",
+"............[/}!,'&*$############",
+"............^](~%&@@#$###########",
+"..........^/};~%&@@#$############",
+".........^/4(~,%@@#$#############",
+".......[^/4(~,%@@*$##############",
+".....[^3]}(~,%&@*$#$#############",
+"|[[:^3]4(;~,%&@*$#$##############"};
+
+
+static char * tabend_xpm[] = {
+"33 42 3 1",
+" c None",
+". c #CECFEF",
+"+ c #FFFFFF",
+"..........................+++++++",
+"........................+++++++++",
+"......................+++++++++++",
+".....................++++++++++++",
+"....................+++++++++++++",
+"...................++++++++++++++",
+"..................+++++++++++++++",
+".................++++++++++++++++",
+".................++++++++++++++++",
+"................+++++++++++++++++",
+"................+++++++++++++++++",
+"................+++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"...............++++++++++++++++++",
+"..............+++++++++++++++++++",
+"..............+++++++++++++++++++",
+"..............+++++++++++++++++++",
+".............++++++++++++++++++++",
+"............+++++++++++++++++++++",
+"............+++++++++++++++++++++",
+"..........+++++++++++++++++++++++",
+".........++++++++++++++++++++++++",
+".......++++++++++++++++++++++++++",
+".....++++++++++++++++++++++++++++",
+"+++++++++++++++++++++++++++++++++"};
+
+
+
+
+QColor fromHsl(QColor c)
+{
+ const qreal h = c.hueF();
+ const qreal s = c.saturationF();
+ const qreal l = c.valueF();
+
+ qreal ca[3] = {0, 0, 0};
+
+ if (s == 0 || h == 1) {
+ // achromatic case
+ ca[0] = ca[1] = ca[2] = l;
+ } else {
+ // chromatic case
+ qreal temp2;
+ if (l < qreal(0.5))
+ temp2 = l * (qreal(1.0) + s);
+ else
+ temp2 = l + s - (l * s);
+
+ const qreal temp1 = (qreal(2.0) * l) - temp2;
+ qreal temp3[3] = { h + (qreal(1.0) / qreal(3.0)),
+ h,
+ h - (qreal(1.0) / qreal(3.0)) };
+
+ for (int i = 0; i != 3; ++i) {
+ if (temp3[i] < qreal(0.0))
+ temp3[i] += qreal(1.0);
+ else if (temp3[i] > qreal(1.0))
+ temp3[i] -= qreal(1.0);
+
+ const qreal sixtemp3 = temp3[i] * qreal(6.0);
+
+ if (sixtemp3 < qreal(1.0))
+ ca[i] = ((temp1 + (temp2 - temp1) * sixtemp3));
+ else if ((temp3[i] * qreal(2.0)) < qreal(1.0))
+ ca[i] = (temp2);
+ else if ((temp3[i] * qreal(3.0)) < qreal(2.0))
+ ca[i] = temp1 + (temp2 -temp1) * (qreal(2.0) /qreal(3.0) - temp3[i]) * qreal(6.0);
+ else ca[i] = temp1;
+ }
+ }
+
+ return QColor::fromRgbF(ca[0], ca[1], ca[2]);
+}
+
+#define Q_MAX_3(a, b, c) ( ( a > b && a > c) ? a : (b > c ? b : c) )
+#define Q_MIN_3(a, b, c) ( ( a < b && a < c) ? a : (b < c ? b : c) )
+
+QColor toHsl(QColor c)
+{
+ QColor color;
+ qreal h;
+ qreal s;
+ qreal l;
+
+ const qreal r = c.redF();
+ const qreal g = c.greenF();
+ const qreal b = c.blueF();
+ const qreal max = Q_MAX_3(r, g, b);
+ const qreal min = Q_MIN_3(r, g, b);
+ const qreal delta = max - min;
+ const qreal delta2 = max + min;
+ const qreal lightness = qreal(0.5) * delta2;
+ l = (lightness);
+ if (qFuzzyIsNull(delta)) {
+ // achromatic case, hue is undefined
+ h = 0;
+ s = 0;
+ } else {
+ // chromatic case
+ qreal hue = 0;
+ if (lightness < qreal(0.5))
+ s = ((delta / delta2));
+ else
+ s = ((delta / (qreal(2.0) - delta2)));
+ if (qFuzzyCompare(r, max)) {
+ hue = ((g - b) /delta);
+ } else if (qFuzzyCompare(g, max)) {
+ hue = (2.0 + (b - r) / delta);
+ } else if (qFuzzyCompare(b, max)) {
+ hue = (4.0 + (r - g) / delta);
+ } else {
+ Q_ASSERT_X(false, "QColor::toHsv", "internal error");
+ }
+ hue *= 60.0;
+ if (hue < 0.0)
+ hue += 360.0;
+ h = (hue * 100);
+ }
+
+ h = h / 36000;
+
+ return QColor::fromHsvF(h, s, l);
+}
+
+void tintColor(QColor &color, QColor tintColor, qreal _saturation)
+{
+ tintColor = toHsl(tintColor);
+ color = toHsl(color);
+ qreal hue = tintColor.hueF();
+
+ qreal saturation = color.saturationF();
+ if (_saturation)
+ saturation = _saturation;
+ qreal lightness = color.valueF();
+ color.setHsvF(hue, saturation, lightness);
+
+ color = fromHsl(color);
+ color.toRgb();
+}
+
+void tintImagePal(QImage *image, QColor color, qreal saturation)
+{
+ QVector<QRgb> colorTable = image->colorTable();
+ for (int i=2;i< colorTable.size();i++) {
+ QColor c(toHsl(colorTable.at(i)));
+ tintColor(c, color, saturation);
+ colorTable[i] = c.rgb();
+ }
+ image->setColorTable(colorTable);
+}
+
+
+void tintImage(QImage *image, QColor color, qreal saturation)
+{
+ *image = image->convertToFormat(QImage::Format_RGB32);
+
+ for (int x = 0; x < image->width(); x++)
+ for (int y = 0; y < image->height(); y++) {
+ QColor c(image->pixel(x,y));
+ tintColor(c, color, saturation);
+ image->setPixel(x, y, c.rgb());
+ }
+}
+
+#endif //Q_WS_WINCE_WM
+
+
+enum QSliderDirection { SliderUp, SliderDown, SliderLeft, SliderRight };
+
+#ifdef Q_WS_WINCE_WM
+
+void QWindowsMobileStylePrivate::tintImagesButton(QColor color)
+{
+ if (currentTintButton == color)
+ return;
+ currentTintButton = color;
+
+ imageTabEnd = QImage(tabend_xpm);
+ imageTabSelectedEnd = QImage(tabselectedend_xpm);
+ imageTabSelectedBegin = QImage(tabselectedbeginn_xpm);
+ imageTabMiddle = QImage(tabmiddle_xpm);
+ tintImage(&imageTabEnd, color, 0.0);
+ tintImage(&imageTabSelectedEnd, color, 0.0);
+ tintImage(&imageTabSelectedBegin, color, 0.0);
+ tintImage(&imageTabMiddle, color, 0.0);
+
+ if (!doubleControls) {
+ int height = imageTabMiddle.height() / 2 + 1;
+ imageTabEnd = imageTabEnd.scaledToHeight(height);
+ imageTabMiddle = imageTabMiddle.scaledToHeight(height);
+ imageTabSelectedEnd = imageTabSelectedEnd.scaledToHeight(height);
+ imageTabSelectedBegin = imageTabSelectedBegin.scaledToHeight(height);
+ }
+}
+
+void QWindowsMobileStylePrivate::tintImagesHigh(QColor color)
+{
+ if (currentTintHigh == color)
+ return;
+ currentTintHigh = color;
+ tintListViewHighlight(color);
+ imageScrollbarHandleUpHigh = imageScrollbarHandleUp;
+ imageScrollbarHandleDownHigh = imageScrollbarHandleDown;
+ tintImagePal(&imageScrollbarHandleDownHigh, color, qreal(0.8));
+ tintImagePal(&imageScrollbarHandleUpHigh, color, qreal(0.8));
+}
+
+void QWindowsMobileStylePrivate::tintListViewHighlight(QColor color)
+{
+ imageListViewHighlightCornerRight = QImage(listviewhighcornerright_xpm);
+ tintImage(&imageListViewHighlightCornerRight, color, qreal(0.0));
+
+ imageListViewHighlightCornerLeft = QImage(listviewhighcornerleft_xpm);
+ tintImage(&imageListViewHighlightCornerLeft, color, qreal(0.0));
+
+ imageListViewHighlightMiddle = QImage(listviewhighmiddle_xpm);
+ tintImage(&imageListViewHighlightMiddle, color, qreal(0.0));
+
+ int height = imageListViewHighlightMiddle.height();
+ if (!doubleControls) {
+ height = height / 2;
+ imageListViewHighlightCornerRight = imageListViewHighlightCornerRight.scaledToHeight(height);
+ imageListViewHighlightCornerLeft = imageListViewHighlightCornerLeft.scaledToHeight(height);
+ imageListViewHighlightMiddle = imageListViewHighlightMiddle.scaledToHeight(height);
+ }
+}
+
+#endif //Q_WS_WINCE_WM
+
+void QWindowsMobileStylePrivate::setupWindowsMobileStyle65()
+{
+#ifdef Q_WS_WINCE_WM
+ wm65 = qt_wince_is_windows_mobile_65();
+ if (wm65) {
+ imageScrollbarHandleUp = QImage(sbhandleup_xpm);
+ imageScrollbarHandleDown = QImage(sbhandledown_xpm);
+ imageScrollbarGripUp = QImage(sbgripup_xpm);
+ imageScrollbarGripDown = QImage(sbgripdown_xpm);
+ imageScrollbarGripMiddle = QImage(sbgripmiddle_xpm);
+
+ if (!doubleControls) {
+ imageScrollbarHandleUp = imageScrollbarHandleUp.scaledToHeight(imageScrollbarHandleUp.height() / 2);
+ imageScrollbarHandleDown = imageScrollbarHandleDown.scaledToHeight(imageScrollbarHandleDown.height() / 2);
+ imageScrollbarGripMiddle = imageScrollbarGripMiddle.scaledToHeight(imageScrollbarGripMiddle.height() / 2);
+ imageScrollbarGripUp = imageScrollbarGripUp.scaledToHeight(imageScrollbarGripUp.height() / 2);
+ imageScrollbarGripDown = imageScrollbarGripDown.scaledToHeight(imageScrollbarGripDown.height() / 2);
+ } else {
+ }
+ tintImagesHigh(Qt::blue);
+ }
+#endif //Q_WS_WINCE_WM
+}
+
+void QWindowsMobileStylePrivate::drawTabBarTab(QPainter *painter, const QStyleOptionTab *tab)
+{
+#ifndef QT_NO_TABBAR
+#ifdef Q_WS_WINCE_WM
+ if (wm65) {
+ tintImagesButton(tab->palette.button().color());
+ QRect r;
+ r.setTopLeft(tab->rect.topRight() - QPoint(imageTabMiddle.width(), 0));
+ r.setBottomRight(tab->rect.bottomRight());
+ if (tab->state & QStyle::State_Selected) {
+ painter->fillRect(tab->rect, tab->palette.window());
+ } else {
+ painter->fillRect(tab->rect, QColor(imageTabMiddle.pixel(0,0)));
+ }
+ if (tab->selectedPosition == QStyleOptionTab::NextIsSelected) {
+ painter->drawImage(r, imageTabSelectedBegin);
+ } else if (tab->position == QStyleOptionTab::End ||
+ tab->position == QStyleOptionTab::OnlyOneTab) {
+ if (!(tab->state & QStyle::State_Selected)) {
+ painter->drawImage(r, imageTabEnd);
+ }
+ } else if (tab->state & QStyle::State_Selected) {
+ painter->drawImage(r, imageTabSelectedEnd);
+ } else {
+ painter->drawImage(r, imageTabMiddle);
+ }
+ if (tab->position == QStyleOptionTab::Beginning && ! (tab->state & QStyle::State_Selected)) {
+ painter->drawImage(tab->rect.topLeft() - QPoint(imageTabMiddle.width() * 0.60, 0), imageTabSelectedEnd);
+ }
+ //imageTabBarBig
+ return;
+ }
+#endif //Q_WS_WINCE_WM
+ painter->save();
+ painter->setPen(tab->palette.shadow().color());
+ if (doubleControls) {
+ QPen pen = painter->pen();
+ pen.setWidth(2);
+ pen.setCapStyle(Qt::FlatCap);
+ painter->setPen(pen);
+ }
+ if(tab->shape == QTabBar::RoundedNorth) {
+ if (tab->state & QStyle::State_Selected) {
+ painter->fillRect(tab->rect, tab->palette.light());
+ painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight());
+ }
+ else {
+ painter->fillRect(tab->rect, tab->palette.button());
+ painter->drawLine(tab->rect.bottomLeft() , tab->rect.bottomRight());
+ painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight());
+ }
+ }
+ else if(tab->shape == QTabBar::RoundedSouth) {
+ if (tab->state & QStyle::State_Selected) {
+ painter->fillRect(tab->rect.adjusted(0,-2,0,0), tab->palette.light());
+ painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight());
+ }
+ else {
+ painter->fillRect(tab->rect, tab->palette.button());
+ if (doubleControls)
+ painter->drawLine(tab->rect.topLeft() + QPoint(0,1), tab->rect.topRight() + QPoint(0,1));
+ else
+ painter->drawLine(tab->rect.topLeft(), tab->rect.topRight());
+ painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight());
+ }
+ }
+ else if(tab->shape == QTabBar::RoundedEast) {
+ if (tab->state & QStyle::State_Selected) {
+ painter->fillRect(tab->rect, tab->palette.light());
+ painter->drawLine(tab->rect.topLeft(), tab->rect.topRight());
+ }
+ else {
+ painter->fillRect(tab->rect, tab->palette.button());
+ painter->drawLine(tab->rect.topLeft(), tab->rect.bottomLeft());
+ painter->drawLine(tab->rect.topLeft(), tab->rect.topRight());
+ }
+ }
+ else if(tab->shape == QTabBar::RoundedWest) {
+ if (tab->state & QStyle::State_Selected) {
+ painter->fillRect(tab->rect, tab->palette.light());
+ painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight());
+ }
+ else {
+ painter->fillRect(tab->rect, tab->palette.button());
+ painter->drawLine(tab->rect.topRight(), tab->rect.bottomRight());
+ painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight());
+ }
+ }
+ painter->restore();
+#endif //QT_NO_TABBAR
+}
+
+void QWindowsMobileStylePrivate::drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect)
+{
+#ifdef Q_WS_WINCE_WM
+ if (wm65) {
+ QRect r;
+ if (rect.isValid())
+ r = rect;
+ else
+ r = option->rect;
+ tintImagesHigh(option->palette.highlight().color());
+
+ painter->setPen(QColor(Qt::lightGray));
+
+ if (option->viewItemPosition == QStyleOptionViewItemV4::Middle) {
+ painter->drawImage(r, imageListViewHighlightMiddle);
+ } else if (option->viewItemPosition == QStyleOptionViewItemV4::Beginning) {
+ painter->drawImage(r.adjusted(10, 0, 0, 0), imageListViewHighlightMiddle);
+ } else if (option->viewItemPosition == QStyleOptionViewItemV4::End) {
+ painter->drawImage(r.adjusted(0, 0, -10, 0), imageListViewHighlightMiddle);
+ } else {
+ painter->drawImage(r.adjusted(10, 0, -10, 0), imageListViewHighlightMiddle);
+ }
+
+ QImage cornerLeft = imageListViewHighlightCornerLeft;
+ QImage cornerRight = imageListViewHighlightCornerRight;
+
+ int width = r.width() > cornerRight.width() ? r.width() : cornerRight.width();
+
+ if ((width * 2) > r.width()) {
+ width = (r.width() - 5) / 2;
+ }
+
+ cornerLeft = cornerLeft.scaled(width, r.height());
+ cornerRight = cornerRight.scaled(width, r.height());
+
+ if ((option->viewItemPosition == QStyleOptionViewItemV4::Beginning) || (option->viewItemPosition == QStyleOptionViewItemV4::OnlyOne) || !option->viewItemPosition) {
+ painter->drawImage(r.topLeft(), cornerLeft);
+ }
+ if ((option->viewItemPosition == QStyleOptionViewItemV4::End) || (option->viewItemPosition == QStyleOptionViewItemV4::OnlyOne) || !option->viewItemPosition) {
+ painter->drawImage(r.topRight() - QPoint(cornerRight.width(),0), cornerRight);
+ }
+ return;
+ }
+#endif //Q_WS_WINCE_WM
+ QPalette::ColorGroup cg = option->state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+
+ if (rect.isValid())
+ painter->fillRect(rect, option->palette.brush(cg, QPalette::Highlight));
+ else
+ painter->fillRect(option->rect, option->palette.brush(cg, QPalette::Highlight));
+}
+
+void QWindowsMobileStylePrivate::drawScrollbarGrip(QPainter *p, QStyleOptionSlider *newScrollbar, const QStyleOptionComplex *option, bool drawCompleteFrame)
+{
+#ifdef Q_WS_WINCE_WM
+ if (wm65) {
+ if (newScrollbar->orientation == Qt::Horizontal) {
+ QTransform transform;
+ transform.rotate(-90);
+ QRect r = newScrollbar->rect;
+ p->drawImage(r.adjusted(10, 0, -10, 0), imageScrollbarGripMiddle.transformed(transform));
+ p->drawImage(r.topLeft(), imageScrollbarGripUp.transformed(transform));
+ p->drawImage(r.topRight() - QPoint(imageScrollbarGripDown.height() - 1, 0), imageScrollbarGripDown.transformed(transform));
+ } else {
+ QRect r = newScrollbar->rect;
+ p->drawImage(r.adjusted(0, 10, 0, -10), imageScrollbarGripMiddle);
+ p->drawImage(r.topLeft(), imageScrollbarGripUp);
+ p->drawImage(r.bottomLeft() - QPoint(0, imageScrollbarGripDown.height() - 1), imageScrollbarGripDown);
+ }
+ return ;
+ }
+#endif
+ if (newScrollbar->orientation == Qt::Horizontal) {
+ p->fillRect(newScrollbar->rect,option->palette.button());
+ QRect r = newScrollbar->rect;
+ p->drawLine(r.topLeft(), r.bottomLeft());
+ p->drawLine(r.topRight(), r.bottomRight());
+ if (smartphone) {
+ p->drawLine(r.topLeft(), r.topRight());
+ p->drawLine(r.bottomLeft(), r.bottomRight());
+ }
+ }
+ else {
+ p->fillRect(newScrollbar->rect,option->palette.button());
+ QRect r = newScrollbar->rect;
+ p->drawLine(r.topLeft(), r.topRight());
+ p->drawLine(r.bottomLeft(), r.bottomRight());
+ if (smartphone) {
+ p->drawLine(r.topLeft(), r.bottomLeft());
+ p->drawLine(r.topRight(), r.bottomRight());
+ }
+ }
+ if (newScrollbar->state & QStyle::State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*newScrollbar);
+ fropt.rect.setRect(newScrollbar->rect.x() + 2, newScrollbar->rect.y() + 2,
+ newScrollbar->rect.width() - 5,
+ newScrollbar->rect.height() - 5);
+ }
+ int gripMargin = doubleControls ? 4 : 2;
+ int doubleLines = doubleControls ? 2 : 1;
+ //If there is a frame around the scrollbar (abstractScrollArea),
+ //then the margin is different, because of the missing frame
+ int gripMarginFrame = doubleControls ? 3 : 1;
+ if (drawCompleteFrame)
+ gripMarginFrame = 0;
+ //draw grips
+ if (!smartphone)
+ if (newScrollbar->orientation == Qt::Horizontal) {
+ for (int i = -3; i < 3; i += 2) {
+ p->drawLine(
+ QPoint(newScrollbar->rect.center().x() + i * doubleLines + 1,
+ newScrollbar->rect.top() + gripMargin +gripMarginFrame),
+ QPoint(newScrollbar->rect.center().x() + i * doubleLines + 1,
+ newScrollbar->rect.bottom() - gripMargin));
+ }
+ } else {
+ for (int i = -2; i < 4 ; i += 2) {
+ p->drawLine(
+ QPoint(newScrollbar->rect.left() + gripMargin + gripMarginFrame ,
+ newScrollbar->rect.center().y() + 1 + i * doubleLines - 1),
+ QPoint(newScrollbar->rect.right() - gripMargin,
+ newScrollbar->rect.center().y() + 1 + i * doubleLines - 1));
+ }
+ }
+ if (!smartphone) {
+ QRect r;
+ if (doubleControls)
+ r = option->rect.adjusted(1, 1, -1, 0);
+ else
+ r = option->rect.adjusted(0, 0, -1, 0);
+ if (drawCompleteFrame && doubleControls)
+ r.adjust(0, 0, 0, -1);
+ //Check if the scrollbar is part of an abstractItemView and draw the frame according
+ if (drawCompleteFrame)
+ p->drawRect(r);
+ else
+ if (newScrollbar->orientation == Qt::Horizontal)
+ p->drawLine(r.topLeft(), r.topRight());
+ else
+ p->drawLine(r.topLeft(), r.bottomLeft());
+ }
+}
+
+void QWindowsMobileStylePrivate::drawScrollbarHandleUp(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool )
+{
+#ifdef Q_WS_WINCE_WM
+ if (wm65) {
+ tintImagesHigh(opt->palette.highlight().color());
+ QRect r = opt->rect;
+ if (opt->orientation == Qt::Horizontal) {
+ QTransform transform;
+ transform.rotate(-90);
+ if (opt->state & QStyle::State_Sunken)
+ p->drawImage(r.topLeft(), imageScrollbarHandleUpHigh.transformed(transform));
+ else
+ p->drawImage(r.topLeft(), imageScrollbarHandleUp.transformed(transform));
+ } else {
+ if (opt->state & QStyle::State_Sunken)
+ p->drawImage(r.topLeft(), imageScrollbarHandleUpHigh);
+ else
+ p->drawImage(r.topLeft(), imageScrollbarHandleUp);
+ }
+ return ;
+ }
+#endif //Q_WS_WINCE_WM
+
+ QBrush fill = opt->palette.button();
+ if (opt->state & QStyle::State_Sunken)
+ fill = opt->palette.shadow();
+
+ QStyleOption arrowOpt = *opt;
+ if (doubleControls)
+ arrowOpt.rect = opt->rect.adjusted(4, 6, -5, -3);
+ else
+ arrowOpt.rect = opt->rect.adjusted(5, 6, -4, -3);
+
+ bool horizontal = (opt->orientation == Qt::Horizontal);
+
+ if (horizontal) {
+ p->fillRect(opt->rect,fill);
+ QRect r = opt->rect.adjusted(0,0,1,0);
+ p->drawLine(r.topRight(), r.bottomRight());
+ if (doubleControls)
+ arrowOpt.rect.adjust(0, -2 ,0, -2);
+ q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowLeft, &arrowOpt, p, 0);
+ } else {
+ p->fillRect(opt->rect,fill);
+ QRect r = opt->rect.adjusted(0, 0, 0, 1);
+ p->drawLine(r.bottomLeft(), r.bottomRight());
+ if (completeFrame)
+ arrowOpt.rect.adjust(-2, 0, -2, 0);
+ if (doubleControls)
+ arrowOpt.rect.adjust(0, -4 , 0, -4);
+ if (completeFrame && doubleControls)
+ arrowOpt.rect.adjust(2, 0, 2, 0);
+ q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowUp, &arrowOpt, p, 0);
+ }
+}
+
+void QWindowsMobileStylePrivate::drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame, bool secondScrollBar)
+{
+#ifndef QT_NO_SCROLLBAR
+#ifdef Q_WS_WINCE_WM
+ if (wm65) {
+ tintImagesHigh(opt->palette.highlight().color());
+ QRect r = opt->rect;
+ if (opt->orientation == Qt::Horizontal) {
+ QTransform transform;
+ transform.rotate(-90);
+ if (opt->state & QStyle::State_Sunken)
+ p->drawImage(r.topLeft(), imageScrollbarHandleDownHigh.transformed(transform));
+ else
+ p->drawImage(r.topLeft(), imageScrollbarHandleDown.transformed(transform));
+ } else {
+ if (opt->state & QStyle::State_Sunken)
+ p->drawImage(r.topLeft(), imageScrollbarHandleDownHigh);
+ else
+ p->drawImage(r.topLeft(), imageScrollbarHandleDown);
+ }
+ return ;
+ }
+#endif //Q_WS_WINCE_WM
+
+ QBrush fill = opt->palette.button();
+ if (opt->state & QStyle::State_Sunken)
+ fill = opt->palette.shadow();
+
+ QStyleOption arrowOpt = *opt;
+ if (doubleControls)
+ arrowOpt.rect = opt->rect.adjusted(4, 0, -5, 3);
+ else
+ arrowOpt.rect = opt->rect.adjusted(5, 6, -4, -3);
+
+ bool horizontal = (opt->orientation == Qt::Horizontal);
+
+ if (horizontal) {
+ p->fillRect(opt->rect,fill);
+ QRect r = opt->rect.adjusted(0, 0, 0, 0);
+ p->drawLine(r.topLeft(), r.bottomLeft());
+ if (secondScrollBar)
+ p->drawLine(r.topRight(), r.bottomRight());
+ if (doubleControls)
+ arrowOpt.rect.adjust(0, 4, 0, 4 );
+ q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowRight, &arrowOpt, p, 0);
+ } else {
+ p->fillRect(opt->rect,fill);
+ QRect r = opt->rect.adjusted(0, -1, 0, -1);
+ p->drawLine(r.topLeft(), r.topRight());
+ if (secondScrollBar)
+ p->drawLine(r.bottomLeft() + QPoint(0,1), r.bottomRight() + QPoint(0, 1));
+ if (completeFrame)
+ arrowOpt.rect.adjust(-2, 0, -2, 0);
+ if (doubleControls)
+ arrowOpt.rect.adjust(1, 0, 1, 0 );
+ if (completeFrame && doubleControls)
+ arrowOpt.rect.adjust(1, 0, 1, 0);
+ q_func()->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p, 0);
+ }
+#endif //QT_NO_SCROLLBAR
+}
+
+void QWindowsMobileStylePrivate::drawScrollbarGroove(QPainter *p,const QStyleOptionSlider *opt)
+{
+#ifndef QT_NO_SCROLLBAR
+#ifdef Q_OS_WINCE_WM
+ if (wm65) {
+ p->fillRect(opt->rect, QColor(231, 231, 231));
+ return ;
+ }
+#endif
+ QBrush fill;
+ if (smartphone) {
+ fill = opt->palette.light();
+ p->fillRect(opt->rect, fill);
+ fill = opt->palette.button();
+ QImage image;
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ if (opt->orientation == Qt::Horizontal)
+ image = QImage(vertlines_xpm);
+ else
+ image = QImage(horlines_xpm);
+#endif
+ image.setColor(1, opt->palette.button().color().rgb());
+ fill.setTextureImage(image);
+ }
+ else {
+ fill = opt->palette.light();
+ }
+ p->fillRect(opt->rect, fill);
+#endif //QT_NO_SCROLLBAR
+}
+
+QWindowsMobileStyle::QWindowsMobileStyle(QWindowsMobileStylePrivate &dd) : QWindowsStyle(dd) {
+ qApp->setEffectEnabled(Qt::UI_FadeMenu, false);
+ qApp->setEffectEnabled(Qt::UI_AnimateMenu, false);
+}
+
+QWindowsMobileStyle::QWindowsMobileStyle() : QWindowsStyle(*new QWindowsMobileStylePrivate) {
+ qApp->setEffectEnabled(Qt::UI_FadeMenu, false);
+ qApp->setEffectEnabled(Qt::UI_AnimateMenu, false);
+}
+
+QWindowsMobileStylePrivate::QWindowsMobileStylePrivate() :QWindowsStylePrivate() {
+
+#ifdef Q_WS_WINCE
+ doubleControls = qt_wince_is_high_dpi();
+ smartphone = qt_wince_is_smartphone();
+#else
+ doubleControls = false;
+ smartphone = false;
+#endif //Q_WS_WINCE
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+
+ imageArrowDown = QImage(arrowdown_xpm);
+ imageArrowUp = QImage(arrowdown_xpm).mirrored();
+ imageArrowLeft = QImage(arrowleft_xpm);
+ imageArrowRight = QImage(arrowleft_xpm).mirrored(true, false);
+ if (doubleControls) {
+ imageRadioButton = QImage(radiobutton_xpm);
+ imageRadioButtonChecked = QImage(radiochecked_xpm);
+ imageChecked = QImage(checkedlight_xpm);
+ imageCheckedBold = QImage(checkedbold_xpm);
+ imageRadioButtonHighlighted = QImage(highlightedradiobutton_xpm);
+ imageClose = QImage(cross_big_xpm);
+ imageMaximize = QImage(max_big_xpm);
+ imageMinimize = QImage(min_big_xpm);
+ imageNormalize = QImage(normal_big_xpm);
+ } else {
+ imageRadioButton = QImage(radiobutton_low_xpm);
+ imageRadioButtonChecked = QImage(radiochecked_low_xpm);
+ imageChecked = QImage(checkedlight_low_xpm);
+ imageCheckedBold = QImage(checkedbold_low_xpm);
+ imageRadioButtonHighlighted = QImage(highlightedradiobutton_low_xpm);
+ imageClose = QImage(cross_small_xpm);
+ imageMaximize = QImage(max_small_xpm);
+ imageMinimize = QImage(min_small_xpm);
+ imageNormalize = QImage(normal_small_xpm);
+ }
+
+ setupWindowsMobileStyle65();
+
+
+ imageArrowDownBig = QImage(arrowdown_big_xpm);
+ imageArrowUpBig = QImage(arrowdown_big_xpm).mirrored();
+ imageArrowLeftBig = QImage(arrowleft_big_xpm);
+ imageArrowRightBig = QImage(arrowleft_big_xpm).mirrored(true, false);
+
+#endif
+}
+
+void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+
+ bool doRestore = false;
+ QRect rect = option->rect;
+ painter->setClipping(false);
+
+ switch (element) {
+ case PE_PanelButtonTool: {
+ int penSize = 1;
+ if (d->doubleControls)
+ penSize = 2;
+ if (widget)
+ if (QWidget *parent = widget->parentWidget())
+#ifndef QT_NO_TABWIDGET
+ if (qobject_cast<QTabWidget *>(parent->parentWidget())) {
+#else
+ if (false) {
+#endif //QT_NO_TABBAR
+ rect.adjust(0,2*penSize,0,-1*penSize);
+ qDrawPlainRect(painter, rect, option->palette.shadow().color(), penSize, &option->palette.light());
+ if (option->state & (State_Sunken))
+ qDrawPlainRect(painter, rect, option->palette.shadow().color(), penSize, &option->palette.shadow());
+ }
+ else {
+ if (!(option->state & State_AutoRaise) || (option->state & (State_Sunken | State_On)))
+ qDrawPlainRect(painter,option->rect.adjusted(0, penSize, 0, -1 * penSize) ,
+ option->palette.button().color(), 0, &option->palette.button());
+ if (option->state & (State_Sunken)) {
+ qDrawPlainRect(painter, rect, option->palette.shadow().color(), penSize, &option->palette.light());
+ }
+ if (option->state & (State_On)){
+ QBrush fill = QBrush(option->palette.light().color());
+ painter->fillRect(rect.adjusted(windowsItemFrame , windowsItemFrame ,
+ -windowsItemFrame , -windowsItemFrame ), fill);
+ qDrawPlainRect(painter, rect, option->palette.shadow().color(), penSize, &option->palette.light());
+ }
+ }
+ break; }
+ case PE_IndicatorButtonDropDown:
+ if (d->doubleControls)
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), 2, &option->palette.button());
+ else
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), 1, &option->palette.button());
+ break;
+#ifndef QT_NO_TABBAR
+ case PE_IndicatorTabTear:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ bool rtl = tab->direction == Qt::RightToLeft;
+ QRect rect = tab->rect;
+ QPainterPath path;
+ rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
+ rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
+ path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
+ int count = 3;
+ for(int jags = 1; jags <= count; ++jags, rtl = !rtl)
+ path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
+ painter->setPen(QPen(tab->palette.light(), qreal(.8)));
+ painter->setBrush(tab->palette.background());
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->drawPath(path);
+ }
+ break;
+#endif //QT_NO_TABBAR
+
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarSeparator: {
+ painter->save();
+ QPoint p1, p2;
+ if (option->state & State_Horizontal) {
+ p1 = QPoint(option->rect.width()/2, 0);
+ p2 = QPoint(p1.x(), option->rect.height());
+ } else {
+ p1 = QPoint(0, option->rect.height()/2);
+ p2 = QPoint(option->rect.width(), p1.y());
+ }
+
+
+ painter->setPen(option->palette.mid().color());
+ if (d->doubleControls) {
+ QPen pen = painter->pen();
+ pen.setWidth(2);
+ pen.setCapStyle(Qt::FlatCap);
+ painter->setPen(pen);
+ }
+ painter->drawLine(p1, p2);
+ painter->restore();
+ break; }
+#endif // QT_NO_TOOLBAR
+ case PE_IndicatorToolBarHandle:
+ painter->save();
+ painter->translate(option->rect.x(), option->rect.y());
+ if (option->state & State_Horizontal) {
+ int x = option->rect.width() / 2 - 4;
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ x -= 2;
+ if (option->rect.height() > 4) {
+ qDrawWinButton(painter,x-1,0,7,option->rect.height(), option->palette, false, 0);
+
+ qDrawShadePanel(painter, x, 1, 3, option->rect.height() - 1,
+ option->palette, false, 0);
+ qDrawShadePanel(painter, x + 3, 1, 3, option->rect.height() - 1,
+ option->palette, false, 0);
+ painter->setPen(option->palette.button().color());
+ }
+ } else {
+ if (option->rect.width() > 4) {
+ int y = option->rect.height() / 2 - 4;
+ qDrawShadePanel(painter, 2, y, option->rect.width() - 2, 3,
+ option->palette, false, 0);
+ qDrawShadePanel(painter, 2, y + 3, option->rect.width() - 2, 3,
+ option->palette, false, 0);
+ }
+ }
+ painter->restore();
+ break;
+
+#ifndef QT_NO_PROGRESSBAR
+ case PE_IndicatorProgressChunk: {
+ bool vertical = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+ vertical = (pb2->orientation == Qt::Vertical);
+ if (!vertical) {
+ painter->fillRect(option->rect.x(), option->rect.y()+2, option->rect.width(), option->rect.height()-4,
+ option->palette.brush(QPalette::Highlight));
+ } else {
+ painter->fillRect(option->rect.x()+2, option->rect.y(), option->rect.width()-4, option->rect.height(),
+ option->palette.brush(QPalette::Highlight));
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+
+ case PE_FrameButtonTool: {
+#ifndef QT_NO_DOCKWIDGET
+ if (widget && widget->inherits("QDockWidgetTitleButton")) {
+ if (const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget->parent()))
+ if (dw->isFloating()){
+ qDrawPlainRect(painter,option->rect.adjusted(1, 1, 0, 0),
+ option->palette.shadow().color(),1,&option->palette.button());
+ return;
+ }
+ }
+#endif // QT_NO_DOCKWIDGET
+ QBrush fill;
+ bool stippled;
+ bool panel = (element == PE_PanelButtonTool);
+ if ((!(option->state & State_Sunken ))
+ && (!(option->state & State_Enabled)
+ || ((option->state & State_Enabled ) && !(option->state & State_MouseOver)))
+ && (option->state & State_On)) {
+ fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ stippled = true;
+ } else {
+ fill = option->palette.brush(QPalette::Button);
+ stippled = false;
+ }
+ if (option->state & (State_Raised | State_Sunken | State_On)) {
+ if (option->state & State_AutoRaise) {
+ if(option->state & (State_Enabled | State_Sunken | State_On)){
+ if (panel)
+ qDrawPlainRect(painter, option->rect,option->palette.shadow().color(),d->doubleControls, &fill);
+ else
+ qDrawPlainRect(painter, option->rect,option->palette.shadow().color(),d->doubleControls, &fill);
+ }
+ if (stippled) {
+ painter->setPen(option->palette.button().color());
+ painter->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ }
+ } else {
+ qDrawPlainRect(painter, option->rect,option->palette.shadow().color(),d->doubleControls, &fill);
+ }
+ } else {
+ painter->fillRect(option->rect, fill);
+ }
+ break; }
+
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) {
+ //### check for d->alt_down
+ int penSize;
+ d->doubleControls ? penSize = 2 : penSize = 1;
+ bool alternateFocusStyle = false;
+ if (!widget)
+ alternateFocusStyle = true;
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox*>(widget))
+ alternateFocusStyle = true;
+#endif
+ if (!(fropt->state & State_KeyboardFocusChange) && !styleHint(SH_UnderlineShortcut, option))
+ return;
+ QRect r = option->rect;
+ painter->save();
+ painter->setBackgroundMode(Qt::TransparentMode);
+ if (alternateFocusStyle) {
+ QColor bg_col = fropt->backgroundColor;
+ if (!bg_col.isValid())
+ bg_col = painter->background().color();
+ // Create an "XOR" color.
+ QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
+ (bg_col.green() ^ 0xff) & 0xff,
+ (bg_col.blue() ^ 0xff) & 0xff);
+ painter->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
+ painter->setBrushOrigin(r.topLeft());
+ }
+ else {
+ painter->setPen(option->palette.highlight().color());
+ painter->setBrush(option->palette.highlight());
+ }
+ painter->setPen(Qt::NoPen);
+ painter->setBrushOrigin(r.topLeft());
+ painter->drawRect(r.left(), r.top(), r.width(), penSize); // Top
+ painter->drawRect(r.left(), r.bottom(), r.width() + penSize - 1, penSize); // Bottom
+ painter->drawRect(r.left(), r.top(), penSize, r.height()); // Left
+ painter->drawRect(r.right(), r.top(), penSize, r.height()); // Right
+ painter->restore();
+ }
+ break;
+
+ case PE_PanelButtonBevel: {
+ QBrush fill;
+ bool panel = element != PE_FrameButtonBevel;
+ painter->setBrushOrigin(option->rect.topLeft());
+ if (!(option->state & State_Sunken) && (option->state & State_On))
+ fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = option->palette.brush(QPalette::Button);
+
+ if (option->state & (State_Raised | State_On | State_Sunken)) {
+ if (d->doubleControls)
+ qDrawPlainRect(painter, option->rect,option->palette.shadow().color(),2,&fill);
+ else
+ qDrawPlainRect(painter, option->rect,option->palette.shadow().color(),1,&fill);
+ } else {
+ if (panel)
+ painter->fillRect(option->rect, fill);
+ else
+ painter->drawRect(option->rect);
+ }
+ break; }
+
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+
+ const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option);
+ if (frame2 && !(frame2->features & QStyleOptionFrameV2::Flat)) {
+ QPen oldPen = painter->pen();
+ QRect r = frame->rect;
+ painter->setPen(frame->palette.shadow().color());
+ painter->fillRect(r.x(), r.y(), r.x() + r.width()-1,
+ r.y() + r.height() - windowsMobileFrameGroupBoxOffset,
+ frame->palette.light());
+ painter ->drawLine(r.topLeft() + QPoint(-2, 1), r.topRight()+ QPoint(0, 1));
+ if (d->doubleControls)
+ painter ->drawLine(r.topLeft() + QPoint(-2, 2), r.topRight()+ QPoint(0, 2));
+ painter->setPen(oldPen);
+ }
+ }
+ break;
+
+ case PE_IndicatorCheckBox: {
+ QBrush fill;
+ QRect r = d->doubleControls ? option->rect.adjusted(0,1,0,-1) : option->rect;
+ if (option->state & State_NoChange)
+ fill = QBrush(option->palette.shadow().color(), Qt::Dense4Pattern);
+ else if (option->state & State_Sunken)
+ fill = option->palette.button();
+ else if (option->state & State_Enabled)
+ fill = option->palette.base();
+ else
+ fill = option->palette.background();
+ painter->save();
+ doRestore = true;
+ if (d->doubleControls && (option->state & State_NoChange))
+ painter->fillRect(r, fill);
+ else
+ painter->fillRect(option->rect, fill);
+ painter->setPen(option->palette.shadow().color());
+ painter->drawLine(r.topLeft(), r.topRight());
+ painter->drawLine(r.topRight(), r.bottomRight());
+ painter->drawLine(r.bottomLeft(), r.bottomRight());
+ painter->drawLine(r.bottomLeft(), r.topLeft());
+ if (d->doubleControls) {
+ QRect r0 = r.adjusted(1, 1, -1, -1);
+ painter->drawLine(r0.topLeft(), r0.topRight());
+ painter->drawLine(r0.topRight(), r0.bottomRight());
+ painter->drawLine(r0.bottomLeft(), r0.bottomRight());
+ painter->drawLine(r0.bottomLeft(), r0.topLeft());
+ }
+ if (option->state & State_HasFocus) {
+ painter->setPen(option->palette.highlight().color());
+ QRect r2 = d->doubleControls ? r.adjusted(2, 2, -2, -2) : r.adjusted(1, 1, -1, -1);
+ painter->drawLine(r2.topLeft(), r2.topRight());
+ painter->drawLine(r2.topRight(), r2.bottomRight());
+ painter->drawLine(r2.bottomLeft(), r2.bottomRight());
+ painter->drawLine(r2.bottomLeft(), r2.topLeft());
+ if (d->doubleControls) {
+ QRect r3 = r2.adjusted(1, 1, -1, -1);
+ painter->drawLine(r3.topLeft(), r3.topRight());
+ painter->drawLine(r3.topRight(), r3.bottomRight());
+ painter->drawLine(r3.bottomLeft(), r3.bottomRight());
+ painter->drawLine(r3.bottomLeft(), r3.topLeft());
+ }
+ painter->setPen(option->palette.shadow().color());
+ }
+ //fall through...
+ }
+ case PE_IndicatorViewItemCheck:
+ case PE_Q3CheckListIndicator: {
+ if (!doRestore) {
+ painter->save();
+ doRestore = true;
+ }
+ if (element == PE_Q3CheckListIndicator || element == PE_IndicatorViewItemCheck) {
+ painter->setPen(option->palette.shadow().color());
+ if (option->state & State_NoChange)
+ painter->setBrush(option->palette.brush(QPalette::Button));
+ if (d->doubleControls) {
+ QRect r = QRect(option->rect.x(), option->rect.y(), windowsMobileitemViewCheckBoxSize * 2, windowsMobileitemViewCheckBoxSize * 2);
+ qDrawPlainRect(painter, r, option->palette.shadow().color(), 2);
+ } else {
+ QRect r = QRect(option->rect.x(), option->rect.y(), windowsMobileitemViewCheckBoxSize, windowsMobileitemViewCheckBoxSize);
+ qDrawPlainRect(painter, r, option->palette.shadow().color(), 1);
+ }
+ if (option->state & State_Enabled)
+ d->imageChecked.setColor(1, option->palette.shadow().color().rgba());
+ else
+ d->imageChecked.setColor(1, option->palette.dark().color().rgba());
+ if (!(option->state & State_Off)) {
+ if (d->doubleControls)
+ painter->drawImage(option->rect.x(), option->rect.y(), d->imageChecked);
+ else
+ painter->drawImage(option->rect.x() + 3, option->rect.y() + 3, d->imageChecked);
+ }
+ }
+ else {
+ if (option->state & State_NoChange)
+ d->imageCheckedBold.setColor(1, option->palette.dark().color().rgba());
+ else if (option->state & State_Enabled)
+ d->imageCheckedBold.setColor(1, option->palette.shadow().color().rgba());
+ else
+ d->imageCheckedBold.setColor(1, option->palette.dark().color().rgba());
+ if (!(option->state & State_Off)) {
+ if (d->doubleControls)
+ painter->drawImage(option->rect.x() + 2, option->rect.y(), d->imageCheckedBold);
+ else
+ painter->drawImage(option->rect.x() + 3, option->rect.y() + 3, d->imageCheckedBold);
+ }
+ }
+ if (doRestore)
+ painter->restore();
+ break; }
+ case PE_IndicatorRadioButton: {
+ painter->save();
+
+ if (option->state & State_HasFocus) {
+ d->imageRadioButtonHighlighted.setColor(1, option->palette.shadow().color().rgba());
+ d->imageRadioButtonHighlighted.setColor(2, option->palette.highlight().color().rgba());
+ painter->drawImage(option->rect.x(), option->rect.y(), d->imageRadioButtonHighlighted);
+ }
+ else {
+ d->imageRadioButton.setColor(1, option->palette.shadow().color().rgba());
+ painter->drawImage(option->rect.x(), option->rect.y(), d->imageRadioButton);
+ }
+ if (option->state & (State_Sunken | State_On)) {
+ if (option->state & State_Enabled)
+ d->imageRadioButtonChecked.setColor(1, option->palette.shadow().color().rgba());
+ else
+ d->imageRadioButtonChecked.setColor(1, option->palette.dark().color().rgba());
+
+ static const int offset = d->doubleControls ? 6 : 3;
+ painter->drawImage(option->rect.x() + offset, option->rect.y() + offset, d->imageRadioButtonChecked);
+ }
+ painter->restore();
+ break; }
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ QBrush fill;
+ State flags = option->state;
+ QPalette pal = option->palette;
+ QRect r = option->rect;
+ if ((flags & State_Sunken || flags & State_On) )
+ fill = pal.brush(QPalette::Shadow);
+ else
+ fill = pal.brush(QPalette::Button);
+ int singleLine = 1;
+ int doubleLine = 2;
+ if (d->doubleControls) {
+ singleLine = 2;
+ doubleLine = 4;
+ }
+ if (button->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
+ if (d->doubleControls) {
+ qDrawPlainRect(painter, r, pal.shadow().color(), 1, &fill);
+ qDrawPlainRect(painter, r.adjusted(1, 1, -1, 1), pal.shadow().color(), 1, &fill);
+ }
+ else {
+ qDrawPlainRect(painter, r, pal.shadow().color(), 1, &fill);
+ }
+ } else if (flags & (State_Raised | State_Sunken | State_On | State_Sunken)) {
+ qDrawPlainRect(painter, r, pal.shadow().color(), singleLine, &fill);
+ } else {
+ painter->fillRect(r, fill);
+ }
+ }
+ break;
+ case PE_FrameDefaultButton: {
+ painter->save();
+ painter->setPen(option->palette.shadow().color());
+ QRect rect = option->rect;
+ if (d->doubleControls) {
+ rect.adjust(1, 1, -2, -2);
+ painter->drawRect(rect);
+ painter->drawRect(rect.adjusted(1, 1, -1, -1));
+ }
+
+ else {
+ rect.adjust(2, 2, -3, -3);
+ painter->drawRect(rect);
+ }
+ painter->restore();
+ break; }
+ case PE_IndicatorSpinPlus:
+ case PE_IndicatorSpinMinus: {
+ QRect r = option->rect;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget)+2;
+ QRect br = r.adjusted(fw, fw, -fw, -fw);
+ int offset = (option->state & State_Sunken) ? 1 : 0;
+ int step = (br.width() + 4) / 5;
+ painter->fillRect(br.x() + offset, br.y() + offset +br.height() / 2 - step / 2,
+ br.width(), step, option->palette.buttonText());
+ if (element == PE_IndicatorSpinPlus)
+ painter->fillRect(br.x() + br.width() / 2 - step / 2 + offset, br.y() + offset+4,
+ step, br.height() - 7, option->palette.buttonText());
+ break; }
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinDown: {
+ painter->save();
+ QPoint points[7];
+ switch (element) {
+ case PE_IndicatorSpinUp:
+ points[0] = QPoint(-2, -4);
+ points[1] = QPoint(-2, 2);
+ points[2] = QPoint(-1, -3);
+ points[3] = QPoint(-1, 1);
+ points[4] = QPoint(0, -2);
+ points[5] = QPoint(0, 0);
+ points[6] = QPoint(1, -1);
+ break;
+ case PE_IndicatorSpinDown:
+ points[0] = QPoint(0, -4);
+ points[1] = QPoint(0, 2);
+ points[2] = QPoint(-1, -3);
+ points[3] = QPoint(-1, 1);
+ points[4] = QPoint(-2, -2);
+ points[5] = QPoint(-2, 0);
+ points[6] = QPoint(-3, -1);
+ break;
+ default:
+ break;
+ }
+ if (option->state & State_Sunken)
+ painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal),
+ proxy()->pixelMetric(PM_ButtonShiftVertical));
+ if (option->state & State_Enabled) {
+ painter->translate(option->rect.x() + option->rect.width() / 2,
+ option->rect.y() + option->rect.height() / 2);
+ painter->setPen(option->palette.buttonText().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ } else {
+ painter->translate(option->rect.x() + option->rect.width() / 2 + 1,
+ option->rect.y() + option->rect.height() / 2 + 1);
+ painter->setPen(option->palette.light().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ painter->translate(-1, -1);
+ painter->setPen(option->palette.mid().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ }
+ painter->restore();
+ break; }
+
+ case PE_IndicatorArrowUpBig:
+ case PE_IndicatorArrowDownBig:
+ case PE_IndicatorArrowLeftBig:
+ case PE_IndicatorArrowRightBig:
+
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft: {
+ painter->save();
+
+ if (d->doubleControls) {
+ QColor color;
+ if (option->state & State_Sunken)
+ color = option->palette.light().color();
+ else
+ color = option->palette.buttonText().color();
+ QImage image;
+ int xoffset, yoffset;
+ bool isTabBarArrow = widget && widget->parent()
+ && widget->inherits("QToolButton")
+ && widget->parent()->inherits("QTabBar");
+
+ switch (element) {
+ case PE_IndicatorArrowUp:
+ image = d->imageArrowUp;
+ xoffset = 1;
+ yoffset = 12;
+ break;
+ case PE_IndicatorArrowDown:
+ image = d->imageArrowDown;
+ xoffset = 1;
+ yoffset =12;
+ break;
+ case PE_IndicatorArrowLeft:
+ image = d->imageArrowLeft;
+ xoffset = 8;
+ yoffset = isTabBarArrow ? 12 : 2;
+ break;
+ case PE_IndicatorArrowRight:
+ image = d->imageArrowRight;
+ xoffset = 8;
+ yoffset = isTabBarArrow ? 12 : 2;
+ break;
+ case PE_IndicatorArrowUpBig:
+ image = d->imageArrowUpBig;
+ xoffset = 3;
+ yoffset = 12;
+ break;
+ case PE_IndicatorArrowDownBig:
+ image = d->imageArrowDownBig;
+ xoffset = 2;
+ yoffset =12;
+ break;
+ case PE_IndicatorArrowLeftBig:
+ image = d->imageArrowLeftBig;
+ xoffset = 8;
+ yoffset = 2;
+ break;
+ case PE_IndicatorArrowRightBig:
+ image = d->imageArrowRightBig;
+ xoffset = 8;
+ yoffset = 2;
+ break;
+ default:
+ break;
+ }
+ image.setColor(1, color.rgba());
+ painter->drawImage(option->rect.x() + xoffset, option->rect.y() + yoffset, image);
+ }
+ else {
+ QPoint points[7];
+ switch (element) {
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowUpBig:
+ points[0] = QPoint(-3, 1);
+ points[1] = QPoint(3, 1);
+ points[2] = QPoint(-2, 0);
+ points[3] = QPoint(2, 0);
+ points[4] = QPoint(-1, -1);
+ points[5] = QPoint(1, -1);
+ points[6] = QPoint(0, -2);
+ break;
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowDownBig:
+ points[0] = QPoint(-3, -1);
+ points[1] = QPoint(3, -1);
+ points[2] = QPoint(-2, 0);
+ points[3] = QPoint(2, 0);
+ points[4] = QPoint(-1, 1);
+ points[5] = QPoint(1, 1);
+ points[6] = QPoint(0, 2);
+ break;
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowRightBig:
+ points[0] = QPoint(-2, -3);
+ points[1] = QPoint(-2, 3);
+ points[2] = QPoint(-1, -2);
+ points[3] = QPoint(-1, 2);
+ points[4] = QPoint(0, -1);
+ points[5] = QPoint(0, 1);
+ points[6] = QPoint(1, 0);
+ break;
+ case PE_IndicatorArrowLeft:
+ case PE_IndicatorArrowLeftBig:
+ points[0] = QPoint(0, -3);
+ points[1] = QPoint(0, 3);
+ points[2] = QPoint(-1, -2);
+ points[3] = QPoint(-1, 2);
+ points[4] = QPoint(-2, -1);
+ points[5] = QPoint(-2, 1);
+ points[6] = QPoint(-3, 0);
+ break;
+ default:
+ break;
+ }
+ if (option->state & State_Sunken)
+ painter->setPen(option->palette.light().color());
+ else
+ painter->setPen(option->palette.buttonText().color());
+ if (option->state & State_Enabled) {
+ painter->translate(option->rect.x() + option->rect.width() / 2,
+ option->rect.y() + option->rect.height() / 2 - 1);
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ } else {
+ painter->translate(option->rect.x() + option->rect.width() / 2,
+ option->rect.y() + option->rect.height() / 2 - 1);
+ painter->setPen(option->palette.mid().color());
+ painter->drawLine(points[0], points[1]);
+ painter->drawLine(points[2], points[3]);
+ painter->drawLine(points[4], points[5]);
+ painter->drawPoint(points[6]);
+ }
+ }
+ painter->restore();
+ break; }
+#ifndef QT_NO_TABWIDGET
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
+ QRect rect = option->rect;
+ QPalette pal = option->palette;
+ painter->save();
+ QBrush fill = pal.light();
+ painter->fillRect(rect, fill);
+ painter->setPen(pal.shadow().color());
+ if (d->doubleControls) {
+ QPen pen = painter->pen();
+ pen.setWidth(2);
+ pen.setCapStyle(Qt::FlatCap);
+ painter->setPen(pen);
+ }
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+#ifdef Q_WS_WINCE_WM
+ if (!d->wm65)
+#endif
+ {
+ if (d->doubleControls)
+ painter->drawLine(rect.topLeft() + QPoint(0, 1), rect.topRight() + QPoint(0, 1));
+ else
+ painter->drawLine(rect.topLeft(), rect.topRight());
+ }
+ break;
+ case QTabBar::RoundedSouth:
+#ifdef Q_WS_WINCE_WM
+ if (!d->wm65)
+#endif
+ {
+ if (d->doubleControls)
+ painter->drawLine(rect.bottomLeft(), rect.bottomRight());
+ else
+ painter->drawLine(rect.bottomLeft(), rect.bottomRight());
+ }
+ break;
+ case QTabBar::RoundedEast:
+#ifdef Q_WS_WINCE_WM
+ if (!d->wm65)
+#endif
+ painter->drawLine(rect.topRight(), rect.bottomRight());
+ break;
+ case QTabBar::RoundedWest:
+#ifdef Q_WS_WINCE_WM
+ if (!d->wm65)
+#endif
+ painter->drawLine(rect.topLeft(), rect.bottomLeft());
+ break;
+ case QTabBar::TriangularWest:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularSouth:
+ case QTabBar::TriangularNorth:
+ if (d->doubleControls)
+ qDrawPlainRect(painter, rect.adjusted(0,-2,0,0), option->palette.shadow().color(),2,&pal.light());
+ else
+ qDrawPlainRect(painter, rect, option->palette.shadow().color(),1,&pal.light());
+ break;
+ default:
+ break;
+ }
+ painter->restore();
+ }
+ break;
+#endif //QT_NO_TABBAR
+#ifndef QT_NO_ITEMVIEWS
+ case PE_PanelItemViewRow:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, option, widget))
+ d->drawPanelItemViewSelected(painter, vopt);
+ else if (vopt->features & QStyleOptionViewItemV2::Alternate)
+ painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase));
+ else if (!(vopt->state & QStyle::State_Enabled))
+ painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Base));
+ }
+ break;
+ case PE_PanelItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) {
+ d->drawPanelItemViewSelected(painter, vopt);
+ } else {
+ if (vopt->backgroundBrush.style() != Qt::NoBrush) {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(vopt->rect.topLeft());
+ painter->fillRect(vopt->rect, vopt->backgroundBrush);
+ painter->setBrushOrigin(oldBO);
+ }
+
+ if (vopt->state & QStyle::State_Selected) {
+ QRect textRect = proxy()->subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+ d->drawPanelItemViewSelected(painter, vopt, textRect);
+ }
+ }
+ }
+ break;
+#endif //QT_NO_ITEMVIEWS
+
+ case PE_FrameWindow: {
+ QPalette popupPal = option->palette;
+ popupPal.setColor(QPalette::Light, option->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, option->palette.light().color());
+ if (d->doubleControls)
+ qDrawPlainRect(painter, option->rect, popupPal.shadow().color(),2,0);
+ else
+ qDrawPlainRect(painter, option->rect, popupPal.shadow().color(),1,0);
+ break; }
+ case PE_FrameTabBarBase: {
+ break; }
+ case PE_Widget:
+ break;
+ case PE_IndicatorMenuCheckMark: {
+ int markW = option->rect.width() > 7 ? 7 : option->rect.width();
+ int markH = markW;
+ if (d->doubleControls)
+ markW*=2;
+ markH*=2;
+ int posX = option->rect.x() + (option->rect.width() - markW)/2 + 1;
+ int posY = option->rect.y() + (option->rect.height() - markH)/2;
+
+ QVector<QLineF> a;
+ a.reserve(markH);
+
+ int i, xx, yy;
+ xx = posX;
+ yy = 3 + posY;
+ for (i = 0; i < markW/2; ++i) {
+ a << QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ ++yy;
+ }
+ yy -= 2;
+ for (; i < markH; ++i) {
+ a << QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ --yy;
+ }
+ if (!(option->state & State_Enabled) && !(option->state & State_On)) {
+ int pnt;
+ painter->setPen(option->palette.highlightedText().color());
+ QPoint offset(1, 1);
+ for (pnt = 0; pnt < a.size(); ++pnt)
+ a[pnt].translate(offset.x(), offset.y());
+ painter->drawLines(a);
+ for (pnt = 0; pnt < a.size(); ++pnt)
+ a[pnt].translate(offset.x(), offset.y());
+ }
+ painter->setPen(option->palette.text().color());
+ painter->drawLines(a);
+ break; }
+ case PE_IndicatorBranch: {
+ // Copied from the Windows style.
+ static const int decoration_size = d->doubleControls ? 18 : 9;
+ static const int ofsA = d->doubleControls ? 4 : 2;
+ static const int ofsB = d->doubleControls ? 8 : 4;
+ static const int ofsC = d->doubleControls ? 12 : 6;
+ static const int ofsD = d->doubleControls ? 1 : 0;
+ int mid_h = option->rect.x() + option->rect.width() / 2;
+ int mid_v = option->rect.y() + option->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ if (option->state & State_Children) {
+ int delta = decoration_size / 2;
+ bef_h -= delta;
+ bef_v -= delta;
+ aft_h += delta;
+ aft_v += delta;
+ QPen oldPen = painter->pen();
+ QPen crossPen = oldPen;
+ crossPen.setWidth(2);
+ painter->setPen(crossPen);
+ painter->drawLine(bef_h + ofsA + ofsD, bef_v + ofsB + ofsD, bef_h + ofsC + ofsD, bef_v + ofsB + ofsD);
+ if (!(option->state & State_Open))
+ painter->drawLine(bef_h + ofsB + ofsD, bef_v + ofsA + ofsD, bef_h + ofsB + ofsD, bef_v + ofsC + ofsD);
+ painter->setPen(option->palette.dark().color());
+ painter->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1);
+ if (d->doubleControls)
+ painter->drawRect(bef_h + 1, bef_v + 1, decoration_size - 3, decoration_size - 3);
+ painter->setPen(oldPen);
+ }
+ QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+ if (option->state & State_Item) {
+ if (option->direction == Qt::RightToLeft)
+ painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+ else
+ painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (option->state & State_Sibling)
+ painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+ if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
+ painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+ break; }
+ case PE_Frame:
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),
+ d->doubleControls ? 2 : 1, &option->palette.background());
+ break;
+ case PE_FrameLineEdit:
+ case PE_FrameMenu:
+ if (d->doubleControls)
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),2);
+ else
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),1);
+ break;
+ case PE_FrameStatusBar:
+ if (d->doubleControls)
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),2,0);
+ else
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),1,0);
+ break;
+
+ default:
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+void QWindowsMobileStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const {
+
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+
+
+ painter->setClipping(false);
+ switch (element) {
+ case CE_MenuBarEmptyArea:
+ painter->setClipping(true);
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ QRect br = button->rect;
+ int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, button, widget);
+
+ if (button->features & QStyleOptionButton::AutoDefaultButton)
+ br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
+ QStyleOptionButton tmpBtn = *button;
+ tmpBtn.rect = br;
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget);
+ if (button->features & QStyleOptionButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
+ QRect ir = button->rect;
+ QStyleOptionButton newButton = *button;
+ if (d->doubleControls)
+ newButton.rect = QRect(ir.right() - mbi, ir.height() - 30, mbi, ir.height() - 4);
+ else
+ newButton.rect = QRect(ir.right() - mbi, ir.height() - 20, mbi, ir.height() - 4);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newButton, painter, widget);
+ }
+ if (button->features & QStyleOptionButton::DefaultButton)
+ proxy()->drawPrimitive(PE_FrameDefaultButton, option, painter, widget);
+ }
+ break;
+ case CE_RadioButton:
+ case CE_CheckBox:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (element == CE_RadioButton);
+ QStyleOptionButton subopt = *button;
+ subopt.rect = proxy()->subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, button, widget);
+ proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, painter, widget);
+ subopt.rect = proxy()->subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, button, widget);
+ proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
+ if (button->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*button);
+ fropt.rect = proxy()->subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, button, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+ break;
+ case CE_RadioButtonLabel:
+ case CE_CheckBoxLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ uint alignment = visualAlignment(button->direction, Qt::AlignLeft | Qt::AlignVCenter);
+ if (!styleHint(SH_UnderlineShortcut, button, widget))
+ alignment |= Qt::TextHideMnemonic;
+ QPixmap pix;
+ QRect textRect = button->rect;
+ if (!button->icon.isNull()) {
+ pix = button->icon.pixmap(button->iconSize, button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
+ proxy()->drawItemPixmap(painter, button->rect, alignment, pix);
+ if (button->direction == Qt::RightToLeft)
+ textRect.setRight(textRect.right() - button->iconSize.width() - 4);
+ else
+ textRect.setLeft(textRect.left() + button->iconSize.width() + 4);
+ }
+ if (!button->text.isEmpty()){
+ if (button->state & State_Enabled)
+ proxy()->drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic,
+ button->palette, false, button->text, QPalette::WindowText);
+ else
+ proxy()->drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic,
+ button->palette, false, button->text, QPalette::Mid);
+ }
+ }
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarGroove:
+ if (d->doubleControls)
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), 2, &option->palette.brush(QPalette::Window));
+ else
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), 1, &option->palette.brush(QPalette::Window));
+ break;
+#endif //QT_NO_PROGRESSBAR
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ proxy()->drawControl(CE_TabBarTabShape, tab, painter, widget);
+ proxy()->drawControl(CE_TabBarTabLabel, tab, painter, widget);
+ }
+ break;
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+
+ if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedEast ||
+ tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::RoundedWest) {
+ d->drawTabBarTab(painter, tab);
+ } else {
+ QCommonStyle::drawControl(element, option, painter, widget);
+ }
+ break; }
+
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ QRect rect = option->rect;
+ painter->save();
+ painter->setPen(option->palette.dark().color());
+ painter->fillRect(rect,option->palette.button());
+ if (d->doubleControls) {
+ QPen pen = painter->pen();
+ pen.setWidth(4);
+ painter->setPen(pen);
+ }
+ if (toolBar->toolBarArea == Qt::TopToolBarArea)
+ painter->drawLine(rect.bottomLeft(), rect.bottomRight());
+ else
+ painter->drawLine(rect.topLeft(), rect.topRight());
+ painter->restore();
+ break; }
+#endif //QT_NO_TOOLBAR
+ case CE_Header:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ QRegion clipRegion = painter->clipRegion();
+ painter->setClipRect(option->rect);
+ proxy()->drawControl(CE_HeaderSection, header, painter, widget);
+ QStyleOptionHeader subopt = *header;
+ subopt.rect = proxy()->subElementRect(SE_HeaderLabel, header, widget);
+ if (header->state & State_Sunken)
+ subopt.palette.setColor(QPalette::ButtonText, header->palette.brightText().color());
+ subopt.state |= QStyle::State_On;
+ if (subopt.rect.isValid())
+ proxy()->drawControl(CE_HeaderLabel, &subopt, painter, widget);
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ subopt.rect = proxy()->subElementRect(SE_HeaderArrow, option, widget);
+ proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget);
+ }
+ painter->setClipRegion(clipRegion);
+ }
+ break;
+
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ QBrush fill;
+ QColor color;
+ QRect rect = option->rect;
+ painter->setPen(option->palette.shadow().color());
+
+ int penSize = 1;
+
+ if (d->doubleControls) {
+ penSize = 2;
+ QPen pen = painter->pen();
+ pen.setWidth(2);
+ pen.setCapStyle(Qt::FlatCap);
+ painter->setPen(pen);
+ }
+
+ //fix Frame
+
+ if (header->position == QStyleOptionHeader::End
+ || (header->position == QStyleOptionHeader::OnlyOneSection
+ && !header->text.isEmpty()))
+ if (Qt::Horizontal == header->orientation )
+ rect.adjust(0, 0, penSize, 0);
+ else
+ rect.adjust(0, 0, 0, penSize);
+
+ if (option->state & State_Sunken) {
+ fill = option->palette.brush(QPalette::Shadow);
+ color = option->palette.light().color();
+ painter->drawLine(rect.bottomLeft(), rect.bottomRight());
+ painter->drawLine(rect.topRight(), rect.bottomRight());
+ rect.adjust(0, 0, -penSize, -penSize);
+ }
+ else {
+ fill = option->palette.brush(QPalette::Button);
+ color = option->palette.shadow().color();
+ if (Qt::Horizontal == header->orientation )
+ rect.adjust(-penSize, 0, 0, 0);
+ else
+ rect.adjust(0, -penSize, 0, 0);
+ }
+ if (Qt::Horizontal == header->orientation )
+ rect.adjust(0,-penSize,0,0);
+ else
+ rect.adjust(-penSize, 0, 0, 0);
+
+ if (option->state & State_Sunken) {
+ qDrawPlainRect(painter, rect, color, penSize, &fill);
+ } else {
+ //Corner
+ rect.adjust(-penSize, 0, 0, 0);
+ qDrawPlainRect(painter, rect, color, penSize, &fill);
+ }
+
+ //Hack to get rid of some double lines... StyleOptions need a clean flag for that
+ rect = option->rect;
+#ifndef QT_NO_SCROLLAREA
+ if (const QAbstractScrollArea *abstractScrollArea = qobject_cast<const QAbstractScrollArea *> (widget) ) {
+ QRect rectScrollArea = abstractScrollArea->geometry();
+ if (Qt::Horizontal == header->orientation )
+ if ((rectScrollArea.right() - rect.right() ) > 1)
+ painter->drawLine(rect.topRight(), rect.bottomRight());
+ else ;
+ else
+ if ((rectScrollArea.bottom() - rect.bottom() ) > 1)
+ painter->drawLine(rect.bottomLeft(), rect.bottomRight());
+ }
+#endif // QT_NO_SCROLLAREA
+ break;
+ }
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ // This is copied from qcommonstyle.cpp with the difference, that
+ // the editRect isn't adjusted when calling drawItemText.
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
+ painter->save();
+ painter->setClipRect(editRect);
+ if (!cb->currentIcon.isNull()) {
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width() + 4);
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ if (cb->editable)
+ painter->fillRect(iconRect, option->palette.brush(QPalette::Base));
+ proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-4 - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + 4, 0);
+ }
+ if (!cb->currentText.isEmpty() && !cb->editable) {
+ proxy()->drawItemText(painter, editRect,
+ visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ cb->palette, cb->state & State_Enabled, cb->currentText);
+ }
+ painter->restore();
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(option);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect rect = dwOpt->rect;
+ QRect r = rect;
+
+ if (verticalTitleBar) {
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ painter->save();
+ painter->translate(r.left(), r.top() + r.width());
+ painter->rotate(-90);
+ painter->translate(-r.left(), -r.top());
+ }
+
+ bool floating = false;
+ bool active = dwOpt->state & State_Active;
+ int menuOffset = 0; //used to center text when floated
+ QColor inactiveCaptionTextColor = option->palette.highlightedText().color();
+ if (dwOpt->movable) {
+ QColor left, right;
+
+ //Titlebar gradient
+ if (widget && widget->isWindow()) {
+ floating = true;
+ if (active) {
+ right = option->palette.highlight().color();
+ left = right.lighter(125);
+ } else {
+ left = option->palette.highlight().color().lighter(125);
+ right = QColor(0xff, 0xff, 0xff);
+ }
+ menuOffset = 2;
+ QBrush fillBrush(left);
+ if (left != right) {
+ QPoint p1(r.x(), r.top() + r.height()/2);
+ QPoint p2(rect.right(), r.top() + r.height()/2);
+ QLinearGradient lg(p1, p2);
+ lg.setColorAt(0, left);
+ lg.setColorAt(1, right);
+ fillBrush = lg;
+ }
+ painter->fillRect(r.adjusted(0, 0, 0, -3), fillBrush);
+ } else {
+ painter->fillRect(r.adjusted(0, 0, 0, -3), option->palette.button().color());
+ }
+ painter->setPen(dwOpt->palette.color(QPalette::Light));
+ if (!widget || !widget->isWindow()) {
+ painter->drawLine(r.topLeft(), r.topRight());
+ painter->setPen(dwOpt->palette.color(QPalette::Dark));
+ painter->drawLine(r.bottomLeft(), r.bottomRight()); }
+ }
+ if (!dwOpt->title.isEmpty()) {
+ QFont oldFont = painter->font();
+ QFont newFont = oldFont;
+ if (newFont.pointSize() > 2)
+ newFont.setPointSize(newFont.pointSize() - 2);
+ if (floating)
+ newFont.setBold(true);
+ painter->setFont(newFont);
+ QPalette palette = dwOpt->palette;
+ palette.setColor(QPalette::Window, inactiveCaptionTextColor);
+ QRect titleRect = proxy()->subElementRect(SE_DockWidgetTitleBarText, option, widget);
+ if (verticalTitleBar) {
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+ }
+ proxy()->drawItemText(painter, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
+ dwOpt->state & State_Enabled, dwOpt->title,
+ floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
+ painter->setFont(oldFont);
+ }
+ if (verticalTitleBar)
+ painter->restore();
+ }
+ return;
+#endif // QT_NO_DOCKWIDGET
+
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ painter->save();
+ QRect ir = button->rect;
+ QPalette::ColorRole colorRole;
+ uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ if (!styleHint(SH_UnderlineShortcut, button, widget))
+ tf |= Qt::TextHideMnemonic;
+
+ if (button->state & (State_On | State_Sunken))
+ colorRole = QPalette::Light;
+ else
+ colorRole = QPalette::ButtonText;
+
+ if (!button->icon.isNull()) {
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+ QIcon::State state = QIcon::Off;
+ if (button->state & State_On)
+ state = QIcon::On;
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ //Center the icon if there is no text
+
+ QPoint point;
+ if (button->text.isEmpty()) {
+ point = QPoint(ir.x() + ir.width() / 2 - pixw / 2,
+ ir.y() + ir.height() / 2 - pixh / 2);
+ } else {
+ point = QPoint(ir.x() + 2, ir.y() + ir.height() / 2 - pixh / 2);
+ }
+ if (button->direction == Qt::RightToLeft)
+ point.rx() += pixw;
+
+ if ((button->state & (State_On | State_Sunken)) && button->direction == Qt::RightToLeft)
+ point.rx() -= proxy()->pixelMetric(PM_ButtonShiftHorizontal, option, widget) * 2;
+
+ painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap);
+
+ if (button->direction == Qt::RightToLeft)
+ ir.translate(-4, 0);
+ else
+ ir.translate(pixw + 4, 0);
+ ir.setWidth(ir.width() - (pixw + 4));
+ // left-align text if there is
+ if (!button->text.isEmpty())
+ tf |= Qt::AlignLeft;
+ } else {
+ tf |= Qt::AlignHCenter;
+ }
+ if (button->state & State_Enabled)
+ proxy()->drawItemText(painter, ir, tf, button->palette, true, button->text, colorRole);
+ else
+ proxy()->drawItemText(painter, ir, tf, button->palette, true, button->text, QPalette::Mid);
+ painter->restore();
+ }
+ break;
+ default:
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const {
+
+ painter->setClipping(false);
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+
+ switch (control) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ int ticks = slider->tickPosition;
+ QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
+
+ if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
+ int mid = thickness / 2;
+ if (ticks & QSlider::TicksAbove)
+ mid += len / 8;
+ if (ticks & QSlider::TicksBelow)
+ mid -= len / 8;
+
+ painter->setPen(slider->palette.shadow().color());
+ if (slider->orientation == Qt::Horizontal) {
+ qDrawPlainRect(painter, groove.x(), groove.y() + mid - 2,
+ groove.width(), 4, option->palette.shadow().color(),1,0);
+ } else {
+ qDrawPlainRect(painter, groove.x()+mid-2, groove.y(),
+ 4, groove.height(), option->palette.shadow().color(),1,0);
+ }
+ }
+ if (slider->subControls & SC_SliderTickmarks) {
+ QStyleOptionSlider tmpSlider = *slider;
+ tmpSlider.subControls = SC_SliderTickmarks;
+ QCommonStyle::drawComplexControl(control, &tmpSlider, painter, widget);
+ }
+
+ if (slider->subControls & SC_SliderHandle) {
+ const QColor c0 = slider->palette.shadow().color();
+ const QColor c1 = slider->palette.dark().color();
+ const QColor c3 = slider->palette.midlight().color();
+ const QColor c4 = slider->palette.dark().color();
+ QBrush handleBrush;
+
+ if (slider->state & State_Enabled) {
+ handleBrush = slider->palette.color(QPalette::Light);
+ } else {
+ handleBrush = QBrush(slider->palette.color(QPalette::Shadow),
+ Qt::Dense4Pattern);
+ }
+ int x = handle.x(), y = handle.y(),
+ wi = handle.width(), he = handle.height();
+ int x1 = x;
+ int x2 = x+wi-1;
+ int y1 = y;
+ int y2 = y+he-1;
+
+ Qt::Orientation orient = slider->orientation;
+ bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
+ bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = proxy()->subElementRect(SE_SliderFocusRect, slider, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
+ Qt::BGMode oldMode = painter->backgroundMode();
+ painter->setBackgroundMode(Qt::OpaqueMode);
+ qDrawPlainRect(painter, QRect(x, y, wi, he)
+ ,slider->palette.shadow().color(),1,&handleBrush);
+ painter->setBackgroundMode(oldMode);
+ QBrush fill = QBrush(option->palette.light().color(), Qt::Dense4Pattern);
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 + 2, y1 + 2, x2 - x1 - 3, y2 - y1 - 3),fill);
+ return;
+ }
+ QSliderDirection dir;
+ if (orient == Qt::Horizontal)
+ if (tickAbove)
+ dir = SliderUp;
+ else
+ dir = SliderDown;
+ else
+ if (tickAbove)
+ dir = SliderLeft;
+ else
+ dir = SliderRight;
+ QPolygon polygon;
+ int d = 0;
+ switch (dir) {
+ case SliderUp:
+ x2++;
+ y1 = y1 + wi / 2;
+ d = (wi + 1) / 2 - 1;
+ polygon.setPoints(5, x1, y1, x1, y2, x2, y2, x2, y1, x1 + d,y1 - d);
+ break;
+ case SliderDown:
+ x2++;
+ y2 = y2 - wi/2;
+ d = (wi + 1) / 2 - 1;
+ polygon.setPoints(5, x1, y1, x1, y2, x1 + d,y2 + d, x2, y2, x2, y1);
+ break;
+ case SliderLeft:
+ d = (he + 1) / 2 - 1;
+ x1 = x1 + he/2;
+ polygon.setPoints(5, x1, y1, x1 - d, y1 + d, x1,y2, x2, y2, x2, y1);
+ y1--;
+ break;
+ case SliderRight:
+ d = (he + 1) / 2 - 1;
+ x2 = x2 - he/2;
+ polygon.setPoints(5, x1, y1, x1, y2, x2,y2, x2 + d, y1 + d, x2, y1);
+ y1--;
+ break;
+ }
+ QBrush oldBrush = painter->brush();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(handleBrush);
+ Qt::BGMode oldMode = painter->backgroundMode();
+ painter->setBackgroundMode(Qt::OpaqueMode);
+ painter->drawRect(x1, y1, x2-x1+1, y2-y1+1);
+ painter->drawPolygon(polygon);
+ QBrush fill = QBrush(option->palette.button().color(), Qt::Dense4Pattern);
+ painter->setBrush(oldBrush);
+ painter->setBackgroundMode(oldMode);
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1, y1, x2 - x1 + 1, y2 - y1 + 1),fill);
+
+ if (dir != SliderUp) {
+ painter->setPen(c0);
+ painter->drawLine(x1, y1, x2, y1);
+ }
+ if (dir != SliderLeft) {
+ painter->setPen(c0);
+ painter->drawLine(x1, y1, x1, y2);
+ }
+ if (dir != SliderRight) {
+ painter->setPen(c0);
+ painter->drawLine(x2, y1, x2, y2);
+ }
+ if (dir != SliderDown) {
+ painter->setPen(c0);
+ painter->drawLine(x1, y2, x2, y2);
+ }
+ switch (dir) {
+ case SliderUp:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 + 3, y1 - d + 2, x2 - x1 - 4, y1),fill);
+ painter->setPen(c0);
+ painter->drawLine(x1, y1, x1 + d, y1 - d);
+ d = wi - d - 1;
+ painter->drawLine(x2, y1, x2 -d , y1 -d );
+ d--;
+ break;
+ case SliderDown:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1+3, y2 - d, x2 - x1 -4,y2 - 8),fill);
+ painter->setPen(c0);
+ painter->drawLine(x1, y2, x1 + d, y2 + d);
+ d = wi - d - 1;
+ painter->drawLine(x2, y2, x2 - d, y2 + d);
+ d--;
+ break;
+ case SliderLeft:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x1 - d + 2, y1 + 2, x1, y2 - y1 - 3),fill);
+ painter->setPen(c0);
+ painter->drawLine(x1, y1, x1 - d, y1 + d);
+ d = he - d - 1;
+ painter->drawLine(x1, y2, x1 - d, y2 - d);
+ d--;
+ break;
+ case SliderRight:
+ if (slider->state & State_Sunken)
+ painter->fillRect(QRectF(x2 - d - 4, y1 + 2, x2 - 4, y2 - y1 - 3),fill);
+ painter->setPen(c0);
+ painter->drawLine(x2, y1, x2 + d, y1 + d);
+ painter->setPen(c0);
+ d = he - d - 1;
+ painter->drawLine(x2, y2, x2 + d, y2 - d);
+ d--;
+ break;
+ }
+ }
+ }
+ break;
+#endif //QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ painter->save();
+ painter->setPen(option->palette.shadow().color());
+ if (d->doubleControls) {
+ QPen pen = painter->pen();
+ pen.setWidth(2);
+ pen.setCapStyle(Qt::SquareCap);
+ painter->setPen(pen);
+ }
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ d->drawScrollbarGroove(painter, scrollbar);
+ // Make a copy here and reset it for each primitive.
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ State saveFlags = scrollbar->state;
+ //Check if the scrollbar is part of an abstractItemView and draw the frame according
+ bool drawCompleteFrame = true;
+ bool secondScrollBar = false;
+ if (widget)
+ if (QWidget *parent = widget->parentWidget()) {
+ if (QAbstractScrollArea *abstractScrollArea = qobject_cast<QAbstractScrollArea *>(parent->parentWidget())) {
+ drawCompleteFrame = (abstractScrollArea->frameStyle() == QFrame::NoFrame) || (abstractScrollArea->frameStyle() == QFrame::StyledPanel);
+ secondScrollBar = (abstractScrollArea->horizontalScrollBar()->isVisible()
+ && abstractScrollArea->verticalScrollBar()->isVisible()) ;
+ }
+#ifndef QT_NO_LISTVIEW
+ if (QListView *listView = qobject_cast<QListView *>(parent->parentWidget()))
+ drawCompleteFrame = false;
+#endif
+ }
+ if (scrollbar->minimum == scrollbar->maximum)
+ saveFlags |= State_Enabled;
+ if (scrollbar->subControls & SC_ScrollBarSubLine) {
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarSubLine, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ d->drawScrollbarHandleUp(painter, &newScrollbar, drawCompleteFrame, secondScrollBar);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarAddLine) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarAddLine, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ d->drawScrollbarHandleDown(painter, &newScrollbar, drawCompleteFrame, secondScrollBar);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarSlider) {
+
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarSlider, widget);
+
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ d->drawScrollbarGrip(painter, &newScrollbar, option, drawCompleteFrame);
+ }
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_SCROLLBAR
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+ bool isTabWidget = false;
+#ifndef QT_NO_TABWIDGET
+ if (widget)
+ if (QWidget *parent = widget->parentWidget())
+ isTabWidget = (qobject_cast<QTabWidget *>(parent->parentWidget()));
+#endif //QT_NO_TABWIDGET
+
+ button = proxy()->subControlRect(control, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+ State buttonFlags = toolbutton->state;
+ if (buttonFlags & State_AutoRaise) {
+ if (!(buttonFlags & State_MouseOver)) {
+ buttonFlags &= ~State_Raised;
+ }
+ }
+ State menuFlags = buttonFlags;
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ buttonFlags |= State_Sunken;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ menuFlags |= State_On;
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ tool.rect = button;
+ tool.state = buttonFlags;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = buttonFlags & State_Enabled;
+ QStyleOption toolMenu(0);
+ toolMenu = *toolbutton;
+ toolMenu.state = menuFlags;
+ if (buttonFlags & State_Sunken)
+ proxy()->drawPrimitive(PE_PanelButtonTool, &toolMenu, painter, widget);
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = tool.rect;
+ arrowOpt.palette = tool.palette;
+ State flags = State_None;
+ if (menuFlags & State_Enabled)
+ flags |= State_Enabled;
+ if ((menuFlags & State_On) && !(buttonFlags & State_Sunken)) {
+ flags |= State_Sunken;
+ painter->fillRect(menuarea, option->palette.shadow());
+ }
+ arrowOpt.state = flags;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
+ }
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect focusRect;
+ focusRect.QStyleOption::operator=(*toolbutton);
+ focusRect.rect.adjust(3, 3, -3, -3);
+ if (toolbutton->features & QStyleOptionToolButton::Menu)
+ focusRect.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
+ toolbutton, widget), 0);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focusRect, painter, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ if (isTabWidget)
+ label.state = toolbutton->state;
+ else
+ label.state = toolbutton->state & State_Enabled;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ // Draw frame
+ painter->save();
+ QFont font = painter->font();
+ font.setBold(true);
+ painter->setFont(font);
+ QStyleOptionGroupBox groupBoxFont = *groupBox;
+ groupBoxFont.fontMetrics = QFontMetrics(font);
+ QRect textRect = proxy()->subControlRect(CC_GroupBox, &groupBoxFont, SC_GroupBoxLabel, widget);
+ QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget).adjusted(0,0,0,0);
+ if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*groupBox);
+ frame.features = groupBox->features;
+ frame.lineWidth = groupBox->lineWidth;
+ frame.midLineWidth = groupBox->midLineWidth;
+ frame.rect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
+ painter->save();
+ QRegion region(groupBox->rect);
+ if (!groupBox->text.isEmpty()) {
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ QRect finalRect = checkBoxRect.united(textRect);
+ if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)
+ finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
+ region -= finalRect;
+ }
+ proxy()->drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
+ painter->restore();
+ }
+ // Draw checkbox
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
+ }
+ // Draw title
+ if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ QColor textColor = groupBox->textColor;
+ if (textColor.isValid())
+ painter->setPen(textColor);
+ else
+ painter->setPen(groupBox->palette.link().color());
+ painter->setPen(groupBox->palette.link().color());
+
+ int alignment = int(groupBox->textAlignment);
+ if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ if (groupBox->state & State_Enabled)
+ proxy()->drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
+ groupBox->palette, true, groupBox->text,
+ textColor.isValid() ? QPalette::NoRole : QPalette::Link);
+ else
+ proxy()->drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
+ groupBox->palette, true, groupBox->text, QPalette::Mid);
+ if (groupBox->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*groupBox);
+ fropt.rect = textRect;
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+ painter->restore();
+ }
+ break;
+#endif //QT_NO_GROUPBOX
+
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ if ((cmb->subControls & SC_ComboBoxFrame) && cmb->frame)
+ qDrawPlainRect(painter, option->rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget), &editBrush);
+ else
+ painter->fillRect(option->rect, editBrush);
+ State flags = State_None;
+ QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
+ if ((option->state & State_On)) {
+ painter->fillRect(ar.adjusted(0, 0, 1, 1),cmb->palette.brush(QPalette::Shadow));
+ }
+ if (d->doubleControls)
+ ar.adjust(5, 0, 5, 0);
+ else
+ ar.adjust(2, 0, -2, 0);
+ if (option->state & State_Enabled)
+ flags |= State_Enabled;
+ if (option->state & State_On)
+ flags |= State_Sunken;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar;
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ proxy()->drawPrimitive(PrimitiveElement(PE_IndicatorArrowDownBig), &arrowOpt, painter, widget);
+ if (cmb->subControls & SC_ComboBoxEditField) {
+ QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
+ if (cmb->state & State_HasFocus && !cmb->editable)
+ painter->fillRect(re.x(), re.y(), re.width(), re.height(),
+ cmb->palette.brush(QPalette::Highlight));
+ if (cmb->state & State_HasFocus) {
+ painter->setPen(cmb->palette.highlightedText().color());
+ painter->setBackground(cmb->palette.highlight());
+ } else {
+ painter->setPen(cmb->palette.text().color());
+ painter->setBackground(cmb->palette.background());
+ }
+ if (cmb->state & State_HasFocus && !cmb->editable) {
+ QStyleOptionFocusRect focus;
+ focus.QStyleOption::operator=(*cmb);
+ focus.rect = proxy()->subElementRect(SE_ComboBoxFocusRect, cmb, widget);
+ focus.state |= State_FocusAtBorder;
+ focus.backgroundColor = cmb->palette.highlight().color();
+ if ((option->state & State_On))
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, painter, widget);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+
+
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QStyleOptionSpinBox copy = *spinBox;
+ //PrimitiveElement primitiveElement;
+ int primitiveElement;
+
+ if (spinBox->frame && (spinBox->subControls & SC_SpinBoxFrame)) {
+ QRect r = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxFrame, widget);
+ qDrawPlainRect(painter, r, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget),0);
+ }
+ QPalette shadePal(option->palette);
+ shadePal.setColor(QPalette::Button, option->palette.light().color());
+ shadePal.setColor(QPalette::Light, option->palette.base().color());
+ if (spinBox->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = spinBox->palette;
+ if (!(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+ if (spinBox->activeSubControls == SC_SpinBoxUp && (spinBox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ primitiveElement = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorArrowUpBig
+ : PE_IndicatorArrowUpBig);
+ copy.rect = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget);
+ if (copy.state & (State_Sunken | State_On))
+ qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), &copy.palette.brush(QPalette::Shadow));
+ else
+ qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), &copy.palette.brush(QPalette::Base));
+ copy.rect.adjust(proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0, -pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0);
+ proxy()->drawPrimitive(PrimitiveElement(primitiveElement), &copy, painter, widget);
+ }
+ if (spinBox->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = spinBox->state;
+ QPalette pal2 = spinBox->palette;
+ if (!(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+ if (spinBox->activeSubControls == SC_SpinBoxDown && (spinBox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ primitiveElement = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorArrowDownBig
+ : PE_IndicatorArrowDownBig);
+ copy.rect = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget);
+ qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), &copy.palette.brush(QPalette::Base));
+ if (copy.state & (State_Sunken | State_On))
+ qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), &copy.palette.brush(QPalette::Shadow));
+ else
+ qDrawPlainRect(painter, copy.rect, option->palette.shadow().color(), proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), &copy.palette.brush(QPalette::Base));
+ copy.rect.adjust(3, 0, -4, 0);
+ if (primitiveElement == PE_IndicatorArrowUp || primitiveElement == PE_IndicatorArrowDown) {
+ int frameWidth = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+ copy.rect = copy.rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth);
+ proxy()->drawPrimitive(PrimitiveElement(primitiveElement), &copy, painter, widget);
+ }
+ else {
+ proxy()->drawPrimitive(PrimitiveElement(primitiveElement), &copy, painter, widget);
+ }
+ if (spinBox->frame && (spinBox->subControls & SC_SpinBoxFrame)) {
+ QRect r = proxy()->subControlRect(CC_SpinBox, spinBox, SC_SpinBoxEditField, widget);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+QSize QWindowsMobileStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const {
+
+ QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ switch (type) {
+ case CT_PushButton:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ newSize = QCommonStyle::sizeFromContents(type, option, size, widget);
+ int w = newSize.width(),
+ h = newSize.height();
+ int defwidth = 0;
+ if (button->features & QStyleOptionButton::AutoDefaultButton)
+ defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, button, widget);
+
+ int minwidth = int(QStyleHelper::dpiScaled(55.0f));
+ int minheight = int(QStyleHelper::dpiScaled(19.0f));
+
+ if (w < minwidth + defwidth && button->icon.isNull())
+ w = minwidth + defwidth;
+ if (h < minheight + defwidth)
+ h = minheight + defwidth;
+ newSize = QSize(w + 4, h + 4);
+ }
+ break;
+
+#ifndef QT_NO_GROUPBOX
+ case CT_GroupBox:
+ if (const QGroupBox *grb = static_cast<const QGroupBox *>(widget)) {
+ newSize = size + QSize(!grb->isFlat() ? 16 : 0, !grb->isFlat() ? 16 : 0);
+ }
+ break;
+#endif // QT_NO_GROUPBOX
+
+ case CT_RadioButton:
+ case CT_CheckBox:
+ newSize = size;
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (type == CT_RadioButton);
+ QRect irect = visualRect(button->direction, button->rect,
+ proxy()->subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, button, widget));
+ int h = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
+ : PM_IndicatorHeight, button, widget);
+ int margins = (!button->icon.isNull() && button->text.isEmpty()) ? 0 : 10;
+ if (d_func()->doubleControls)
+ margins *= 2;
+ newSize += QSize(irect.right() + margins, 1);
+ newSize.setHeight(qMax(newSize.height(), h));
+ }
+ break;
+#ifndef QT_NO_COMBOBOX
+ case CT_ComboBox:
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int fw = comboBox->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, option, widget) * 2 : 0;
+ newSize = QSize(newSize.width() + fw + 9, newSize.height() + fw); //Nine is a magic Number - See CommonStyle for real magic (23)
+ }
+ break;
+#endif
+#ifndef QT_NO_SPINBOX
+ case CT_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ int fw = spinBox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget) * 2 : 0;
+ newSize = QSize(newSize.width() + fw-5, newSize.height() + fw-6);
+ }
+ break;
+#endif
+#ifndef QT_NO_LINEEDIT
+ case CT_LineEdit:
+ newSize += QSize(0,1);
+ break;
+#endif
+ case CT_ToolButton:
+ newSize = QSize(newSize.width() + 1, newSize.height());
+ break;
+ case CT_TabBarTab:
+ if (d_func()->doubleControls)
+ newSize = QSize(newSize.width(), 42);
+ else
+ newSize = QSize(newSize.width(), 21);
+ break;
+ case CT_HeaderSection:
+ newSize += QSize(4, 2);
+ break;
+#ifndef QT_NO_ITEMVIEWS
+#ifdef Q_WS_WINCE_WM
+ case CT_ItemViewItem:
+ if (d_func()->wm65)
+ if (d_func()->doubleControls)
+ newSize.setHeight(46);
+ else
+ newSize.setHeight(23);
+ break;
+#endif //Q_WS_WINCE_WM
+#endif //QT_NO_ITEMVIEWS
+ default:
+ break;
+ }
+ return newSize;
+}
+
+QRect QWindowsMobileStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+ QRect rect = QWindowsStyle::subElementRect(element, option, widget);
+ switch (element) {
+#ifndef QT_NO_TABWIDGET
+ case SE_TabWidgetTabBar:
+ if (d->doubleControls)
+ rect.adjust(-2, 0, 2, 0);
+ else
+ rect.adjust(-2, 0, 2, 0);
+ break;
+#endif //QT_NO_TABWIDGET
+ case SE_CheckBoxFocusRect:
+ rect.adjust(1,0,-2,-1);
+ break;
+ case SE_RadioButtonFocusRect:
+ rect.adjust(1,1,-2,-2);
+ break;
+ default:
+ break;
+#ifndef QT_NO_SLIDER
+ case SE_SliderFocusRect:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ rect = slider->rect;
+ }
+ break;
+ case SE_PushButtonFocusRect:
+ if (d->doubleControls)
+ rect.adjust(-1, -1, 0, 0);
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_ITEMVIEWS
+ case SE_ItemViewItemFocusRect:
+#ifdef Q_WS_WINCE_WM
+ if (d->wm65)
+ rect = QRect();
+#endif
+ break;
+#endif //QT_NO_ITEMVIEWS
+ }
+ return rect;
+}
+
+QRect QWindowsMobileStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+
+ QRect rect = QCommonStyle::subControlRect(control, option, subControl, widget);
+ switch (control) {
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int sliderButtonExtent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar, widget);
+ float stretchFactor = 1.4f;
+ int sliderButtonExtentDir = int (sliderButtonExtent * stretchFactor);
+
+#ifdef Q_WS_WINCE_WM
+ if (d->wm65)
+ {
+ sliderButtonExtent = d->imageScrollbarHandleUp.width();
+ sliderButtonExtentDir = d->imageScrollbarHandleUp.height();
+ }
+#endif //Q_WS_WINCE_WM
+
+ int sliderlen;
+ int maxlen = ((scrollbar->orientation == Qt::Horizontal) ?
+ scrollbar->rect.width() : scrollbar->rect.height()) - (sliderButtonExtentDir * 2);
+ // calculate slider length
+ if (scrollbar->maximum != scrollbar->minimum) {
+ uint range = scrollbar->maximum - scrollbar->minimum;
+ sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep);
+
+ int slidermin = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollbar, widget);
+ if (sliderlen < slidermin || range > INT_MAX / 2)
+ sliderlen = slidermin;
+ if (sliderlen > maxlen)
+ sliderlen = maxlen;
+ } else {
+ sliderlen = maxlen;
+ }
+ int sliderstart = sliderButtonExtentDir + sliderPositionFromValue(scrollbar->minimum,
+ scrollbar->maximum,
+ scrollbar->sliderPosition,
+ maxlen - sliderlen,
+ scrollbar->upsideDown);
+ if (d->smartphone) {
+ sliderstart -= sliderButtonExtentDir;
+ sliderlen += 2*sliderButtonExtent;
+ }
+ switch (subControl) {
+ case SC_ScrollBarSubLine: // top/left button
+ if (scrollbar->orientation == Qt::Horizontal) {
+ int buttonWidth = qMin(scrollbar->rect.width() / 2, sliderButtonExtentDir );
+ rect.setRect(0, 0, buttonWidth, sliderButtonExtent);
+ } else {
+ int buttonHeight = qMin(scrollbar->rect.height() / 2, sliderButtonExtentDir);
+ rect.setRect(0, 0, sliderButtonExtent, buttonHeight);
+ }
+ if (d->smartphone)
+ rect.setRect(0, 0, 0, 0);
+ break;
+ case SC_ScrollBarAddLine: // bottom/right button
+ if (scrollbar->orientation == Qt::Horizontal) {
+ int buttonWidth = qMin(scrollbar->rect.width()/2, sliderButtonExtentDir);
+ rect.setRect(scrollbar->rect.width() - buttonWidth, 0, buttonWidth, sliderButtonExtent);
+ } else {
+ int buttonHeight = qMin(scrollbar->rect.height()/2, sliderButtonExtentDir );
+ rect.setRect(0, scrollbar->rect.height() - buttonHeight, sliderButtonExtent, buttonHeight);
+ }
+ if (d->smartphone)
+ rect.setRect(0, 0, 0, 0);
+ break;
+ case SC_ScrollBarSubPage: // between top/left button and slider
+ if (scrollbar->orientation == Qt::Horizontal)
+ if (d->smartphone)
+ rect.setRect(0, 0, sliderstart, sliderButtonExtent);
+ else
+ rect.setRect(sliderButtonExtent, 0, sliderstart - sliderButtonExtent, sliderButtonExtent);
+ else
+ if (d->smartphone)
+ rect.setRect(0, 0, sliderButtonExtent, sliderstart);
+ else
+ rect.setRect(0, sliderButtonExtent, sliderButtonExtent, sliderstart - sliderButtonExtent);
+ break;
+ case SC_ScrollBarAddPage: // between bottom/right button and slider
+ if (scrollbar->orientation == Qt::Horizontal)
+ if (d->smartphone)
+ rect.setRect(sliderstart + sliderlen, 0,
+ maxlen - sliderstart - sliderlen + 2*sliderButtonExtent, sliderButtonExtent);
+ else
+ rect.setRect(sliderstart + sliderlen, 0,
+ maxlen - sliderstart - sliderlen + sliderButtonExtent, sliderButtonExtent);
+ else
+ if (d->smartphone)
+ rect.setRect(0, sliderstart + sliderlen, sliderButtonExtent,
+ maxlen - sliderstart - sliderlen + 2*sliderButtonExtent);
+ else
+ rect.setRect(0, sliderstart + sliderlen, sliderButtonExtent,
+ maxlen - sliderstart - sliderlen + sliderButtonExtent);
+ break;
+ case SC_ScrollBarGroove:
+ if (scrollbar->orientation == Qt::Horizontal)
+ rect.setRect(sliderButtonExtent, 0, scrollbar->rect.width() - sliderButtonExtent * 2,
+ scrollbar->rect.height());
+ else
+ rect.setRect(0, sliderButtonExtent, scrollbar->rect.width(),
+ scrollbar->rect.height() - sliderButtonExtent * 2);
+ break;
+ case SC_ScrollBarSlider:
+ if (scrollbar->orientation == Qt::Horizontal)
+ rect.setRect(sliderstart, 0, sliderlen, sliderButtonExtent);
+ else
+ rect.setRect(0, sliderstart, sliderButtonExtent, sliderlen);
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(scrollbar->direction, scrollbar->rect, rect);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+
+
+
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolButton, widget);
+ rect = toolButton->rect;
+ switch (subControl) {
+ case SC_ToolButton:
+ if ((toolButton->features
+ & (QStyleOptionToolButton::Menu | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::Menu)
+ rect.adjust(0, 0, -mbi, 0);
+ break;
+ case SC_ToolButtonMenu:
+ if ((toolButton->features
+ & (QStyleOptionToolButton::Menu | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::Menu)
+ rect.adjust(rect.width() - mbi, 1, 0, 1);
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(toolButton->direction, toolButton->rect, rect);
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ switch (subControl) {
+ case SC_SliderHandle: {
+ int sliderPos = 0;
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ slider->sliderPosition,
+ (horizontal ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown);
+ if (horizontal)
+ rect.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness);
+ else
+ rect.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len);
+ break; }
+ default:
+ break;
+ }
+ rect = visualRect(slider->direction, slider->rect, rect);
+ }
+ break;
+#endif //QT_NO_SLIDER
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int x = comboBox->rect.x(),
+ y = comboBox->rect.y(),
+ wi = comboBox->rect.width(),
+ he = comboBox->rect.height();
+ int xpos = x;
+ int margin = comboBox->frame ? (d->doubleControls ? 2 : 1) : 0;
+ int bmarg = comboBox->frame ? (d->doubleControls ? 2 : 1) : 0;
+ if (subControl == SC_ComboBoxArrow)
+ xpos += wi - int((he - 2*bmarg)*0.9) - bmarg;
+ else
+ xpos += wi - (he - 2*bmarg) - bmarg;
+ switch (subControl) {
+ case SC_ComboBoxArrow:
+ rect.setRect(xpos, y + bmarg, he - 2*bmarg, he - 2*bmarg);
+ break;
+ case SC_ComboBoxEditField:
+ rect.setRect(x + margin, y + margin, wi - 2 * margin - int((he - 2*bmarg) * 0.84f), he - 2 * margin);
+ if (d->doubleControls) {
+ if (comboBox->editable)
+ rect.adjust(2, 0, 0, 0);
+ else
+ rect.adjust(4, 2, 0, -2);
+ } else if (!comboBox->editable) {
+ rect.adjust(2, 1, 0, -1);
+ }
+ break;
+ case SC_ComboBoxFrame:
+ rect = comboBox->rect;
+ break;
+ default:
+ break;
+ }
+ }
+#endif //QT_NO_COMBOBOX
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ QSize bs;
+ int fw = spinBox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinBox, widget) : 0;
+ bs.setHeight(qMax(d->doubleControls ? 28 : 14, (spinBox->rect.height())));
+ // 1.6 -approximate golden mean
+ bs.setWidth(qMax(d->doubleControls ? 28 : 14, qMin((bs.height()*7/8), (spinBox->rect.width() / 8))));
+ bs = bs.expandedTo(QApplication::globalStrut());
+ int x, lx, rx;
+ x = spinBox->rect.width() - bs.width()*2;
+ lx = fw;
+ rx = x - fw;
+ switch (subControl) {
+ case SC_SpinBoxUp:
+ rect = QRect(x + proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget), 0 , bs.width(), bs.height());
+ break;
+ case SC_SpinBoxDown:
+ rect = QRect(x + bs.width(), 0, bs.width(), bs.height());
+ break;
+ case SC_SpinBoxEditField:
+ if (spinBox->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ rect = QRect(lx, fw, spinBox->rect.width() - 2*fw - 2, spinBox->rect.height() - 2*fw);
+ } else {
+ rect = QRect(lx, fw, rx-2, spinBox->rect.height() - 2*fw);
+ }
+ break;
+ case SC_SpinBoxFrame:
+ rect = spinBox->rect;
+ default:
+ break;
+ }
+ rect = visualRect(spinBox->direction, spinBox->rect, rect);
+ }
+ break;
+#endif // Qt_NO_SPINBOX
+#ifndef QT_NO_GROUPBOX
+ case CC_GroupBox: {
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ switch (subControl) {
+ case SC_GroupBoxFrame:
+ // FALL THROUGH
+ case SC_GroupBoxContents: {
+ int topMargin = 0;
+ int topHeight = 0;
+ int bottomMargin = 0;
+ int labelMargin = 2;
+
+ QRect frameRect = groupBox->rect;
+ int verticalAlignment = styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
+ if (groupBox->text.size()) {
+ topHeight = groupBox->fontMetrics.height();
+ if (verticalAlignment & Qt::AlignVCenter)
+ topMargin = topHeight+5;
+ else if (verticalAlignment & Qt::AlignTop)
+ topMargin = -topHeight+5;
+ }
+ if (subControl == SC_GroupBoxFrame) {
+ frameRect.setTop(topMargin);
+ frameRect.setBottom(frameRect.height() + bottomMargin);
+ rect = frameRect;
+ break;
+ }
+ int frameWidth = 0;
+ if (groupBox->text.size()) {
+ frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, groupBox, widget);
+ rect = frameRect.adjusted(frameWidth, frameWidth + topHeight + labelMargin, -frameWidth, -frameWidth);
+ }
+ else {
+ rect = groupBox->rect;
+ }
+ break;
+ }
+ case SC_GroupBoxCheckBox:
+ // FALL THROUGH
+ case SC_GroupBoxLabel: {
+ QFontMetrics fontMetrics = groupBox->fontMetrics;
+ int h = fontMetrics.height();
+ int textWidth = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
+ int margX = (groupBox->features & QStyleOptionFrameV2::Flat) ? 0 : 2;
+ int margY = (groupBox->features & QStyleOptionFrameV2::Flat) ? 0 : 2;
+ rect = groupBox->rect.adjusted(margX, margY, -margX, 0);
+ if (groupBox->text.size())
+ rect.setHeight(h);
+ else
+ rect.setHeight(0);
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
+ int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, option, widget) - 1;
+ bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
+ int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
+
+ // Adjusted rect for label + indicatorWidth + indicatorSpace
+ QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment,
+ QSize(textWidth + checkBoxSize, h), rect);
+
+ // Adjust totalRect if checkbox is set
+ if (hasCheckBox) {
+ bool ltr = groupBox->direction == Qt::LeftToRight;
+ int left = 2;
+ // Adjust for check box
+ if (subControl == SC_GroupBoxCheckBox) {
+ int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
+ left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
+ int top = totalRect.top() + (fontMetrics.height() - indicatorHeight) / 2;
+ totalRect.setRect(left, top, indicatorWidth, indicatorHeight);
+ // Adjust for label
+ } else {
+ left = ltr ? (totalRect.left() + checkBoxSize - 2) : totalRect.left();
+ totalRect.setRect(left, totalRect.top(),
+ totalRect.width() - checkBoxSize, totalRect.height());
+ }
+ }
+ if ((subControl== SC_GroupBoxLabel))
+ totalRect.adjust(-2,0,6,0);
+ rect = totalRect;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
+ }
+#endif // QT_NO_GROUPBOX
+ default:
+ break;
+ }
+ return rect;
+}
+
+QPalette QWindowsMobileStyle::standardPalette() const {
+ QPalette palette (Qt::black,QColor(198, 195, 198), QColor(222, 223, 222 ),
+ QColor(132, 130, 132), QColor(198, 195, 198), Qt::black, Qt::white, Qt::white, QColor(198, 195, 198));
+ palette.setColor(QPalette::Window, QColor(206, 223, 239));
+ palette.setColor(QPalette::Link, QColor(8,77,123)); //Alternate TextColor for labels...
+ palette.setColor(QPalette::Base, Qt::white);
+ palette.setColor(QPalette::Button, QColor(206, 223, 239));
+ palette.setColor(QPalette::Highlight, QColor(49, 146, 214));
+ palette.setColor(QPalette::Light, Qt::white);
+ palette.setColor(QPalette::Text, Qt::black);
+ palette.setColor(QPalette::ButtonText, Qt::black);
+ palette.setColor(QPalette::Midlight, QColor(222, 223, 222 ));
+ palette.setColor(QPalette::Dark, QColor(132, 130, 132));
+ palette.setColor(QPalette::Mid, QColor(189, 190, 189));
+ palette.setColor(QPalette::Shadow, QColor(0, 0, 0));
+ palette.setColor(QPalette::BrightText, QColor(33, 162, 33)); //color for ItemView checked indicator (arrow)
+ return palette;
+}
+
+
+/*! \reimp */
+void QWindowsMobileStyle::polish(QApplication *application) {
+ QWindowsStyle::polish(application);
+}
+
+/*! \reimp */
+void QWindowsMobileStyle::polish(QWidget *widget) {
+
+#ifndef QT_NO_TOOLBAR
+ if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
+ QPalette pal = toolBar->palette();
+ pal.setColor(QPalette::Background, pal.button().color());
+ toolBar->setPalette(pal);
+ }
+ else
+#endif //QT_NO_TOOLBAR
+
+ QWindowsStyle::polish(widget);
+}
+
+void QWindowsMobileStyle::unpolish(QWidget *widget)
+{
+ QWindowsStyle::unpolish(widget);
+}
+
+void QWindowsMobileStyle::unpolish(QApplication *app)
+{
+ QWindowsStyle::unpolish(app);
+}
+
+/*! \reimp */
+void QWindowsMobileStyle::polish(QPalette &palette) {
+ QWindowsStyle::polish(palette);
+}
+
+int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+ int ret;
+
+ switch (pm) {
+ case PM_DefaultTopLevelMargin:
+ ret =0;
+ break;
+ case PM_DefaultLayoutSpacing:
+ d->doubleControls ? ret = 8 : ret = 4;
+ break;
+ case PM_HeaderMargin:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+ case PM_DefaultChildMargin:
+ d->doubleControls ? ret = 10 : ret = 5;
+ break;
+ case PM_ToolBarSeparatorExtent:
+ d->doubleControls ? ret = 6 : ret = 3;
+ break;
+ case PM_DefaultFrameWidth:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+ case PM_MenuVMargin:
+ ret = 1;
+ break;
+ case PM_MenuHMargin:
+ ret = 1;
+ break;
+ case PM_MenuButtonIndicator:
+ ret = d->doubleControls ? 24 : 14;
+ break;
+ case PM_ComboBoxFrameWidth:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+ case PM_SpinBoxFrameWidth:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+ case PM_ButtonDefaultIndicator:
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+#ifndef QT_NO_TABBAR
+ case PM_TabBarTabShiftHorizontal:
+ ret = 0;
+ break;
+ case PM_TabBarTabShiftVertical:
+ ret = 0;
+ break;
+#endif
+ case PM_MaximumDragDistance:
+ ret = 60;
+ break;
+ case PM_TabBarTabVSpace:
+ ret = d->doubleControls ? 12 : 6;
+ break;
+ case PM_TabBarBaseHeight:
+ ret = 0;
+ break;
+ case PM_IndicatorWidth:
+ ret = d->doubleControls ? windowsMobileIndicatorSize * 2 : windowsMobileIndicatorSize;
+ break;
+ case PM_IndicatorHeight:
+ ret = d->doubleControls ? windowsMobileIndicatorSize * 2 : windowsMobileIndicatorSize;
+ break;
+ case PM_ExclusiveIndicatorWidth:
+ ret = d->doubleControls ? windowsMobileExclusiveIndicatorSize * 2 + 4: windowsMobileExclusiveIndicatorSize + 2;
+ break;
+ case PM_ExclusiveIndicatorHeight:
+ ret = d->doubleControls ? windowsMobileExclusiveIndicatorSize * 2 + 4: windowsMobileExclusiveIndicatorSize + 2;
+ break;
+#ifndef QT_NO_SLIDER
+ case PM_SliderLength:
+ ret = d->doubleControls ? 16 : 8;
+ break;
+ case PM_FocusFrameHMargin:
+ ret = d->doubleControls ? 1 : 2;
+ break;
+ case PM_SliderThickness:
+ ret = d->doubleControls ? windowsMobileSliderThickness * 2: windowsMobileSliderThickness;
+ break;
+ case PM_TabBarScrollButtonWidth:
+ ret = d->doubleControls ? 14 * 2 : 18;
+ break;
+ case PM_CheckBoxLabelSpacing:
+ case PM_RadioButtonLabelSpacing:
+ ret = d->doubleControls ? 6 * 2 : 6;
+ break;
+ // Returns the number of pixels to use for the business part of the
+ // slider (i.e., the non-tickmark portion). The remaining space is shared
+ // equally between the tickmark regions.
+ case PM_SliderControlThickness:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
+ int ticks = sl->tickPosition;
+ int n = 0;
+ if (ticks & QSlider::TicksAbove)
+ ++n;
+ if (ticks & QSlider::TicksBelow)
+ ++n;
+ if (!n) {
+ ret = space;
+ break;
+ }
+ int thick = 8;
+ if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
+ thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;
+
+ space -= thick;
+ if (space > 0)
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ } else {
+ ret = 0;
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_MENU
+ case PM_SmallIconSize:
+ d->doubleControls ? ret = windowsMobileIconSize * 2 : ret = windowsMobileIconSize;
+ break;
+ case PM_ButtonMargin:
+ d->doubleControls ? ret = 8 : ret = 4;
+ break;
+ case PM_LargeIconSize:
+ d->doubleControls ? ret = 64 : ret = 32;
+ break;
+ case PM_IconViewIconSize:
+ ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
+ break;
+ case PM_ToolBarIconSize:
+ d->doubleControls ? ret = 2 * windowsMobileIconSize : ret = windowsMobileIconSize;
+ break;
+ case PM_DockWidgetTitleMargin:
+ ret = 2;
+ break;
+#if defined(Q_WS_WIN)
+#else
+ case PM_DockWidgetFrameWidth:
+ ret = 4;
+ break;
+#endif // Q_WS_WIN
+ break;
+#endif // QT_NO_MENU
+
+ case PM_TitleBarHeight:
+ d->doubleControls ? ret = 42 : ret = 21;
+ break;
+ case PM_ScrollBarSliderMin:
+#ifdef Q_WS_WINCE_WM
+ if (d->wm65)
+#else
+ if (false)
+#endif
+ {
+ d->doubleControls ? ret = 68 : ret = 34;
+ } else {
+ d->doubleControls ? ret = 36 : ret = 18;
+ }
+ break;
+ case PM_ScrollBarExtent: {
+
+ if (d->smartphone)
+ ret = 9;
+ else
+ d->doubleControls ? ret = 25 : ret = 13;
+
+#ifdef Q_WS_WINCE_WM
+ if (d->wm65)
+#else
+ if (false)
+#endif
+ {
+ d->doubleControls ? ret = 26 : ret = 13;
+ break;
+ }
+
+#ifndef QT_NO_SCROLLAREA
+ //Check if the scrollbar is part of an abstractItemView and set size according
+ if (widget)
+ if (QWidget *parent = widget->parentWidget())
+ if (qobject_cast<QAbstractScrollArea *>(parent->parentWidget()))
+ if (d->smartphone)
+ ret = 8;
+ else
+ d->doubleControls ? ret = 24 : ret = 12;
+#endif
+ }
+ break;
+ case PM_SplitterWidth:
+ ret = qMax(4, QApplication::globalStrut().width());
+ break;
+
+#if defined(Q_WS_WIN)
+ case PM_MDIFrameWidth:
+ ret = 1;
+ break;
+#endif
+ case PM_ToolBarExtensionExtent:
+ d->doubleControls ? ret = 32 : ret = 16;
+ break;
+ case PM_ToolBarItemMargin:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+ case PM_ToolBarItemSpacing:
+ d->doubleControls ? ret = 2 : ret = 1;
+ break;
+ case PM_ToolBarHandleExtent:
+ d->doubleControls ? ret = 16 : ret = 8;
+ break;
+ case PM_ButtonIconSize:
+ d->doubleControls ? ret = 32 : ret = 16;
+ break;
+ case PM_TextCursorWidth:
+ ret = 2;
+ break;
+ case PM_TabBar_ScrollButtonOverlap:
+ ret = 0;
+ break;
+ default:
+ ret = QWindowsStyle::pixelMetric(pm, opt, widget);
+ break;
+ }
+ return ret;
+}
+
+int QWindowsMobileStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *returnData) const {
+
+ int ret;
+ switch (hint) {
+ case SH_Menu_MouseTracking:
+ case SH_ComboBox_ListMouseTracking:
+ case SH_EtchDisabledText:
+ ret = 0;
+ break;
+ case SH_DitherDisabledText:
+ ret = 0;
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+ ret = 0;
+ break;
+#ifndef QT_NO_TABWIDGET
+ case SH_TabWidget_DefaultTabPosition:
+ ret = QTabWidget::South;
+ break;
+#endif
+ case SH_ToolBar_Movable:
+ ret = false;
+ break;
+ case SH_ScrollBar_ContextMenu:
+ ret = false;
+ break;
+ case SH_MenuBar_AltKeyNavigation:
+ ret = false;
+ break;
+ case SH_RequestSoftwareInputPanel:
+ ret = RSIP_OnMouseClick;
+ break;
+ default:
+ ret = QWindowsStyle::styleHint(hint, opt, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+QPixmap QWindowsMobileStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+ switch (sp) {
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ case SP_ToolBarHorizontalExtensionButton: {
+ QPixmap pixmap = QCommonStyle::standardPixmap(sp, option, widget);
+ if (d->doubleControls)
+ return pixmap.scaledToHeight(pixmap.height() * 2);
+ else
+ return pixmap;
+ }
+ case SP_TitleBarMaxButton:
+ case SP_TitleBarCloseButton:
+ case SP_TitleBarNormalButton:
+ case SP_TitleBarMinButton: {
+ QImage image;
+ switch (sp) {
+ case SP_TitleBarMaxButton:
+ image = d->imageMaximize;
+ break;
+ case SP_TitleBarCloseButton:
+ image = d->imageClose;
+ break;
+ case SP_TitleBarNormalButton:
+ image = d->imageNormalize;
+ break;
+ case SP_TitleBarMinButton:
+ image = d->imageMinimize;
+ break;
+ default:
+ break;
+ }
+ if (option) {
+ image.setColor(0, option->palette.shadow().color().rgba());
+ image.setColor(1, option->palette.highlight().color().rgba());
+ image.setColor(2, option->palette.highlight().color().lighter(150).rgba());
+ image.setColor(3, option->palette.highlightedText().color().rgba());
+ }
+
+ return QPixmap::fromImage(image);
+ }
+
+#endif
+ default:
+ return QWindowsStyle::standardPixmap(sp, option, widget);
+ }
+}
+
+QPixmap QWindowsMobileStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *option) const {
+
+ switch (iconMode) {
+ case QIcon::Selected: {
+#ifdef Q_WS_WINCE_WM
+ if (d_func()->wm65)
+ return pixmap;
+#endif //Q_WS_WINCE_WM
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ int imgh = img.height();
+ int imgw = img.width();
+ for (int y = 0; y < imgh; y += 2) {
+ for (int x = 0; x < imgw; x += 2) {
+ QColor c = option->palette.highlight().color().rgb();
+ c.setAlpha( qAlpha(img.pixel(x, y)));
+ QRgb pixel = c.rgba();
+ img.setPixel(x, y, pixel);
+ }
+ }
+ return QPixmap::fromImage(img);
+ }
+ default:
+ break;
+ }
+ return QWindowsStyle::generatedIconPixmap(iconMode, pixmap, option);
+}
+
+
+bool QWindowsMobileStyle::doubleControls() const {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+
+ return d->doubleControls;
+}
+
+void QWindowsMobileStyle::setDoubleControls(bool doubleControls) {
+
+ QWindowsMobileStylePrivate *d = const_cast<QWindowsMobileStylePrivate*>(d_func());
+
+ d->doubleControls = doubleControls;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWSMOBILE
+
diff --git a/src/widgets/styles/qwindowsmobilestyle.h b/src/widgets/styles/qwindowsmobilestyle.h
new file mode 100644
index 0000000000..2a2a697ca9
--- /dev/null
+++ b/src/widgets/styles/qwindowsmobilestyle.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMOBILESTYLE_H
+#define QWINDOWSMOBILESTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSMOBILE)
+
+class QWindowsMobileStylePrivate;
+
+class Q_GUI_EXPORT QWindowsMobileStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QWindowsMobileStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *option) const;
+
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QPalette &);
+
+ QPalette standardPalette() const;
+
+ bool doubleControls() const;
+
+ void setDoubleControls(bool);
+
+protected:
+ QWindowsMobileStyle(QWindowsMobileStylePrivate &dd);
+
+private:
+ Q_DECLARE_PRIVATE(QWindowsMobileStyle)
+};
+
+#endif // QT_NO_STYLE_WINDOWSMOBILE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QWINDOWSMOBILESTYLE_H
diff --git a/src/widgets/styles/qwindowsmobilestyle_p.h b/src/widgets/styles/qwindowsmobilestyle_p.h
new file mode 100644
index 0000000000..32ebe911ef
--- /dev/null
+++ b/src/widgets/styles/qwindowsmobilestyle_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMOBILESTYLE_P_H
+#define QWINDOWSMOBILESTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsmobilestyle.h"
+#include "qwindowsstyle_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_STYLE_WINDOWSMOBILE
+
+class QStyleOptionTab;
+class QStyleOptionSlider;
+class QStyleOptionViewItemV4;
+
+class QWindowsMobileStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsMobileStyle)
+public:
+ QWindowsMobileStylePrivate();
+ bool doubleControls;
+ bool smartphone;
+#ifdef Q_WS_WINCE_WM
+ bool wm65;
+#endif
+
+ QImage imageRadioButton;
+ QImage imageRadioButtonChecked;
+ QImage imageRadioButtonHighlighted;
+ QImage imageChecked;
+ QImage imageCheckedBold;
+ QImage imageArrowDown;
+ QImage imageArrowUp;
+ QImage imageArrowLeft;
+ QImage imageArrowRight;
+ QImage imageArrowDownBig;
+ QImage imageArrowUpBig;
+ QImage imageArrowLeftBig;
+ QImage imageArrowRightBig;
+ QImage imageClose;
+ QImage imageMaximize;
+ QImage imageNormalize;
+ QImage imageMinimize;
+
+ void setupWindowsMobileStyle65();
+
+#ifdef Q_WS_WINCE_WM
+ //Windows Mobile 6.5 images
+ QImage imageScrollbarHandleUp;
+ QImage imageScrollbarHandleDown;
+ QImage imageScrollbarHandleUpHigh;
+ QImage imageScrollbarHandleDownHigh;
+ QImage imageScrollbarGripUp;
+ QImage imageScrollbarGripDown;
+ QImage imageScrollbarGripMiddle;
+ QImage imageListViewHighlightCornerLeft;
+ QImage imageListViewHighlightCornerRight;
+ QImage imageListViewHighlightMiddle;
+ QImage imageTabEnd;
+ QImage imageTabSelectedEnd;
+ QImage imageTabSelectedBegin;
+ QImage imageTabMiddle;
+
+ QColor currentTintHigh;
+ QColor currentTintButton;
+
+ void tintImagesHigh(QColor color);
+ void tintImagesButton(QColor color);
+ void tintListViewHighlight(QColor color);
+
+#endif //Q_WS_WINCE_WM
+
+ void drawScrollbarHandleUp(QPainter *p, QStyleOptionSlider *opt, bool completeFrame = false, bool secondScrollBar = false);
+ void drawScrollbarHandleDown(QPainter *p, QStyleOptionSlider *opt, bool completeFrame = false, bool secondScrollBar = false);
+ void drawScrollbarGroove(QPainter *p, const QStyleOptionSlider *opt);
+ void drawScrollbarGrip(QPainter *p, QStyleOptionSlider *newScrollbar, const QStyleOptionComplex *option, bool drawCompleteFrame);
+ void drawTabBarTab(QPainter *p, const QStyleOptionTab *tab);
+ void drawPanelItemViewSelected(QPainter *painter, const QStyleOptionViewItemV4 *option, QRect rect = QRect());
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWSMOBILE
+#endif //QWINDOWSMOBILESTYLE_P_H
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
new file mode 100644
index 0000000000..c0992733f8
--- /dev/null
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -0,0 +1,3390 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsstyle.h"
+#include "qwindowsstyle_p.h"
+
+#if !defined(QT_NO_STYLE_WINDOWS) || defined(QT_PLUGIN)
+
+#include <private/qsystemlibrary_p.h>
+#include "qapplication.h"
+#include "qbitmap.h"
+#include "qdrawutil.h" // for now
+#include "qevent.h"
+#include "qmenu.h"
+#include "qmenubar.h"
+#include <private/qmenubar_p.h>
+#include "qpaintengine.h"
+#include "qpainter.h"
+#include "qprogressbar.h"
+#include "qrubberband.h"
+#include "qstyleoption.h"
+#include "qtabbar.h"
+#include "qwidget.h"
+#include "qdebug.h"
+#include "qmainwindow.h"
+#include "qfile.h"
+#include "qtextstream.h"
+#include "qpixmapcache.h"
+#include "qwizard.h"
+#include "qlistview.h"
+#include <private/qmath_p.h>
+#include <qmath.h>
+
+#ifdef Q_WS_X11
+#include "qfileinfo.h"
+#include "qdir.h"
+#include <private/qt_x11_p.h>
+#endif
+
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_WS_WIN)
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qt_windows.h"
+QT_END_INCLUDE_NAMESPACE
+# ifndef COLOR_GRADIENTACTIVECAPTION
+# define COLOR_GRADIENTACTIVECAPTION 27
+# endif
+# ifndef COLOR_GRADIENTINACTIVECAPTION
+# define COLOR_GRADIENTINACTIVECAPTION 28
+# endif
+
+
+typedef struct
+{
+ DWORD cbSize;
+ HICON hIcon;
+ int iSysImageIndex;
+ int iIcon;
+ WCHAR szPath[MAX_PATH];
+} QSHSTOCKICONINFO;
+
+#define _SHGFI_SMALLICON 0x000000001
+#define _SHGFI_LARGEICON 0x000000000
+#define _SHGFI_ICON 0x000000100
+#define _SIID_SHIELD 77
+
+typedef HRESULT (WINAPI *PtrSHGetStockIconInfo)(int siid, int uFlags, QSHSTOCKICONINFO *psii);
+static PtrSHGetStockIconInfo pSHGetStockIconInfo = 0;
+
+#endif //Q_WS_WIN
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <limits.h>
+QT_END_INCLUDE_NAMESPACE
+
+enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
+
+/*
+ \internal
+*/
+QWindowsStylePrivate::QWindowsStylePrivate()
+ : alt_down(false), menuBarTimer(0), animationFps(10), animateTimer(0), animateStep(0)
+{
+#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ QSystemLibrary shellLib(QLatin1String("shell32"));
+ pSHGetStockIconInfo = (PtrSHGetStockIconInfo)shellLib.resolve("SHGetStockIconInfo");
+ }
+#endif
+ startTime.start();
+}
+
+// Returns true if the toplevel parent of \a widget has seen the Alt-key
+bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const
+{
+ widget = widget->window();
+ return seenAlt.contains(widget);
+}
+
+/*!
+ \reimp
+*/
+void QWindowsStyle::timerEvent(QTimerEvent *event)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QWindowsStyle);
+ if (event->timerId() == d->animateTimer) {
+ Q_ASSERT(d->animationFps> 0);
+ d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
+ foreach (QProgressBar *bar, d->bars) {
+ if ((bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ }
+#endif // QT_NO_PROGRESSBAR
+ event->ignore();
+}
+
+/*!
+ \reimp
+*/
+bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
+{
+ // Records Alt- and Focus events
+ if (!o->isWidgetType())
+ return QObject::eventFilter(o, e);
+
+ QWidget *widget = qobject_cast<QWidget*>(o);
+ Q_D(QWindowsStyle);
+ switch(e->type()) {
+ case QEvent::KeyPress:
+ if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) {
+ widget = widget->window();
+
+ // Alt has been pressed - find all widgets that care
+ QList<QWidget *> l = widget->findChildren<QWidget *>();
+ for (int pos=0 ; pos < l.size() ; ++pos) {
+ QWidget *w = l.at(pos);
+ if (w->isWindow() || !w->isVisible() ||
+ w->style()->styleHint(SH_UnderlineShortcut, 0, w))
+ l.removeAt(pos);
+ }
+ // Update states before repainting
+ d->seenAlt.append(widget);
+ d->alt_down = true;
+
+ // Repaint all relevant widgets
+ for (int pos = 0; pos < l.size(); ++pos)
+ l.at(pos)->update();
+ }
+ break;
+ case QEvent::KeyRelease:
+ if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) {
+ widget = widget->window();
+
+ // Update state and repaint the menu bars.
+ d->alt_down = false;
+#ifndef QT_NO_MENUBAR
+ QList<QMenuBar *> l = widget->findChildren<QMenuBar *>();
+ for (int i = 0; i < l.size(); ++i)
+ l.at(i)->update();
+#endif
+ }
+ break;
+ case QEvent::Close:
+ // Reset widget when closing
+ d->seenAlt.removeAll(widget);
+ d->seenAlt.removeAll(widget->window());
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case QEvent::StyleChange:
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
+ if (!d->bars.contains(bar)) {
+ d->bars << bar;
+ if (d->bars.size() == 1) {
+ Q_ASSERT(d->animationFps> 0);
+ d->animateTimer = startTimer(1000 / d->animationFps);
+ }
+ }
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ // reinterpret_cast because there is no type info when getting
+ // the destroy event. We know that it is a QProgressBar.
+ if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
+ d->bars.removeAll(bar);
+ if (d->bars.isEmpty() && d->animateTimer) {
+ killTimer(d->animateTimer);
+ d->animateTimer = 0;
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ default:
+ break;
+ }
+ return QCommonStyle::eventFilter(o, e);
+}
+
+/*!
+ \class QWindowsStyle
+ \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel.
+
+ \ingroup appearance
+
+ This style is Qt's default GUI style on Windows.
+
+ \img qwindowsstyle.png
+ \sa QWindowsXPStyle, QMacStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QWindowsStyle object.
+*/
+QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate)
+{
+}
+
+/*!
+ \internal
+
+ Constructs a QWindowsStyle object.
+*/
+QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd)
+{
+}
+
+
+/*! Destroys the QWindowsStyle object. */
+QWindowsStyle::~QWindowsStyle()
+{
+}
+
+#ifdef Q_WS_WIN
+static inline QRgb colorref2qrgb(COLORREF col)
+{
+ return qRgb(GetRValue(col), GetGValue(col), GetBValue(col));
+}
+#endif
+
+/*! \reimp */
+void QWindowsStyle::polish(QApplication *app)
+{
+ QCommonStyle::polish(app);
+ QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
+ // We only need the overhead when shortcuts are sometimes hidden
+ if (!proxy()->styleHint(SH_UnderlineShortcut, 0) && app)
+ app->installEventFilter(this);
+
+ d->activeCaptionColor = app->palette().highlight().color();
+ d->activeGradientCaptionColor = app->palette().highlight() .color();
+ d->inactiveCaptionColor = app->palette().dark().color();
+ d->inactiveGradientCaptionColor = app->palette().dark().color();
+ d->inactiveCaptionText = app->palette().background().color();
+
+#if defined(Q_WS_WIN) //fetch native title bar colors
+ if(app->desktopSettingsAware()){
+ DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
+ DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
+ DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION);
+ DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
+ DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
+ d->activeCaptionColor = colorref2qrgb(activeCaption);
+ d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption);
+ d->inactiveCaptionColor = colorref2qrgb(inactiveCaption);
+ d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption);
+ d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText);
+ }
+#endif
+}
+
+/*! \reimp */
+void QWindowsStyle::unpolish(QApplication *app)
+{
+ QCommonStyle::unpolish(app);
+ app->removeEventFilter(this);
+}
+
+/*! \reimp */
+void QWindowsStyle::polish(QWidget *widget)
+{
+ QCommonStyle::polish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+}
+
+/*! \reimp */
+void QWindowsStyle::unpolish(QWidget *widget)
+{
+ QCommonStyle::unpolish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (QProgressBar *bar=qobject_cast<QProgressBar *>(widget)) {
+ Q_D(QWindowsStyle);
+ widget->removeEventFilter(this);
+ d->bars.removeAll(bar);
+ }
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QWindowsStyle::polish(QPalette &pal)
+{
+ QCommonStyle::polish(pal);
+}
+
+/*!
+ \reimp
+*/
+int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
+{
+ int ret;
+
+ switch (pm) {
+ case PM_ButtonDefaultIndicator:
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ ret = 1;
+ break;
+#ifndef QT_NO_TABBAR
+ case PM_TabBarTabShiftHorizontal:
+ ret = 0;
+ break;
+ case PM_TabBarTabShiftVertical:
+ ret = 2;
+ break;
+#endif
+ case PM_MaximumDragDistance:
+#if defined(Q_WS_WIN)
+ {
+ HDC hdcScreen = GetDC(0);
+ int dpi = GetDeviceCaps(hdcScreen, LOGPIXELSX);
+ ReleaseDC(0, hdcScreen);
+ ret = (int)(dpi * 1.375);
+ }
+#else
+ ret = 60;
+#endif
+ break;
+
+#ifndef QT_NO_SLIDER
+ case PM_SliderLength:
+ ret = int(QStyleHelper::dpiScaled(11.));
+ break;
+
+ // Returns the number of pixels to use for the business part of the
+ // slider (i.e., the non-tickmark portion). The remaining space is shared
+ // equally between the tickmark regions.
+ case PM_SliderControlThickness:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
+ int ticks = sl->tickPosition;
+ int n = 0;
+ if (ticks & QSlider::TicksAbove)
+ ++n;
+ if (ticks & QSlider::TicksBelow)
+ ++n;
+ if (!n) {
+ ret = space;
+ break;
+ }
+
+ int thick = 6; // Magic constant to get 5 + 16 + 5
+ if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
+ thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;
+
+ space -= thick;
+ if (space > 0)
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ } else {
+ ret = 0;
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_MENU
+ case PM_MenuBarHMargin:
+ ret = 0;
+ break;
+
+ case PM_MenuBarVMargin:
+ ret = 0;
+ break;
+
+ case PM_MenuBarPanelWidth:
+ ret = 0;
+ break;
+
+ case PM_SmallIconSize:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+
+ case PM_LargeIconSize:
+ ret = int(QStyleHelper::dpiScaled(32.));
+ break;
+
+ case PM_IconViewIconSize:
+ ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
+ break;
+
+ case PM_DockWidgetTitleMargin:
+ ret = int(QStyleHelper::dpiScaled(2.));
+ break;
+ case PM_DockWidgetTitleBarButtonMargin:
+ ret = int(QStyleHelper::dpiScaled(4.));
+ break;
+#if defined(Q_WS_WIN)
+ case PM_DockWidgetFrameWidth:
+#if defined(Q_OS_WINCE)
+ ret = GetSystemMetrics(SM_CXDLGFRAME);
+#else
+ ret = GetSystemMetrics(SM_CXFRAME);
+#endif
+ break;
+#else
+ case PM_DockWidgetFrameWidth:
+ ret = 4;
+ break;
+#endif // Q_WS_WIN
+ break;
+
+#endif // QT_NO_MENU
+
+
+#if defined(Q_WS_WIN)
+ case PM_TitleBarHeight:
+#ifdef QT3_SUPPORT
+ // qt3 dockwindow height should be equal to tool windows
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ ret = GetSystemMetrics(SM_CYSMCAPTION) - 1;
+ } else
+#endif
+ if (widget && (widget->windowType() == Qt::Tool)) {
+ // MS always use one less than they say
+#if defined(Q_OS_WINCE)
+ ret = GetSystemMetrics(SM_CYCAPTION) - 1;
+#else
+ ret = GetSystemMetrics(SM_CYSMCAPTION) - 1;
+#endif
+ } else {
+ ret = GetSystemMetrics(SM_CYCAPTION) - 1;
+ }
+
+ break;
+
+ case PM_ScrollBarExtent:
+ {
+#ifndef Q_OS_WINCE
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+ if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
+ ret = qMax(ncm.iScrollHeight, ncm.iScrollWidth);
+ else
+#endif
+ ret = QCommonStyle::pixelMetric(pm, opt, widget);
+ }
+ break;
+#endif // Q_WS_WIN
+
+ case PM_SplitterWidth:
+ ret = qMax(4, QApplication::globalStrut().width());
+ break;
+
+#if defined(Q_WS_WIN)
+ case PM_MdiSubWindowFrameWidth:
+#if defined(Q_OS_WINCE)
+ ret = GetSystemMetrics(SM_CYDLGFRAME);
+#else
+ ret = GetSystemMetrics(SM_CYFRAME);
+#endif
+ break;
+ case PM_TextCursorWidth: {
+ DWORD caretWidth = 1;
+#if defined(SPI_GETCARETWIDTH)
+ SystemParametersInfo(SPI_GETCARETWIDTH, 0, &caretWidth, 0);
+#endif
+ ret = (int)caretWidth;
+ break; }
+#endif
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 0;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = int(QStyleHelper::dpiScaled(10.));
+ break;
+ default:
+ ret = QCommonStyle::pixelMetric(pm, opt, widget);
+ break;
+ }
+
+ return ret;
+}
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+
+/* XPM */
+static const char * const qt_menu_xpm[] = {
+"16 16 72 1",
+" c None",
+". c #65AF36",
+"+ c #66B036",
+"@ c #77B94C",
+"# c #A7D28C",
+"$ c #BADBA4",
+"% c #A4D088",
+"& c #72B646",
+"* c #9ACB7A",
+"= c #7FBD56",
+"- c #85C05F",
+"; c #F4F9F0",
+"> c #FFFFFF",
+", c #E5F1DC",
+"' c #ECF5E7",
+") c #7ABA50",
+"! c #83BF5C",
+"~ c #AED595",
+"{ c #D7EACA",
+"] c #A9D28D",
+"^ c #BCDDA8",
+"/ c #C4E0B1",
+"( c #81BE59",
+"_ c #D0E7C2",
+": c #D4E9C6",
+"< c #6FB542",
+"[ c #6EB440",
+"} c #88C162",
+"| c #98CA78",
+"1 c #F4F9F1",
+"2 c #8FC56C",
+"3 c #F1F8EC",
+"4 c #E8F3E1",
+"5 c #D4E9C7",
+"6 c #74B748",
+"7 c #80BE59",
+"8 c #73B747",
+"9 c #6DB43F",
+"0 c #CBE4BA",
+"a c #80BD58",
+"b c #6DB33F",
+"c c #FEFFFE",
+"d c #68B138",
+"e c #F9FCF7",
+"f c #91C66F",
+"g c #E8F3E0",
+"h c #DCEDD0",
+"i c #91C66E",
+"j c #A3CF86",
+"k c #C9E3B8",
+"l c #B0D697",
+"m c #E3F0DA",
+"n c #95C873",
+"o c #E6F2DE",
+"p c #9ECD80",
+"q c #BEDEAA",
+"r c #C7E2B6",
+"s c #79BA4F",
+"t c #6EB441",
+"u c #BCDCA7",
+"v c #FAFCF8",
+"w c #F6FAF3",
+"x c #84BF5D",
+"y c #EDF6E7",
+"z c #FAFDF9",
+"A c #88C263",
+"B c #98CA77",
+"C c #CDE5BE",
+"D c #67B037",
+"E c #D9EBCD",
+"F c #6AB23C",
+"G c #77B94D",
+" .++++++++++++++",
+".+++++++++++++++",
+"+++@#$%&+++*=+++",
+"++-;>,>')+!>~+++",
+"++{>]+^>/(_>:~<+",
+"+[>>}+|>123>456+",
+"+7>>8+->>90>~+++",
+"+a>>b+a>c[0>~+++",
+"+de>=+f>g+0>~+++",
+"++h>i+j>k+0>~+++",
+"++l>mno>p+q>rst+",
+"++duv>wl++xy>zA+",
+"++++B>Cb++++&D++",
+"+++++0zE++++++++",
+"++++++FG+++++++.",
+"++++++++++++++. "};
+
+static const char * const qt_close_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+".##....##.",
+"..##..##..",
+"...####...",
+"....##....",
+"...####...",
+"..##..##..",
+".##....##.",
+"..........",
+".........."};
+
+static const char * const qt_maximize_xpm[]={
+"10 10 2 1",
+"# c #000000",
+". c None",
+"#########.",
+"#########.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#########.",
+".........."};
+
+static const char * const qt_minimize_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+"..........",
+"..........",
+"..........",
+"..........",
+"..........",
+"..........",
+".#######..",
+".#######..",
+".........."};
+
+static const char * const qt_normalizeup_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"...######.",
+"...######.",
+"...#....#.",
+".######.#.",
+".######.#.",
+".#....###.",
+".#....#...",
+".#....#...",
+".######...",
+".........."};
+
+static const char * const qt_help_xpm[] = {
+"10 10 2 1",
+". c None",
+"# c #000000",
+"..........",
+"..######..",
+".##....##.",
+"......##..",
+".....##...",
+"....##....",
+"....##....",
+"..........",
+"....##....",
+".........."};
+
+static const char * const qt_shade_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+"..........",
+"..........",
+"..........",
+"....#.....",
+"...###....",
+"..#####...",
+".#######..",
+"..........",
+".........."};
+
+static const char * const qt_unshade_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+"..........",
+"..........",
+".#######..",
+"..#####...",
+"...###....",
+"....#.....",
+"..........",
+"..........",
+".........."};
+
+static const char * dock_widget_close_xpm[] = {
+"8 8 2 1",
+"# c #000000",
+". c None",
+"........",
+".##..##.",
+"..####..",
+"...##...",
+"..####..",
+".##..##.",
+"........",
+"........"};
+
+/* XPM */
+static const char * const information_xpm[]={
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaabbbbaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaaabbbbbbaaaaaaaaac....",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+"...caaaaaaabbbbbbbbbaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+/* XPM */
+static const char* const warning_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #ffff00",
+"* c #000000",
+"b c #999999",
+".............***................",
+"............*aaa*...............",
+"...........*aaaaa*b.............",
+"...........*aaaaa*bb............",
+"..........*aaaaaaa*bb...........",
+"..........*aaaaaaa*bb...........",
+".........*aaaaaaaaa*bb..........",
+".........*aaaaaaaaa*bb..........",
+"........*aaaaaaaaaaa*bb.........",
+"........*aaaa***aaaa*bb.........",
+".......*aaaa*****aaaa*bb........",
+".......*aaaa*****aaaa*bb........",
+"......*aaaaa*****aaaaa*bb.......",
+"......*aaaaa*****aaaaa*bb.......",
+".....*aaaaaa*****aaaaaa*bb......",
+".....*aaaaaa*****aaaaaa*bb......",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"...*aaaaaaaaa***aaaaaaaaa*bb....",
+"...*aaaaaaaaaa*aaaaaaaaaa*bb....",
+"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
+"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
+".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
+".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
+"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
+"..*************************bbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
+".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
+/* XPM */
+static const char* const critical_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #999999",
+"* c #ff0000",
+"b c #ffffff",
+"...........********.............",
+".........************...........",
+".......****************.........",
+"......******************........",
+".....********************a......",
+"....**********************a.....",
+"...************************a....",
+"..*******b**********b*******a...",
+"..******bbb********bbb******a...",
+".******bbbbb******bbbbb******a..",
+".*******bbbbb****bbbbb*******a..",
+"*********bbbbb**bbbbb*********a.",
+"**********bbbbbbbbbb**********a.",
+"***********bbbbbbbb***********aa",
+"************bbbbbb************aa",
+"************bbbbbb************aa",
+"***********bbbbbbbb***********aa",
+"**********bbbbbbbbbb**********aa",
+"*********bbbbb**bbbbb*********aa",
+".*******bbbbb****bbbbb*******aa.",
+".******bbbbb******bbbbb******aa.",
+"..******bbb********bbb******aaa.",
+"..*******b**********b*******aa..",
+"...************************aaa..",
+"....**********************aaa...",
+"....a********************aaa....",
+".....a******************aaa.....",
+"......a****************aaa......",
+".......aa************aaaa.......",
+".........aa********aaaaa........",
+"...........aaaaaaaaaaa..........",
+".............aaaaaaa............"};
+/* XPM */
+static const char *const question_xpm[] = {
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaaaaaaaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaabaaabbbbaaaaaaaac....",
+".*aaaaaaaabbaaaabbbbaaaaaaaac...",
+".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
+"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
+"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
+"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
+".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbaaaaaaaaaac***.",
+"...caaaaaaaaaabbaaaaaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+
+#endif //QT_NO_IMAGEFORMAT_XPM
+
+#ifdef Q_OS_WIN
+static QPixmap loadIconFromShell32( int resourceId, int size )
+{
+#ifdef Q_OS_WINCE
+ HMODULE hmod = LoadLibrary(L"ceshell");
+#else
+ HMODULE hmod = QSystemLibrary::load(L"shell32");
+#endif
+ if( hmod ) {
+ HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size, size, 0);
+ if( iconHandle ) {
+ QPixmap iconpixmap = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ return iconpixmap;
+ }
+ }
+ return QPixmap();
+}
+#endif
+
+/*!
+ \reimp
+ */
+QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
+ QPixmap desktopIcon;
+ switch(standardPixmap) {
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ {
+ desktopIcon = loadIconFromShell32(12, 16);
+ break;
+ }
+ case SP_DriveNetIcon:
+ {
+ desktopIcon = loadIconFromShell32(10, 16);
+ break;
+ }
+ case SP_DriveHDIcon:
+ {
+ desktopIcon = loadIconFromShell32(9, 16);
+ break;
+ }
+ case SP_DriveFDIcon:
+ {
+ desktopIcon = loadIconFromShell32(7, 16);
+ break;
+ }
+ case SP_FileIcon:
+ {
+ desktopIcon = loadIconFromShell32(1, 16);
+ break;
+ }
+ case SP_FileLinkIcon:
+ {
+ desktopIcon = loadIconFromShell32(1, 16);
+ QPainter painter(&desktopIcon);
+ QPixmap link = loadIconFromShell32(30, 16);
+ painter.drawPixmap(0, 0, 16, 16, link);
+ break;
+ }
+ case SP_DirLinkIcon:
+ {
+ desktopIcon = loadIconFromShell32(4, 16);
+ QPainter painter(&desktopIcon);
+ QPixmap link = loadIconFromShell32(30, 16);
+ painter.drawPixmap(0, 0, 16, 16, link);
+ break;
+ }
+ case SP_DirClosedIcon:
+ {
+ desktopIcon = loadIconFromShell32(4, 16);
+ break;
+ }
+ case SP_DesktopIcon:
+ {
+ desktopIcon = loadIconFromShell32(35, 16);
+ break;
+ }
+ case SP_ComputerIcon:
+ {
+ desktopIcon = loadIconFromShell32(16, 16);
+ break;
+ }
+ case SP_DirOpenIcon:
+ {
+ desktopIcon = loadIconFromShell32(5, 16);
+ break;
+ }
+ case SP_FileDialogNewFolder:
+ {
+ desktopIcon = loadIconFromShell32(319, 16);
+ break;
+ }
+ case SP_DirHomeIcon:
+ {
+ desktopIcon = loadIconFromShell32(235, 16);
+ break;
+ }
+ case SP_TrashIcon:
+ {
+ desktopIcon = loadIconFromShell32(191, 16);
+ break;
+ }
+ case SP_MessageBoxInformation:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_INFORMATION);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_MessageBoxWarning:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_WARNING);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_MessageBoxCritical:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_ERROR);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_MessageBoxQuestion:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_QUESTION);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_VistaShield:
+ {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based
+ && pSHGetStockIconInfo)
+ {
+ QPixmap pixmap;
+ QSHSTOCKICONINFO iconInfo;
+ memset(&iconInfo, 0, sizeof(iconInfo));
+ iconInfo.cbSize = sizeof(iconInfo);
+ if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_SMALLICON, &iconInfo) == S_OK) {
+ pixmap = QPixmap::fromWinHICON(iconInfo.hIcon);
+ DestroyIcon(iconInfo.hIcon);
+ return pixmap;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (!desktopIcon.isNull()) {
+ return desktopIcon;
+ }
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ switch (standardPixmap) {
+ case SP_TitleBarMenuButton:
+ return QPixmap(qt_menu_xpm);
+ case SP_TitleBarShadeButton:
+ return QPixmap(qt_shade_xpm);
+ case SP_TitleBarUnshadeButton:
+ return QPixmap(qt_unshade_xpm);
+ case SP_TitleBarNormalButton:
+ return QPixmap(qt_normalizeup_xpm);
+ case SP_TitleBarMinButton:
+ return QPixmap(qt_minimize_xpm);
+ case SP_TitleBarMaxButton:
+ return QPixmap(qt_maximize_xpm);
+ case SP_TitleBarCloseButton:
+ return QPixmap(qt_close_xpm);
+ case SP_TitleBarContextHelpButton:
+ return QPixmap(qt_help_xpm);
+ case SP_DockWidgetCloseButton:
+ return QPixmap(dock_widget_close_xpm);
+ case SP_MessageBoxInformation:
+ return QPixmap(information_xpm);
+ case SP_MessageBoxWarning:
+ return QPixmap(warning_xpm);
+ case SP_MessageBoxCritical:
+ return QPixmap(critical_xpm);
+ case SP_MessageBoxQuestion:
+ return QPixmap(question_xpm);
+ default:
+ break;
+ }
+#endif //QT_NO_IMAGEFORMAT_XPM
+ return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+/*! \reimp */
+int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = 0;
+
+ switch (hint) {
+ case SH_EtchDisabledText:
+ case SH_Slider_SnapToValue:
+ case SH_PrintDialog_RightAlignButtons:
+ case SH_FontDialog_SelectAssociatedText:
+ case SH_Menu_AllowActiveAndDisabled:
+ case SH_MenuBar_AltKeyNavigation:
+ case SH_MenuBar_MouseTracking:
+ case SH_Menu_MouseTracking:
+ case SH_ComboBox_ListMouseTracking:
+ case SH_ScrollBar_StopMouseOverSlider:
+ case SH_MainWindow_SpaceBelowMenuBar:
+ ret = 1;
+
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+#ifndef QT_NO_LISTVIEW
+ if (qobject_cast<const QListView*>(widget))
+ ret = 1;
+#endif
+ break;
+ case SH_ItemView_ChangeHighlightOnFocus:
+ ret = 1;
+ break;
+ case SH_ToolBox_SelectedPageTitleBold:
+ ret = 0;
+ break;
+
+#if defined(Q_WS_WIN)
+ case SH_UnderlineShortcut:
+ {
+ ret = 1;
+ BOOL cues = false;
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
+ ret = int(cues);
+ // Do nothing if we always paint underlines
+ Q_D(const QWindowsStyle);
+ if (!ret && widget && d) {
+#ifndef QT_NO_MENUBAR
+ const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget);
+ if (!menuBar && qobject_cast<const QMenu *>(widget)) {
+ QWidget *w = QApplication::activeWindow();
+ if (w && w != widget)
+ menuBar = w->findChild<QMenuBar *>();
+ }
+ // If we paint a menu bar draw underlines if is in the keyboardState
+ if (menuBar) {
+ if (menuBar->d_func()->keyboardState || d->altDown())
+ ret = 1;
+ // Otherwise draw underlines if the toplevel widget has seen an alt-press
+ } else
+#endif // QT_NO_MENUBAR
+ if (d->hasSeenAlt(widget)) {
+ ret = 1;
+ }
+ }
+ break;
+ }
+#endif
+#ifndef QT_NO_RUBBERBAND
+ case SH_RubberBand_Mask:
+ if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ ret = 0;
+ if (rbOpt->shape == QRubberBand::Rectangle) {
+ ret = true;
+ if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
+ mask->region = opt->rect;
+ int size = 1;
+ if (widget && widget->isWindow())
+ size = 4;
+ mask->region -= opt->rect.adjusted(size, size, -size, -size);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_RUBBERBAND
+ case SH_LineEdit_PasswordCharacter:
+ {
+#ifdef Q_WS_WIN
+ if (widget && (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ const QFontMetrics &fm = widget->fontMetrics();
+ if (fm.inFont(QChar(0x25CF)))
+ ret = 0x25CF;
+ else if (fm.inFont(QChar(0x2022)))
+ ret = 0x2022;
+ }
+#endif
+ if (!ret)
+ ret = '*';
+ }
+ break;
+#ifndef QT_NO_WIZARD
+ case SH_WizardStyle:
+ ret = QWizard::ModernStyle;
+ break;
+#endif
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = true;
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+ ret = 0;
+ break;
+ default:
+ ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+/*! \reimp */
+void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox
+ bool doRestore = false;
+
+ switch (pe) {
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarSeparator:
+ {
+ QRect rect = opt->rect;
+ const int margin = 2;
+ QPen oldPen = p->pen();
+ if(opt->state & State_Horizontal){
+ const int offset = rect.width()/2;
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.bottomLeft().x() + offset,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset,
+ rect.topLeft().y() + margin);
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.bottomLeft().x() + offset + 1,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset + 1,
+ rect.topLeft().y() + margin);
+ }
+ else{ //Draw vertical separator
+ const int offset = rect.height()/2;
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset);
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset + 1,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset + 1);
+ }
+ p->setPen(oldPen);
+ }
+ break;
+ case PE_IndicatorToolBarHandle:
+ p->save();
+ p->translate(opt->rect.x(), opt->rect.y());
+ if (opt->state & State_Horizontal) {
+ int x = opt->rect.width() / 2 - 4;
+ if (opt->direction == Qt::RightToLeft)
+ x -= 2;
+ if (opt->rect.height() > 4) {
+ qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
+ opt->palette, false, 1, 0);
+ qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
+ opt->palette, false, 1, 0);
+ }
+ } else {
+ if (opt->rect.width() > 4) {
+ int y = opt->rect.height() / 2 - 4;
+ qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
+ opt->palette, false, 1, 0);
+ qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
+ opt->palette, false, 1, 0);
+ }
+ }
+ p->restore();
+ break;
+
+#endif // QT_NO_TOOLBAR
+ case PE_FrameButtonTool:
+ case PE_PanelButtonTool: {
+ QPen oldPen = p->pen();
+#ifndef QT_NO_DOCKWIDGET
+ if (w && w->inherits("QDockWidgetTitleButton")) {
+ if (const QWidget *dw = w->parentWidget())
+ if (dw->isWindow()){
+ qDrawWinButton(p, opt->rect.adjusted(1, 1, 0, 0), opt->palette, opt->state & (State_Sunken | State_On),
+ &opt->palette.button());
+
+ return;
+ }
+ }
+#endif // QT_NO_DOCKWIDGET
+ QBrush fill;
+ bool stippled;
+ bool panel = (pe == PE_PanelButtonTool);
+ if ((!(opt->state & State_Sunken ))
+ && (!(opt->state & State_Enabled)
+ || !(opt->state & State_MouseOver && opt->state & State_AutoRaise))
+ && (opt->state & State_On)) {
+ fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ stippled = true;
+ } else {
+ fill = opt->palette.brush(QPalette::Button);
+ stippled = false;
+ }
+
+ if (opt->state & (State_Raised | State_Sunken | State_On)) {
+ if (opt->state & State_AutoRaise) {
+ if(opt->state & (State_Enabled | State_Sunken | State_On)){
+ if (panel)
+ qDrawShadePanel(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1, &fill);
+ else
+ qDrawShadeRect(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1);
+ }
+ if (stippled) {
+ p->setPen(opt->palette.button().color());
+ p->drawRect(opt->rect.adjusted(1,1,-2,-2));
+ }
+ } else {
+ qDrawWinButton(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), panel ? &fill : 0);
+ }
+ } else {
+ p->fillRect(opt->rect, fill);
+ }
+ p->setPen(oldPen);
+ break; }
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QBrush fill;
+ State flags = opt->state;
+ QPalette pal = opt->palette;
+ QRect r = opt->rect;
+ if (! (flags & State_Sunken) && (flags & State_On))
+ fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
+ else
+ fill = pal.brush(QPalette::Button);
+
+ if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
+ p->setPen(pal.dark().color());
+ p->setBrush(fill);
+ p->drawRect(r.adjusted(0, 0, -1, -1));
+ } else if (flags & (State_Raised | State_Sunken | State_On | State_Sunken)) {
+ qDrawWinButton(p, r, pal, flags & (State_Sunken | State_On),
+ &fill);
+ } else {
+ p->fillRect(r, fill);
+ }
+ }
+ break;
+ case PE_FrameDefaultButton: {
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.shadow().color());
+ QRect rect = opt->rect;
+ rect.adjust(0, 0, -1, -1);
+ p->drawRect(rect);
+ p->setPen(oldPen);
+ break;
+ }
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft:
+ {
+ if (opt->rect.width() <= 1 || opt->rect.height() <= 1)
+ break;
+ QRect r = opt->rect;
+ int size = qMin(r.height(), r.width());
+ QPixmap pixmap;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-")
+ % QLatin1String(metaObject()->className()), opt, QSize(size, size))
+ % HexString<uint>(pe);
+ if (!QPixmapCache::find(pixmapName, pixmap)) {
+ int border = size/5;
+ int sqsize = 2*(size/2);
+ QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0);
+ QPainter imagePainter(&image);
+
+ QPolygon a;
+ switch (pe) {
+ case PE_IndicatorArrowUp:
+ a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
+ break;
+ case PE_IndicatorArrowDown:
+ a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
+ break;
+ case PE_IndicatorArrowRight:
+ a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
+ break;
+ case PE_IndicatorArrowLeft:
+ a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
+ break;
+ default:
+ break;
+ }
+
+ int bsx = 0;
+ int bsy = 0;
+
+ if (opt->state & State_Sunken) {
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, w);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt, w);
+ }
+
+ QRect bounds = a.boundingRect();
+ int sx = sqsize / 2 - bounds.center().x() - 1;
+ int sy = sqsize / 2 - bounds.center().y() - 1;
+ imagePainter.translate(sx + bsx, sy + bsy);
+ imagePainter.setPen(opt->palette.buttonText().color());
+ imagePainter.setBrush(opt->palette.buttonText());
+
+ if (!(opt->state & State_Enabled)) {
+ imagePainter.translate(1, 1);
+ imagePainter.setBrush(opt->palette.light().color());
+ imagePainter.setPen(opt->palette.light().color());
+ imagePainter.drawPolygon(a);
+ imagePainter.translate(-1, -1);
+ imagePainter.setBrush(opt->palette.mid().color());
+ imagePainter.setPen(opt->palette.mid().color());
+ }
+
+ imagePainter.drawPolygon(a);
+ imagePainter.end();
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(pixmapName, pixmap);
+ }
+ int xOffset = r.x() + (r.width() - size)/2;
+ int yOffset = r.y() + (r.height() - size)/2;
+ p->drawPixmap(xOffset, yOffset, pixmap);
+ }
+ break;
+ case PE_IndicatorCheckBox: {
+ QBrush fill;
+ if (opt->state & State_NoChange)
+ fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern);
+ else if (opt->state & State_Sunken)
+ fill = opt->palette.button();
+ else if (opt->state & State_Enabled)
+ fill = opt->palette.base();
+ else
+ fill = opt->palette.background();
+ p->save();
+ doRestore = true;
+ qDrawWinPanel(p, opt->rect, opt->palette, true, &fill);
+ if (opt->state & State_NoChange)
+ p->setPen(opt->palette.dark().color());
+ else
+ p->setPen(opt->palette.text().color());
+ } // Fall through!
+ case PE_IndicatorViewItemCheck:
+ case PE_Q3CheckListIndicator:
+ if (!doRestore) {
+ p->save();
+ doRestore = true;
+ }
+ if (pe == PE_Q3CheckListIndicator || pe == PE_IndicatorViewItemCheck) {
+ const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
+ p->setPen(itemViewOpt
+ && itemViewOpt->showDecorationSelected
+ && opt->state & State_Selected
+ ? opt->palette.highlightedText().color()
+ : opt->palette.text().color());
+ if (opt->state & State_NoChange)
+ p->setBrush(opt->palette.brush(QPalette::Button));
+ p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11);
+ }
+ if (!(opt->state & State_Off)) {
+ QLineF lines[7];
+ int i, xx, yy;
+ xx = opt->rect.x() + 3;
+ yy = opt->rect.y() + 5;
+ for (i = 0; i < 3; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ ++yy;
+ }
+ yy -= 2;
+ for (i = 3; i < 7; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ --yy;
+ }
+ p->drawLines(lines, 7);
+ }
+ if (doRestore)
+ p->restore();
+ break;
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
+ //### check for d->alt_down
+ if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(SH_UnderlineShortcut, opt))
+ return;
+ QRect r = opt->rect;
+ p->save();
+ p->setBackgroundMode(Qt::TransparentMode);
+ QColor bg_col = fropt->backgroundColor;
+ if (!bg_col.isValid())
+ bg_col = p->background().color();
+ // Create an "XOR" color.
+ QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
+ (bg_col.green() ^ 0xff) & 0xff,
+ (bg_col.blue() ^ 0xff) & 0xff);
+ p->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
+ p->setBrushOrigin(r.topLeft());
+ p->setPen(Qt::NoPen);
+ p->drawRect(r.left(), r.top(), r.width(), 1); // Top
+ p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom
+ p->drawRect(r.left(), r.top(), 1, r.height()); // Left
+ p->drawRect(r.right(), r.top(), 1, r.height()); // Right
+ p->restore();
+ }
+ break;
+ case PE_IndicatorRadioButton:
+ {
+#define PTSARRLEN(x) sizeof(x)/(sizeof(QPoint))
+ static const QPoint pts1[] = { // dark lines
+ QPoint(1, 9), QPoint(1, 8), QPoint(0, 7), QPoint(0, 4), QPoint(1, 3), QPoint(1, 2),
+ QPoint(2, 1), QPoint(3, 1), QPoint(4, 0), QPoint(7, 0), QPoint(8, 1), QPoint(9, 1)
+ };
+ static const QPoint pts2[] = { // black lines
+ QPoint(2, 8), QPoint(1, 7), QPoint(1, 4), QPoint(2, 3), QPoint(2, 2), QPoint(3, 2),
+ QPoint(4, 1), QPoint(7, 1), QPoint(8, 2), QPoint(9, 2)
+ };
+ static const QPoint pts3[] = { // background lines
+ QPoint(2, 9), QPoint(3, 9), QPoint(4, 10), QPoint(7, 10), QPoint(8, 9), QPoint(9, 9),
+ QPoint(9, 8), QPoint(10, 7), QPoint(10, 4), QPoint(9, 3)
+ };
+ static const QPoint pts4[] = { // white lines
+ QPoint(2, 10), QPoint(3, 10), QPoint(4, 11), QPoint(7, 11), QPoint(8, 10),
+ QPoint(9, 10), QPoint(10, 9), QPoint(10, 8), QPoint(11, 7), QPoint(11, 4),
+ QPoint(10, 3), QPoint(10, 2)
+ };
+ static const QPoint pts5[] = { // inner fill
+ QPoint(4, 2), QPoint(7, 2), QPoint(9, 4), QPoint(9, 7), QPoint(7, 9), QPoint(4, 9),
+ QPoint(2, 7), QPoint(2, 4)
+ };
+
+ // make sure the indicator is square
+ QRect ir = opt->rect;
+
+ if (opt->rect.width() < opt->rect.height()) {
+ ir.setTop(opt->rect.top() + (opt->rect.height() - opt->rect.width()) / 2);
+ ir.setHeight(opt->rect.width());
+ } else if (opt->rect.height() < opt->rect.width()) {
+ ir.setLeft(opt->rect.left() + (opt->rect.width() - opt->rect.height()) / 2);
+ ir.setWidth(opt->rect.height());
+ }
+
+ p->save();
+ bool down = opt->state & State_Sunken;
+ bool enabled = opt->state & State_Enabled;
+ bool on = opt->state & State_On;
+ QPolygon a;
+
+ //center when rect is larger than indicator size
+ int xOffset = 0;
+ int yOffset = 0;
+ int indicatorWidth = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth);
+ int indicatorHeight = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth);
+ if (ir.width() > indicatorWidth)
+ xOffset += (ir.width() - indicatorWidth)/2;
+ if (ir.height() > indicatorHeight)
+ yOffset += (ir.height() - indicatorHeight)/2;
+ p->translate(xOffset, yOffset);
+
+ p->translate(ir.x(), ir.y());
+
+ p->setPen(opt->palette.dark().color());
+ p->drawPolyline(pts1, PTSARRLEN(pts1));
+
+ p->setPen(opt->palette.shadow().color());
+ p->drawPolyline(pts2, PTSARRLEN(pts2));
+
+ p->setPen(opt->palette.midlight().color());
+ p->drawPolyline(pts3, PTSARRLEN(pts3));
+
+ p->setPen(opt->palette.light().color());
+ p->drawPolyline(pts4, PTSARRLEN(pts4));
+
+ QColor fillColor = (down || !enabled)
+ ? opt->palette.button().color()
+ : opt->palette.base().color();
+ p->setPen(fillColor);
+ p->setBrush(fillColor) ;
+ p->drawPolygon(pts5, PTSARRLEN(pts5));
+
+ p->translate(-ir.x(), -ir.y()); // restore translate
+
+ if (on) {
+ p->setPen(Qt::NoPen);
+ p->setBrush(opt->palette.text());
+ p->drawRect(ir.x() + 5, ir.y() + 4, 2, 4);
+ p->drawRect(ir.x() + 4, ir.y() + 5, 4, 2);
+ }
+ p->restore();
+ break;
+ }
+#ifndef QT_NO_FRAME
+ case PE_Frame:
+ case PE_FrameMenu:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (frame->lineWidth == 2 || pe == PE_Frame) {
+ QPalette popupPal = frame->palette;
+ if (pe == PE_FrameMenu) {
+ popupPal.setColor(QPalette::Light, frame->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, frame->palette.light().color());
+ }
+ if (pe == PE_Frame && (frame->state & State_Raised))
+ qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken);
+ else if (pe == PE_Frame && (frame->state & State_Sunken))
+ {
+ popupPal.setColor(QPalette::Midlight, frame->palette.background().color());
+ qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
+ }
+ else
+ qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
+ } else {
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ }
+ } else {
+ QPalette popupPal = opt->palette;
+ popupPal.setColor(QPalette::Light, opt->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
+ qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
+ }
+ break;
+#endif // QT_NO_FRAME
+ case PE_IndicatorBranch: {
+ // This is _way_ too similar to the common style.
+ static const int decoration_size = 9;
+ int mid_h = opt->rect.x() + opt->rect.width() / 2;
+ int mid_v = opt->rect.y() + opt->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ if (opt->state & State_Children) {
+ int delta = decoration_size / 2;
+ bef_h -= delta;
+ bef_v -= delta;
+ aft_h += delta;
+ aft_v += delta;
+ p->drawLine(bef_h + 2, bef_v + 4, bef_h + 6, bef_v + 4);
+ if (!(opt->state & State_Open))
+ p->drawLine(bef_h + 4, bef_v + 2, bef_h + 4, bef_v + 6);
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.dark().color());
+ p->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1);
+ p->setPen(oldPen);
+ }
+ QBrush brush(opt->palette.dark().color(), Qt::Dense4Pattern);
+ if (opt->state & State_Item) {
+ if (opt->direction == Qt::RightToLeft)
+ p->fillRect(opt->rect.left(), mid_v, bef_h - opt->rect.left(), 1, brush);
+ else
+ p->fillRect(aft_h, mid_v, opt->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (opt->state & State_Sibling)
+ p->fillRect(mid_h, aft_v, 1, opt->rect.bottom() - aft_v + 1, brush);
+ if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
+ p->fillRect(mid_h, opt->rect.y(), 1, bef_v - opt->rect.y(), brush);
+ break; }
+ case PE_FrameButtonBevel:
+ case PE_PanelButtonBevel: {
+ QBrush fill;
+ bool panel = pe != PE_FrameButtonBevel;
+ p->setBrushOrigin(opt->rect.topLeft());
+ if (!(opt->state & State_Sunken) && (opt->state & State_On))
+ fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = opt->palette.brush(QPalette::Button);
+
+ if (opt->state & (State_Raised | State_On | State_Sunken)) {
+ qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
+ panel ? &fill : 0);
+ } else {
+ if (panel)
+ p->fillRect(opt->rect, fill);
+ else
+ p->drawRect(opt->rect);
+ }
+ break; }
+ case PE_FrameWindow: {
+ QPalette popupPal = opt->palette;
+ popupPal.setColor(QPalette::Light, opt->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
+ qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
+ break; }
+#ifndef QT_NO_DOCKWIDGET
+ case PE_IndicatorDockWidgetResizeHandle: {
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.light().color());
+ if (opt->state & State_Horizontal) {
+ p->drawLine(opt->rect.left(), opt->rect.top(),
+ opt->rect.right(), opt->rect.top());
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(opt->rect.left(), opt->rect.bottom() - 1,
+ opt->rect.right(), opt->rect.bottom() - 1);
+ p->setPen(opt->palette.shadow().color());
+ p->drawLine(opt->rect.left(), opt->rect.bottom(),
+ opt->rect.right(), opt->rect.bottom());
+ } else {
+ p->drawLine(opt->rect.left(), opt->rect.top(),
+ opt->rect.left(), opt->rect.bottom());
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(opt->rect.right() - 1, opt->rect.top(),
+ opt->rect.right() - 1, opt->rect.bottom());
+ p->setPen(opt->palette.shadow().color());
+ p->drawLine(opt->rect.right(), opt->rect.top(),
+ opt->rect.right(), opt->rect.bottom());
+ }
+ p->setPen(oldPen);
+ break; }
+case PE_FrameDockWidget:
+ if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ proxy()->drawPrimitive(QStyle::PE_FrameWindow, opt, p, w);
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+
+ case PE_FrameStatusBarItem:
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 1, 0);
+ break;
+
+#ifndef QT_NO_PROGRESSBAR
+ case PE_IndicatorProgressChunk:
+ {
+ bool vertical = false, inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+
+ int space = 2;
+ int chunksize = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, w) - space;
+ if (!vertical) {
+ if (opt->rect.width() <= chunksize)
+ space = 0;
+
+ if (inverted)
+ p->fillRect(opt->rect.x() + space, opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
+ opt->palette.brush(QPalette::Highlight));
+ else
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
+ opt->palette.brush(QPalette::Highlight));
+ } else {
+ if (opt->rect.height() <= chunksize)
+ space = 0;
+
+ if (inverted)
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height() - space,
+ opt->palette.brush(QPalette::Highlight));
+ else
+ p->fillRect(opt->rect.x(), opt->rect.y() + space, opt->rect.width(), opt->rect.height() - space,
+ opt->palette.brush(QPalette::Highlight));
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+
+ case PE_FrameTabWidget: {
+ qDrawWinButton(p, opt->rect, opt->palette, false, 0);
+ break;
+ }
+ default:
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ }
+}
+
+/*! \reimp */
+void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch (ce) {
+#ifndef QT_NO_RUBBERBAND
+ case CE_RubberBand:
+ if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ // ### workaround for slow general painter path
+ QPixmap tiledPixmap(16, 16);
+ QPainter pixmapPainter(&tiledPixmap);
+ pixmapPainter.setPen(Qt::NoPen);
+ pixmapPainter.setBrush(Qt::Dense4Pattern);
+ pixmapPainter.setBackground(Qt::white);
+ pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
+ pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
+ pixmapPainter.end();
+ tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
+ p->save();
+ QRect r = opt->rect;
+ QStyleHintReturnMask mask;
+ if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
+ p->setClipRegion(mask.region);
+ p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
+ p->restore();
+ return;
+ }
+ break;
+#endif // QT_NO_RUBBERBAND
+
+#if !defined(QT_NO_MENU) && !defined(QT_NO_MAINWINDOW)
+ case CE_MenuBarEmptyArea:
+ if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
+ p->fillRect(opt->rect, opt->palette.button());
+ QPen oldPen = p->pen();
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
+ p->setPen(oldPen);
+ }
+ break;
+#endif
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
+
+ QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill);
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
+ int yoff = y-1 + h / 2;
+ p->setPen(menuitem->palette.dark().color());
+ p->drawLine(x + 2, yoff, x + w - 4, yoff);
+ p->setPen(menuitem->palette.light().color());
+ p->drawLine(x + 2, yoff + 1, x + w - 4, yoff + 1);
+ return;
+ }
+
+ QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
+ if (!menuitem->icon.isNull() && checked) {
+ if (act) {
+ qDrawShadePanel(p, vCheckRect,
+ menuitem->palette, true, 1,
+ &menuitem->palette.brush(QPalette::Button));
+ } else {
+ QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
+ qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &fill);
+ }
+ } else if (!act) {
+ p->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button));
+ }
+
+ // On Windows Style, if we have a checkable item and an icon we
+ // draw the icon recessed to indicate an item is checked. If we
+ // have no icon, we draw a checkmark instead.
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ if (act && !dis && !checked)
+ qDrawShadePanel(p, vCheckRect, menuitem->palette, false, 1,
+ &menuitem->palette.brush(QPalette::Button));
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ p->setPen(menuitem->palette.text().color());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checked) {
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+ newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
+ menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
+ checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
+ menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
+ proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
+ }
+ p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ p->setPen(discol);
+ }
+
+ int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
+ w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
+ QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+ p->setPen(discol);
+ }
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+ p->setPen(discol);
+ }
+ p->drawText(vTextRect, text_flags, s.left(t));
+ p->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ if (act)
+ newMI.palette.setColor(QPalette::ButtonText,
+ newMI.palette.highlightedText().color());
+ proxy()->drawPrimitive(arrow, &newMI, p, widget);
+ }
+
+ }
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_MENUBAR
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ bool active = mbi->state & State_Selected;
+ bool hasFocus = mbi->state & State_HasFocus;
+ bool down = mbi->state & State_Sunken;
+ QStyleOptionMenuItem newMbi = *mbi;
+ p->fillRect(mbi->rect, mbi->palette.brush(QPalette::Button));
+ if (active || hasFocus) {
+ QBrush b = mbi->palette.brush(QPalette::Button);
+ if (active && down)
+ p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1));
+ if (active && hasFocus)
+ qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(),
+ mbi->rect.height(), mbi->palette, active && down, 1, 0, &b);
+ if (active && down) {
+ newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget));
+ p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1));
+ }
+ }
+ QCommonStyle::drawControl(ce, &newMbi, p, widget);
+ }
+ break;
+#endif // QT_NO_MENUBAR
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ bool rtlHorTabs = (tab->direction == Qt::RightToLeft
+ && (tab->shape == QTabBar::RoundedNorth
+ || tab->shape == QTabBar::RoundedSouth));
+ bool selected = tab->state & State_Selected;
+ bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning));
+ bool firstTab = ((!rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::End));
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool previousSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
+ bool nextSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition
+ == QStyleOptionTab::PreviousIsSelected));
+ int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget);
+ bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignRight);
+
+ bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignLeft);
+
+ QColor light = tab->palette.light().color();
+ QColor dark = tab->palette.dark().color();
+ QColor shadow = tab->palette.shadow().color();
+ int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
+ if (selected)
+ borderThinkness /= 2;
+ QRect r2(opt->rect);
+ int x1 = r2.left();
+ int x2 = r2.right();
+ int y1 = r2.top();
+ int y2 = r2.bottom();
+ switch (tab->shape) {
+ default:
+ QCommonStyle::drawControl(ce, tab, p, widget);
+ break;
+ case QTabBar::RoundedNorth: {
+ if (!selected) {
+ y1 += 2;
+ x1 += onlyOne || firstTab ? borderThinkness : 0;
+ x2 -= onlyOne || lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.background());
+ p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.background());
+ }
+ // Left
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ p->drawPoint(x1 + 1, y1 + 1);
+ }
+ // Top
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ p->setPen(light);
+ p->drawLine(beg, y1, end, y1);
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ p->drawPoint(x2 - 1, y1 + 1);
+ p->setPen(dark);
+ p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ }
+ break; }
+ case QTabBar::RoundedSouth: {
+ if (!selected) {
+ y2 -= 2;
+ x1 += firstTab ? borderThinkness : 0;
+ x2 -= lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.background());
+ p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.background());
+ }
+ // Left
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ p->drawPoint(x1 + 1, y2 - 1);
+ }
+ // Bottom
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ p->setPen(shadow);
+ p->drawLine(beg, y2, end, y2);
+ p->setPen(dark);
+ p->drawLine(beg, y2 - 1, end, y2 - 1);
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ p->drawPoint(x2 - 1, y2 - 1);
+ p->setPen(dark);
+ p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ }
+ break; }
+ case QTabBar::RoundedWest: {
+ if (!selected) {
+ x1 += 2;
+ y1 += firstTab ? borderThinkness : 0;
+ y2 -= lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.background());
+ p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.background());
+ }
+ // Top
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
+ p->drawPoint(x1 + 1, y1 + 1);
+ }
+ // Left
+ {
+ int beg = y1 + (previousSelected ? 0 : 2);
+ int end = y2 - (nextSelected ? 0 : 2);
+ p->setPen(light);
+ p->drawLine(x1, beg, x1, end);
+ }
+ // Bottom
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
+ p->drawPoint(x1 + 2, y2 - 1);
+ p->setPen(dark);
+ p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
+ p->drawPoint(x1 + 1, y2 - 1);
+ p->drawPoint(x1 + 2, y2);
+ }
+ break; }
+ case QTabBar::RoundedEast: {
+ if (!selected) {
+ x2 -= 2;
+ y1 += firstTab ? borderThinkness : 0;
+ y2 -= lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.background());
+ p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.background());
+ }
+ // Top
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
+ p->drawPoint(x2 - 1, y1 + 1);
+ }
+ // Right
+ {
+ int beg = y1 + (previousSelected ? 0 : 2);
+ int end = y2 - (nextSelected ? 0 : 2);
+ p->setPen(shadow);
+ p->drawLine(x2, beg, x2, end);
+ p->setPen(dark);
+ p->drawLine(x2 - 1, beg, x2 - 1, end);
+ }
+ // Bottom
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
+ p->drawPoint(x2 - 1, y2 - 1);
+ p->setPen(dark);
+ p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
+ }
+ break; }
+ }
+ }
+ break;
+#endif // QT_NO_TABBAR
+ case CE_ToolBoxTabShape:
+ qDrawShadePanel(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1,
+ &opt->palette.brush(QPalette::Button));
+ break;
+#ifndef QT_NO_SPLITTER
+ case CE_Splitter:
+ p->eraseRect(opt->rect);
+ break;
+#endif // QT_NO_SPLITTER
+#ifndef QT_NO_SCROLLBAR
+ case CE_ScrollBarSubLine:
+ case CE_ScrollBarAddLine: {
+ if ((opt->state & State_Sunken)) {
+ p->setPen(opt->palette.dark().color());
+ p->setBrush(opt->palette.brush(QPalette::Button));
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ } else {
+ QStyleOption buttonOpt = *opt;
+ if (!(buttonOpt.state & State_Sunken))
+ buttonOpt.state |= State_Raised;
+ QPalette pal(opt->palette);
+ pal.setColor(QPalette::Button, opt->palette.light().color());
+ pal.setColor(QPalette::Light, opt->palette.button().color());
+ qDrawWinButton(p, opt->rect, pal, opt->state & (State_Sunken | State_On),
+ &opt->palette.brush(QPalette::Button));
+ }
+ PrimitiveElement arrow;
+ if (opt->state & State_Horizontal) {
+ if (ce == CE_ScrollBarAddLine)
+ arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
+ else
+ arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ } else {
+ if (ce == CE_ScrollBarAddLine)
+ arrow = PE_IndicatorArrowDown;
+ else
+ arrow = PE_IndicatorArrowUp;
+ }
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.rect = opt->rect.adjusted(4, 4, -4, -4);
+ proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
+ break; }
+ case CE_ScrollBarAddPage:
+ case CE_ScrollBarSubPage: {
+ QBrush br;
+ QBrush bg = p->background();
+ Qt::BGMode bg_mode = p->backgroundMode();
+ p->setPen(Qt::NoPen);
+ p->setBackgroundMode(Qt::OpaqueMode);
+
+ if (opt->state & State_Sunken) {
+ br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
+ p->setBackground(opt->palette.dark().color());
+ p->setBrush(br);
+ } else {
+ QPixmap pm = opt->palette.brush(QPalette::Light).texture();
+ br = !pm.isNull() ? QBrush(pm) : QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ p->setBackground(opt->palette.background().color());
+ p->setBrush(br);
+ }
+ p->drawRect(opt->rect);
+ p->setBackground(bg);
+ p->setBackgroundMode(bg_mode);
+ break; }
+ case CE_ScrollBarSlider:
+ if (!(opt->state & State_Enabled)) {
+ QPixmap pm = opt->palette.brush(QPalette::Light).texture();
+ QBrush br = !pm.isNull() ? QBrush(pm) : QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ p->setPen(Qt::NoPen);
+ p->setBrush(br);
+ p->setBackgroundMode(Qt::OpaqueMode);
+ p->drawRect(opt->rect);
+ } else {
+ QStyleOptionButton buttonOpt;
+ buttonOpt.QStyleOption::operator=(*opt);
+ buttonOpt.state = State_Enabled | State_Raised;
+
+ QPalette pal(opt->palette);
+ pal.setColor(QPalette::Button, opt->palette.light().color());
+ pal.setColor(QPalette::Light, opt->palette.button().color());
+ qDrawWinButton(p, opt->rect, pal, false, &opt->palette.brush(QPalette::Button));
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ case CE_HeaderSection: {
+ QBrush fill;
+ if (opt->state & State_On)
+ fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = opt->palette.brush(QPalette::Button);
+
+ if (opt->state & (State_Raised | State_Sunken)) {
+ qDrawWinButton(p, opt->rect, opt->palette, opt->state & State_Sunken, &fill);
+ } else {
+ p->fillRect(opt->rect, fill);
+ }
+ break; }
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ QRect rect = opt->rect;
+
+ bool paintLeftBorder = true;
+ bool paintRightBorder = true;
+ bool paintBottomBorder = true;
+
+ switch (toolbar->toolBarArea){
+ case Qt::BottomToolBarArea :
+ switch(toolbar->positionOfLine){
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintBottomBorder = false;
+ default:
+ break;
+ }
+ case Qt::TopToolBarArea :
+ switch(toolbar->positionWithinLine){
+ case QStyleOptionToolBar::Beginning:
+ paintLeftBorder = false;
+ break;
+ case QStyleOptionToolBar::End:
+ paintRightBorder = false;
+ break;
+ case QStyleOptionToolBar::OnlyOne:
+ paintRightBorder = false;
+ paintLeftBorder = false;
+ default:
+ break;
+ }
+ if(opt->direction == Qt::RightToLeft){ //reverse layout changes the order of Beginning/end
+ bool tmp = paintLeftBorder;
+ paintRightBorder=paintLeftBorder;
+ paintLeftBorder=tmp;
+ }
+ break;
+ case Qt::RightToolBarArea :
+ switch (toolbar->positionOfLine){
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintRightBorder = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ case Qt::LeftToolBarArea :
+ switch (toolbar->positionOfLine){
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintLeftBorder = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ //draw top border
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.topRight().x(),
+ rect.topRight().y());
+
+ if (paintLeftBorder){
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.bottomLeft().x(),
+ rect.bottomLeft().y());
+ }
+
+ if (paintRightBorder){
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.topRight().x(),
+ rect.topRight().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ }
+
+ if (paintBottomBorder){
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.bottomLeft().x(),
+ rect.bottomLeft().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ }
+ }
+ break;
+
+
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QRect rect = pb->rect;
+ if (!rect.isValid())
+ return;
+
+ bool vertical = false;
+ bool inverted = false;
+
+ // Get extra style options if version 2
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
+ if (pb2) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+ QMatrix m;
+ if (vertical) {
+ rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+ QPalette pal2 = pb->palette;
+ // Correct the highlight color if it is the same as the background
+ if (pal2.highlight() == pal2.background())
+ pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
+ QPalette::Highlight));
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ int w = rect.width();
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ Q_D(const QWindowsStyle);
+ const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
+ QStyleOptionProgressBarV2 pbBits = *pb;
+ Q_ASSERT(unit_width >0);
+
+ pbBits.rect = rect;
+ pbBits.palette = pal2;
+
+ int chunkCount = w / unit_width + 1;
+ int step = d->animateStep%chunkCount;
+ int chunksInRow = 5;
+ int myY = pbBits.rect.y();
+ int myHeight = pbBits.rect.height();
+ int chunksToDraw = chunksInRow;
+
+ if(step > chunkCount - 5)chunksToDraw = (chunkCount - step);
+ p->save();
+ p->setClipRect(m.mapRect(QRectF(rect)).toRect());
+
+ int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width : rect.left() + unit_width * step;
+ int x = 0;
+
+ for (int i = 0; i < chunksToDraw ; ++i) {
+ pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
+ pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
+ proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
+ x += reverse ? -unit_width : unit_width;
+ }
+ //Draw wrap-around chunks
+ if( step > chunkCount-5){
+ x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ;
+ x = 0;
+ int chunksToDraw = step - (chunkCount - chunksInRow);
+ for (int i = 0; i < chunksToDraw ; ++i) {
+ pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
+ pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
+ proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
+ x += reverse ? -unit_width : unit_width;
+ }
+ }
+ p->restore(); //restore state
+ }
+ else {
+ QCommonStyle::drawControl(ce, opt, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
+ Q_D(const QWindowsStyle);
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect rect = dwOpt->rect;
+ QRect r = rect;
+
+ if (verticalTitleBar) {
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ p->save();
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ bool floating = false;
+ bool active = dwOpt->state & State_Active;
+ QColor inactiveCaptionTextColor = d->inactiveCaptionText;
+ if (dwOpt->movable) {
+ QColor left, right;
+
+ //Titlebar gradient
+ if (widget && widget->isWindow()) {
+ floating = true;
+ if (active) {
+ left = d->activeCaptionColor;
+ right = d->activeGradientCaptionColor;
+ } else {
+ left = d->inactiveCaptionColor;
+ right = d->inactiveGradientCaptionColor;
+ }
+ QBrush fillBrush(left);
+ if (left != right) {
+ QPoint p1(r.x(), r.top() + r.height()/2);
+ QPoint p2(rect.right(), r.top() + r.height()/2);
+ QLinearGradient lg(p1, p2);
+ lg.setColorAt(0, left);
+ lg.setColorAt(1, right);
+ fillBrush = lg;
+ }
+ p->fillRect(r.adjusted(0, 0, 0, -3), fillBrush);
+ }
+ p->setPen(dwOpt->palette.color(QPalette::Light));
+ if (!widget || !widget->isWindow()) {
+ p->drawLine(r.topLeft(), r.topRight());
+ p->setPen(dwOpt->palette.color(QPalette::Dark));
+ p->drawLine(r.bottomLeft(), r.bottomRight()); }
+ }
+ if (!dwOpt->title.isEmpty()) {
+ QFont oldFont = p->font();
+ if (floating) {
+ QFont font = oldFont;
+ font.setBold(true);
+ p->setFont(font);
+ }
+ QPalette palette = dwOpt->palette;
+ palette.setColor(QPalette::Window, inactiveCaptionTextColor);
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, widget);
+ if (verticalTitleBar) {
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+ }
+ proxy()->drawItemText(p, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
+ dwOpt->state & State_Enabled, dwOpt->title,
+ floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
+ p->setFont(oldFont);
+ }
+ if (verticalTitleBar)
+ p->restore();
+ }
+ return;
+#endif // QT_NO_DOCKWIDGET
+ default:
+ QCommonStyle::drawControl(ce, opt, p, widget);
+ }
+}
+
+/*! \reimp */
+QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
+{
+ QRect r;
+ switch (sr) {
+ case SE_SliderFocusRect:
+ case SE_ToolBoxTabContents:
+ r = visualRect(opt->direction, opt->rect, opt->rect);
+ break;
+ case SE_DockWidgetTitleBarText: {
+ r = QCommonStyle::subElementRect(sr, opt, w);
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+ int m = proxy()->pixelMetric(PM_DockWidgetTitleMargin, opt, w);
+ if (verticalTitleBar) {
+ r.adjust(0, 0, 0, -m);
+ } else {
+ if (opt->direction == Qt::LeftToRight)
+ r.adjust(m, 0, 0, 0);
+ else
+ r.adjust(0, 0, -m, 0);
+ }
+ break;
+ }
+ case SE_ProgressBarContents:
+ r = QCommonStyle::subElementRect(SE_ProgressBarGroove, opt, w);
+ r.adjust(3, 3, -3, -3);
+ break;
+ default:
+ r = QCommonStyle::subElementRect(sr, opt, w);
+ }
+ return r;
+}
+
+#ifdef QT3_SUPPORT
+Q_GLOBAL_STATIC_WITH_ARGS(QBitmap, globalVerticalLine, (1, 129))
+Q_GLOBAL_STATIC_WITH_ARGS(QBitmap, globalHorizontalLine, (128, 1))
+#endif
+
+/*! \reimp */
+void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ QPainter *p, const QWidget *widget) const
+{
+ switch (cc) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ int ticks = slider->tickPosition;
+ QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
+
+ if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
+ int mid = thickness / 2;
+
+ if (ticks & QSlider::TicksAbove)
+ mid += len / 8;
+ if (ticks & QSlider::TicksBelow)
+ mid -= len / 8;
+
+ p->setPen(slider->palette.shadow().color());
+ if (slider->orientation == Qt::Horizontal) {
+ qDrawWinPanel(p, groove.x(), groove.y() + mid - 2,
+ groove.width(), 4, slider->palette, true);
+ p->drawLine(groove.x() + 1, groove.y() + mid - 1,
+ groove.x() + groove.width() - 3, groove.y() + mid - 1);
+ } else {
+ qDrawWinPanel(p, groove.x() + mid - 2, groove.y(),
+ 4, groove.height(), slider->palette, true);
+ p->drawLine(groove.x() + mid - 1, groove.y() + 1,
+ groove.x() + mid - 1, groove.y() + groove.height() - 3);
+ }
+ }
+
+ if (slider->subControls & SC_SliderTickmarks) {
+ QStyleOptionSlider tmpSlider = *slider;
+ tmpSlider.subControls = SC_SliderTickmarks;
+ QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
+ }
+
+ if (slider->subControls & SC_SliderHandle) {
+ // 4444440
+ // 4333310
+ // 4322210
+ // 4322210
+ // 4322210
+ // 4322210
+ // *43210*
+ // **410**
+ // ***0***
+ const QColor c0 = slider->palette.shadow().color();
+ const QColor c1 = slider->palette.dark().color();
+ // const QColor c2 = g.button();
+ const QColor c3 = slider->palette.midlight().color();
+ const QColor c4 = slider->palette.light().color();
+ QBrush handleBrush;
+
+ if (slider->state & State_Enabled) {
+ handleBrush = slider->palette.color(QPalette::Button);
+ } else {
+ handleBrush = QBrush(slider->palette.color(QPalette::Button),
+ Qt::Dense4Pattern);
+ }
+
+
+ int x = handle.x(), y = handle.y(),
+ wi = handle.width(), he = handle.height();
+
+ int x1 = x;
+ int x2 = x+wi-1;
+ int y1 = y;
+ int y2 = y+he-1;
+
+ Qt::Orientation orient = slider->orientation;
+ bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
+ bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+
+ if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
+ Qt::BGMode oldMode = p->backgroundMode();
+ p->setBackgroundMode(Qt::OpaqueMode);
+ qDrawWinButton(p, QRect(x, y, wi, he), slider->palette, false,
+ &handleBrush);
+ p->setBackgroundMode(oldMode);
+ return;
+ }
+
+ QSliderDirection dir;
+
+ if (orient == Qt::Horizontal)
+ if (tickAbove)
+ dir = SlUp;
+ else
+ dir = SlDown;
+ else
+ if (tickAbove)
+ dir = SlLeft;
+ else
+ dir = SlRight;
+
+ QPolygon a;
+
+ int d = 0;
+ switch (dir) {
+ case SlUp:
+ y1 = y1 + wi/2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d);
+ break;
+ case SlDown:
+ y2 = y2 - wi/2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1);
+ break;
+ case SlLeft:
+ d = (he + 1) / 2 - 1;
+ x1 = x1 + he/2;
+ a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1);
+ break;
+ case SlRight:
+ d = (he + 1) / 2 - 1;
+ x2 = x2 - he/2;
+ a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1);
+ break;
+ }
+
+ QBrush oldBrush = p->brush();
+ p->setPen(Qt::NoPen);
+ p->setBrush(handleBrush);
+ Qt::BGMode oldMode = p->backgroundMode();
+ p->setBackgroundMode(Qt::OpaqueMode);
+ p->drawRect(x1, y1, x2-x1+1, y2-y1+1);
+ p->drawPolygon(a);
+ p->setBrush(oldBrush);
+ p->setBackgroundMode(oldMode);
+
+ if (dir != SlUp) {
+ p->setPen(c4);
+ p->drawLine(x1, y1, x2, y1);
+ p->setPen(c3);
+ p->drawLine(x1, y1+1, x2, y1+1);
+ }
+ if (dir != SlLeft) {
+ p->setPen(c3);
+ p->drawLine(x1+1, y1+1, x1+1, y2);
+ p->setPen(c4);
+ p->drawLine(x1, y1, x1, y2);
+ }
+ if (dir != SlRight) {
+ p->setPen(c0);
+ p->drawLine(x2, y1, x2, y2);
+ p->setPen(c1);
+ p->drawLine(x2-1, y1+1, x2-1, y2-1);
+ }
+ if (dir != SlDown) {
+ p->setPen(c0);
+ p->drawLine(x1, y2, x2, y2);
+ p->setPen(c1);
+ p->drawLine(x1+1, y2-1, x2-1, y2-1);
+ }
+
+ switch (dir) {
+ case SlUp:
+ p->setPen(c4);
+ p->drawLine(x1, y1, x1+d, y1-d);
+ p->setPen(c0);
+ d = wi - d - 1;
+ p->drawLine(x2, y1, x2-d, y1-d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x1+1, y1, x1+1+d, y1-d);
+ p->setPen(c1);
+ p->drawLine(x2-1, y1, x2-1-d, y1-d);
+ break;
+ case SlDown:
+ p->setPen(c4);
+ p->drawLine(x1, y2, x1+d, y2+d);
+ p->setPen(c0);
+ d = wi - d - 1;
+ p->drawLine(x2, y2, x2-d, y2+d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x1+1, y2, x1+1+d, y2+d);
+ p->setPen(c1);
+ p->drawLine(x2-1, y2, x2-1-d, y2+d);
+ break;
+ case SlLeft:
+ p->setPen(c4);
+ p->drawLine(x1, y1, x1-d, y1+d);
+ p->setPen(c0);
+ d = he - d - 1;
+ p->drawLine(x1, y2, x1-d, y2-d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x1, y1+1, x1-d, y1+1+d);
+ p->setPen(c1);
+ p->drawLine(x1, y2-1, x1-d, y2-1-d);
+ break;
+ case SlRight:
+ p->setPen(c4);
+ p->drawLine(x2, y1, x2+d, y1+d);
+ p->setPen(c0);
+ d = he - d - 1;
+ p->drawLine(x2, y2, x2+d, y2-d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x2, y1+1, x2+d, y1+1+d);
+ p->setPen(c1);
+ p->drawLine(x2, y2-1, x2+d, y2-1-d);
+ break;
+ }
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ if (scrollbar->minimum == scrollbar->maximum)
+ newScrollbar.state &= ~State_Enabled; //do not draw the slider.
+ QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifdef QT3_SUPPORT
+ case CC_Q3ListView:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ int i;
+ if (lv->subControls & SC_Q3ListView)
+ QCommonStyle::drawComplexControl(cc, lv, p, widget);
+ if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
+ if (lv->items.isEmpty())
+ break;
+ QStyleOptionQ3ListViewItem item = lv->items.at(0);
+ int y = lv->rect.y();
+ int c;
+ int dotoffset = 0;
+ QPolygon dotlines;
+ if ((lv->activeSubControls & SC_All) && (lv->subControls & SC_Q3ListViewExpand)) {
+ c = 2;
+ dotlines.resize(2);
+ dotlines[0] = QPoint(lv->rect.right(), lv->rect.top());
+ dotlines[1] = QPoint(lv->rect.right(), lv->rect.bottom());
+ } else {
+ int linetop = 0, linebot = 0;
+ // each branch needs at most two lines, ie. four end points
+ dotoffset = (item.itemY + item.height - y) % 2;
+ dotlines.resize(item.childCount * 4);
+ c = 0;
+
+ // skip the stuff above the exposed rectangle
+ for (i = 1; i < lv->items.size(); ++i) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.height + y > 0)
+ break;
+ y += child.totalHeight;
+ }
+ int bx = lv->rect.width() / 2;
+
+ // paint stuff in the magical area
+ while (i < lv->items.size() && y < lv->rect.height()) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.features & QStyleOptionQ3ListViewItem::Visible) {
+ int lh;
+ if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
+ lh = child.height;
+ else
+ lh = p->fontMetrics().height() + 2 * lv->itemMargin;
+ lh = qMax(lh, QApplication::globalStrut().height());
+ if (lh % 2 > 0)
+ ++lh;
+ linebot = y + lh / 2;
+ if (child.features & QStyleOptionQ3ListViewItem::Expandable
+ || (child.childCount > 0 && child.height > 0)) {
+ // needs a box
+ p->setPen(lv->palette.mid().color());
+ p->drawRect(bx - 4, linebot - 4, 8, 8);
+ // plus or minus
+ p->setPen(lv->palette.text().color());
+ p->drawLine(bx - 2, linebot, bx + 2, linebot);
+ if (!(child.state & State_Open))
+ p->drawLine(bx, linebot - 2, bx, linebot + 2);
+ // dotlinery
+ p->setPen(lv->palette.mid().color());
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot - 4);
+ dotlines[c++] = QPoint(bx + 5, linebot);
+ dotlines[c++] = QPoint(lv->rect.width(), linebot);
+ linetop = linebot + 5;
+ } else {
+ // just dotlinery
+ dotlines[c++] = QPoint(bx+1, linebot -1);
+ dotlines[c++] = QPoint(lv->rect.width(), linebot -1);
+ }
+ y += child.totalHeight;
+ }
+ ++i;
+ }
+
+ // Expand line height to edge of rectangle if there's any
+ // visible child below
+ while (i < lv->items.size() && lv->items.at(i).height <= 0)
+ ++i;
+ if (i < lv->items.size())
+ linebot = lv->rect.height();
+
+ if (linetop < linebot) {
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot);
+ }
+ }
+ p->setPen(lv->palette.text().color());
+ QBitmap *verticalLine = globalVerticalLine();
+ QBitmap *horizontalLine = globalHorizontalLine();
+ static bool isInit = false;
+ if (!isInit) {
+ isInit = true;
+ // make 128*1 and 1*128 bitmaps that can be used for
+ // drawing the right sort of lines.
+ verticalLine->clear();
+ horizontalLine->clear();
+ QPolygon a(64);
+ QPainter p;
+ p.begin(verticalLine);
+ for(i = 0; i < 64; ++i)
+ a.setPoint(i, 0, i * 2 + 1);
+ p.setPen(Qt::color1);
+ p.drawPoints(a);
+ p.end();
+ QApplication::flush();
+ verticalLine->setMask(*verticalLine);
+ p.begin(horizontalLine);
+ for(i = 0; i < 64; ++i)
+ a.setPoint(i, i * 2 + 1, 0);
+ p.setPen(Qt::color1);
+ p.drawPoints(a);
+ p.end();
+ QApplication::flush();
+ horizontalLine->setMask(*horizontalLine);
+ }
+
+ int line; // index into dotlines
+ if (lv->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
+ // assumptions here: lines are horizontal or vertical.
+ // lines always start with the numerically lowest
+ // coordinate.
+
+ // point ... relevant coordinate of current point
+ // end ..... same coordinate of the end of the current line
+ // other ... the other coordinate of the current point/line
+ if (dotlines[line].y() == dotlines[line+1].y()) {
+ int end = dotlines[line + 1].x();
+ int point = dotlines[line].x();
+ int other = dotlines[line].y();
+ while (point < end) {
+ int i = 128;
+ if (i + point > end)
+ i = end-point;
+ p->drawPixmap(point, other, *horizontalLine, 0, 0, i, 1);
+ point += i;
+ }
+ } else {
+ int end = dotlines[line + 1].y();
+ int point = dotlines[line].y();
+ int other = dotlines[line].x();
+ int pixmapoffset = ((point & 1) != dotoffset) ? 1 : 0;
+ while(point < end) {
+ int i = 128;
+ if (i + point > end)
+ i = end-point;
+ p->drawPixmap(other, point, *verticalLine, 0, pixmapoffset, 1, i);
+ point += i;
+ }
+ }
+ }
+ }
+ }
+ break;
+#endif // QT3_SUPPORT
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ if ((cmb->subControls & SC_ComboBoxFrame)) {
+ if (cmb->frame) {
+ QPalette shadePal = opt->palette;
+ shadePal.setColor(QPalette::Midlight, shadePal.button().color());
+ qDrawWinPanel(p, opt->rect, shadePal, true, &editBrush);
+ }
+ else {
+ p->fillRect(opt->rect, editBrush);
+ }
+ }
+ if (cmb->subControls & SC_ComboBoxArrow) {
+ State flags = State_None;
+
+ QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
+ bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow
+ && cmb->state & State_Sunken;
+ if (sunkenArrow) {
+ p->setPen(cmb->palette.dark().color());
+ p->setBrush(cmb->palette.brush(QPalette::Button));
+ p->drawRect(ar.adjusted(0,0,-1,-1));
+ } else {
+ // Make qDrawWinButton use the right colors for drawing the shade of the button
+ QPalette pal(cmb->palette);
+ pal.setColor(QPalette::Button, cmb->palette.light().color());
+ pal.setColor(QPalette::Light, cmb->palette.button().color());
+ qDrawWinButton(p, ar, pal, false,
+ &cmb->palette.brush(QPalette::Button));
+ }
+
+ ar.adjust(2, 2, -2, -2);
+ if (opt->state & State_Enabled)
+ flags |= State_Enabled;
+ if (opt->state & State_HasFocus)
+ flags |= State_HasFocus;
+
+ if (sunkenArrow)
+ flags |= State_Sunken;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar.adjusted(1, 1, -1, -1);
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
+ }
+
+ if (cmb->subControls & SC_ComboBoxEditField) {
+ QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
+ if (cmb->state & State_HasFocus && !cmb->editable)
+ p->fillRect(re.x(), re.y(), re.width(), re.height(),
+ cmb->palette.brush(QPalette::Highlight));
+
+ if (cmb->state & State_HasFocus) {
+ p->setPen(cmb->palette.highlightedText().color());
+ p->setBackground(cmb->palette.highlight());
+
+ } else {
+ p->setPen(cmb->palette.text().color());
+ p->setBackground(cmb->palette.background());
+ }
+
+ if (cmb->state & State_HasFocus && !cmb->editable) {
+ QStyleOptionFocusRect focus;
+ focus.QStyleOption::operator=(*cmb);
+ focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget);
+ focus.state |= State_FocusAtBorder;
+ focus.backgroundColor = cmb->palette.highlight().color();
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox copy = *sb;
+ PrimitiveElement pe;
+ bool enabled = opt->state & State_Enabled;
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ QBrush editBrush = sb->palette.brush(QPalette::Base);
+ QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
+ QPalette shadePal = sb->palette;
+ shadePal.setColor(QPalette::Midlight, shadePal.button().color());
+ qDrawWinPanel(p, r, shadePal, true, &editBrush);
+ }
+
+ QPalette shadePal(opt->palette);
+ shadePal.setColor(QPalette::Button, opt->palette.light().color());
+ shadePal.setColor(QPalette::Light, opt->palette.button().color());
+
+ if (sb->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
+ qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
+ &copy.palette.brush(QPalette::Button));
+ copy.rect.adjust(4, 1, -5, -1);
+ if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
+ && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
+ {
+ QStyleOptionSpinBox lightCopy = copy;
+ lightCopy.rect.adjust(1, 1, 1, 1);
+ lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
+ proxy()->drawPrimitive(pe, &lightCopy, p, widget);
+ }
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+
+ if (sb->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = sb->state;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+ qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
+ &copy.palette.brush(QPalette::Button));
+ copy.rect.adjust(4, 0, -5, -1);
+ if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
+ && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
+ {
+ QStyleOptionSpinBox lightCopy = copy;
+ lightCopy.rect.adjust(1, 1, 1, 1);
+ lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
+ proxy()->drawPrimitive(pe, &lightCopy, p, widget);
+ }
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ default:
+ QCommonStyle::drawComplexControl(cc, opt, p, widget);
+ }
+}
+
+/*! \reimp */
+QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *widget) const
+{
+ QSize sz(csz);
+ switch (ct) {
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ int w = sz.width(),
+ h = sz.height();
+ int defwidth = 0;
+ if (btn->features & QStyleOptionButton::AutoDefaultButton)
+ defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
+ int minwidth = int(QStyleHelper::dpiScaled(75.));
+ int minheight = int(QStyleHelper::dpiScaled(23.));
+
+#ifndef QT_QWS_SMALL_PUSHBUTTON
+ if (w < minwidth + defwidth && !btn->text.isEmpty())
+ w = minwidth + defwidth;
+ if (h < minheight + defwidth)
+ h = minheight + defwidth;
+#endif
+ sz = QSize(w, h);
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int w = sz.width();
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
+ }
+ else if (mi->icon.isNull()) {
+ sz.setHeight(sz.height() - 2);
+ w -= 6;
+ }
+
+ if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ sz.setHeight(qMax(sz.height(),
+ mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
+ + 2 * QWindowsStylePrivate::windowsItemFrame));
+ }
+ int maxpmw = mi->maxIconWidth;
+ int tabSpacing = 20;
+ if (mi->text.contains(QLatin1Char('\t')))
+ w += tabSpacing;
+ else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
+ else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
+ // adjust the font and add the difference in size.
+ // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
+ QFontMetrics fm(mi->font);
+ QFont fontBold = mi->font;
+ fontBold.setBold(true);
+ QFontMetrics fmBold(fontBold);
+ w += fmBold.width(mi->text) - fm.width(mi->text);
+ }
+
+ int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
+ w += checkcol;
+ w += int(QWindowsStylePrivate::windowsRightBorder) + 10;
+ sz.setWidth(w);
+ }
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_MENUBAR
+ case CT_MenuBarItem:
+ if (!sz.isEmpty())
+ sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
+ break;
+#endif
+ // Otherwise, fall through
+ case CT_ToolButton:
+ if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
+ return sz += QSize(7, 6);
+ // Otherwise, fall through
+
+ default:
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ }
+ return sz;
+}
+
+/*!
+ \internal
+*/
+QIcon QWindowsStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ QIcon icon;
+ QPixmap pixmap;
+#ifdef Q_OS_WIN
+ switch (standardIcon) {
+ case SP_FileDialogNewFolder:
+ {
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(319, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ }
+ case SP_DirHomeIcon:
+ {
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(235, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ }
+ case SP_DirIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(4, size);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
+ pixmap = loadIconFromShell32(5, size);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
+ }
+ break;
+ case SP_DirLinkIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ QPixmap link = loadIconFromShell32(30, size);
+ pixmap = loadIconFromShell32(4, size);
+ if (!pixmap.isNull() && !link.isNull()) {
+ QPainter painter(&pixmap);
+ painter.drawPixmap(0, 0, size, size, link);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
+ }
+ link = loadIconFromShell32(30, size);
+ pixmap = loadIconFromShell32(5, size);
+ if (!pixmap.isNull() && !link.isNull()) {
+ QPainter painter(&pixmap);
+ painter.drawPixmap(0, 0, size, size, link);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
+ }
+ }
+ break;
+ case SP_FileIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(1, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_ComputerIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(16, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+
+ case SP_DesktopIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(35, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(12, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveNetIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(10, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveHDIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(9, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveFDIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(7, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_FileLinkIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ QPixmap link;
+ link = loadIconFromShell32(30, size);
+ pixmap = loadIconFromShell32(1, size);
+ if (!pixmap.isNull() && !link.isNull()) {
+ QPainter painter(&pixmap);
+ painter.drawPixmap(0, 0, size, size, link);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ }
+ break;
+ case SP_VistaShield:
+ {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based
+ && pSHGetStockIconInfo)
+ {
+ icon.addPixmap(proxy()->standardPixmap(SP_VistaShield, option, widget)); //fetches small icon
+ QSHSTOCKICONINFO iconInfo; //append large icon
+ memset(&iconInfo, 0, sizeof(iconInfo));
+ iconInfo.cbSize = sizeof(iconInfo);
+ if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_LARGEICON, &iconInfo) == S_OK) {
+ icon.addPixmap(QPixmap::fromWinHICON(iconInfo.hIcon));
+ DestroyIcon(iconInfo.hIcon);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+#endif
+
+ if (icon.isNull())
+ icon = QCommonStyle::standardIconImplementation(standardIcon, option, widget);
+ return icon;
+}
+
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWS
diff --git a/src/widgets/styles/qwindowsstyle.h b/src/widgets/styles/qwindowsstyle.h
new file mode 100644
index 0000000000..9c732132d4
--- /dev/null
+++ b/src/widgets/styles/qwindowsstyle.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSSTYLE_H
+#define QWINDOWSSTYLE_H
+
+#include <QtWidgets/qcommonstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWS)
+
+class QWindowsStylePrivate;
+
+class Q_GUI_EXPORT QWindowsStyle : public QCommonStyle
+{
+ Q_OBJECT
+public:
+ QWindowsStyle();
+ ~QWindowsStyle();
+
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+
+ void polish(QWidget*);
+ void unpolish(QWidget*);
+
+ void polish(QPalette &);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+protected:
+ bool eventFilter(QObject *o, QEvent *e);
+ void timerEvent(QTimerEvent *event);
+ QWindowsStyle(QWindowsStylePrivate &dd);
+
+private:
+ Q_DISABLE_COPY(QWindowsStyle)
+ Q_DECLARE_PRIVATE(QWindowsStyle)
+ void *reserved;
+};
+
+#endif // QT_NO_STYLE_WINDOWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOWSSTYLE_H
diff --git a/src/widgets/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h
new file mode 100644
index 0000000000..b9f39a0940
--- /dev/null
+++ b/src/widgets/styles/qwindowsstyle_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSSTYLE_P_H
+#define QWINDOWSSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsstyle.h"
+#include "qcommonstyle_p.h"
+
+#ifndef QT_NO_STYLE_WINDOWS
+#include <qlist.h>
+#include <qhash.h>
+#include <qelapsedtimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTime;
+class QProgressBar;
+
+class QWindowsStylePrivate : public QCommonStylePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsStyle)
+public:
+ QWindowsStylePrivate();
+ bool hasSeenAlt(const QWidget *widget) const;
+ bool altDown() const { return alt_down; }
+ bool alt_down;
+ QList<const QWidget *> seenAlt;
+ int menuBarTimer;
+
+ QList<QProgressBar *> bars;
+ int animationFps;
+ int animateTimer;
+ QElapsedTimer startTime;
+ int animateStep;
+ QColor inactiveCaptionText;
+ QColor activeCaptionColor;
+ QColor activeGradientCaptionColor;
+ QColor inactiveCaptionColor;
+ QColor inactiveGradientCaptionColor;
+
+ enum {
+ windowsItemFrame = 2, // menu item frame width
+ windowsSepHeight = 9, // separator item height
+ windowsItemHMargin = 3, // menu item hor text margin
+ windowsItemVMargin = 2, // menu item ver text margin
+ windowsArrowHMargin = 6, // arrow horizontal margin
+ windowsRightBorder = 15, // right border on windows
+ windowsCheckMarkWidth = 12 // checkmarks width on windows
+ };
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWS
+
+#endif //QWINDOWSSTYLE_P_H
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
new file mode 100644
index 0000000000..da484bafe1
--- /dev/null
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -0,0 +1,2669 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsvistastyle.h"
+#include "qwindowsvistastyle_p.h"
+#include <private/qstylehelper_p.h>
+#include <private/qsystemlibrary_p.h>
+
+#if !defined(QT_NO_STYLE_WINDOWSVISTA) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 4; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 15; // right border on windows
+
+#ifndef TMT_CONTENTMARGINS
+# define TMT_CONTENTMARGINS 3602
+#endif
+#ifndef TMT_SIZINGMARGINS
+# define TMT_SIZINGMARGINS 3601
+#endif
+#ifndef LISS_NORMAL
+# define LISS_NORMAL 1
+# define LISS_HOT 2
+# define LISS_SELECTED 3
+# define LISS_DISABLED 4
+# define LISS_SELECTEDNOTFOCUS 5
+# define LISS_HOTSELECTED 6
+#endif
+#ifndef BP_COMMANDLINK
+# define BP_COMMANDLINK 6
+# define BP_COMMANDLINKGLYPH 7
+# define CMDLGS_NORMAL 1
+# define CMDLGS_HOT 2
+# define CMDLGS_PRESSED 3
+# define CMDLGS_DISABLED 4
+#endif
+
+// Runtime resolved theme engine function calls
+
+
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
+typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
+typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
+typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
+typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
+typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeTransitionDuration)(HTHEME hTheme, int iPartId, int iStateFromId, int iStateToId, int iPropId, int *pDuration);
+typedef HRESULT (WINAPI *PtrIsThemePartDefined)(HTHEME hTheme, int iPartId, int iStateId);
+typedef HRESULT (WINAPI *PtrSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
+
+static PtrIsThemePartDefined pIsThemePartDefined = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+static PtrGetThemeBool pGetThemeBool = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
+static PtrGetThemeFilename pGetThemeFilename = 0;
+static PtrGetThemeFont pGetThemeFont = 0;
+static PtrGetThemeInt pGetThemeInt = 0;
+static PtrGetThemeIntList pGetThemeIntList = 0;
+static PtrGetThemeMargins pGetThemeMargins = 0;
+static PtrGetThemeMetric pGetThemeMetric = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemePosition pGetThemePosition = 0;
+static PtrGetThemeRect pGetThemeRect = 0;
+static PtrGetThemeString pGetThemeString = 0;
+static PtrGetThemeTransitionDuration pGetThemeTransitionDuration= 0;
+static PtrSetWindowTheme pSetWindowTheme = 0;
+static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
+
+/* \internal
+ Checks if we should use Vista style , or if we should
+ fall back to Windows style.
+*/
+bool QWindowsVistaStylePrivate::useVista()
+{
+ return (QWindowsVistaStylePrivate::useXP() &&
+ (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA &&
+ QSysInfo::WindowsVersion < QSysInfo::WV_NT_based));
+}
+
+/*!
+ \class QWindowsVistaStyle
+ \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
+ \since 4.3
+ \ingroup appearance
+
+ \warning This style is only available on the Windows Vista platform
+ because it makes use of Windows Vista's style engine.
+
+ \sa QMacStyle, QWindowsXPStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QWindowsVistaStyle object.
+*/
+QWindowsVistaStyle::QWindowsVistaStyle()
+ : QWindowsXPStyle(*new QWindowsVistaStylePrivate)
+{
+}
+
+//convert Qt state flags to uxtheme button states
+static int buttonStateId(int flags, int partId)
+{
+ int stateId = 0;
+ if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) {
+ if (!(flags & QStyle::State_Enabled))
+ stateId = RBS_UNCHECKEDDISABLED;
+ else if (flags & QStyle::State_Sunken)
+ stateId = RBS_UNCHECKEDPRESSED;
+ else if (flags & QStyle::State_MouseOver)
+ stateId = RBS_UNCHECKEDHOT;
+ else
+ stateId = RBS_UNCHECKEDNORMAL;
+
+ if (flags & QStyle::State_On)
+ stateId += RBS_CHECKEDNORMAL-1;
+
+ } else if (partId == BP_PUSHBUTTON) {
+ if (!(flags & QStyle::State_Enabled))
+ stateId = PBS_DISABLED;
+ else if (flags & (QStyle::State_Sunken | QStyle::State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & QStyle::State_MouseOver)
+ stateId = PBS_HOT;
+ else
+ stateId = PBS_NORMAL;
+ } else {
+ Q_ASSERT(1);
+ }
+ return stateId;
+}
+
+void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(painter);
+}
+
+/*! \internal
+
+ Helperfunction to paint the current transition state between two
+ animation frames.
+
+ The result is a blended image consisting of ((alpha)*_primaryImage)
+ + ((1-alpha)*_secondaryImage)
+
+*/
+void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
+ if (_secondaryImage.isNull() || _primaryImage.isNull())
+ return;
+
+ if (_tempImage.isNull())
+ _tempImage = _secondaryImage;
+
+ const int a = qRound(alpha*256);
+ const int ia = 256 - a;
+ const int sw = _primaryImage.width();
+ const int sh = _primaryImage.height();
+ const int bpl = _primaryImage.bytesPerLine();
+ switch(_primaryImage.depth()) {
+ case 32:
+ {
+ uchar *mixed_data = _tempImage.bits();
+ const uchar *back_data = _primaryImage.bits();
+ const uchar *front_data = _secondaryImage.bits();
+ for (int sy = 0; sy < sh; sy++) {
+ quint32* mixed = (quint32*)mixed_data;
+ const quint32* back = (const quint32*)back_data;
+ const quint32* front = (const quint32*)front_data;
+ for (int sx = 0; sx < sw; sx++) {
+ quint32 bp = back[sx];
+ quint32 fp = front[sx];
+ mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
+ (qGreen(bp)*ia + qGreen(fp)*a)>>8,
+ (qBlue(bp)*ia + qBlue(fp)*a)>>8,
+ (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
+ }
+ mixed_data += bpl;
+ back_data += bpl;
+ front_data += bpl;
+ }
+ }
+ default:
+ break;
+ }
+ painter->drawImage(rect, _tempImage);
+}
+
+/*! \internal
+ Paints a transition state. The result will be a mix between the
+ initial and final state of the transition, depending on the time
+ difference between _startTime and current time.
+*/
+void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option)
+{
+ float alpha = 1.0;
+ if (_duration > 0) {
+ QTime current = QTime::currentTime();
+
+ if (_startTime > current)
+ _startTime = current;
+
+ int timeDiff = _startTime.msecsTo(current);
+ alpha = timeDiff/(float)_duration;
+ if (timeDiff > _duration) {
+ _running = false;
+ alpha = 1.0;
+ }
+ }
+ else {
+ _running = false;
+ }
+ drawBlendedImage(painter, option->rect, alpha);
+}
+
+/*! \internal
+ Paints a pulse. The result will be a mix between the primary and
+ secondary pulse images depending on the time difference between
+ _startTime and current time.
+*/
+void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option)
+{
+ float alpha = 1.0;
+ if (_duration > 0) {
+ QTime current = QTime::currentTime();
+
+ if (_startTime > current)
+ _startTime = current;
+
+ int timeDiff = _startTime.msecsTo(current) % _duration*2;
+ if (timeDiff > _duration)
+ timeDiff = _duration*2 - timeDiff;
+ alpha = timeDiff/(float)_duration;
+ } else {
+ _running = false;
+ }
+ drawBlendedImage(painter, option->rect, alpha);
+}
+
+
+/*!
+ \internal
+
+ Animations are used for some state transitions on specific widgets.
+
+ Only one running animation can exist for a widget at any specific
+ time. Animations can be added through
+ QWindowsVistaStylePrivate::startAnimation(Animation *) and any
+ existing animation on a widget can be retrieved with
+ QWindowsVistaStylePrivate::widgetAnimation(Widget *).
+
+ Once an animation has been started,
+ QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will
+ continuously call update() on the widget until it is stopped,
+ meaning that drawPrimitive will be called many times until the
+ transition has completed. During this time, the result will be
+ retrieved by the Animation::paint(...) function and not by the style
+ itself.
+
+ To determine if a transition should occur, the style needs to know
+ the previous state of the widget as well as the current one. This is
+ solved by updating dynamic properties on the widget every time the
+ function is called.
+
+ Transitions interrupting existing transitions should always be
+ smooth, so whenever a hover-transition is started on a pulsating
+ button, it uses the current frame of the pulse-animation as the
+ starting image for the hover transition.
+
+ */
+void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+
+ int state = option->state;
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+
+ QRect oldRect;
+ QRect newRect;
+
+ if (widget && d->transitionsEnabled())
+ {
+ /* all widgets that supports state transitions : */
+ if (
+#ifndef QT_NO_LINEEDIT
+ (qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) ||
+#endif // QT_NO_LINEEDIT
+ (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) ||
+ (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) ||
+ (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) ||
+ (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel)
+ )
+ {
+ // Retrieve and update the dynamic properties tracking
+ // the previous state of the widget:
+ QWidget *w = const_cast<QWidget *> (widget);
+ int oldState = w->property("_q_stylestate").toInt();
+ oldRect = w->property("_q_stylerect").toRect();
+ newRect = w->rect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylerect", w->rect());
+
+ bool doTransition = oldState &&
+ ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
+
+ if (oldRect != newRect ||
+ (state & State_Enabled) != (oldState & State_Enabled) ||
+ (state & State_Active) != (oldState & State_Active))
+ d->stopAnimation(widget);
+
+#ifndef QT_NO_LINEEDIT
+ if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget))
+ if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits
+ doTransition = false;
+#endif // QT_NO_LINEEDIT
+
+ if (doTransition) {
+
+ // We create separate images for the initial and final transition states and store them in the
+ // Transition object.
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QStyleOption opt = *option;
+
+ opt.rect.setRect(0, 0, option->rect.width(), option->rect.height());
+ opt.state = (QStyle::State)oldState;
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
+ t->setWidget(w);
+
+ // If we have a running animation on the widget already, we will use that to paint the initial
+ // state of the new transition, this ensures a smooth transition from a current animation such as a
+ // pulsating default button into the intended target state.
+
+ if (!anim)
+ proxy()->drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0
+ else // this ensures that we do not recurse in the animation logic above
+ anim->paint(&startPainter, &opt);
+
+ d->startAnimation(t);
+ t->setStartImage(startImage);
+
+ // The end state of the transition is simply the result we would have painted
+ // if the style was not animated.
+
+ QPainter endPainter(&endImage);
+ endImage.fill(0);
+ QStyleOption opt2 = opt;
+ opt2.state = option->state;
+ proxy()->drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0
+ // this ensures that we do not recurse in the animation logic above
+ t->setEndImage(endImage);
+
+ HTHEME theme;
+ int partId;
+ int duration;
+ int fromState = 0;
+ int toState = 0;
+
+ //translate state flags to UXTHEME states :
+ if (element == PE_FrameLineEdit) {
+ theme = pOpenThemeData(0, L"Edit");
+ partId = EP_EDITBORDER_NOSCROLL;
+
+ if (oldState & State_MouseOver)
+ fromState = ETS_HOT;
+ else if (oldState & State_HasFocus)
+ fromState = ETS_FOCUSED;
+ else
+ fromState = ETS_NORMAL;
+
+ if (state & State_MouseOver)
+ toState = ETS_HOT;
+ else if (state & State_HasFocus)
+ toState = ETS_FOCUSED;
+ else
+ toState = ETS_NORMAL;
+
+ } else {
+ theme = pOpenThemeData(0, L"Button");
+ if (element == PE_IndicatorRadioButton)
+ partId = BP_RADIOBUTTON;
+ else if (element == PE_IndicatorCheckBox)
+ partId = BP_CHECKBOX;
+ else
+ partId = BP_PUSHBUTTON;
+
+ fromState = buttonStateId(oldState, partId);
+ toState = buttonStateId(option->state, partId);
+ }
+
+ // Retrieve the transition time between the states from the system.
+ if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
+ TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+ {
+ t->setDuration(duration);
+ }
+ t->setStartTime(QTime::currentTime());
+ }
+ }
+ } // End of animation part
+
+
+ QRect rect = option->rect;
+
+ switch (element) {
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ int stateId = HSAS_SORTEDDOWN;
+ if (header->sortIndicator & QStyleOptionHeader::SortDown)
+ stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours
+ XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ {
+ XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW"));
+ static int decoration_size = 0;
+ if (theme.isValid() && !decoration_size) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size);
+ decoration_size = qMax(size.cx, size.cy);
+ }
+ int mid_h = option->rect.x() + option->rect.width() / 2;
+ int mid_v = option->rect.y() + option->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ if (option->state & State_Children) {
+ int delta = decoration_size / 2;
+ theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size);
+ theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH;
+ theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
+ if (option->direction == Qt::RightToLeft)
+ theme.mirrorHorizontally = true;
+ d->drawBackground(theme);
+ bef_h -= delta + 2;
+ bef_v -= delta + 2;
+ aft_h += delta - 2;
+ aft_v += delta - 2;
+ }
+#if 0
+ QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+ if (option->state & State_Item) {
+ if (option->direction == Qt::RightToLeft)
+ painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+ else
+ painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (option->state & State_Sibling && option->rect.bottom() > aft_v)
+ painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+ if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y()))
+ painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+#endif
+ }
+ break;
+
+ case PE_PanelButtonBevel:
+ case PE_IndicatorCheckBox:
+ case PE_IndicatorRadioButton:
+ {
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
+ a->paint(painter, option);
+ } else {
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ }
+ }
+ break;
+
+ case PE_FrameMenu:
+ {
+ int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE;
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+ case PE_Frame:
+#ifndef QT_NO_TEXTEDIT
+ if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) {
+ painter->save();
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (edit->isReadOnly())
+ stateId = ETS_READONLY;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect);
+ uint resolve_mask = option->palette.resolve();
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
+ int borderSize = 1;
+ pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
+ QRegion clipRegion = option->rect;
+ QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ clipRegion ^= content;
+ painter->setClipRegion(clipRegion);
+ }
+ d->drawBackground(theme);
+ painter->restore();
+ } else
+#endif // QT_NO_TEXTEDIT
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ break;
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ QBrush bg;
+ bool usePalette = false;
+ bool isEnabled = option->state & State_Enabled;
+ uint resolve_mask = panel->palette.resolve();
+ if (widget) {
+ //Since spin box and combo box includes a line edit we need to resolve the palette on the parent instead
+#ifndef QT_NO_SPINBOX
+ if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
+ resolve_mask = spinbox->palette().resolve();
+#endif // QT_NO_SPINBOX
+ }
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Base color is set for this widget, so use it
+ bg = panel->palette.brush(QPalette::Base);
+ usePalette = true;
+ }
+ if (usePalette) {
+ painter->fillRect(panel->rect, bg);
+ } else {
+ int partId = EP_BACKGROUND;
+ int stateId = EBS_NORMAL;
+ if (!isEnabled)
+ stateId = EBS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = EBS_READONLY;
+ else if (state & State_MouseOver)
+ stateId = EBS_HOT;
+
+ XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+ int bgType;
+ pGetThemeEnumValue( theme.handle(),
+ partId,
+ stateId,
+ TMT_BGTYPE,
+ &bgType);
+ if( bgType == BT_IMAGEFILE ) {
+ d->drawBackground(theme);
+ } else {
+ QBrush fillColor = option->palette.brush(QPalette::Base);
+ if (!isEnabled) {
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
+ // Use only if the fill property comes from our part
+ if ((origin == PO_PART || origin == PO_STATE)) {
+ COLORREF bgRef;
+ pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
+ fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
+ }
+ }
+ painter->fillRect(option->rect, fillColor);
+ }
+ }
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
+ return;
+ }
+ break;
+
+ case PE_FrameLineEdit:
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
+ anim->paint(painter, option);
+ } else {
+ QPainter *p = painter;
+ QWidget *parentWidget = 0;
+ if (widget) {
+ parentWidget = widget->parentWidget();
+ if (parentWidget)
+ parentWidget = parentWidget->parentWidget();
+ }
+ if (widget && widget->inherits("QLineEdit")
+ && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+ // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
+ QPen oldPen = p->pen();
+ // Inner white border
+ p->setPen(QPen(option->palette.base().color(), 1));
+ p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ // Outer dark border
+ p->setPen(QPen(option->palette.shadow().color(), 1));
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ return;
+ } else {
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = ETS_READONLY;
+ else if (state & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect);
+ painter->save();
+ QRegion clipRegion = option->rect;
+ clipRegion -= option->rect.adjusted(2, 2, -2, -2);
+ painter->setClipRegion(clipRegion);
+ d->drawBackground(theme);
+ painter->restore();
+ }
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle:
+ {
+ XPThemeData theme;
+ QRect rect;
+ if (option->state & State_Horizontal) {
+ theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+ rect = option->rect.adjusted(0, 1, 0, -2);
+ rect.setWidth(4);
+ } else {
+ theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+ rect = option->rect.adjusted(1, 0, -1, 0);
+ rect.setHeight(4);
+ }
+ theme.rect = rect;
+ d->drawBackground(theme);
+ }
+ break;
+
+ case PE_IndicatorToolBarSeparator:
+ {
+ QPen pen = painter->pen();
+ int margin = 3;
+ painter->setPen(option->palette.background().color().darker(114));
+ if (option->state & State_Horizontal) {
+ int x1 = option->rect.center().x();
+ painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin));
+ } else {
+ int y1 = option->rect.center().y();
+ painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1));
+ }
+ painter->setPen(pen);
+ }
+ break;
+
+ case PE_PanelTipLabel: {
+ XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+ d->drawBackground(theme);
+ break;
+ }
+
+ case PE_PanelItemViewItem:
+ {
+ const QStyleOptionViewItemV4 *vopt;
+ const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+ bool newStyle = true;
+
+ if (qobject_cast<const QTableView*>(widget))
+ newStyle = false;
+
+ if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
+ bool selected = vopt->state & QStyle::State_Selected;
+ bool hover = vopt->state & QStyle::State_MouseOver;
+ bool active = vopt->state & QStyle::State_Active;
+
+ if (vopt->features & QStyleOptionViewItemV2::Alternate)
+ painter->fillRect(vopt->rect, vopt->palette.alternateBase());
+
+ QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+ QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0);
+ itemRect.setTop(vopt->rect.top());
+ itemRect.setBottom(vopt->rect.bottom());
+
+ QSize sectionSize = itemRect.size();
+ if (vopt->showDecorationSelected)
+ sectionSize = vopt->rect.size();
+
+ if (view->selectionBehavior() == QAbstractItemView::SelectRows)
+ sectionSize.setWidth(vopt->rect.width());
+ if (view->selectionMode() == QAbstractItemView::NoSelection)
+ hover = false;
+ QPixmap pixmap;
+
+ if (vopt->backgroundBrush.style() != Qt::NoBrush) {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(vopt->rect.topLeft());
+ painter->fillRect(vopt->rect, vopt->backgroundBrush);
+ }
+
+ if (hover || selected) {
+ QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width())
+ .arg(sectionSize.height()).arg(selected).arg(active).arg(hover);
+ if (!QPixmapCache::find(key, pixmap)) {
+ pixmap = QPixmap(sectionSize);
+ pixmap.fill(Qt::transparent);
+
+ int state;
+ if (selected && hover)
+ state = LISS_HOTSELECTED;
+ else if (selected && !active)
+ state = LISS_SELECTEDNOTFOCUS;
+ else if (selected)
+ state = LISS_SELECTED;
+ else
+ state = LISS_HOT;
+
+ QPainter pixmapPainter(&pixmap);
+ XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"),
+ LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
+ if (theme.isValid()) {
+ d->drawBackground(theme);
+ } else {
+ QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
+ break;;
+ }
+ QPixmapCache::insert(key, pixmap);
+ }
+
+ if (vopt->showDecorationSelected) {
+ const int frame = 2; //Assumes a 2 pixel pixmap border
+ QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height());
+ QRect pixmapRect = vopt->rect;
+ bool reverse = vopt->direction == Qt::RightToLeft;
+ bool leftSection = vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning;
+ bool rightSection = vopt->viewItemPosition == QStyleOptionViewItemV4::End;
+ if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne
+ || vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid)
+ painter->drawPixmap(pixmapRect.topLeft(), pixmap);
+ else if (reverse ? rightSection : leftSection){
+ painter->drawPixmap(QRect(pixmapRect.topLeft(),
+ QSize(frame, pixmapRect.height())), pixmap,
+ QRect(QPoint(0, 0), QSize(frame, pixmapRect.height())));
+ painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0),
+ pixmap, srcRect.adjusted(frame, 0, -frame, 0));
+ } else if (reverse ? leftSection : rightSection) {
+ painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0),
+ QSize(frame, pixmapRect.height())), pixmap,
+ QRect(QPoint(pixmapRect.width() - frame, 0),
+ QSize(frame, pixmapRect.height())));
+ painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0),
+ pixmap, srcRect.adjusted(frame, 0, -frame, 0));
+ } else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle)
+ painter->drawPixmap(pixmapRect, pixmap,
+ srcRect.adjusted(frame, 0, -frame, 0));
+ } else {
+ if (vopt->text.isEmpty() && vopt->icon.isNull())
+ break;
+ painter->drawPixmap(itemRect.topLeft(), pixmap);
+ }
+ }
+ } else {
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ }
+ break;
+ }
+ case PE_Widget:
+ {
+ const QDialogButtonBox *buttonBox = 0;
+
+ if (qobject_cast<const QMessageBox *> (widget))
+ buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
+#ifndef QT_NO_INPUTDIALOG
+ else if (qobject_cast<const QInputDialog *> (widget))
+ buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
+#endif // QT_NO_INPUTDIALOG
+
+ if (buttonBox) {
+ //draw white panel part
+ XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect);
+ QRect toprect = option->rect;
+ toprect.setBottom(buttonBox->geometry().top());
+ theme.rect = toprect;
+ d->drawBackground(theme);
+
+ //draw bottom panel part
+ QRect buttonRect = option->rect;
+ buttonRect.setTop(buttonBox->geometry().top());
+ theme.rect = buttonRect;
+ theme.partId = TDLG_SECONDARYPANEL;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+ default:
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+
+/*!
+ \internal
+
+ see drawPrimitive for comments on the animation support
+ */
+void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ return;
+ }
+
+ bool selected = option->state & State_Selected;
+ bool pressed = option->state & State_Sunken;
+ bool disabled = !(option->state & State_Enabled);
+
+ int state = option->state;
+ QString name;
+
+ QRect rect(option->rect);
+ State flags = option->state;
+ int partId = 0;
+ int stateId = 0;
+
+ QRect oldRect;
+ QRect newRect;
+
+ if (d->transitionsEnabled() && widget) {
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ if ((qobject_cast<const QPushButton*>(widget) && element == CE_PushButtonBevel))
+ {
+ QWidget *w = const_cast<QWidget *> (widget);
+ int oldState = w->property("_q_stylestate").toInt();
+ oldRect = w->property("_q_stylerect").toRect();
+ newRect = w->rect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylerect", w->rect());
+
+ bool wasDefault = w->property("_q_isdefault").toBool();
+ bool isDefault = button->features & QStyleOptionButton::DefaultButton;
+ w->setProperty("_q_isdefault", isDefault);
+
+ bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
+
+ if (oldRect != newRect || (wasDefault && !isDefault))
+ {
+ doTransition = false;
+ d->stopAnimation(widget);
+ }
+
+ if (doTransition) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+
+ QStyleOptionButton opt = *button;
+ opt.state = (QStyle::State)oldState;
+
+ startImage.fill(0);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
+ t->setWidget(w);
+ QPainter startPainter(&startImage);
+
+ if (!anim) {
+ proxy()->drawControl(element, &opt, &startPainter, 0 /* Intentional */);
+ } else {
+ anim->paint(&startPainter, &opt);
+ d->stopAnimation(widget);
+ }
+
+ t->setStartImage(startImage);
+ d->startAnimation(t);
+
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+ proxy()->drawControl(element, option, &endPainter, 0 /* Intentional */);
+ t->setEndImage(endImage);
+ int duration = 0;
+ HTHEME theme = pOpenThemeData(0, L"Button");
+
+ int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
+ int toState = buttonStateId(option->state, BP_PUSHBUTTON);
+ if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+ t->setDuration(duration);
+ else
+ t->setDuration(0);
+ t->setStartTime(QTime::currentTime());
+ }
+ }
+ }
+ }
+ switch (element) {
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
+ {
+
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ if (anim && (btn->state & State_Enabled)) {
+ anim->paint(painter, option);
+ } else {
+ name = QLatin1String("BUTTON");
+ partId = BP_PUSHBUTTON;
+ if (btn->features & QStyleOptionButton::CommandLinkButton)
+ partId = BP_COMMANDLINK;
+ bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
+ if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
+ stateId = PBS_DISABLED;
+ else if (justFlat)
+ ;
+ else if (flags & (State_Sunken | State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+
+ if (!justFlat) {
+
+ if (widget && d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
+ !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
+ (state & State_Enabled) && (state & State_Active))
+ {
+ if (!anim && widget) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ startImage.fill(0);
+ QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ alternateImage.fill(0);
+
+ QWindowsVistaPulse *pulse = new QWindowsVistaPulse;
+ pulse->setWidget(const_cast<QWidget*>(widget));
+
+ QPainter startPainter(&startImage);
+ stateId = PBS_DEFAULTED;
+ XPThemeData theme(widget, &startPainter, name, partId, stateId, rect);
+ d->drawBackground(theme);
+
+ QPainter alternatePainter(&alternateImage);
+ theme.stateId = PBS_DEFAULTED_ANIMATING;
+ theme.painter = &alternatePainter;
+ d->drawBackground(theme);
+ pulse->setPrimaryImage(startImage);
+ pulse->setAlternateImage(alternateImage);
+ pulse->setStartTime(QTime::currentTime());
+ pulse->setDuration(2000);
+ d->startAnimation(pulse);
+ anim = pulse;
+ }
+
+ if (anim)
+ anim->paint(painter, option);
+ else {
+ XPThemeData theme(widget, painter, name, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
+ }
+ else {
+ d->stopAnimation(widget);
+ XPThemeData theme(widget, painter, name, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
+ }
+ }
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbiw = 0, mbih = 0;
+ XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON);
+ if (theme.isValid()) {
+ SIZE size;
+ if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
+ mbiw = size.cx;
+ mbih = size.cy;
+ }
+ }
+ QRect ir = subElementRect(SE_PushButtonContents, option, 0);
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QStyle::visualRect(option->direction, option->rect,
+ QRect(ir.right() - mbiw - 2,
+ option->rect.top() + (option->rect.height()/2) - (mbih/2),
+ mbiw + 1, mbih + 1));
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
+ }
+ return;
+ }
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *bar
+ = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ int stateId = MBI_NORMAL;
+ if (disabled)
+ stateId = MBI_DISABLED;
+ bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0);
+ bool vertical = false;
+ bool inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+
+ if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) {
+ if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) {
+ if (!d->widgetAnimation(progressbar)) {
+ QWindowsVistaAnimation *a = new QWindowsVistaAnimation;
+ a->setWidget(const_cast<QWidget*>(widget));
+ a->setStartTime(QTime::currentTime());
+ d->startAnimation(a);
+ }
+ } else {
+ d->stopAnimation(progressbar);
+ }
+ }
+
+ XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL);
+ theme.rect = option->rect;
+ bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted);
+ QTime current = QTime::currentTime();
+
+ if (isIndeterminate) {
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
+ int glowSize = 120;
+ int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
+ int animOffset = a->startTime().msecsTo(current) / 4;
+ if (animOffset > animationWidth)
+ a->setStartTime(QTime::currentTime());
+ painter->save();
+ painter->setClipRect(theme.rect);
+ QRect animRect;
+ QSize pixmapSize(14, 14);
+ if (vertical) {
+ animRect = QRect(theme.rect.left(),
+ inverted ? rect.top() - glowSize + animOffset :
+ rect.bottom() + glowSize - animOffset,
+ rect.width(), glowSize);
+ pixmapSize.setHeight(animRect.height());
+ } else {
+ animRect = QRect(rect.left() - glowSize + animOffset,
+ rect.top(), glowSize, rect.height());
+ animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight,
+ option->rect, animRect);
+ pixmapSize.setWidth(animRect.width());
+ }
+ QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height());
+ QPixmap pixmap;
+ if (!QPixmapCache::find(name, pixmap)) {
+ QImage image(pixmapSize, QImage::Format_ARGB32);
+ image.fill(Qt::transparent);
+ QPainter imagePainter(&image);
+ theme.painter = &imagePainter;
+ theme.partId = vertical ? PP_FILLVERT : PP_FILL;
+ theme.rect = QRect(QPoint(0,0), theme.rect.size());
+ QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(),
+ vertical ? image.height() : 0);
+ alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
+ alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220));
+ alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
+ imagePainter.fillRect(image.rect(), alphaGradient);
+ imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ d->drawBackground(theme);
+ imagePainter.end();
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(name, pixmap);
+ }
+ painter->drawPixmap(animRect, pixmap);
+ painter->restore();
+ }
+ }
+ else {
+ qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar
+
+ if (vertical) {
+ int maxHeight = option->rect.height();
+ int minHeight = 0;
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight);
+ int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight);
+ theme.rect.setHeight(height);
+ if (!inverted)
+ theme.rect.moveTop(rect.height() - theme.rect.height());
+ } else {
+ int maxWidth = option->rect.width();
+ int minWidth = 0;
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth);
+ int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth);
+ theme.rect.setWidth(width);
+ theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight,
+ option->rect, theme.rect);
+ }
+ d->drawBackground(theme);
+
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
+ int glowSize = 140;
+ int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
+ int animOffset = a->startTime().msecsTo(current) / 4;
+ theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
+ if (animOffset > animationWidth) {
+ if (bar->progress < bar->maximum)
+ a->setStartTime(QTime::currentTime());
+ else
+ d->stopAnimation(widget); //we stop the glow motion only after it has
+ //moved out of view
+ }
+ painter->save();
+ painter->setClipRect(theme.rect);
+ if (vertical) {
+ theme.rect = QRect(theme.rect.left(),
+ inverted ? rect.top() - glowSize + animOffset :
+ rect.bottom() + glowSize - animOffset,
+ rect.width(), glowSize);
+ } else {
+ theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height());
+ theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect);
+ }
+ d->drawBackground(theme);
+ painter->restore();
+ }
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ case CE_MenuBarItem:
+ {
+
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ break;
+
+ QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
+ QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
+
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ //The rect adjustment is a workaround for the menu not really filling its background.
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
+ d->drawBackground(theme);
+
+ int stateId = MBI_NORMAL;
+ if (disabled)
+ stateId = MBI_DISABLED;
+ else if (pressed)
+ stateId = MBI_PUSHED;
+ else if (selected)
+ stateId = MBI_HOT;
+
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect);
+ d->drawBackground(theme2);
+
+ if (!pix.isNull())
+ drawItemPixmap(painter, mbi->rect, alignment, pix);
+ else
+ drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = 28;
+ {
+ SIZE size;
+ MARGINS margins;
+ XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+ pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+ pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
+ checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
+ }
+ QColor darkLine = option->palette.background().color().darker(108);
+ QColor lightLine = option->palette.background().color().lighter(107);
+ QRect rect = option->rect;
+ QStyleOptionMenuItem mbiCopy = *menuitem;
+
+ //draw vertical menu line
+ QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
+ QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
+ QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect);
+ d->drawBackground(theme2);
+
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-2 + h / 2;
+ QPoint p1 = QPoint(x + checkcol, yoff);
+ QPoint p2 = QPoint(x + w + 6 , yoff);
+ stateId = MBI_HOT;
+ QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
+ subRect = QStyle::visualRect(option->direction, option->rect, subRect );
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect);
+ d->drawBackground(theme2);
+ return;
+ }
+
+ QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
+ menuitem->rect.y(), checkcol - 6, menuitem->rect.height()));
+
+ if (act) {
+ stateId = MBI_HOT;
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect);
+ d->drawBackground(theme2);
+ }
+
+ if (checked) {
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND,
+ menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
+ SIZE size;
+ MARGINS margins;
+ pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+ pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0,
+ TMT_CONTENTMARGINS, NULL, &margins);
+ QRect checkRect(0, 0, size.cx + margins.cxLeftWidth + margins.cxRightWidth ,
+ size.cy + margins.cyBottomHeight + margins.cyTopHeight);
+ checkRect.moveCenter(vCheckRect.center());
+ theme.rect = checkRect;
+
+ d->drawBackground(theme);
+
+ if (menuitem->icon.isNull()) {
+ checkRect = QRect(0, 0, size.cx, size.cy);
+ checkRect.moveCenter(theme.rect.center());
+ theme.rect = checkRect;
+
+ theme.partId = MENU_POPUPCHECK;
+ bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive;
+ if (dis)
+ theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED;
+ else
+ theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL;
+ d->drawBackground(theme);
+ }
+ }
+
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(menuitem->palette.text().color());
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ }
+
+ painter->setPen(menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ painter->setPen(discol);
+ }
+
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ painter->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ painter->setFont(font);
+ painter->setPen(discol);
+ painter->drawText(vTextRect, text_flags, s.left(t));
+ painter->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ proxy()->drawPrimitive(arrow, &newMI, painter, widget);
+ }
+ }
+ break;
+#endif // QT_NO_MENU
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ name = QLatin1String("HEADER");
+ partId = HP_HEADERITEM;
+ if (flags & State_Sunken)
+ stateId = HIS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = HIS_HOT;
+ else
+ stateId = HIS_NORMAL;
+
+ if (header->sortIndicator != QStyleOptionHeader::None)
+ stateId += 3;
+
+ XPThemeData theme(widget, painter, name, partId, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ {
+ stateId = MBI_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = MBI_DISABLED;
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ QPalette pal = option->palette;
+ pal.setColor(QPalette::Dark, option->palette.background().color().darker(130));
+ QStyleOptionToolBar copyOpt = *toolbar;
+ copyOpt.palette = pal;
+ QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
+ }
+ break;
+ case CE_DockWidgetTitle:
+ if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
+ QRect rect = option->rect;
+ if (dockWidget->isFloating()) {
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ break; //otherwise fall through
+ }
+
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ if (verticalTitleBar) {
+ QSize s = rect.size();
+ s.transpose();
+ rect.setSize(s);
+
+ painter->translate(rect.left() - 1, rect.top() + rect.width());
+ painter->rotate(-90);
+ painter->translate(-rect.left() + 1, -rect.top());
+ }
+
+ painter->setBrush(option->palette.background().color().darker(110));
+ painter->setPen(option->palette.background().color().darker(130));
+ painter->drawRect(rect.adjusted(0, 1, -1, -3));
+
+ int buttonMargin = 4;
+ int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+ int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
+ const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
+ bool isFloating = dw != 0 && dw->isFloating();
+
+ QRect r = option->rect.adjusted(0, 2, -1, -3);
+ QRect titleRect = r;
+
+ if (dwOpt->closable) {
+ QSize sz = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (dwOpt->floatable) {
+ QSize sz = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (isFloating) {
+ titleRect.adjust(0, -fw, 0, 0);
+ if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+ } else {
+ titleRect.adjust(mw, 0, 0, 0);
+ if (!dwOpt->floatable && !dwOpt->closable)
+ titleRect.adjust(0, 0, -mw, 0);
+ }
+ if (!verticalTitleBar)
+ titleRect = visualRect(dwOpt->direction, r, titleRect);
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
+ verticalTitleBar ? titleRect.height() : titleRect.width());
+ const int indent = painter->fontMetrics().descent();
+ drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1),
+ Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ }
+ break;
+ }
+#ifndef QT_NO_ITEMVIEWS
+ case CE_ItemViewItem:
+ {
+ const QStyleOptionViewItemV4 *vopt;
+ const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+ bool newStyle = true;
+
+ if (qobject_cast<const QTableView*>(widget))
+ newStyle = false;
+
+ if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
+ /*
+ // We cannot currently get the correct selection color for "explorer style" views
+ COLORREF cref = 0;
+ XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0);
+ unsigned int res = pGetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref);
+ QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+ */
+ QPalette palette = vopt->palette;
+ palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text));
+ // Note that setting a saturated color here results in ugly XOR colors in the focus rect
+ palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108));
+ QStyleOptionViewItemV4 adjustedOption = *vopt;
+ adjustedOption.palette = palette;
+ // We hide the focusrect in singleselection as it is not required
+ if ((view->selectionMode() == QAbstractItemView::SingleSelection)
+ && !(vopt->state & State_KeyboardFocusChange))
+ adjustedOption.state &= ~State_HasFocus;
+ QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget);
+ } else {
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ }
+ break;
+ }
+#endif // QT_NO_ITEMVIEWS
+
+ default:
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \internal
+
+ see drawPrimitive for comments on the animation support
+
+ */
+void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ return;
+ }
+
+ State state = option->state;
+ SubControls sub = option->subControls;
+ QRect r = option->rect;
+
+ int partId = 0;
+ int stateId = 0;
+
+ State flags = option->state;
+ if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
+ flags |= State_MouseOver;
+
+ if (d->transitionsEnabled() && widget) {
+ if ((qobject_cast<const QScrollBar *>(widget) && control == CC_ScrollBar)
+#ifndef QT_NO_SPINBOX
+ || (qobject_cast<const QAbstractSpinBox*>(widget) && control == CC_SpinBox)
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ || (qobject_cast<const QComboBox*>(widget) && control == CC_ComboBox)
+#endif // QT_NO_COMBOBOX
+ )
+ {
+ QWidget *w = const_cast<QWidget *> (widget);
+
+ int oldState = w->property("_q_stylestate").toInt();
+ int oldActiveControls = w->property("_q_stylecontrols").toInt();
+ QRect oldRect = w->property("_q_stylerect").toRect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylecontrols", (int)option->activeSubControls);
+ w->setProperty("_q_stylerect", w->rect());
+
+ bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver) ||
+ oldActiveControls != option->activeSubControls);
+
+
+ if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect oldSliderPos = w->property("_q_stylesliderpos").toRect();
+ QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ w->setProperty("_q_stylesliderpos", currentPos);
+ if (oldSliderPos != currentPos) {
+ doTransition = false;
+ d->stopAnimation(widget);
+ }
+ } else if (control == CC_SpinBox) {
+ //spinboxes have a transition when focus changes
+ if (!doTransition)
+ doTransition = (state & State_HasFocus) != (oldState & State_HasFocus);
+ }
+
+ if (oldRect != option->rect) {
+ doTransition = false;
+ d->stopAnimation(widget);
+ }
+
+ if (doTransition) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
+ t->setWidget(w);
+ if (!anim) {
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
+ //Combo boxes are special cased to avoid cleartype issues
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+ QStyleOptionComboBox startCombo = *combo;
+ startCombo.state = (QStyle::State)oldState;
+ startCombo.activeSubControls = (QStyle::SubControl)oldActiveControls;
+ proxy()->drawComplexControl(control, &startCombo, &startPainter, 0 /* Intentional */);
+ t->setStartImage(startImage);
+ } else if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
+ //This is a workaround for the direct3d engine as it currently has some issues with grabWindow
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+ QStyleOptionSlider startSlider = *slider;
+ startSlider.state = (QStyle::State)oldState;
+ startSlider.activeSubControls = (QStyle::SubControl)oldActiveControls;
+ proxy()->drawComplexControl(control, &startSlider, &startPainter, 0 /* Intentional */);
+ t->setStartImage(startImage);
+ } else {
+ QPoint offset(0, 0);
+ if (!widget->internalWinId())
+ offset = widget->mapTo(widget->nativeParentWidget(), offset);
+ t->setStartImage(QPixmap::grabWindow(widget->effectiveWinId(), offset.x(), offset.y(),
+ option->rect.width(), option->rect.height()).toImage());
+ }
+ } else {
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+ anim->paint(&startPainter, option);
+ t->setStartImage(startImage);
+ }
+ d->startAnimation(t);
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+ proxy()->drawComplexControl(control, option, &endPainter, 0 /* Intentional */);
+ t->setEndImage(endImage);
+ t->setStartTime(QTime::currentTime());
+
+ if (option->state & State_MouseOver || option->state & State_Sunken)
+ t->setDuration(150);
+ else
+ t->setDuration(500);
+ }
+
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
+ anim->paint(painter, option);
+ return;
+ }
+
+ }
+ }
+
+ switch (control) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ {
+ if (cmb->editable) {
+ if (sub & SC_ComboBoxEditField) {
+ partId = EP_EDITBORDER_NOSCROLL;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = ETS_FOCUSED;
+ else
+ stateId = ETS_NORMAL;
+
+ XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ComboBoxArrow) {
+ QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
+ XPThemeData theme(widget, painter, QLatin1String("COMBOBOX"));
+ theme.rect = subRect;
+ partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
+
+ if (!(cmb->state & State_Enabled))
+ stateId = CBXS_DISABLED;
+ else if (cmb->state & State_Sunken || cmb->state & State_On)
+ stateId = CBXS_PRESSED;
+ else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
+ stateId = CBXS_HOT;
+ else
+ stateId = CBXS_NORMAL;
+
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+
+ } else {
+ if (sub & SC_ComboBoxFrame) {
+ QStyleOptionButton btn;
+ btn.QStyleOption::operator=(*option);
+ btn.rect = option->rect.adjusted(-1, -1, 1, 1);
+ if (sub & SC_ComboBoxArrow)
+ btn.features = QStyleOptionButton::HasMenu;
+ proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget);
+ }
+ }
+ }
+ break;
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ {
+ XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR"));
+
+ bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
+ if (maxedOut)
+ flags &= ~State_Enabled;
+
+ bool isHorz = flags & State_Horizontal;
+ bool isRTL = option->direction == Qt::RightToLeft;
+ if (sub & SC_ScrollBarAddLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
+ else if (scrollbar->state & State_MouseOver)
+ stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSubLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
+ else if (scrollbar->state & State_MouseOver)
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (maxedOut) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
+ partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ stateId = SCRBS_DISABLED;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ } else {
+ if (sub & SC_ScrollBarSubPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
+ partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarAddPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
+ partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSlider) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else if (option->state & State_MouseOver)
+ stateId = SCRBS_HOVER;
+ else
+ stateId = SCRBS_NORMAL;
+
+ // Draw handle
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+
+ // Calculate rect of gripper
+ const int swidth = theme.rect.width();
+ const int sheight = theme.rect.height();
+
+ MARGINS contentsMargin;
+ RECT rect = theme.toRECT(theme.rect);
+ pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
+
+ SIZE size;
+ theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ int gw = size.cx, gh = size.cy;
+
+
+ QRect gripperBounds;
+ if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ }
+
+ // Draw gripper if there is enough space
+ if (!gripperBounds.isEmpty() && flags & State_Enabled) {
+ painter->save();
+ XPThemeData grippBackground = theme;
+ grippBackground.partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ theme.rect = gripperBounds;
+ painter->setClipRegion(d->region(theme));// Only change inside the region of the gripper
+ d->drawBackground(grippBackground);// The gutter is the grippers background
+ d->drawBackground(theme); // Transparent gripper ontop of background
+ painter->restore();
+ }
+ }
+ }
+ }
+ break;
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
+ {
+ XPThemeData theme(widget, painter, QLatin1String("SPIN"));
+ if (sb->frame && (sub & SC_SpinBoxFrame)) {
+ partId = EP_EDITBORDER_NOSCROLL;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = ETS_SELECTED;
+ else
+ stateId = ETS_NORMAL;
+
+ XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+ ftheme.noContent = true;
+ d->drawBackground(ftheme);
+ }
+ if (sub & SC_SpinBoxUp) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1);
+ partId = SPNP_UP;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
+ stateId = UPS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
+ stateId = UPS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
+ stateId = UPS_HOT;
+ else
+ stateId = UPS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_SpinBoxDown) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+ partId = SPNP_DOWN;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
+ stateId = DNS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
+ stateId = DNS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
+ stateId = DNS_HOT;
+ else
+ stateId = DNS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+ default:
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \internal
+ */
+QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista())
+ return QWindowsStyle::sizeFromContents(type, option, size, widget);
+
+ QSize sz(size);
+ switch (type) {
+ case CT_MenuItem:
+ sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+ int minimumHeight;
+ {
+ SIZE size;
+ MARGINS margins;
+ XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+ pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+ pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
+ minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height());
+ sz.rwidth() += size.cx + margins.cxLeftWidth + margins.cxRightWidth;
+ }
+
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ if (menuitem->menuItemType != QStyleOptionMenuItem::Separator)
+ sz.setHeight(minimumHeight);
+ }
+ return sz;
+#ifndef QT_NO_MENUBAR
+ case CT_MenuBarItem:
+ if (!sz.isEmpty())
+ sz += QSize(windowsItemHMargin * 5 + 1, 5);
+ return sz;
+ break;
+#endif
+ case CT_ItemViewItem:
+ sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+ sz.rheight() += 2;
+ return sz;
+ case CT_SpinBox:
+ {
+ //Spinbox adds frame twice
+ sz = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+ sz -= QSize(2*border, 2*border);
+ }
+ return sz;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+}
+
+/*!
+ \internal
+ */
+QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista())
+ return QWindowsStyle::subElementRect(element, option, widget);
+
+ QRect rect = QWindowsXPStyle::subElementRect(element, option, widget);
+ switch (element) {
+
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ MARGINS borderSize;
+ HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
+ if (theme) {
+ int stateId = PBS_NORMAL;
+ if (!(option->state & State_Enabled))
+ stateId = PBS_DISABLED;
+ else if (option->state & State_Sunken)
+ stateId = PBS_PRESSED;
+ else if (option->state & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton)
+ stateId = PBS_DEFAULTED;
+
+ int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+ rect = option->rect.adjusted(border, border, -border, -border);
+
+ int result = pGetThemeMargins(theme,
+ NULL,
+ BP_PUSHBUTTON,
+ stateId,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &borderSize);
+
+ if (result == S_OK) {
+ rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
+ -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ }
+ }
+ break;
+
+ case SE_HeaderArrow:
+ {
+ QRect r = rect;
+ int h = option->rect.height();
+ int w = option->rect.width();
+ int x = option->rect.x();
+ int y = option->rect.y();
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
+
+ XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
+
+ int arrowWidth = 13;
+ int arrowHeight = 5;
+ if (theme.isValid()) {
+ SIZE size;
+ if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
+ arrowWidth = size.cx;
+ arrowHeight = size.cy;
+ }
+ }
+ if (option->state & State_Horizontal) {
+ r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight);
+ } else {
+ int vert_size = w / 2;
+ r.setRect(x + 5, y + h - margin * 2 - vert_size,
+ w - margin * 2 - 5, vert_size);
+ }
+ rect = visualRect(option->direction, option->rect, r);
+ }
+ break;
+
+ case SE_HeaderLabel:
+ {
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
+ QRect r = option->rect;
+ r.setRect(option->rect.x() + margin, option->rect.y() + margin,
+ option->rect.width() - margin * 2, option->rect.height() - margin * 2);
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ // Subtract width needed for arrow, if there is one
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top
+ r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2));
+ }
+ }
+ rect = visualRect(option->direction, option->rect, r);
+ }
+ break;
+ case SE_ProgressBarContents:
+ rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
+ break;
+ case SE_ItemViewItemDecoration:
+ if (qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))
+ rect.adjust(-2, 0, 2, 0);
+ break;
+ case SE_ItemViewItemFocusRect:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+ QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget);
+ if (!vopt->icon.isNull())
+ rect = textRect.united(displayRect);
+ else
+ rect = textRect;
+ rect = rect.adjusted(1, 0, -1, 0);
+ }
+ break;
+ default:
+ break;
+ }
+ return rect;
+}
+
+
+/*
+ This function is used by subControlRect to check if a button
+ should be drawn for the given subControl given a set of window flags.
+*/
+static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ const uint flags = tb->titleBarFlags;
+ bool retVal = false;
+ switch (sc) {
+ case QStyle::SC_TitleBarContextHelpButton:
+ if (flags & Qt::WindowContextHelpButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMinButton:
+ if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarNormalButton:
+ if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMaxButton:
+ if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarShadeButton:
+ if (!isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarUnshadeButton:
+ if (isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarCloseButton:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarSysMenu:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ default :
+ retVal = true;
+ }
+ return retVal;
+}
+
+
+/*! \internal */
+int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+ int ret = 0;
+ switch (hint) {
+ case SH_MessageBox_CenterButtons:
+ ret = false;
+ break;
+ case SH_ToolTip_Mask:
+ if (option) {
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
+ ret = true;
+ XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+ mask->region = d->region(themeData);
+ }
+ }
+ break;
+ case SH_Table_GridLineColor:
+ if (option)
+ ret = option->palette.color(QPalette::Base).darker(118).rgb();
+ else
+ ret = -1;
+ break;
+ default:
+ ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+
+/*!
+ \internal
+ */
+QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista())
+ return QWindowsStyle::subControlRect(control, option, subControl, widget);
+
+ QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
+ switch (control) {
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int x = cb->rect.x(),
+ y = cb->rect.y(),
+ wi = cb->rect.width(),
+ he = cb->rect.height();
+ int xpos = x;
+ int margin = cb->frame ? 3 : 0;
+ int bmarg = cb->frame ? 2 : 0;
+ int arrowButtonWidth = bmarg + 16;
+ xpos += wi - arrowButtonWidth;
+
+ switch (subControl) {
+ case SC_ComboBoxFrame:
+ rect = cb->rect;
+ break;
+ case SC_ComboBoxArrow:
+ rect.setRect(xpos, y , arrowButtonWidth, he);
+ break;
+ case SC_ComboBoxEditField:
+ rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
+ break;
+ case SC_ComboBoxListBoxPopup:
+ rect = cb->rect;
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(cb->direction, cb->rect, rect);
+ return rect;
+ }
+#endif // QT_NO_COMBOBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ if (!buttonVisible(subControl, tb))
+ return rect;
+ const bool isToolTitle = false;
+ const int height = tb->rect.height();
+ const int width = tb->rect.width();
+ int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
+
+ const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
+ const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
+ const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
+ const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
+ const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
+ const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
+
+ switch (subControl) {
+ case SC_TitleBarLabel:
+ rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
+ if (isToolTitle) {
+ if (sysmenuHint) {
+ rect.adjust(0, 0, -buttonWidth - 3, 0);
+ }
+ if (minimizeHint || maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ } else {
+ if (sysmenuHint) {
+ const int leftOffset = height - 8;
+ rect.adjust(leftOffset, 0, 0, 4);
+ }
+ if (minimizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (contextHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (shadeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ }
+ rect.translate(0, 2);
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ case SC_TitleBarSysMenu:
+ {
+ const int controlTop = 6;
+ const int controlHeight = height - controlTop - 3;
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
+ if (tb->icon.isNull())
+ iconSize = QSize(controlHeight, controlHeight);
+ int hPad = (controlHeight - iconSize.height())/2;
+ int vPad = (controlHeight - iconSize.width())/2;
+ rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
+ rect.translate(0, 3);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return rect;
+}
+
+/*!
+ \internal
+ */
+bool QWindowsVistaStyle::event(QEvent *e)
+{
+ Q_D(QWindowsVistaStyle);
+ switch (e->type()) {
+ case QEvent::Timer:
+ {
+ QTimerEvent *timerEvent = (QTimerEvent *)e;
+ if (d->animationTimer.timerId() == timerEvent->timerId()) {
+ d->timerEvent();
+ e->accept();
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::event(e);
+}
+
+/*!
+ \internal
+ */
+QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
+ }
+ return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+/*!
+ \internal
+ */
+int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::pixelMetric(metric, option, widget);
+ }
+ switch (metric) {
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ return int(QStyleHelper::dpiScaled(5.));
+ case PM_ScrollBarSliderMin:
+ return int(QStyleHelper::dpiScaled(18.));
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ return 0;
+ case PM_MenuPanelWidth:
+ return 3;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::pixelMetric(metric, option, widget);
+}
+
+/*!
+ \internal
+ */
+QPalette QWindowsVistaStyle::standardPalette() const
+{
+ return QWindowsXPStyle::standardPalette();
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QApplication *app)
+{
+ QWindowsXPStyle::polish(app);
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QWidget *widget)
+{
+ QWindowsXPStyle::polish(widget);
+#ifndef QT_NO_LINEEDIT
+ if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else
+#endif // QT_NO_LINEEDIT
+ if (qobject_cast<QGroupBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else if (qobject_cast<QCommandLinkButton*>(widget)) {
+ QFont buttonFont = widget->font();
+ buttonFont.setFamily(QLatin1String("Segoe UI"));
+ widget->setFont(buttonFont);
+ }
+ else if (widget->inherits("QTipLabel")){
+ //note that since tooltips are not reused
+ //we do not have to care about unpolishing
+ widget->setContentsMargins(3, 0, 4, 0);
+ COLORREF bgRef;
+ HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
+ if (theme) {
+ if (pGetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef) == S_OK) {
+ QColor textColor = QColor::fromRgb(bgRef);
+ QPalette pal;
+ pal.setColor(QPalette::All, QPalette::ToolTipText, textColor);
+ widget->setPalette(pal);
+ }
+ }
+ } else if (qobject_cast<QMessageBox *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 9, 0, 0);
+ }
+#ifndef QT_NO_INPUTDIALOG
+ else if (qobject_cast<QInputDialog *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 9, 0, 0);
+ }
+#endif // QT_NO_INPUTDIALOG
+ else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
+ tree->viewport()->setAttribute(Qt::WA_Hover);
+ }
+ else if (QListView *list = qobject_cast<QListView *> (widget)) {
+ list->viewport()->setAttribute(Qt::WA_Hover);
+ }
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::unpolish(QWidget *widget)
+{
+ QWindowsXPStyle::unpolish(widget);
+
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+ d->stopAnimation(widget);
+
+#ifndef QT_NO_LINEEDIT
+ if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else
+#endif // QT_NO_LINEEDIT
+ if (qobject_cast<QGroupBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else if (qobject_cast<QMessageBox *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 0, 0, 0);
+ }
+#ifndef QT_NO_INPUTDIALOG
+ else if (qobject_cast<QInputDialog *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 0, 0, 0);
+ }
+#endif // QT_NO_INPUTDIALOG
+ else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
+ tree->viewport()->setAttribute(Qt::WA_Hover, false);
+ } else if (qobject_cast<QCommandLinkButton*>(widget)) {
+ QFont font = QApplication::font("QCommandLinkButton");
+ QFont widgetFont = widget->font();
+ widgetFont.setFamily(font.family()); //Only family set by polish
+ widget->setFont(widgetFont);
+ }
+}
+
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::unpolish(QApplication *app)
+{
+ QWindowsXPStyle::unpolish(app);
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QPalette &pal)
+{
+ QWindowsStyle::polish(pal);
+ pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104));
+}
+
+/*!
+ \internal
+ */
+QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+ }
+ return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() :
+ QWindowsXPStylePrivate(), m_treeViewHelper(0)
+{
+ resolveSymbols();
+}
+
+QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate()
+{
+ delete m_treeViewHelper;
+}
+
+void QWindowsVistaStylePrivate::timerEvent()
+{
+ for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+
+ if (animations[i]->widget())
+ animations[i]->widget()->update();
+
+ if (!animations[i]->widget() ||
+ !animations[i]->widget()->isVisible() ||
+ animations[i]->widget()->window()->isMinimized() ||
+ !animations[i]->running() ||
+ !QWindowsVistaStylePrivate::useVista())
+ {
+ QWindowsVistaAnimation *a = animations.takeAt(i);
+ delete a;
+ }
+ }
+ if (animations.size() == 0 && animationTimer.isActive()) {
+ animationTimer.stop();
+ }
+}
+
+void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w)
+{
+ for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+ if (animations[i]->widget() == w) {
+ QWindowsVistaAnimation *a = animations.takeAt(i);
+ delete a;
+ break;
+ }
+ }
+}
+
+void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t)
+{
+ Q_Q(QWindowsVistaStyle);
+ stopAnimation(t->widget());
+ animations.append(t);
+ if (animations.size() > 0 && !animationTimer.isActive()) {
+ animationTimer.start(45, q);
+ }
+}
+
+bool QWindowsVistaStylePrivate::transitionsEnabled() const
+{
+ BOOL animEnabled = false;
+ if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0))
+ {
+ if (animEnabled)
+ return true;
+ }
+ return false;
+}
+
+
+QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
+{
+ if (!widget)
+ return 0;
+ foreach (QWindowsVistaAnimation *a, animations) {
+ if (a->widget() == widget)
+ return a;
+ }
+ return 0;
+}
+
+
+/*! \internal
+ Returns true if all the necessary theme engine symbols were
+ resolved.
+*/
+bool QWindowsVistaStylePrivate::resolveSymbols()
+{
+ static bool tried = false;
+ if (!tried) {
+ tried = true;
+ QSystemLibrary themeLib(QLatin1String("uxtheme"));
+ pSetWindowTheme = (PtrSetWindowTheme )themeLib.resolve("SetWindowTheme");
+ pIsThemePartDefined = (PtrIsThemePartDefined )themeLib.resolve("IsThemePartDefined");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
+ pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
+ pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
+ pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
+ pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
+ pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
+ pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
+ pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
+ pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
+ pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
+ pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
+ pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
+ pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
+ pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
+ pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
+ pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
+ pGetThemeTransitionDuration = (PtrGetThemeTransitionDuration)themeLib.resolve("GetThemeTransitionDuration");
+ pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+ }
+ return pGetThemeTransitionDuration != 0;
+}
+
+/*
+ * We need to set the windows explorer theme explicitly on a native widget
+ * in order to get Vista-style item view themes
+ */
+QWidget *QWindowsVistaStylePrivate::treeViewHelper()
+{
+ if (!m_treeViewHelper) {
+ m_treeViewHelper = new QWidget(0);
+ pSetWindowTheme(m_treeViewHelper->winId(), L"explorer", NULL);
+ }
+ return m_treeViewHelper;
+}
+
+
+/*!
+\internal
+*/
+QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func());
+ switch(standardIcon) {
+ case SP_CommandLink:
+ {
+ XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ QIcon linkGlyph;
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+
+ theme.stateId = CMDLGS_PRESSED;
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+
+ theme.stateId = CMDLGS_HOT;
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+
+ theme.stateId = CMDLGS_DISABLED;
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ return linkGlyph;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_WINDOWSVISTA
diff --git a/src/widgets/styles/qwindowsvistastyle.h b/src/widgets/styles/qwindowsvistastyle.h
new file mode 100644
index 0000000000..24d673091a
--- /dev/null
+++ b/src/widgets/styles/qwindowsvistastyle.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSVISTASTYLE_H
+#define QWINDOWSVISTASTYLE_H
+
+#include <QtWidgets/qwindowsxpstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+
+class QWindowsVistaStylePrivate;
+class Q_GUI_EXPORT QWindowsVistaStyle : public QWindowsXPStyle
+{
+ Q_OBJECT
+public:
+ QWindowsVistaStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+ void unpolish(QApplication *app);
+ bool event(QEvent *event);
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QWindowsVistaStyle)
+ Q_DECLARE_PRIVATE(QWindowsVistaStyle)
+ friend class QStyleFactory;
+};
+#endif //QT_NO_STYLE_WINDOWSVISTA
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QWINDOWSVISTASTYLE_H
diff --git a/src/widgets/styles/qwindowsvistastyle_p.h b/src/widgets/styles/qwindowsvistastyle_p.h
new file mode 100644
index 0000000000..4167bc4d0f
--- /dev/null
+++ b/src/widgets/styles/qwindowsvistastyle_p.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSVISTASTYLE_P_H
+#define QWINDOWSVISTASTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsvistastyle.h"
+
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+#include <private/qwindowsxpstyle_p.h>
+#include <private/qpaintengine_raster_p.h>
+#include <qlibrary.h>
+#include <qpaintengine.h>
+#include <qwidget.h>
+#include <qapplication.h>
+#include <qpixmapcache.h>
+#include <qstyleoption.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qgroupbox.h>
+#include <qtoolbutton.h>
+#include <qspinbox.h>
+#include <qtoolbar.h>
+#include <qcombobox.h>
+#include <qscrollbar.h>
+#include <qprogressbar.h>
+#include <qdockwidget.h>
+#include <qlistview.h>
+#include <qtreeview.h>
+#include <qtextedit.h>
+#include <qmessagebox.h>
+#include <qdialogbuttonbox.h>
+#include <qinputdialog.h>
+#include <qtreeview.h>
+#include <qlistview.h>
+#include <qtableview.h>
+#include <qbasictimer.h>
+#include <qdatetime.h>
+#include <qcommandlinkbutton.h>
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(SCHEMA_VERIFY_VSSYM32)
+#define TMT_ANIMATIONDURATION 5006
+#define TMT_TRANSITIONDURATIONS 6000
+#define EP_EDITBORDER_NOSCROLL 6
+#define EP_EDITBORDER_HVSCROLL 9
+#define EP_BACKGROUND 3
+#define EBS_NORMAL 1
+#define EBS_HOT 2
+#define EBS_DISABLED 3
+#define EBS_READONLY 5
+#define PBS_DEFAULTED_ANIMATING 6
+#define MBI_NORMAL 1
+#define MBI_HOT 2
+#define MBI_PUSHED 3
+#define MBI_DISABLED 4
+#define MB_ACTIVE 1
+#define MB_INACTIVE 2
+#define PP_FILL 5
+#define PP_FILLVERT 6
+#define PP_MOVEOVERLAY 8
+#define PP_MOVEOVERLAYVERT 10
+#define MENU_BARBACKGROUND 7
+#define MENU_BARITEM 8
+#define MENU_POPUPCHECK 11
+#define MENU_POPUPCHECKBACKGROUND 12
+#define MENU_POPUPGUTTER 13
+#define MENU_POPUPITEM 14
+#define MENU_POPUPBORDERS 10
+#define MENU_POPUPSEPARATOR 15
+#define MC_CHECKMARKNORMAL 1
+#define MC_CHECKMARKDISABLED 2
+#define MC_BULLETNORMAL 3
+#define MC_BULLETDISABLED 4
+#define ABS_UPHOVER 17
+#define ABS_DOWNHOVER 18
+#define ABS_LEFTHOVER 19
+#define ABS_RIGHTHOVER 20
+#define CP_DROPDOWNBUTTONRIGHT 6
+#define CP_DROPDOWNBUTTONLEFT 7
+#define SCRBS_HOVER 5
+#define TVP_HOTGLYPH 4
+#define SPI_GETCLIENTAREAANIMATION 0x1042
+#define TDLG_PRIMARYPANEL 1
+#define TDLG_SECONDARYPANEL 8
+#endif
+
+class QWindowsVistaAnimation
+{
+public :
+ QWindowsVistaAnimation() : _running(true) { }
+ virtual ~QWindowsVistaAnimation() { }
+ QWidget * widget() const { return _widget; }
+ bool running() const { return _running; }
+ const QTime &startTime() const { return _startTime; }
+ void setRunning(bool val) { _running = val; }
+ void setWidget(QWidget *widget) { _widget = widget; }
+ void setStartTime(const QTime &startTime) { _startTime = startTime; }
+ virtual void paint(QPainter *painter, const QStyleOption *option);
+
+protected:
+ void drawBlendedImage(QPainter *painter, QRect rect, float value);
+ QTime _startTime;
+ QPointer<QWidget> _widget;
+ QImage _primaryImage;
+ QImage _secondaryImage;
+ QImage _tempImage;
+ bool _running;
+};
+
+
+// Handles state transition animations
+class QWindowsVistaTransition : public QWindowsVistaAnimation
+{
+public :
+ QWindowsVistaTransition() : QWindowsVistaAnimation() {}
+ virtual ~QWindowsVistaTransition() { }
+ void setDuration(int duration) { _duration = duration; }
+ void setStartImage(const QImage &image) { _primaryImage = image; }
+ void setEndImage(const QImage &image) { _secondaryImage = image; }
+ virtual void paint(QPainter *painter, const QStyleOption *option);
+ int duration() const { return _duration; }
+ int _duration; //set time in ms to complete a state transition
+};
+
+
+// Handles pulse animations (default buttons)
+class QWindowsVistaPulse: public QWindowsVistaAnimation
+{
+public :
+ QWindowsVistaPulse() : QWindowsVistaAnimation() {}
+ virtual ~QWindowsVistaPulse() { }
+ void setDuration(int duration) { _duration = duration; }
+ void setPrimaryImage(const QImage &image) { _primaryImage = image; }
+ void setAlternateImage(const QImage &image) { _secondaryImage = image; }
+ virtual void paint(QPainter *painter, const QStyleOption *option);
+ int duration() const { return _duration; }
+ int _duration; //time in ms to complete a pulse cycle
+};
+
+
+class QWindowsVistaStylePrivate : public QWindowsXPStylePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsVistaStyle)
+
+public:
+ QWindowsVistaStylePrivate();
+ ~QWindowsVistaStylePrivate();
+ static bool resolveSymbols();
+ static inline bool useVista();
+ void startAnimation(QWindowsVistaAnimation *);
+ void stopAnimation(const QWidget *);
+ QWindowsVistaAnimation* widgetAnimation(const QWidget *) const;
+ void timerEvent();
+ bool transitionsEnabled() const;
+ QWidget *treeViewHelper();
+
+private:
+ QList <QWindowsVistaAnimation*> animations;
+ QBasicTimer animationTimer;
+ QWidget *m_treeViewHelper;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWSVISTA
+
+#endif // QWINDOWSVISTASTYLE_P_H
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
new file mode 100644
index 0000000000..3c33df3d11
--- /dev/null
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -0,0 +1,4277 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qwindowsxpstyle.h"
+#include "qwindowsxpstyle_p.h"
+
+#if !defined(QT_NO_STYLE_WINDOWSXP) || defined(QT_PLUGIN)
+
+#include <private/qobject_p.h>
+#include <private/qpaintengine_raster_p.h>
+#include <private/qapplication_p.h>
+#include <private/qstylehelper_p.h>
+#include <private/qwidget_p.h>
+#include <private/qsystemlibrary_p.h>
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <qwidget.h>
+#include <qapplication.h>
+#include <qpixmapcache.h>
+
+#include <qdesktopwidget.h>
+#include <qtoolbutton.h>
+#include <qtabbar.h>
+#include <qcombobox.h>
+#include <qscrollbar.h>
+#include <qheaderview.h>
+#include <qspinbox.h>
+#include <qlistview.h>
+#include <qstackedwidget.h>
+#include <qpushbutton.h>
+#include <qtoolbar.h>
+#include <qlabel.h>
+#include <qvarlengtharray.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+// Runtime resolved theme engine function calls
+typedef bool (WINAPI *PtrIsAppThemed)();
+typedef bool (WINAPI *PtrIsThemeActive)();
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+typedef HRESULT (WINAPI *PtrGetThemeDocumentationProperty)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, OUT LPWSTR pszValueBuff, int cchMaxValChars);
+typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
+typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
+typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
+typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
+typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
+typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
+typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeBackgroundRegion)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pRect, OUT HRGN *pRegion);
+typedef BOOL (WINAPI *PtrIsThemeBackgroundPartiallyTransparent)(HTHEME hTheme, int iPartId, int iStateId);
+
+static PtrIsAppThemed pIsAppThemed = 0;
+static PtrIsThemeActive pIsThemeActive = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+static PtrGetThemeBool pGetThemeBool = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
+static PtrGetThemeFilename pGetThemeFilename = 0;
+static PtrGetThemeFont pGetThemeFont = 0;
+static PtrGetThemeInt pGetThemeInt = 0;
+static PtrGetThemeIntList pGetThemeIntList = 0;
+static PtrGetThemeMargins pGetThemeMargins = 0;
+static PtrGetThemeMetric pGetThemeMetric = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemePosition pGetThemePosition = 0;
+static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
+static PtrGetThemeRect pGetThemeRect = 0;
+static PtrGetThemeString pGetThemeString = 0;
+static PtrGetThemeBackgroundRegion pGetThemeBackgroundRegion = 0;
+static PtrGetThemeDocumentationProperty pGetThemeDocumentationProperty = 0;
+static PtrIsThemeBackgroundPartiallyTransparent pIsThemeBackgroundPartiallyTransparent = 0;
+
+// General const values
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 0; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 12; // right border on windows
+
+// External function calls
+extern Q_GUI_EXPORT HDC qt_win_display_dc();
+extern QRegion qt_region_from_HRGN(HRGN rgn);
+
+
+
+// Theme data helper ------------------------------------------------------------------------------
+/* \internal
+ Returns true if the themedata is valid for use.
+*/
+bool XPThemeData::isValid()
+{
+ return QWindowsXPStylePrivate::useXP() && name.size() && handle();
+}
+
+
+/* \internal
+ Returns the theme engine handle to the specific class.
+ If the handle hasn't been opened before, it opens the data, and
+ adds it to a static map, for caching.
+*/
+HTHEME XPThemeData::handle()
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return 0;
+
+ if (!htheme && QWindowsXPStylePrivate::handleMap)
+ htheme = QWindowsXPStylePrivate::handleMap->operator[](name);
+
+ if (!htheme) {
+ htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16());
+ if (htheme) {
+ if (!QWindowsXPStylePrivate::handleMap)
+ QWindowsXPStylePrivate::handleMap = new QMap<QString, HTHEME>;
+ QWindowsXPStylePrivate::handleMap->operator[](name) = htheme;
+ }
+ }
+
+ return htheme;
+}
+
+/* \internal
+ Converts a QRect to the native RECT structure.
+*/
+RECT XPThemeData::toRECT(const QRect &qr)
+{
+ RECT r;
+ r.left = qr.x();
+ r.right = qr.x() + qr.width();
+ r.top = qr.y();
+ r.bottom = qr.y() + qr.height();
+ return r;
+}
+
+/* \internal
+ Returns the native region of a part, if the part is considered
+ transparent. The region is scaled to the parts size (rect).
+*/
+HRGN XPThemeData::mask()
+{
+ if (!pIsThemeBackgroundPartiallyTransparent(handle(), partId, stateId))
+ return 0;
+
+ HRGN hrgn;
+ HDC dc = painter == 0 ? 0 : painter->paintEngine()->getDC();
+ RECT nativeRect = toRECT(rect);
+ pGetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn);
+ if (dc)
+ painter->paintEngine()->releaseDC(dc);
+ return hrgn;
+}
+
+// QWindowsXPStylePrivate -------------------------------------------------------------------------
+// Static initializations
+QWidget *QWindowsXPStylePrivate::limboWidget = 0;
+QPixmap *QWindowsXPStylePrivate::tabbody = 0;
+QMap<QString,HTHEME> *QWindowsXPStylePrivate::handleMap = 0;
+bool QWindowsXPStylePrivate::use_xp = false;
+QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
+
+/* \internal
+ Checks if the theme engine can/should be used, or if we should
+ fall back to Windows style.
+*/
+bool QWindowsXPStylePrivate::useXP(bool update)
+{
+ if (!update)
+ return use_xp;
+ return (use_xp = resolveSymbols() && pIsThemeActive()
+ && (pIsAppThemed() || !QApplication::instance()));
+}
+
+/* \internal
+ Handles refcounting, and queries the theme engine for usage.
+*/
+void QWindowsXPStylePrivate::init(bool force)
+{
+ if (ref.ref() && !force)
+ return;
+ if (!force) // -1 based atomic refcounting
+ ref.ref();
+
+ useXP(true);
+}
+
+/* \internal
+ Cleans up all static data.
+*/
+void QWindowsXPStylePrivate::cleanup(bool force)
+{
+ if(bufferBitmap) {
+ if (bufferDC && nullBitmap)
+ SelectObject(bufferDC, nullBitmap);
+ DeleteObject(bufferBitmap);
+ bufferBitmap = 0;
+ }
+
+ if(bufferDC)
+ DeleteDC(bufferDC);
+ bufferDC = 0;
+
+ if (ref.deref() && !force)
+ return;
+ if (!force) // -1 based atomic refcounting
+ ref.deref();
+
+ use_xp = false;
+ cleanupHandleMap();
+ if (limboWidget) {
+ if (QApplication::closingDown())
+ delete limboWidget;
+ else
+ limboWidget->deleteLater();
+ }
+ delete tabbody;
+ limboWidget = 0;
+ tabbody = 0;
+}
+
+/* \internal
+ Closes all open theme data handles to ensure that we don't leak
+ resources, and that we don't refere to old handles when for
+ example the user changes the theme style.
+*/
+void QWindowsXPStylePrivate::cleanupHandleMap()
+{
+ if (!handleMap)
+ return;
+
+ QMap<QString, HTHEME>::Iterator it;
+ for (it = handleMap->begin(); it != handleMap->end(); ++it)
+ pCloseThemeData(it.value());
+ delete handleMap;
+ handleMap = 0;
+}
+
+/*! \internal
+ This function will always return a valid window handle, and might
+ create a limbo widget to do so.
+ We often need a window handle to for example open theme data, so
+ this function ensures that we get one.
+*/
+HWND QWindowsXPStylePrivate::winId(const QWidget *widget)
+{
+ if (widget && widget->internalWinId())
+ return widget->internalWinId();
+
+ if (!limboWidget) {
+ limboWidget = new QWidget(0);
+ limboWidget->createWinId();
+ limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
+ // We don't need this internal widget to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets)
+ QWidgetPrivate::allWidgets->remove(limboWidget);
+ }
+
+ return limboWidget->winId();
+}
+
+/*! \internal
+ Returns the pointer to a tab widgets body pixmap, scaled to the
+ height of the screen. This way the theme engine doesn't need to
+ scale the body for every time we ask for it. (Speed optimization)
+*/
+const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *)
+{
+ if (!tabbody) {
+ SIZE sz;
+ XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY);
+ pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
+
+ tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
+ QPainter painter(tabbody);
+ theme.rect = QRect(0, 0, sz.cx, sz.cy);
+ drawBackground(theme);
+ // We fill with the last line of the themedata, that
+ // way we don't get a tiled pixmap inside big tabs
+ QPixmap temp(sz.cx, 1);
+ painter.drawPixmap(0, 0, temp, 0, sz.cy-1, -1, -1);
+ painter.drawTiledPixmap(0, sz.cy, sz.cx, tabbody->height()-sz.cy, temp);
+ }
+ return tabbody;
+}
+
+/*! \internal
+ Returns true if all the necessary theme engine symbols were
+ resolved.
+*/
+bool QWindowsXPStylePrivate::resolveSymbols()
+{
+ static bool tried = false;
+ if (!tried) {
+ tried = true;
+ QSystemLibrary themeLib(QLatin1String("uxtheme"));
+ pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
+ if (pIsAppThemed) {
+ pIsThemeActive = (PtrIsThemeActive )themeLib.resolve("IsThemeActive");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
+ pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
+ pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
+ pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
+ pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
+ pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
+ pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
+ pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
+ pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
+ pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
+ pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
+ pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
+ pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
+ pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
+ pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+ pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
+ pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
+ pGetThemeBackgroundRegion = (PtrGetThemeBackgroundRegion )themeLib.resolve("GetThemeBackgroundRegion");
+ pGetThemeDocumentationProperty = (PtrGetThemeDocumentationProperty )themeLib.resolve("GetThemeDocumentationProperty");
+ pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
+ }
+ }
+
+ return pIsAppThemed != 0;
+}
+
+/*! \internal
+ Returns a native buffer (DIB section) of at least the size of
+ ( \a x , \a y ). The buffer has a 32 bit depth, to not lose
+ the alpha values on proper alpha-pixmaps.
+*/
+HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
+{
+ // If we already have a HBITMAP which is of adequate size, just return that
+ if (bufferBitmap) {
+ if (bufferW >= w && bufferH >= h)
+ return bufferBitmap;
+ // Not big enough, discard the old one
+ if (bufferDC && nullBitmap)
+ SelectObject(bufferDC, nullBitmap);
+ DeleteObject(bufferBitmap);
+ bufferBitmap = 0;
+ }
+
+ w = qMax(bufferW, w);
+ h = qMax(bufferH, h);
+
+ if (!bufferDC)
+ bufferDC = CreateCompatibleDC(qt_win_display_dc());
+
+ // Define the header
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ // Create the pixmap
+ bufferPixels = 0;
+ bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
+ GdiFlush();
+ nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
+
+ if (!bufferBitmap) {
+ qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection");
+ bufferW = 0;
+ bufferH = 0;
+ return 0;
+ }
+ if (!bufferPixels) {
+ qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data");
+ bufferW = 0;
+ bufferH = 0;
+ return 0;
+ }
+ bufferW = w;
+ bufferH = h;
+#ifdef DEBUG_XP_STYLE
+ qDebug("Creating new dib section (%d, %d)", w, h);
+#endif
+ return bufferBitmap;
+}
+
+/*! \internal
+ Returns true if the part contains any transparency at all. This does
+ not indicate what kind of transparency we're dealing with. It can be
+ - Alpha transparency
+ - Masked transparency
+*/
+bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
+{
+ return pIsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId,
+ themeData.stateId);
+}
+
+
+/*! \internal
+ Returns a QRegion of the region of the part
+*/
+QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
+{
+ HRGN hRgn = 0;
+ RECT rect = themeData.toRECT(themeData.rect);
+ if (!SUCCEEDED(pGetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
+ themeData.stateId, &rect, &hRgn)))
+ return QRegion();
+
+ HRGN dest = CreateRectRgn(0, 0, 0, 0);
+ const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
+
+ QRegion region;
+
+ if (success)
+ region = qt_region_from_HRGN(dest);
+
+ DeleteObject(hRgn);
+ DeleteObject(dest);
+
+ return region;
+}
+
+/*! \internal
+ Sets the parts region on a window.
+*/
+void QWindowsXPStylePrivate::setTransparency(QWidget *widget, XPThemeData &themeData)
+{
+ HRGN hrgn = themeData.mask();
+ if (hrgn && widget)
+ SetWindowRgn(winId(widget), hrgn, true);
+}
+
+/*! \internal
+ Returns true if the native doublebuffer contains a pixel which
+ has a non-0xFF alpha value. Should only be use when its
+ guaranteed that data painted into the buffer wasn't a proper
+ alpha pixmap.
+*/
+bool QWindowsXPStylePrivate::hasAnyData(const QRect &rect)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+
+ for (int y = startY; y < h; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (int x = startX; x < w; ++x, ++buffer) {
+ int alpha = (*buffer) >> 24;
+ if (alpha != 0xFF) // buffer has been touched
+ return true;
+ }
+ }
+ return false;
+}
+
+/*! \internal
+ Returns true if the native doublebuffer contains pixels with
+ varying alpha value.
+*/
+bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+
+ int firstAlpha = -1;
+ for (int y = startY; y < h/2; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (int x = startX; x < w; ++x, ++buffer) {
+ int alpha = (*buffer) >> 24;
+ if (firstAlpha == -1)
+ firstAlpha = alpha;
+ else if (alpha != firstAlpha)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*! \internal
+ When the theme engine paints both a true alpha pixmap and a glyph
+ into our buffer, the glyph might not contain a proper alpha value.
+ The rule of thumb for premultiplied pixmaps is that the color
+ values of a pixel can never be higher than the alpha values, so
+ we use this to our advantage here, and fix all instances where
+ this occures.
+*/
+bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+ bool hasFixedAlphaValue = false;
+
+ for (int y = startY; y < h; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (register int x = startX; x < w; ++x, ++buffer) {
+ uint pixel = *buffer;
+ int alpha = qAlpha(pixel);
+ if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {
+ *buffer |= 0xff000000;
+ hasFixedAlphaValue = true;
+ }
+ }
+ }
+ return hasFixedAlphaValue;
+}
+
+/*! \internal
+ Swaps the alpha values on certain pixels:
+ 0xFF?????? -> 0x00??????
+ 0x00?????? -> 0xFF??????
+ Used to determin the mask of a non-alpha transparent pixmap in
+ the native doublebuffer, and swap the alphas so we may paint
+ the image as a Premultiplied QImage with drawImage(), and obtain
+ the mask transparency.
+*/
+bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+ bool valueChange = false;
+
+ // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
+ for (int y = startY; y < h; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (register int x = startX; x < w; ++x, ++buffer) {
+ if (allPixels) {
+ *buffer |= 0xFF000000;
+ continue;
+ }
+ register unsigned int alphaValue = (*buffer) & 0xFF000000;
+ if (alphaValue == 0xFF000000) {
+ *buffer = 0;
+ valueChange = true;
+ } else if (alphaValue == 0) {
+ *buffer |= 0xFF000000;
+ valueChange = true;
+ }
+ }
+ }
+ return valueChange;
+}
+
+/*! \internal
+ Main theme drawing function.
+ Determines the correct lowlevel drawing method depending on several
+ factors.
+ Use drawBackgroundThruNativeBuffer() if:
+ - Painter does not have an HDC
+ - Theme part is flipped (mirrored horizontally)
+ else use drawBackgroundDirectly().
+*/
+void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
+{
+ if (themeData.rect.isEmpty())
+ return;
+
+ QPainter *painter = themeData.painter;
+ Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
+ if (!painter || !painter->isActive())
+ return;
+
+ painter->save();
+
+ bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate;
+
+ bool translucentToplevel = false;
+ QPaintDevice *pdev = painter->device();
+ if (pdev->devType() == QInternal::Widget) {
+ QWidget *win = ((QWidget *) pdev)->window();
+ translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground);
+ }
+
+ bool useFallback = painter->paintEngine()->getDC() == 0
+ || painter->opacity() != 1.0
+ || themeData.rotate
+ || complexXForm
+ || themeData.mirrorVertically
+ || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0)
+ || translucentToplevel;
+
+ if (!useFallback)
+ drawBackgroundDirectly(themeData);
+ else
+ drawBackgroundThruNativeBuffer(themeData);
+
+ painter->restore();
+}
+
+/*! \internal
+ This function draws the theme parts directly to the paintengines HDC.
+ Do not use this if you need to perform other transformations on the
+ resulting data.
+*/
+void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
+{
+ QPainter *painter = themeData.painter;
+ HDC dc = painter->paintEngine()->getDC();
+
+ QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
+ int(painter->deviceMatrix().dy()));
+ QRect area = themeData.rect.translated(redirectionDelta);
+
+ QRegion sysRgn = painter->paintEngine()->systemClip();
+ if (sysRgn.isEmpty())
+ sysRgn = area;
+ else
+ sysRgn &= area;
+ if (painter->hasClipping())
+ sysRgn &= painter->clipRegion().translated(redirectionDelta);
+ SelectClipRgn(dc, sysRgn.handle());
+
+#ifdef DEBUG_XP_STYLE
+ printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",
+ qPrintable(themeData.name), themeData.partId, themeData.stateId);
+ showProperties(themeData);
+#endif
+
+ RECT drawRECT = themeData.toRECT(area);
+ DTBGOPTS drawOptions;
+ drawOptions.dwSize = sizeof(drawOptions);
+ drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
+ drawOptions.dwFlags = DTBG_CLIPRECT
+ | (themeData.noBorder ? DTBG_OMITBORDER : 0)
+ | (themeData.noContent ? DTBG_OMITCONTENT : 0)
+ | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
+
+ if (pDrawThemeBackgroundEx != 0) {
+ pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
+ } else {
+ // We are running on a system where the uxtheme.dll does not have
+ // the DrawThemeBackgroundEx function, so we need to clip away
+ // borders or contents manually. All flips and mirrors uses the
+ // fallback implementation
+
+ int borderSize = 0;
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
+ pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
+
+ // Clip away border region
+ QRegion extraClip = sysRgn;
+ if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
+ if (themeData.noBorder) {
+ // extraClip &= area is already done
+ drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));
+ }
+
+ // Clip away content region
+ if (themeData.noContent) {
+ QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ extraClip ^= content;
+ }
+
+ // Set the clip region, if used..
+ if (themeData.noBorder || themeData.noContent)
+ SelectClipRgn(dc, extraClip.handle());
+ }
+
+ pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
+ }
+ SelectClipRgn(dc, 0);
+}
+
+/*! \internal
+ This function uses a secondary Native doublebuffer for painting parts.
+ It should only be used when the painteengine doesn't provide a proper
+ HDC for direct painting (e.g. when doing a grabWidget(), painting to
+ other pixmaps etc), or when special transformations are needed (e.g.
+ flips (horizonal mirroring only, vertical are handled by the theme
+ engine).
+*/
+void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData)
+{
+ QPainter *painter = themeData.painter;
+ QRect rect = themeData.rect;
+
+ if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
+ rect = QRect(0, 0, rect.height(), rect.width());
+ }
+ rect.moveTo(0,0);
+ int partId = themeData.partId;
+ int stateId = themeData.stateId;
+ int w = rect.width();
+ int h = rect.height();
+
+ // Values initialized later, either from cached values, or from function calls
+ AlphaChannelType alphaType = UnknownAlpha;
+ bool stateHasData = true; // We assume so;
+ bool hasAlpha = false;
+ bool partIsTransparent;
+ bool inspectData;
+ bool potentialInvalidAlpha;
+
+ QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
+ .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
+ .arg(w).arg(h);
+ QPixmap cachedPixmap;
+ ThemeMapKey key(themeData);
+ ThemeMapData data = alphaCache.value(key);
+
+ bool haveCachedPixmap = false;
+ bool isCached = data.dataValid;
+ if (isCached) {
+ if (!(stateHasData = data.hasAnyData))
+ return; // Cached NOOP
+ inspectData = data.wasAlphaSwapped;
+ partIsTransparent = data.partIsTransparent;
+ hasAlpha = data.hasAlphaChannel;
+ alphaType = data.alphaType;
+ potentialInvalidAlpha = data.hadInvalidAlpha;
+
+ haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
+
+#ifdef DEBUG_XP_STYLE
+ char buf[25];
+ ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
+ printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
+ haveCachedPixmap ? buf : "]-------------------",
+ qPrintable(themeData.name), themeData.partId, themeData.stateId);
+#endif
+ } else {
+ // Not cached, so get values from Theme Engine
+ BOOL tmt_borderonly = false;
+ COLORREF tmt_transparentcolor = 0x0;
+ PROPERTYORIGIN proporigin = PO_NOTFOUND;
+ pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);
+ pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);
+ inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);
+
+ // ### This is a vista-specific workaround for broken alpha in titlebar pixmaps
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ if (themeData.partId == WP_CAPTION || themeData.partId == WP_SMALLCAPTION)
+ inspectData = false;
+ }
+
+ partIsTransparent = isTransparent(themeData);
+
+ potentialInvalidAlpha = false;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);
+ if (proporigin == PO_PART || proporigin == PO_STATE) {
+ int tmt_glyphtype = GT_NONE;
+ pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
+ potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;
+ }
+
+#ifdef DEBUG_XP_STYLE
+ printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
+ qPrintable(themeData.name), themeData.partId, themeData.stateId);
+ printf("-->partIsTransparen = %d\n", partIsTransparent);
+ printf("-->inspectData = %d\n", inspectData);
+ printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
+ showProperties(themeData);
+#endif
+ }
+ bool wasAlphaSwapped = false;
+ bool wasAlphaFixed = false;
+
+ // OLD PSDK Workaround ------------------------------------------------------------------------
+ // See if we need extra clipping for the older PSDK, which does
+ // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER
+ // and DTGB_OMITCONTENT
+ bool addBorderContentClipping = false;
+ QRegion extraClip;
+ QRect area = rect;
+ if (themeData.noBorder || themeData.noContent) {
+ extraClip = area;
+ // We are running on a system where the uxtheme.dll does not have
+ // the DrawThemeBackgroundEx function, so we need to clip away
+ // borders or contents manually.
+
+ int borderSize = 0;
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
+ pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
+
+ // Clip away border region
+ if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
+ if (themeData.noBorder) {
+ extraClip &= area;
+ area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
+ }
+
+ // Clip away content region
+ if (themeData.noContent) {
+ QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ extraClip ^= content;
+ }
+ }
+ addBorderContentClipping = (themeData.noBorder | themeData.noContent);
+ }
+
+ QImage img;
+ if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
+ buffer(w, h); // Ensure a buffer of at least (w, h) in size
+ HDC dc = bufferHDC();
+
+ // Clear the buffer
+ if (alphaType != NoAlpha) {
+ // Consider have separate "memset" function for small chunks for more speedup
+ memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);
+ }
+
+ // Difference between area and rect
+ int dx = area.x() - rect.x();
+ int dy = area.y() - rect.y();
+ int dr = area.right() - rect.right();
+ int db = area.bottom() - rect.bottom();
+
+ // Adjust so painting rect starts from Origo
+ rect.moveTo(0,0);
+ area.moveTo(dx,dy);
+ DTBGOPTS drawOptions;
+ drawOptions.dwSize = sizeof(drawOptions);
+ drawOptions.rcClip = themeData.toRECT(rect);
+ drawOptions.dwFlags = DTBG_CLIPRECT
+ | (themeData.noBorder ? DTBG_OMITBORDER : 0)
+ | (themeData.noContent ? DTBG_OMITCONTENT : 0);
+
+ // Drawing the part into the backing store
+ if (pDrawThemeBackgroundEx != 0) {
+ RECT rect(themeData.toRECT(area));
+ pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &rect, &drawOptions);
+ } else {
+ // Set the clip region, if used..
+ if (addBorderContentClipping) {
+ SelectClipRgn(dc, extraClip.handle());
+ // Compensate for the noBorder area difference (noContent has the same area)
+ drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));
+ }
+
+ pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);
+
+ if (addBorderContentClipping)
+ SelectClipRgn(dc, 0);
+ }
+
+ // If not cached, analyze the buffer data to figure
+ // out alpha type, and if it contains data
+ if (!isCached) {
+ if (inspectData)
+ stateHasData = hasAnyData(rect);
+ // SHORTCUT: If the part's state has no data, cache it for NOOP later
+ if (!stateHasData) {
+ memset(&data, 0, sizeof(data));
+ data.dataValid = true;
+ alphaCache.insert(key, data);
+ return;
+ }
+ hasAlpha = hasAlphaChannel(rect);
+ if (!hasAlpha && partIsTransparent)
+ potentialInvalidAlpha = true;
+#if defined(DEBUG_XP_STYLE) && 1
+ dumpNativeDIB(w, h);
+#endif
+ }
+
+ // Swap alpha values, if needed
+ if (inspectData)
+ wasAlphaSwapped = swapAlphaChannel(rect);
+
+ // Fix alpha values, if needed
+ if (potentialInvalidAlpha)
+ wasAlphaFixed = fixAlphaChannel(rect);
+
+ QImage::Format format;
+ if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
+ format = QImage::Format_ARGB32_Premultiplied;
+ alphaType = RealAlpha;
+ } else if (wasAlphaSwapped) {
+ format = QImage::Format_ARGB32_Premultiplied;
+ alphaType = MaskAlpha;
+ } else {
+ format = QImage::Format_RGB32;
+ // The image data we got from the theme engine does not have any transparency,
+ // thus the alpha channel is set to 0.
+ // However, Format_RGB32 requires the alpha part to be set to 0xff, thus
+ // we must flip it from 0x00 to 0xff
+ swapAlphaChannel(rect, true);
+ alphaType = NoAlpha;
+ }
+#if defined(DEBUG_XP_STYLE) && 1
+ printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
+#endif
+ img = QImage(bufferPixels, bufferW, bufferH, format);
+ }
+
+ // Blitting backing store
+ bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
+
+ QRegion newRegion;
+ QRegion oldRegion;
+ if (useRegion) {
+ newRegion = region(themeData);
+ oldRegion = painter->clipRegion();
+ painter->setClipRegion(newRegion);
+#if defined(DEBUG_XP_STYLE) && 0
+ printf("Using region:\n");
+ QVector<QRect> rects = newRegion.rects();
+ for (int i = 0; i < rects.count(); ++i) {
+ const QRect &r = rects.at(i);
+ printf(" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
+ }
+#endif
+ }
+
+ if (addBorderContentClipping)
+ painter->setClipRegion(extraClip, Qt::IntersectClip);
+
+ if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
+ if (!haveCachedPixmap)
+ painter->drawImage(themeData.rect, img, rect);
+ else
+ painter->drawPixmap(themeData.rect, cachedPixmap);
+ } else {
+ // This is _slow_!
+ // Make a copy containing only the necessary data, and mirror
+ // on all wanted axes. Then draw the copy.
+ // If cached, the normal pixmap is cached, instead of caching
+ // all possible orientations for each part and state.
+ QImage imgCopy;
+ if (!haveCachedPixmap)
+ imgCopy = img.copy(rect);
+ else
+ imgCopy = cachedPixmap.toImage();
+
+ if (themeData.rotate) {
+ QMatrix rotMatrix;
+ rotMatrix.rotate(themeData.rotate);
+ imgCopy = imgCopy.transformed(rotMatrix);
+ }
+ if (themeData.mirrorHorizontally || themeData.mirrorVertically) {
+ imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);
+ }
+ painter->drawImage(themeData.rect,
+ imgCopy);
+ }
+
+ if (useRegion || addBorderContentClipping) {
+ if (oldRegion.isEmpty())
+ painter->setClipping(false);
+ else
+ painter->setClipRegion(oldRegion);
+ }
+
+ // Cache the pixmap to avoid expensive swapAlphaChannel() calls
+ if (!haveCachedPixmap && w && h) {
+ QPixmap pix = QPixmap::fromImage(img).copy(rect);
+ QPixmapCache::insert(pixmapCacheKey, pix);
+#ifdef DEBUG_XP_STYLE
+ printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
+ w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
+#endif
+ }
+
+ // Add to theme part cache
+ if (!isCached) {
+ memset(&data, 0, sizeof(data));
+ data.dataValid = true;
+ data.partIsTransparent = partIsTransparent;
+ data.alphaType = alphaType;
+ data.hasAlphaChannel = hasAlpha;
+ data.hasAnyData = stateHasData;
+ data.wasAlphaSwapped = wasAlphaSwapped;
+ data.hadInvalidAlpha = wasAlphaFixed;
+ alphaCache.insert(key, data);
+ }
+}
+
+
+// ------------------------------------------------------------------------------------------------
+
+/*!
+ \class QWindowsXPStyle
+ \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel.
+
+ \ingroup appearance
+
+ \warning This style is only available on the Windows XP platform
+ because it makes use of Windows XP's style engine.
+
+ Most of the functions are documented in the base classes
+ QWindowsStyle, QCommonStyle, and QStyle, but the
+ QWindowsXPStyle overloads of drawComplexControl(), drawControl(),
+ drawControlMask(), drawPrimitive(), proxy()->subControlRect(), and
+ sizeFromContents(), are documented here.
+
+ \img qwindowsxpstyle.png
+ \sa QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QWindowsStyle
+*/
+QWindowsXPStyle::QWindowsXPStyle()
+ : QWindowsStyle(*new QWindowsXPStylePrivate)
+{
+}
+
+/*!
+ Destroys the style.
+*/
+QWindowsXPStyle::~QWindowsXPStyle()
+{
+}
+
+/*! \reimp */
+void QWindowsXPStyle::unpolish(QApplication *app)
+{
+ QWindowsStyle::unpolish(app);
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QApplication *app)
+{
+ QWindowsStyle::polish(app);
+ if (!QWindowsXPStylePrivate::useXP())
+ return;
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QWidget *widget)
+{
+ QWindowsStyle::polish(widget);
+ if (!QWindowsXPStylePrivate::useXP())
+ return;
+
+ if (qobject_cast<QAbstractButton*>(widget)
+ || qobject_cast<QToolButton*>(widget)
+ || qobject_cast<QTabBar*>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox*>(widget)
+#endif // QT_NO_COMBOBOX
+ || qobject_cast<QScrollBar*>(widget)
+ || qobject_cast<QSlider*>(widget)
+ || qobject_cast<QHeaderView*>(widget)
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox*>(widget)
+ || qobject_cast<QSpinBox*>(widget)
+#endif // QT_NO_SPINBOX
+ || widget->inherits("QWorkspaceChild")
+ || widget->inherits("Q3TitleBar"))
+ widget->setAttribute(Qt::WA_Hover);
+
+#ifndef QT_NO_RUBBERBAND
+ if (qobject_cast<QRubberBand*>(widget)) {
+ widget->setWindowOpacity(0.6);
+ }
+#endif
+ if (qobject_cast<QStackedWidget*>(widget) &&
+ qobject_cast<QTabWidget*>(widget->parent()))
+ widget->parentWidget()->setAttribute(Qt::WA_ContentsPropagated);
+
+ Q_D(QWindowsXPStyle);
+ if (!d->hasInitColors) {
+ // Get text color for group box labels
+ COLORREF cref;
+ XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0);
+ pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
+ d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+ pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
+ d->groupBoxTextColorDisabled = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+ // Where does this color come from?
+ //pGetThemeColor(theme.handle(), TKP_TICS, TSS_NORMAL, TMT_COLOR, &cref);
+ d->sliderTickColor = qRgb(165, 162, 148);
+ d->hasInitColors = true;
+ }
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QPalette &pal)
+{
+ QWindowsStyle::polish(pal);
+ pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110));
+}
+
+/*! \reimp */
+void QWindowsXPStyle::unpolish(QWidget *widget)
+{
+#ifndef QT_NO_RUBBERBAND
+ if (qobject_cast<QRubberBand*>(widget)) {
+ widget->setWindowOpacity(1.0);
+ }
+#endif
+ Q_D(QWindowsXPStyle);
+ // Unpolish of widgets is the first thing that
+ // happens when a theme changes, or the theme
+ // engine is turned off. So we detect it here.
+ bool oldState = QWindowsXPStylePrivate::useXP();
+ bool newState = QWindowsXPStylePrivate::useXP(true);
+ if ((oldState != newState) && newState) {
+ d->cleanup(true);
+ d->init(true);
+ } else {
+ // Cleanup handle map, if just changing style,
+ // or turning it on. In both cases the values
+ // already in the map might be old (other style).
+ d->cleanupHandleMap();
+ }
+ if (qobject_cast<QAbstractButton*>(widget)
+ || qobject_cast<QToolButton*>(widget)
+ || qobject_cast<QTabBar*>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox*>(widget)
+#endif // QT_NO_COMBOBOX
+ || qobject_cast<QScrollBar*>(widget)
+ || qobject_cast<QSlider*>(widget)
+ || qobject_cast<QHeaderView*>(widget)
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox*>(widget)
+ || qobject_cast<QSpinBox*>(widget)
+#endif // QT_NO_SPINBOX
+ || widget->inherits("QWorkspaceChild")
+ || widget->inherits("Q3TitleBar"))
+ widget->setAttribute(Qt::WA_Hover, false);
+ QWindowsStyle::unpolish(widget);
+}
+
+/*! \reimp */
+QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP()) {
+ return QWindowsStyle::subElementRect(sr, option, widget);
+ }
+
+ QRect rect(option->rect);
+ switch(sr) {
+ case SE_DockWidgetCloseButton:
+ case SE_DockWidgetFloatButton:
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ return rect.translated(0, 1);
+ break;
+ case SE_TabWidgetTabContents:
+ if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
+ {
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ if (sr == SE_TabWidgetTabContents) {
+ if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) {
+ if (tabWidget->documentMode())
+ break;
+ }
+
+ rect.adjust(0, 0, -2, -2);
+ }
+ }
+ break;
+ case SE_TabWidgetTabBar: {
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ const QStyleOptionTabWidgetFrame *twfOption =
+ qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option);
+ if (twfOption && twfOption->direction == Qt::RightToLeft
+ && (twfOption->shape == QTabBar::RoundedNorth
+ || twfOption->shape == QTabBar::RoundedSouth))
+ {
+ QStyleOptionTab otherOption;
+ otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth
+ ? QTabBar::RoundedEast : QTabBar::RoundedSouth);
+ int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption, widget);
+ int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0);
+ }
+ break;}
+
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ MARGINS borderSize;
+ if (widget) {
+ XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+ HTHEME theme = buttontheme.handle();
+ if (theme) {
+ int stateId;
+ if (!(option->state & State_Enabled))
+ stateId = PBS_DISABLED;
+ else if (option->state & State_Sunken)
+ stateId = PBS_PRESSED;
+ else if (option->state & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton)
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+
+ int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+ rect = option->rect.adjusted(border, border, -border, -border);
+
+ int result = pGetThemeMargins(theme,
+ NULL,
+ BP_PUSHBUTTON,
+ stateId,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &borderSize);
+
+ if (result == S_OK) {
+ rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
+ -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ }
+ }
+ }
+ break;
+ case SE_ProgressBarContents:
+ rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
+ if (option->state & QStyle::State_Horizontal)
+ rect.adjust(4, 3, -4, -3);
+ else
+ rect.adjust(3, 2, -3, -2);
+ break;
+ default:
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ }
+ return rect;
+}
+
+/*!
+ \reimp
+*/
+void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
+ const QWidget *widget) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+
+ if (!QWindowsXPStylePrivate::useXP()) {
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+
+ QString name;
+ int partId = 0;
+ int stateId = 0;
+ QRect rect = option->rect;
+ State flags = option->state;
+ bool hMirrored = false;
+ bool vMirrored = false;
+ bool noBorder = false;
+ bool noContent = false;
+ int rotate = 0;
+
+ switch (pe) {
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+ p->save();
+ switch (tbb->shape) {
+ case QTabBar::RoundedNorth:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
+ break;
+ case QTabBar::RoundedWest:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
+ break;
+ case QTabBar::RoundedSouth:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.left(), tbb->rect.top(),
+ tbb->rect.right(), tbb->rect.top());
+ break;
+ case QTabBar::RoundedEast:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
+ break;
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ case QTabBar::TriangularSouth:
+ p->restore();
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ p->restore();
+ }
+ return;
+ case PE_PanelButtonBevel:
+ name = QLatin1String("BUTTON");
+ partId = BP_PUSHBUTTON;
+ if (!(flags & State_Enabled))
+ stateId = PBS_DISABLED;
+ else if ((flags & State_Sunken) || (flags & State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ //else if (flags & State_ButtonDefault)
+ // stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+ break;
+
+ case PE_PanelButtonTool:
+ if (widget && widget->inherits("QDockWidgetTitleButton")) {
+ if (const QWidget *dw = widget->parentWidget())
+ if (dw->isWindow())
+ return;
+ }
+ name = QLatin1String("TOOLBAR");
+ partId = TP_BUTTON;
+ if (!(flags & State_Enabled))
+ stateId = TS_DISABLED;
+ else if (flags & State_Sunken)
+ stateId = TS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+ else if (flags & State_On)
+ stateId = TS_CHECKED;
+ else if (!(flags & State_AutoRaise))
+ stateId = TS_HOT;
+ else
+ stateId = TS_NORMAL;
+ break;
+
+ case PE_IndicatorButtonDropDown:
+ name = QLatin1String("TOOLBAR");
+ partId = TP_SPLITBUTTONDROPDOWN;
+ if (!(flags & State_Enabled))
+ stateId = TS_DISABLED;
+ else if (flags & State_Sunken)
+ stateId = TS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+ else if (flags & State_On)
+ stateId = TS_CHECKED;
+ else if (!(flags & State_AutoRaise))
+ stateId = TS_HOT;
+ else
+ stateId = TS_NORMAL;
+ if (option->direction == Qt::RightToLeft)
+ hMirrored = true;
+ break;
+
+ case PE_IndicatorCheckBox:
+ name = QLatin1String("BUTTON");
+ partId = BP_CHECKBOX;
+ if (!(flags & State_Enabled))
+ stateId = CBS_UNCHECKEDDISABLED;
+ else if (flags & State_Sunken)
+ stateId = CBS_UNCHECKEDPRESSED;
+ else if (flags & State_MouseOver)
+ stateId = CBS_UNCHECKEDHOT;
+ else
+ stateId = CBS_UNCHECKEDNORMAL;
+
+ if (flags & State_On)
+ stateId += CBS_CHECKEDNORMAL-1;
+ else if (flags & State_NoChange)
+ stateId += CBS_MIXEDNORMAL-1;
+
+ break;
+
+ case PE_IndicatorRadioButton:
+ name = QLatin1String("BUTTON");
+ partId = BP_RADIOBUTTON;
+ if (!(flags & State_Enabled))
+ stateId = RBS_UNCHECKEDDISABLED;
+ else if (flags & State_Sunken)
+ stateId = RBS_UNCHECKEDPRESSED;
+ else if (flags & State_MouseOver)
+ stateId = RBS_UNCHECKEDHOT;
+ else
+ stateId = RBS_UNCHECKEDNORMAL;
+
+ if (flags & State_On)
+ stateId += RBS_CHECKEDNORMAL-1;
+ break;
+
+ case PE_IndicatorDockWidgetResizeHandle:
+ return;
+
+case PE_Frame:
+ {
+ if (flags & State_Raised)
+ return;
+ name = QLatin1String("LISTVIEW");
+ partId = LVP_LISTGROUP;
+ XPThemeData theme(0, 0, name, partId, 0);
+
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else
+ stateId = ETS_NORMAL;
+ int fillType;
+ if (pGetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
+ if (fillType == BT_BORDERFILL) {
+ COLORREF bcRef;
+ pGetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
+ QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
+ QPen oldPen = p->pen();
+ // int borderSize = 1;
+ // pGetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize);
+
+ // Inner white border
+ p->setPen(QPen(option->palette.base().color(), 1));
+ p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ // Outer dark border
+ p->setPen(QPen(bordercolor, 1));
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ return;
+ } else if (fillType == BT_NONE) {
+ return;
+ } else {
+ break;
+ }
+ }
+ }
+ case PE_FrameLineEdit: {
+ // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
+ QWidget *parentWidget = 0;
+ if (widget)
+ parentWidget = widget->parentWidget();
+ if (parentWidget)
+ parentWidget = parentWidget->parentWidget();
+ if (widget && widget->inherits("QLineEdit")
+ && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+ QPen oldPen = p->pen();
+ // Inner white border
+ p->setPen(QPen(option->palette.base().color(), 1));
+ p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ // Outer dark border
+ p->setPen(QPen(option->palette.shadow().color(), 1));
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ return;
+ } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ name = QLatin1String("EDIT");
+ partId = EP_EDITTEXT;
+ noContent = true;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else
+ stateId = ETS_NORMAL;
+ }
+ break;
+ }
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ name = QLatin1String("EDIT");
+ partId = EP_EDITTEXT;
+ noBorder = true;
+ QBrush bg;
+ bool usePalette = false;
+ bool isEnabled = flags & State_Enabled;
+ uint resolve_mask = panel->palette.resolve();
+
+#ifndef QT_NO_SPINBOX
+ //Since spin box includes a line edit we need to resolve the palette on the spin box instead
+ if (widget) {
+ if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
+ resolve_mask = spinbox->palette().resolve();
+ }
+#endif // QT_NO_SPINBOX
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Base color is set for this widget, so use it
+ bg = panel->palette.brush(QPalette::Base);
+ usePalette = true;
+ }
+
+ stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
+
+ if (usePalette) {
+ p->fillRect(panel->rect, bg);
+ } else {
+ XPThemeData theme(0, p, name, partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ int bgType;
+ pGetThemeEnumValue( theme.handle(),
+ partId,
+ stateId,
+ TMT_BGTYPE,
+ &bgType);
+ if( bgType == BT_IMAGEFILE ) {
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ theme.noBorder = noBorder;
+ theme.noContent = noContent;
+ theme.rotate = rotate;
+ d->drawBackground(theme);
+ } else {
+ QBrush fillColor = option->palette.brush(QPalette::Base);
+
+ if (!isEnabled) {
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
+ // Use only if the fill property comes from our part
+ if ((origin == PO_PART || origin == PO_STATE)) {
+ COLORREF bgRef;
+ pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
+ fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
+ }
+ }
+ p->fillRect(option->rect, fillColor);
+ }
+ }
+
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
+ return;
+ }
+ break;
+
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
+ {
+ name = QLatin1String("TAB");
+ partId = TABP_PANE;
+
+ if (widget) {
+ bool useGradient = true;
+ const int maxlength = 256;
+ wchar_t themeFileName[maxlength];
+ wchar_t themeColor[maxlength];
+ // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
+ if (pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
+ wchar_t *offset = 0;
+ if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
+ offset++;
+ if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
+ useGradient = false;
+ }
+ }
+ }
+ // This should work, but currently there's an error in the ::drawBackgroundDirectly()
+ // code, when using the HDC directly..
+ if (useGradient) {
+ QStyleOptionTabWidgetFrameV2 frameOpt = *tab;
+ frameOpt.rect = widget->rect();
+ QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget);
+ QRegion reg = option->rect;
+ reg -= contentsRect;
+ p->setClipRegion(reg);
+ XPThemeData theme(widget, p, name, partId, stateId, rect);
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ d->drawBackground(theme);
+ p->setClipRect(contentsRect);
+ partId = TABP_BODY;
+ }
+ }
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ vMirrored = true;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ rotate = 90;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ rotate = 90;
+ hMirrored = true;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case PE_FrameMenu:
+ p->save();
+ p->setPen(option->palette.dark().color());
+ p->drawRect(rect.adjusted(0, 0, -1, -1));
+ p->restore();
+ return;
+
+ case PE_PanelMenuBar:
+ break;
+
+ case PE_FrameDockWidget:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
+ {
+ name = QLatin1String("WINDOW");
+ if (flags & State_Active)
+ stateId = FS_ACTIVE;
+ else
+ stateId = FS_INACTIVE;
+
+ int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget);
+
+ XPThemeData theme(widget, p, name, 0, stateId);
+ if (!theme.isValid())
+ break;
+ theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT;
+ d->drawBackground(theme);
+ theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
+ theme.partId = WP_SMALLFRAMERIGHT;
+ d->drawBackground(theme);
+ theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
+ theme.partId = WP_SMALLFRAMEBOTTOM;
+ d->drawBackground(theme);
+ return;
+ }
+ break;
+
+ case PE_IndicatorHeaderArrow:
+ {
+#if 0 // XP theme engine doesn't know about this :(
+ name = QLatin1String("HEADER");
+ partId = HP_HEADERSORTARROW;
+ if (flags & State_Down)
+ stateId = HSAS_SORTEDDOWN;
+ else
+ stateId = HSAS_SORTEDUP;
+#else
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ p->save();
+ p->setPen(option->palette.dark().color());
+ p->translate(0, option->rect.height()/2 - 4);
+ if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide
+ p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
+ p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
+ p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
+ p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
+ p->drawPoint(option->rect.x()+4, option->rect.y()+4);
+ } else if(header->sortIndicator & QStyleOptionHeader::SortDown) {
+ p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
+ p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
+ p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
+ p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
+ p->drawPoint(option->rect.x()+4, option->rect.y());
+ }
+ p->restore();
+ return;
+ }
+#endif
+ }
+ break;
+
+ case PE_FrameStatusBarItem:
+ name = QLatin1String("STATUS");
+ partId = SP_PANE;
+ break;
+
+ case PE_FrameGroupBox:
+ name = QLatin1String("BUTTON");
+ partId = BP_GROUPBOX;
+ if (!(flags & State_Enabled))
+ stateId = GBS_DISABLED;
+ else
+ stateId = GBS_NORMAL;
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option);
+ if (frame2->features & QStyleOptionFrameV2::Flat) {
+ // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style
+ QRect fr = frame->rect;
+ QPoint p1(fr.x(), fr.y() + 1);
+ QPoint p2(fr.x() + fr.width(), p1.y() + 1);
+ rect = QRect(p1, p2);
+ name = QLatin1String("");
+ }
+ }
+ break;
+
+ case PE_IndicatorProgressChunk:
+ {
+ Qt::Orientation orient = Qt::Horizontal;
+ bool inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ orient = pb2->orientation;
+ if (pb2->invertedAppearance)
+ inverted = true;
+ }
+ if (orient == Qt::Horizontal) {
+ partId = PP_CHUNK;
+ rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
+ if (inverted && option->direction == Qt::LeftToRight)
+ hMirrored = true;
+ } else {
+ partId = PP_CHUNKVERT;
+ rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
+ }
+ name = QLatin1String("PROGRESS");
+ stateId = 1;
+ }
+ break;
+
+ case PE_Q3DockWindowSeparator:
+ name = QLatin1String("TOOLBAR");
+ if (flags & State_Horizontal)
+ partId = TP_SEPARATOR;
+ else
+ partId = TP_SEPARATORVERT;
+ break;
+
+ case PE_FrameWindow:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
+ {
+ name = QLatin1String("WINDOW");
+ if (flags & State_Active)
+ stateId = FS_ACTIVE;
+ else
+ stateId = FS_INACTIVE;
+
+ int fwidth = frm->lineWidth + frm->midLineWidth;
+
+ XPThemeData theme(0, p, name, 0, stateId);
+ if (!theme.isValid())
+ break;
+
+ theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
+ theme.partId = WP_FRAMELEFT;
+ d->drawBackground(theme);
+ theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
+ theme.partId = WP_FRAMERIGHT;
+ d->drawBackground(theme);
+ theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
+ theme.partId = WP_FRAMEBOTTOM;
+ d->drawBackground(theme);
+ theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
+ theme.partId = WP_CAPTION;
+ d->drawBackground(theme);
+ return;
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ {
+ static const int decoration_size = 9;
+ int mid_h = option->rect.x() + option->rect.width() / 2;
+ int mid_v = option->rect.y() + option->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+ if (option->state & State_Item) {
+ if (option->direction == Qt::RightToLeft)
+ p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+ else
+ p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (option->state & State_Sibling)
+ p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+ if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
+ p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+ if (option->state & State_Children) {
+ int delta = decoration_size / 2;
+ bef_h -= delta;
+ bef_v -= delta;
+ aft_h += delta;
+ aft_v += delta;
+ XPThemeData theme(0, p, QLatin1String("TREEVIEW"));
+ theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
+ theme.partId = TVP_GLYPH;
+ theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
+ d->drawBackground(theme);
+ }
+ }
+ return;
+
+ case PE_IndicatorToolBarSeparator:
+ if (option->rect.height() < 3) {
+ // XP style requires a few pixels for the separator
+ // to be visible.
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ name = QLatin1String("TOOLBAR");
+ partId = TP_SEPARATOR;
+
+ if (option->state & State_Horizontal)
+ partId = TP_SEPARATOR;
+ else
+ partId = TP_SEPARATORVERT;
+
+ break;
+
+ case PE_IndicatorToolBarHandle:
+
+ name = QLatin1String("REBAR");
+ partId = RP_GRIPPER;
+ if (option->state & State_Horizontal) {
+ partId = RP_GRIPPER;
+ rect.adjust(0, 0, -2, 0);
+ }
+ else {
+ partId = RP_GRIPPERVERT;
+ rect.adjust(0, 0, 0, -2);
+ }
+ break;
+
+ case PE_IndicatorItemViewItemCheck: {
+ QStyleOptionButton button;
+ button.QStyleOption::operator=(*option);
+ button.state &= ~State_MouseOver;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p, widget);
+ return;
+ }
+
+ default:
+ break;
+ }
+
+ XPThemeData theme(0, p, name, partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ theme.noBorder = noBorder;
+ theme.noContent = noContent;
+ theme.rotate = rotate;
+ d->drawBackground(theme);
+}
+
+/*!
+ \reimp
+*/
+void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
+ const QWidget *widget) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+ if (!QWindowsXPStylePrivate::useXP()) {
+ QWindowsStyle::drawControl(element, option, p, widget);
+ return;
+ }
+
+ QRect rect(option->rect);
+ State flags = option->state;
+
+ int rotate = 0;
+ bool hMirrored = false;
+ bool vMirrored = false;
+
+ QString name;
+ int partId = 0;
+ int stateId = 0;
+ switch (element) {
+ case CE_SizeGrip:
+ {
+ name = QLatin1String("STATUS");
+ partId = SP_GRIPPER;
+ SIZE sz;
+ XPThemeData theme(0, p, name, partId, 0);
+ pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz);
+ --sz.cy;
+ if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
+ switch (sg->corner) {
+ case Qt::BottomRightCorner:
+ rect = QRect(rect.right() - sz.cx, rect.bottom() - sz.cy, sz.cx, sz.cy);
+ break;
+ case Qt::BottomLeftCorner:
+ rect = QRect(rect.left() + 1, rect.bottom() - sz.cy, sz.cx, sz.cy);
+ hMirrored = true;
+ break;
+ case Qt::TopRightCorner:
+ rect = QRect(rect.right() - sz.cx, rect.top() + 1, sz.cx, sz.cy);
+ vMirrored = true;
+ break;
+ case Qt::TopLeftCorner:
+ rect = QRect(rect.left() + 1, rect.top() + 1, sz.cx, sz.cy);
+ hMirrored = vMirrored = true;
+ }
+ }
+ }
+ break;
+
+ case CE_HeaderSection:
+ name = QLatin1String("HEADER");
+ partId = HP_HEADERITEM;
+ if (flags & State_Sunken)
+ stateId = HIS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = HIS_HOT;
+ else
+ stateId = HIS_NORMAL;
+ break;
+
+ case CE_Splitter:
+ p->eraseRect(option->rect);
+ return;
+
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
+ {
+ name = QLatin1String("BUTTON");
+ partId = BP_PUSHBUTTON;
+ bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
+ || ((btn->features & QStyleOptionButton::CommandLinkButton)
+ && !(flags & State_MouseOver)
+ && !(btn->features & QStyleOptionButton::DefaultButton));
+ if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
+ stateId = PBS_DISABLED;
+ else if (justFlat)
+ ;
+ else if (flags & (State_Sunken | State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton)
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+
+ if (!justFlat) {
+ XPThemeData theme(widget, p, name, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
+
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbiw = 0, mbih = 0;
+ XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ mbiw = size.cx;
+ mbih = size.cy;
+ }
+
+ QRect ir = btn->rect;
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ return;
+ }
+ break;
+ case CE_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
+ {
+ stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
+ }
+ break;
+
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
+ {
+ name = QLatin1String("TAB");
+ bool isDisabled = !(tab->state & State_Enabled);
+ bool hasFocus = tab->state & State_HasFocus;
+ bool isHot = tab->state & State_MouseOver;
+ bool selected = tab->state & State_Selected;
+ bool lastTab = tab->position == QStyleOptionTab::End;
+ bool firstTab = tab->position == QStyleOptionTab::Beginning;
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignLeft;
+ bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignCenter;
+ int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option, widget);
+
+ if (isDisabled)
+ stateId = TIS_DISABLED;
+ else if (selected)
+ stateId = TIS_SELECTED;
+ else if (hasFocus)
+ stateId = TIS_FOCUSED;
+ else if (isHot)
+ stateId = TIS_HOT;
+ else
+ stateId = TIS_NORMAL;
+
+ // Selecting proper part depending on position
+ if (firstTab || onlyOne) {
+ if (leftAligned) {
+ partId = TABP_TABITEMLEFTEDGE;
+ } else if (centerAligned) {
+ partId = TABP_TABITEM;
+ } else { // rightAligned
+ partId = TABP_TABITEMRIGHTEDGE;
+ }
+ } else {
+ partId = TABP_TABITEM;
+ }
+
+ if (tab->direction == Qt::RightToLeft
+ && (tab->shape == QTabBar::RoundedNorth
+ || tab->shape == QTabBar::RoundedSouth)) {
+ bool temp = firstTab;
+ firstTab = lastTab;
+ lastTab = temp;
+ }
+ bool begin = firstTab || onlyOne;
+ bool end = lastTab || onlyOne;
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ if (selected)
+ rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
+ else
+ rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
+ break;
+ case QTabBar::RoundedSouth:
+ //vMirrored = true;
+ rotate = 180; // Not 100% correct, but works
+ if (selected)
+ rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
+ else
+ rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
+ break;
+ case QTabBar::RoundedEast:
+ rotate = 90;
+ if (selected) {
+ rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
+ }else{
+ rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
+ }
+ break;
+ case QTabBar::RoundedWest:
+ hMirrored = true;
+ rotate = 90;
+ if (selected) {
+ rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
+ }else{
+ rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
+ }
+ break;
+ default:
+ name = QLatin1String(""); // Do our own painting for triangular
+ break;
+ }
+
+ if (!selected) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ rect.adjust(0,0, 0,-1);
+ break;
+ case QTabBar::RoundedSouth:
+ rect.adjust(0,1, 0,0);
+ break;
+ case QTabBar::RoundedEast:
+ rect.adjust( 1,0, 0,0);
+ break;
+ case QTabBar::RoundedWest:
+ rect.adjust(0,0, -1,0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+
+ case CE_ProgressBarGroove:
+ {
+ Qt::Orientation orient = Qt::Horizontal;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+ orient = pb2->orientation;
+ partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
+ name = QLatin1String("PROGRESS");
+ stateId = 1;
+ }
+ break;
+
+ case CE_MenuEmptyArea:
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool act = menuitem->state & State_Selected;
+ bool checkable = menuitem->menuHasCheckableItems;
+ bool checked = checkable ? menuitem->checked : false;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax(menuitem->maxIconWidth, 12);
+
+ int x, y, w, h;
+ rect.getRect(&x, &y, &w, &h);
+
+ QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ p->fillRect(rect, fill);
+
+ if (element == CE_MenuEmptyArea)
+ break;
+
+ // draw separator -------------------------------------------------
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-1 + h / 2;
+ p->setPen(menuitem->palette.dark().color());
+ p->drawLine(x, yoff, x+w, yoff);
+ ++yoff;
+ p->setPen(menuitem->palette.light().color());
+ p->drawLine(x, yoff, x+w, yoff);
+ return;
+ }
+
+ int xpos = x;
+
+ // draw icon ------------------------------------------------------
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap = checked ?
+ menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On) :
+ menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect iconRect(0, 0, pixw, pixh);
+ iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
+ QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
+ p->setPen(menuitem->palette.text().color());
+ p->setBrush(Qt::NoBrush);
+ if (checked)
+ p->drawRect(vIconRect.adjusted(-1, -1, 0, 0));
+ p->drawPixmap(vIconRect.topLeft(), pixmap);
+
+ // draw checkmark -------------------------------------------------
+ } else if (checked) {
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+
+ QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame,
+ menuitem->rect.y() + windowsItemFrame,
+ checkcol - 2 * windowsItemFrame,
+ menuitem->rect.height() - 2*windowsItemFrame);
+ newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
+ proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
+ }
+
+ QColor textColor = dis ? menuitem->palette.text().color() :
+ act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
+ p->setPen(textColor);
+
+ // draw text ------------------------------------------------------
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, option->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) {
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ // draw tab text ----------------
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+ p->setPen(textColor);
+ }
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+ p->setPen(textColor);
+ }
+ p->drawText(vTextRect, text_flags, s);
+ p->restore();
+ }
+
+ // draw sub menu arrow --------------------------------------------
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
+ int dim = (h - 2) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ if (act)
+ newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color());
+ proxy()->drawPrimitive(arrow, &newMI, p, widget);
+ }
+ }
+ return;
+
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ break;
+
+ bool act = mbi->state & State_Selected;
+ bool dis = !(mbi->state & State_Enabled);
+
+ QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ QPalette::ColorRole textRole = dis ? QPalette::Text:
+ act ? QPalette::HighlightedText : QPalette::ButtonText;
+ QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
+
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ p->fillRect(rect, fill);
+ if (!pix.isNull())
+ drawItemPixmap(p, mbi->rect, alignment, pix);
+ else
+ drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+ return;
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ int buttonMargin = 4;
+ int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+ int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
+ bool isFloating = widget && widget->isWindow();
+ bool isActive = dwOpt->state & State_Active;
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ if (verticalTitleBar) {
+ QSize s = rect.size();
+ s.transpose();
+ rect.setSize(s);
+
+ p->translate(rect.left() - 1, rect.top() + rect.width());
+ p->rotate(-90);
+ p->translate(-rect.left() + 1, -rect.top());
+ }
+ QRect r = rect.adjusted(0, 2, -1, -3);
+ QRect titleRect = r;
+
+ if (dwOpt->closable) {
+ QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (dwOpt->floatable) {
+ QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (isFloating) {
+ titleRect.adjust(0, -fw, 0, 0);
+ if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+ } else {
+ titleRect.adjust(mw, 0, 0, 0);
+ if (!dwOpt->floatable && !dwOpt->closable)
+ titleRect.adjust(0, 0, -mw, 0);
+ }
+
+ if (!verticalTitleBar)
+ titleRect = visualRect(dwOpt->direction, r, titleRect);
+
+ if (!isFloating) {
+ QPen oldPen = p->pen();
+ QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+ p->setPen(dwOpt->palette.color(QPalette::Dark));
+ p->drawRect(r);
+
+ if (!titleText.isEmpty()) {
+ drawItemText(p, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+
+ p->setPen(oldPen);
+ } else {
+ name = QLatin1String("WINDOW");
+ if (isActive)
+ stateId = CS_ACTIVE;
+ else
+ stateId = CS_INACTIVE;
+
+ int titleHeight = rect.height() - 2;
+ rect = rect.adjusted(-fw, -fw, fw, 0);
+
+ XPThemeData theme(widget, p, name, 0, stateId);
+ if (!theme.isValid())
+ break;
+
+ // Draw small type title bar
+ theme.rect = rect;
+ theme.partId = WP_SMALLCAPTION;
+ d->drawBackground(theme);
+
+ // Figure out maximal button space on title bar
+
+ QIcon ico = widget->windowIcon();
+ bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
+ if (hasIcon) {
+ QPixmap pxIco = ico.pixmap(titleHeight);
+ if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
+ p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
+ else
+ p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
+ }
+ if (!dwOpt->title.isEmpty()) {
+ QPen oldPen = p->pen();
+ QFont oldFont = p->font();
+ QFont titleFont = oldFont;
+ titleFont.setBold(true);
+ p->setFont(titleFont);
+ QString titleText
+ = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+
+ int result = TST_NONE;
+ pGetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
+ if (result != TST_NONE) {
+ COLORREF textShadowRef;
+ pGetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
+ QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
+ p->setPen(textShadow);
+ drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
+ Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText);
+ }
+
+ COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
+ QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
+ p->setPen(textColor);
+ drawItemText(p, titleRect,
+ Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText);
+ p->setFont(oldFont);
+ p->setPen(oldPen);
+ }
+
+ }
+
+ return;
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_RUBBERBAND
+ case CE_RubberBand:
+ if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
+ QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
+ p->save();
+ QRect r = option->rect;
+ p->setPen(highlight.darker(120));
+ QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
+ qMin(highlight.green()/2 + 110, 255),
+ qMin(highlight.blue()/2 + 110, 255),
+ (widget && widget->isTopLevel())? 255 : 127);
+ p->setBrush(dimHighlight);
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->restore();
+ return;
+ }
+#endif // QT_NO_RUBBERBAND
+ case CE_HeaderEmptyArea:
+ if (option->state & State_Horizontal)
+ {
+ name = QLatin1String("HEADER");
+ stateId = HIS_NORMAL;
+ }
+ else {
+ QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p, widget);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ XPThemeData theme(widget, p, name, partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawControl(element, option, p, widget);
+ return;
+ }
+
+ theme.rotate = rotate;
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ d->drawBackground(theme);
+}
+
+
+/*!
+ \reimp
+*/
+void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
+ QPainter *p, const QWidget *widget) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+
+ if (!QWindowsXPStylePrivate::useXP()) {
+ QWindowsStyle::drawComplexControl(cc, option, p, widget);
+ return;
+ }
+
+ State flags = option->state;
+ SubControls sub = option->subControls;
+ QRect r = option->rect;
+
+ int partId = 0;
+ int stateId = 0;
+ if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
+ flags |= State_MouseOver;
+
+ switch (cc) {
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
+ {
+ XPThemeData theme(widget, p, QLatin1String("SPIN"));
+
+ if (sb->frame && (sub & SC_SpinBoxFrame)) {
+ partId = EP_EDITTEXT;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_HasFocus)
+ stateId = ETS_FOCUSED;
+ else
+ stateId = ETS_NORMAL;
+
+ XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+ ftheme.noContent = true;
+ d->drawBackground(ftheme);
+ }
+ if (sub & SC_SpinBoxUp) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
+ partId = SPNP_UP;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
+ stateId = UPS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
+ stateId = UPS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
+ stateId = UPS_HOT;
+ else
+ stateId = UPS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_SpinBoxDown) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+ partId = SPNP_DOWN;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
+ stateId = DNS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
+ stateId = DNS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
+ stateId = DNS_HOT;
+ else
+ stateId = DNS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ {
+ if (sub & SC_ComboBoxEditField) {
+ if (cmb->frame) {
+ partId = EP_EDITTEXT;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_HasFocus)
+ stateId = ETS_FOCUSED;
+ else
+ stateId = ETS_NORMAL;
+ XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+ d->drawBackground(theme);
+ } else {
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ p->fillRect(option->rect, editBrush);
+ }
+ if (!cmb->editable) {
+ QRect re = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
+ if (option->state & State_HasFocus) {
+ p->fillRect(re, option->palette.highlight());
+ p->setPen(option->palette.highlightedText().color());
+ p->setBackground(option->palette.highlight());
+ } else {
+ p->fillRect(re, option->palette.base());
+ p->setPen(option->palette.text().color());
+ p->setBackground(option->palette.base());
+ }
+ }
+ }
+
+ if (sub & SC_ComboBoxArrow) {
+ XPThemeData theme(widget, p, QLatin1String("COMBOBOX"));
+ theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
+ partId = CP_DROPDOWNBUTTON;
+ if (!(flags & State_Enabled))
+ stateId = CBXS_DISABLED;
+ else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_Sunken))
+ stateId = CBXS_PRESSED;
+ else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_MouseOver))
+ stateId = CBXS_HOT;
+ else
+ stateId = CBXS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ {
+ XPThemeData theme(widget, p, QLatin1String("SCROLLBAR"));
+ bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
+ if (maxedOut)
+ flags &= ~State_Enabled;
+
+ bool isHorz = flags & State_Horizontal;
+ bool isRTL = option->direction == Qt::RightToLeft;
+ if (sub & SC_ScrollBarAddLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSubLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (maxedOut) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
+ partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ stateId = SCRBS_DISABLED;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ } else {
+ if (sub & SC_ScrollBarSubPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
+ partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarAddPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
+ partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSlider) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+
+ // Draw handle
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+
+ // Calculate rect of gripper
+ const int swidth = theme.rect.width();
+ const int sheight = theme.rect.height();
+
+ MARGINS contentsMargin;
+ RECT rect = theme.toRECT(theme.rect);
+ pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
+
+ SIZE size;
+ theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ int gw = size.cx, gh = size.cy;
+
+
+ QRect gripperBounds;
+ if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ }
+
+ // Draw gripper if there is enough space
+ if (!gripperBounds.isEmpty()) {
+ p->save();
+ theme.rect = gripperBounds;
+ p->setClipRegion(d->region(theme));// Only change inside the region of the gripper
+ d->drawBackground(theme); // Transparent gripper ontop of background
+ p->restore();
+ }
+ }
+ }
+ }
+ break;
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ {
+ XPThemeData theme(widget, p, QLatin1String("TRACKBAR"));
+ QRect slrect = slider->rect;
+ QRegion tickreg = slrect;
+ if (sub & SC_SliderGroove) {
+ theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ if (slider->orientation == Qt::Horizontal) {
+ partId = TKP_TRACK;
+ stateId = TRS_NORMAL;
+ theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
+ } else {
+ partId = TKP_TRACKVERT;
+ stateId = TRVS_NORMAL;
+ theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
+ }
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ tickreg -= theme.rect;
+ }
+ if (sub & SC_SliderTickmarks) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int ticks = slider->tickPosition;
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+ if (interval <= 0) {
+ interval = slider->singleStep;
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+ if (!interval)
+ interval = 1;
+ int fudge = len / 2;
+ int pos;
+ int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0;
+ p->setPen(d->sliderTickColor);
+ QVarLengthArray<QLine, 32> lines;
+ int v = slider->minimum;
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
+ pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, available) + fudge;
+ if (slider->orientation == Qt::Horizontal) {
+ if (ticks & QSlider::TicksAbove)
+ lines.append(QLine(pos, tickOffset - 1 - bothOffset,
+ pos, tickOffset - 1 - bothOffset - tickLength));
+
+ if (ticks & QSlider::TicksBelow)
+ lines.append(QLine(pos, tickOffset + thickness + bothOffset,
+ pos, tickOffset + thickness + bothOffset + tickLength));
+ } else {
+ if (ticks & QSlider::TicksAbove)
+ lines.append(QLine(tickOffset - 1 - bothOffset, pos,
+ tickOffset - 1 - bothOffset - tickLength, pos));
+
+ if (ticks & QSlider::TicksBelow)
+ lines.append(QLine(tickOffset + thickness + bothOffset, pos,
+ tickOffset + thickness + bothOffset + tickLength, pos));
+ }
+ // in the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ if (lines.size() > 0) {
+ p->save();
+ p->translate(slrect.topLeft());
+ p->drawLines(lines.constData(), lines.size());
+ p->restore();
+ }
+ }
+ if (sub & SC_SliderHandle) {
+ theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+ if (slider->orientation == Qt::Horizontal) {
+ if (slider->tickPosition == QSlider::TicksAbove)
+ partId = TKP_THUMBTOP;
+ else if (slider->tickPosition == QSlider::TicksBelow)
+ partId = TKP_THUMBBOTTOM;
+ else
+ partId = TKP_THUMB;
+
+ if (!(slider->state & State_Enabled))
+ stateId = TUS_DISABLED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
+ stateId = TUS_PRESSED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
+ stateId = TUS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = TUS_FOCUSED;
+ else
+ stateId = TUS_NORMAL;
+ } else {
+ if (slider->tickPosition == QSlider::TicksLeft)
+ partId = TKP_THUMBLEFT;
+ else if (slider->tickPosition == QSlider::TicksRight)
+ partId = TKP_THUMBRIGHT;
+ else
+ partId = TKP_THUMBVERT;
+
+ if (!(slider->state & State_Enabled))
+ stateId = TUVS_DISABLED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
+ stateId = TUVS_PRESSED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
+ stateId = TUVS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = TUVS_FOCUSED;
+ else
+ stateId = TUVS_NORMAL;
+ }
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+#endif
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
+
+ State bflags = toolbutton->state & ~State_Sunken;
+ State mflags = bflags;
+ bool autoRaise = flags & State_AutoRaise;
+ if (autoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton) {
+ bflags |= State_Sunken;
+ mflags |= State_MouseOver | State_Sunken;
+ } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
+ mflags |= State_Sunken;
+ bflags |= State_MouseOver;
+ }
+ }
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
+ if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
+ XPThemeData theme(widget, p, QLatin1String("TOOLBAR"));
+ theme.partId = TP_SPLITBUTTON;
+ theme.rect = button;
+ if (!(bflags & State_Enabled))
+ stateId = TS_DISABLED;
+ else if (bflags & State_Sunken)
+ stateId = TS_PRESSED;
+ else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
+ stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+ else if (bflags & State_On)
+ stateId = TS_CHECKED;
+ else
+ stateId = TS_NORMAL;
+ if (option->direction == Qt::RightToLeft)
+ theme.mirrorHorizontally = true;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ } else {
+ tool.rect = option->rect;
+ tool.state = bflags;
+ if (autoRaise) // for tool bars
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ else
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
+ }
+ }
+ }
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect.adjust(3, 3, -3, -3);
+ if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
+ fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
+ toolbutton, widget), 0);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ int fw = 2;
+ if (!autoRaise)
+ label.state &= ~State_Sunken;
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if (autoRaise) {
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+ } else {
+ tool.state = mflags;
+ menuarea.adjust(-2, 0, 0, 0);
+ // Draw menu button
+ if ((bflags & State_Sunken) != (mflags & State_Sunken)){
+ p->save();
+ p->setClipRect(menuarea);
+ tool.rect = option->rect;
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0);
+ p->restore();
+ }
+ // Draw arrow
+ p->save();
+ p->setPen(option->palette.dark().color());
+ p->drawLine(menuarea.left(), menuarea.top() + 3,
+ menuarea.left(), menuarea.bottom() - 3);
+ p->setPen(option->palette.light().color());
+ p->drawLine(menuarea.left() - 1, menuarea.top() + 3,
+ menuarea.left() - 1, menuarea.bottom() - 3);
+
+ tool.rect = menuarea.adjusted(2, 3, -2, -1);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
+ p->restore();
+ }
+ } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+
+ case CC_TitleBar:
+ {
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
+ {
+ bool isActive = tb->titleBarState & QStyle::State_Active;
+ XPThemeData theme(widget, p, QLatin1String("WINDOW"));
+ if (sub & SC_TitleBarLabel) {
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ partId = WP_SMALLCAPTION;
+ } else
+#endif
+ partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
+ theme.rect = option->rect;
+ if (widget && !widget->isEnabled())
+ stateId = CS_DISABLED;
+ else if (isActive)
+ stateId = CS_ACTIVE;
+ else
+ stateId = CS_INACTIVE;
+
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+
+ QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
+
+ int result = TST_NONE;
+ pGetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
+ if (result != TST_NONE) {
+ COLORREF textShadowRef;
+ pGetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
+ QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
+ p->setPen(textShadow);
+ p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+ COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
+ QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
+ p->setPen(textColor);
+ p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+ if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu, widget);
+ partId = WP_SYSBUTTON;
+ if ((widget && !widget->isEnabled()) || !isActive)
+ stateId = SBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
+ stateId = SBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
+ stateId = SBS_HOT;
+ else
+ stateId = SBS_NORMAL;
+ if (!tb->icon.isNull()) {
+ tb->icon.paint(p, theme.rect);
+ } else {
+ theme.partId = partId;
+ theme.stateId = stateId;
+ SIZE sz;
+ pGetThemePartSize(theme.handle(), qt_win_display_dc(), theme.partId, theme.stateId, 0, TS_TRUE, &sz);
+ if (sz.cx == 0 || sz.cy == 0) {
+ int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
+ QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb, widget).pixmap(iconSize, iconSize);
+ p->save();
+ drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
+ p->restore();
+ } else {
+ d->drawBackground(theme);
+ }
+ }
+ }
+
+ if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
+ && !(tb->titleBarState & Qt::WindowMinimized)) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget);
+ partId = WP_MINBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MINBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken))
+ stateId = MINBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver))
+ stateId = MINBS_HOT;
+ else if (!isActive)
+ stateId = MINBS_INACTIVE;
+ else
+ stateId = MINBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
+ && !(tb->titleBarState & Qt::WindowMaximized)) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget);
+ partId = WP_MAXBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MAXBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken))
+ stateId = MAXBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver))
+ stateId = MAXBS_HOT;
+ else if (!isActive)
+ stateId = MAXBS_INACTIVE;
+ else
+ stateId = MAXBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarContextHelpButton
+ && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget);
+ partId = WP_HELPBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MINBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken))
+ stateId = MINBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver))
+ stateId = MINBS_HOT;
+ else if (!isActive)
+ stateId = MINBS_INACTIVE;
+ else
+ stateId = MINBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ bool drawNormalButton = (sub & SC_TitleBarNormalButton)
+ && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ && (tb->titleBarState & Qt::WindowMinimized))
+ || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ && (tb->titleBarState & Qt::WindowMaximized)));
+ if (drawNormalButton) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget);
+ partId = WP_RESTOREBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = RBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken))
+ stateId = RBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver))
+ stateId = RBS_HOT;
+ else if (!isActive)
+ stateId = RBS_INACTIVE;
+ else
+ stateId = RBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
+ && !(tb->titleBarState & Qt::WindowMinimized)) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget);
+ partId = WP_MINBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MINBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken))
+ stateId = MINBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver))
+ stateId = MINBS_HOT;
+ else if (!isActive)
+ stateId = MINBS_INACTIVE;
+ else
+ stateId = MINBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
+ && tb->titleBarState & Qt::WindowMinimized) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget);
+ partId = WP_RESTOREBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = RBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken))
+ stateId = RBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver))
+ stateId = RBS_HOT;
+ else if (!isActive)
+ stateId = RBS_INACTIVE;
+ else
+ stateId = RBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget);
+ //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
+ partId = WP_CLOSEBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = CBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken))
+ stateId = CBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver))
+ stateId = CBS_HOT;
+ else if (!isActive)
+ stateId = CBS_INACTIVE;
+ else
+ stateId = CBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ }
+ break;
+
+#ifndef QT_NO_WORKSPACE
+ case CC_MdiControls:
+ {
+ QRect buttonRect;
+ XPThemeData theme(widget, p, QLatin1String("WINDOW"), WP_MDICLOSEBUTTON, CBS_NORMAL);
+
+ if (option->subControls & SC_MdiCloseButton) {
+ buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
+ if (theme.isValid()) {
+ theme.partId = WP_MDICLOSEBUTTON;
+ theme.rect = buttonRect;
+ if (!(flags & State_Enabled))
+ theme.stateId = CBS_INACTIVE;
+ else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton))
+ theme.stateId = CBS_PUSHED;
+ else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton))
+ theme.stateId = CBS_HOT;
+ else
+ theme.stateId = CBS_NORMAL;
+ d->drawBackground(theme);
+ }
+ }
+ if (option->subControls & SC_MdiNormalButton) {
+ buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget);
+ if (theme.isValid()) {
+ theme.partId = WP_MDIRESTOREBUTTON;
+ theme.rect = buttonRect;
+ if (!(flags & State_Enabled))
+ theme.stateId = CBS_INACTIVE;
+ else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton))
+ theme.stateId = CBS_PUSHED;
+ else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton))
+ theme.stateId = CBS_HOT;
+ else
+ theme.stateId = CBS_NORMAL;
+ d->drawBackground(theme);
+ }
+ }
+ if (option->subControls & QStyle::SC_MdiMinButton) {
+ buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget);
+ if (theme.isValid()) {
+ theme.partId = WP_MDIMINBUTTON;
+ theme.rect = buttonRect;
+ if (!(flags & State_Enabled))
+ theme.stateId = CBS_INACTIVE;
+ else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton))
+ theme.stateId = CBS_PUSHED;
+ else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton))
+ theme.stateId = CBS_HOT;
+ else
+ theme.stateId = CBS_NORMAL;
+ d->drawBackground(theme);
+ }
+ }
+ }
+ break;
+#endif //QT_NO_WORKSPACE
+#ifndef QT_NO_DIAL
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ QStyleHelper::drawDial(dial, p);
+ break;
+#endif // QT_NO_DIAL
+ default:
+ QWindowsStyle::drawComplexControl(cc, option, p, widget);
+ break;
+ }
+}
+
+/*! \reimp */
+int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::pixelMetric(pm, option, widget);
+
+ int res = 0;
+ switch (pm) {
+ case PM_MenuBarPanelWidth:
+ res = 0;
+ break;
+
+ case PM_DefaultFrameWidth:
+ if (qobject_cast<const QListView*>(widget))
+ res = 2;
+ else
+ res = 1;
+ break;
+ case PM_MenuPanelWidth:
+ case PM_SpinBoxFrameWidth:
+ res = 1;
+ break;
+
+ case PM_TabBarTabOverlap:
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ res = 2;
+ break;
+
+ case PM_TabBarBaseOverlap:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ res = 1;
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ res = 2;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ res = 3;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ res = 1;
+ break;
+ }
+ }
+ break;
+
+ case PM_SplitterWidth:
+ res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width());
+ break;
+
+ case PM_IndicatorWidth:
+ case PM_IndicatorHeight:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = (pm == PM_IndicatorWidth) ? size.cx : size.cy;
+ }
+ }
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = (pm == PM_ExclusiveIndicatorWidth) ? size.cx : size.cy;
+ }
+ }
+ break;
+
+ case PM_ProgressBarChunkWidth:
+ {
+ Qt::Orientation orient = Qt::Horizontal;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+ orient = pb2->orientation;
+ XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = (orient == Qt::Horizontal) ? size.cx : size.cy;
+ }
+ }
+ break;
+
+ case PM_SliderThickness:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = size.cy;
+ }
+ }
+ break;
+
+ case PM_TitleBarHeight:
+ {
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+ } else
+#endif
+ if (widget && (widget->windowType() == Qt::Tool))
+ res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+ else
+ res = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+ }
+ break;
+
+ case PM_MdiSubWindowFrameWidth:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size);
+ res = size.cx-1;
+ }
+ }
+ break;
+
+ case PM_MdiSubWindowMinimizedWidth:
+ res = 160;
+ break;
+
+#ifndef QT_NO_TOOLBAR
+ case PM_ToolBarHandleExtent:
+ res = int(QStyleHelper::dpiScaled(8.));
+ break;
+
+#endif // QT_NO_TOOLBAR
+ case PM_DockWidgetFrameWidth:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = size.cx;
+ }
+ }
+ break;
+ case PM_DockWidgetSeparatorExtent:
+ res = int(QStyleHelper::dpiScaled(4.));
+ break;
+ case PM_DockWidgetTitleMargin:
+ res = int(QStyleHelper::dpiScaled(4.));
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ if (qstyleoption_cast<const QStyleOptionToolButton *>(option))
+ res = 1;
+ else
+ res = 0;
+ break;
+
+ case PM_ButtonDefaultIndicator:
+ res = 0;
+ break;
+
+ default:
+ res = QWindowsStyle::pixelMetric(pm, option, widget);
+ }
+
+ return res;
+}
+
+/*
+ This function is used by subControlRect to check if a button
+ should be drawn for the given subControl given a set of window flags.
+*/
+static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ const uint flags = tb->titleBarFlags;
+ bool retVal = false;
+ switch (sc) {
+ case QStyle::SC_TitleBarContextHelpButton:
+ if (flags & Qt::WindowContextHelpButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMinButton:
+ if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarNormalButton:
+ if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMaxButton:
+ if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarShadeButton:
+ if (!isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarUnshadeButton:
+ if (isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarCloseButton:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarSysMenu:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ default :
+ retVal = true;
+ }
+ return retVal;
+}
+
+/*!
+ \reimp
+*/
+QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::subControlRect(cc, option, subControl, widget);
+
+ QRect rect;
+
+ switch (cc) {
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ if (!buttonVisible(subControl, tb))
+ return rect;
+ const bool isToolTitle = false;
+ const int height = tb->rect.height();
+ const int width = tb->rect.width();
+ int buttonHeight = GetSystemMetrics(SM_CYSIZE) - 4;
+ int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
+ const int delta = buttonWidth + 2;
+ int controlTop = option->rect.bottom() - buttonHeight - 2;
+ const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
+ const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
+ const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
+ const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
+ const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
+ const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ int offset = 0;
+
+ switch (subControl) {
+ case SC_TitleBarLabel:
+ rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
+ if (isToolTitle) {
+ if (sysmenuHint) {
+ rect.adjust(0, 0, -buttonWidth - 3, 0);
+ }
+ if (minimizeHint || maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ } else {
+ if (sysmenuHint) {
+ const int leftOffset = height - 8;
+ rect.adjust(leftOffset, 0, 0, 0);
+ }
+ if (minimizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (contextHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (shadeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ }
+ break;
+
+ case SC_TitleBarContextHelpButton:
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ offset += delta;
+ //fall through
+ case SC_TitleBarMinButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarMinButton)
+ break;
+ //fall through
+ case SC_TitleBarNormalButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarNormalButton)
+ break;
+ //fall through
+ case SC_TitleBarMaxButton:
+ if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarMaxButton)
+ break;
+ //fall through
+ case SC_TitleBarShadeButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarShadeButton)
+ break;
+ //fall through
+ case SC_TitleBarUnshadeButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarUnshadeButton)
+ break;
+ //fall through
+ case SC_TitleBarCloseButton:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ offset += delta;
+ else if (subControl == SC_TitleBarCloseButton)
+ break;
+
+ rect.setRect(width - offset - controlTop + 1, controlTop,
+ buttonWidth, buttonHeight);
+ break;
+
+ case SC_TitleBarSysMenu:
+ {
+ const int controlTop = 6;
+ const int controlHeight = height - controlTop - 3;
+ const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
+ if (tb->icon.isNull())
+ iconSize = QSize(controlHeight, controlHeight);
+ int hPad = (controlHeight - iconSize.height())/2;
+ int vPad = (controlHeight - iconSize.width())/2;
+ rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
+ int xpos = x;
+ xpos += wi - 1 - 16;
+
+ switch (subControl) {
+ case SC_ComboBoxFrame:
+ rect = cmb->rect;
+ break;
+
+ case SC_ComboBoxArrow:
+ rect = QRect(xpos, y+1, 16, he-2);
+ break;
+
+ case SC_ComboBoxEditField:
+ rect = QRect(x+2, y+2, wi-3-16, he-4);
+ break;
+
+ case SC_ComboBoxListBoxPopup:
+ rect = cmb->rect;
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+#ifndef QT_NO_WORKSPACE
+ case CC_MdiControls:
+ {
+ int numSubControls = 0;
+ if (option->subControls & SC_MdiCloseButton)
+ ++numSubControls;
+ if (option->subControls & SC_MdiMinButton)
+ ++numSubControls;
+ if (option->subControls & SC_MdiNormalButton)
+ ++numSubControls;
+ if (numSubControls == 0)
+ break;
+
+ int buttonWidth = option->rect.width()/ numSubControls;
+ int offset = 0;
+ switch (subControl) {
+ case SC_MdiCloseButton:
+ // Only one sub control, no offset needed.
+ if (numSubControls == 1)
+ break;
+ offset += buttonWidth;
+ //FALL THROUGH
+ case SC_MdiNormalButton:
+ // No offset needed if
+ // 1) There's only one sub control
+ // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
+ if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
+ break;
+ if (option->subControls & SC_MdiNormalButton)
+ offset += buttonWidth;
+ break;
+ default:
+ break;
+ }
+ rect = QRect(offset, 0, buttonWidth, option->rect.height());
+ break;
+ }
+#endif // QT_NO_WORKSPACE
+
+ default:
+ rect = visualRect(option->direction, option->rect,
+ QWindowsStyle::subControlRect(cc, option, subControl, widget));
+ break;
+ }
+ return visualRect(option->direction, option->rect, rect);
+}
+
+/*!
+ \reimp
+*/
+QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *option,
+ const QSize &contentsSize, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
+
+ QSize sz(contentsSize);
+ switch (ct) {
+ case CT_LineEdit:
+ case CT_ComboBox:
+ {
+ XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+ HTHEME theme = buttontheme.handle();
+ MARGINS borderSize;
+ if (theme) {
+ int result = pGetThemeMargins(theme,
+ NULL,
+ BP_PUSHBUTTON,
+ PBS_NORMAL,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &borderSize);
+ if (result == S_OK) {
+ sz += QSize(borderSize.cxLeftWidth + borderSize.cxRightWidth - 2,
+ borderSize.cyBottomHeight + borderSize.cyTopHeight - 2);
+ }
+ const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
+ sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
+ + textMargins, 23), 0); //arrow button
+ }
+ }
+ break;
+ case CT_SpinBox:
+ {
+ //Spinbox adds frame twice
+ sz = QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
+ int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+ sz -= QSize(2*border, 2*border);
+ }
+ break;
+ case CT_TabWidget:
+ sz += QSize(6, 6);
+ break;
+ case CT_Menu:
+ sz += QSize(1, 0);
+ break;
+#ifndef QT_NO_MENUBAR
+ case CT_MenuBarItem:
+ if (!sz.isEmpty())
+ sz += QSize(windowsItemHMargin * 5 + 1, 6);
+ break;
+#endif
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) {
+ sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+ sz.setHeight(sz.height() - 2);
+ return sz;
+ }
+ }
+ sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+ break;
+
+ case CT_MdiControls:
+ if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
+ int width = 0;
+ if (styleOpt->subControls & SC_MdiMinButton)
+ width += 17 + 1;
+ if (styleOpt->subControls & SC_MdiNormalButton)
+ width += 17 + 1;
+ if (styleOpt->subControls & SC_MdiCloseButton)
+ width += 17 + 1;
+ sz = QSize(width, 19);
+ } else {
+ sz = QSize(54, 19);
+ }
+ break;
+
+ default:
+ sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+ break;
+ }
+
+ return sz;
+}
+
+
+/*! \reimp */
+int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::styleHint(hint, option, widget, returnData);
+
+ int res = 0;
+ switch (hint) {
+
+ case SH_EtchDisabledText:
+ res = (qobject_cast<const QLabel*>(widget) != 0);
+ break;
+
+ case SH_SpinControls_DisableOnBounds:
+ res = 0;
+ break;
+
+ case SH_TitleBar_AutoRaise:
+ case SH_TitleBar_NoBorder:
+ res = 1;
+ break;
+
+ case SH_GroupBox_TextLabelColor:
+ if (!widget || (widget && widget->isEnabled()))
+ res = d->groupBoxTextColor;
+ else
+ res = d->groupBoxTextColorDisabled;
+ break;
+
+ case SH_Table_GridLineColor:
+ res = 0xC0C0C0;
+ break;
+
+ case SH_WindowFrame_Mask:
+ {
+ res = 1;
+ QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData);
+ const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
+ if (mask && titlebar) {
+ // Note certain themes will not return the whole window frame but only the titlebar part when
+ // queried This function needs to return the entire window mask, hence we will only fetch the mask for the
+ // titlebar itself and add the remaining part of the window rect at the bottom.
+ int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget);
+ QRect titleBarRect = option->rect;
+ titleBarRect.setHeight(tbHeight);
+ XPThemeData themeData;
+ if (titlebar->titleBarState & Qt::WindowMinimized) {
+ themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect);
+ } else
+ themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect);
+ mask->region = d->region(themeData) +
+ QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight);
+ }
+ }
+ break;
+#ifndef QT_NO_RUBBERBAND
+ case SH_RubberBand_Mask:
+ if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
+ res = 0;
+ break;
+ }
+#endif // QT_NO_RUBBERBAND
+
+ case SH_ItemView_DrawDelegateFrame:
+ res = 1;
+ break;
+
+ default:
+ res =QWindowsStyle::styleHint(hint, option, widget, returnData);
+ }
+
+ return res;
+}
+
+/*! \reimp */
+QPalette QWindowsXPStyle::standardPalette() const
+{
+ if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal)
+ return *QApplicationPrivate::sys_pal;
+ else
+ return QWindowsStyle::standardPalette();
+}
+
+/*!
+ \reimp
+*/
+QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+
+ switch(standardPixmap) {
+ case SP_TitleBarMaxButton:
+ case SP_TitleBarCloseButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (widget && widget->isWindow()) {
+ XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE sz;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz);
+ return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(QSize(sz.cx, sz.cy));
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+/*!
+ \internal
+*/
+QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP()) {
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+ switch(standardIcon) {
+ case SP_TitleBarMaxButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (d->dockFloat.isNull()) {
+ XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+ theme.stateId = MAXBS_PUSHED;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+ theme.stateId = MAXBS_HOT;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+ theme.stateId = MAXBS_INACTIVE;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ }
+ }
+ if (widget && widget->isWindow())
+ return d->dockFloat;
+
+ }
+ break;
+ case SP_TitleBarCloseButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (d->dockClose.isNull()) {
+ XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.partId = WP_CLOSEBUTTON; // ####
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+ theme.stateId = CBS_PUSHED;
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+ theme.stateId = CBS_HOT;
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+ theme.stateId = CBS_INACTIVE;
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ }
+ }
+ if (widget && widget->isWindow())
+ return d->dockClose;
+ }
+ break;
+ case SP_TitleBarNormalButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (d->dockFloat.isNull()) {
+ XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+ theme.stateId = RBS_PUSHED;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+ theme.stateId = RBS_HOT;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+ theme.stateId = RBS_INACTIVE;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ }
+ }
+ if (widget && widget->isWindow())
+ return d->dockFloat;
+
+ }
+ break;
+ default:
+ break;
+ }
+
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+/*!
+ \internal
+
+ Constructs a QWindowsXPStyle object.
+*/
+QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd)
+{
+}
+
+
+// Debugging code ---------------------------------------------------------------------[ START ]---
+// The code for this point on is not compiled by default, but only used as assisting
+// debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file.
+
+#ifdef DEBUG_XP_STYLE
+// The schema file expects these to be defined by the user.
+#define TMT_ENUMDEF 8
+#define TMT_ENUMVAL TEXT('A')
+#define TMT_ENUM TEXT('B')
+#define SCHEMA_STRINGS // For 2nd pass on schema file
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <tmschema.h>
+QT_END_INCLUDE_NAMESPACE
+
+// A property's value, type and name combo
+struct PropPair {
+ int propValue;
+ int propType;
+ LPCWSTR propName;
+};
+
+// Operator for sorting of PropPairs
+bool operator<(PropPair a, PropPair b) {
+ return wcscmp(a.propName, b.propName) < 0;
+}
+
+// Our list of all possible properties
+static QList<PropPair> all_props;
+
+
+/*! \internal
+ Dumps a portion of the full native DIB section double buffer.
+ The DIB section double buffer is only used when doing special
+ transformations to the theme part, or when the real double
+ buffer in the paintengine does not have an HDC we may use
+ directly.
+ Since we cannot rely on the pixel data we get from Microsoft
+ when drawing into the DIB section, we use this function to
+ see the actual data we got, and can determin the appropriate
+ action.
+*/
+void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
+{
+ if (w && h) {
+ static int pCount = 0;
+ DWORD *bufPix = (DWORD*)bufferPixels;
+
+ char *bufferDump = new char[bufferH * bufferW * 16];
+ char *bufferPos = bufferDump;
+
+ memset(bufferDump, 0, sizeof(bufferDump));
+ bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
+ bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
+ bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
+ for (int iy = 0; iy < h; ++iy) {
+ bufferPos += sprintf(bufferPos, "\n ");
+ bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4));
+ for (int ix = 0; ix < w; ++ix) {
+ bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix);
+ ++bufPix;
+ }
+ }
+ bufferPos += sprintf(bufferPos, "\n};\n\n");
+ printf(bufferDump);
+
+ delete[] bufferDump;
+ ++pCount;
+ }
+}
+
+/*! \internal
+ Shows the value of a given property for a part.
+*/
+static void showProperty(XPThemeData &themeData, const PropPair &prop)
+{
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+ const char *originStr;
+ switch(origin) {
+ case PO_STATE:
+ originStr = "State ";
+ break;
+ case PO_PART:
+ originStr = "Part ";
+ break;
+ case PO_CLASS:
+ originStr = "Class ";
+ break;
+ case PO_GLOBAL:
+ originStr = "Globl ";
+ break;
+ case PO_NOTFOUND:
+ default:
+ originStr = "Unkwn ";
+ break;
+ }
+
+ switch(prop.propType) {
+ case TMT_STRING:
+ {
+ wchar_t buffer[512];
+ pGetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
+ printf(" (%sString) %-20S: %S\n", originStr, prop.propName, buffer);
+ }
+ break;
+ case TMT_ENUM:
+ {
+ int result = -1;
+ pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sEnum) %-20S: %d\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_INT:
+ {
+ int result = -1;
+ pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sint) %-20S: %d\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_BOOL:
+ {
+ BOOL result = false;
+ pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sbool) %-20S: %d\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_COLOR:
+ {
+ COLORREF result = 0;
+ pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%scolor) %-20S: 0x%08X\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_MARGINS:
+ {
+ MARGINS result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result);
+ printf(" (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr,
+ prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight);
+ }
+ break;
+ case TMT_FILENAME:
+ {
+ wchar_t buffer[512];
+ pGetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
+ printf(" (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer);
+ }
+ break;
+ case TMT_SIZE:
+ {
+ SIZE result1;
+ SIZE result2;
+ SIZE result3;
+ memset(&result1, 0, sizeof(result1));
+ memset(&result2, 0, sizeof(result2));
+ memset(&result3, 0, sizeof(result3));
+ pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN, &result1);
+ pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2);
+ pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3);
+ printf(" (%ssize) %-20S: Min (%d, %d), True(%d, %d), Draw(%d, %d)\n", originStr, prop.propName,
+ result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy);
+ }
+ break;
+ case TMT_POSITION:
+ {
+ POINT result;
+ memset(&result, 0, sizeof(result));
+ pGetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y);
+ }
+ break;
+ case TMT_RECT:
+ {
+ RECT result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sRect) %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom);
+ }
+ break;
+ case TMT_FONT:
+ {
+ LOGFONT result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sFont) %-20S: %S height(%d) width(%d) weight(%d)\n", originStr, prop.propName,
+ result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight);
+ }
+ break;
+ case TMT_INTLIST:
+ {
+ INTLIST result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sInt list)%-20S: { ", originStr, prop.propName);
+ for (int i = 0; i < result.iValueCount; ++i)
+ printf("%d ", result.iValues[i]);
+ printf("}\n");
+ }
+ break;
+ default:
+ printf(" %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType);
+ }
+}
+
+/*! \internal
+ Dump all valid properties for a part.
+ If it's the first time this function is called, then the name,
+ enum value and documentation of all properties are shown, as
+ well as all global properties.
+*/
+void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData)
+{
+ if (!all_props.count()) {
+ const TMSCHEMAINFO *infoTable = GetSchemaInfo();
+ for (int i = 0; i < infoTable->iPropCount; ++i) {
+ int propType = infoTable->pPropTable[i].bPrimVal;
+ int propValue = infoTable->pPropTable[i].sEnumVal;
+ LPCWSTR propName = infoTable->pPropTable[i].pszName;
+
+ switch(propType) {
+ case TMT_ENUMDEF:
+ case TMT_ENUMVAL:
+ continue;
+ default:
+ if (propType != propValue) {
+ PropPair prop;
+ prop.propValue = propValue;
+ prop.propName = propName;
+ prop.propType = propType;
+ all_props.append(prop);
+ }
+ }
+ }
+ qSort(all_props);
+
+ {// List all properties
+ printf("part properties count = %d:\n", all_props.count());
+ printf(" Enum Property Name Description\n");
+ printf("-----------------------------------------------------------\n");
+ wchar_t themeName[256];
+ pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0);
+ for (int j = 0; j < all_props.count(); ++j) {
+ PropPair prop = all_props.at(j);
+ wchar_t buf[500];
+ pGetThemeDocumentationProperty(themeName, prop.propName, buf, 500);
+ printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf);
+ }
+ }
+
+ {// Show Global values
+ printf("Global Properties:\n");
+ for (int j = 0; j < all_props.count(); ++j) {
+ PropPair prop = all_props.at(j);
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+ if (origin == PO_GLOBAL) {
+ showProperty(themeData, prop);
+ }
+ }
+ }
+ }
+
+ for (int j = 0; j < all_props.count(); ++j) {
+ PropPair prop = all_props.at(j);
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+ if (origin != PO_NOTFOUND)
+ {
+ showProperty(themeData, prop);
+ }
+ }
+}
+#endif
+// Debugging code -----------------------------------------------------------------------[ END ]---
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_WINDOWSXP
diff --git a/src/widgets/styles/qwindowsxpstyle.h b/src/widgets/styles/qwindowsxpstyle.h
new file mode 100644
index 0000000000..d0f1329c30
--- /dev/null
+++ b/src/widgets/styles/qwindowsxpstyle.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSXPSTYLE_H
+#define QWINDOWSXPSTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSXP)
+
+class QWindowsXPStylePrivate;
+class Q_GUI_EXPORT QWindowsXPStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QWindowsXPStyle();
+ QWindowsXPStyle(QWindowsXPStylePrivate &dd);
+ ~QWindowsXPStyle();
+
+ void unpolish(QApplication*);
+ void polish(QApplication*);
+ void polish(QWidget*);
+ void polish(QPalette&);
+ void unpolish(QWidget*);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
+ const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
+ const QWidget *wwidget = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *option, const QWidget *widget = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc,
+ const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p,
+ const QWidget *widget = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize,
+ const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric pm, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ QPalette standardPalette() const;
+ QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QWindowsXPStyle)
+ Q_DECLARE_PRIVATE(QWindowsXPStyle)
+ friend class QStyleFactory;
+ void *reserved;
+};
+
+#endif // QT_NO_STYLE_WINDOWSXP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOWSXPSTYLE_H
diff --git a/src/widgets/styles/qwindowsxpstyle_p.h b/src/widgets/styles/qwindowsxpstyle_p.h
new file mode 100644
index 0000000000..73803607a1
--- /dev/null
+++ b/src/widgets/styles/qwindowsxpstyle_p.h
@@ -0,0 +1,356 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSXPSTYLE_P_H
+#define QWINDOWSXPSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsxpstyle.h"
+#include "qwindowsstyle_p.h"
+#include <qmap.h>
+#include <qt_windows.h>
+
+// Note, these tests are duplicated in qwizard_win.cpp.
+#ifdef Q_CC_GNU
+# include <w32api.h>
+# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5))
+# ifdef _WIN32_WINNT
+# undef _WIN32_WINNT
+# endif
+# define _WIN32_WINNT 0x0501
+# include <commctrl.h>
+# endif
+#endif
+
+#include <uxtheme.h>
+
+#if WINVER >= 0x0600
+#include <vssym32.h>
+#else
+#include <tmschema.h>
+#endif
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+// Older Platform SDKs do not have the extended DrawThemeBackgroundEx
+// function. We add the needed parts here, and use the extended
+// function dynamically, if available in uxtheme.dll. Else, we revert
+// back to using the DrawThemeBackground function.
+#ifndef DTBG_OMITBORDER
+# ifndef DTBG_CLIPRECT
+# define DTBG_CLIPRECT 0x00000001
+# endif
+# ifndef DTBG_DRAWSOLID
+# define DTBG_DRAWSOLID 0x00000002
+# endif
+# ifndef DTBG_OMITBORDER
+# define DTBG_OMITBORDER 0x00000004
+# endif
+# ifndef DTBG_OMITCONTENT
+# define DTBG_OMITCONTENT 0x00000008
+# endif
+# ifndef DTBG_COMPUTINGREGION
+# define DTBG_COMPUTINGREGION 0x00000010
+# endif
+# ifndef DTBG_MIRRORDC
+# define DTBG_MIRRORDC 0x00000020
+# endif
+ typedef struct _DTBGOPTS
+ {
+ DWORD dwSize;
+ DWORD dwFlags;
+ RECT rcClip;
+ } DTBGOPTS, *PDTBGOPTS;
+#endif // _DTBGOPTS
+
+// Undefined for some compile environments
+#ifndef TMT_TEXTCOLOR
+# define TMT_TEXTCOLOR 3803
+#endif
+#ifndef TMT_BORDERCOLORHINT
+# define TMT_BORDERCOLORHINT 3822
+#endif
+#ifndef TMT_BORDERSIZE
+# define TMT_BORDERSIZE 2403
+#endif
+#ifndef TMT_BORDERONLY
+# define TMT_BORDERONLY 2203
+#endif
+#ifndef TMT_TRANSPARENTCOLOR
+# define TMT_TRANSPARENTCOLOR 3809
+#endif
+#ifndef TMT_CAPTIONMARGINS
+# define TMT_CAPTIONMARGINS 3603
+#endif
+#ifndef TMT_CONTENTMARGINS
+# define TMT_CONTENTMARGINS 3602
+#endif
+#ifndef TMT_SIZINGMARGINS
+# define TMT_SIZINGMARGINS 3601
+#endif
+#ifndef TMT_GLYPHTYPE
+# define TMT_GLYPHTYPE 4012
+#endif
+#ifndef TMT_BGTYPE
+# define TMT_BGTYPE 4001
+#endif
+#ifndef TMT_TEXTSHADOWTYPE
+# define TMT_TEXTSHADOWTYPE 4010
+#endif
+#ifndef TMT_BORDERCOLOR
+# define TMT_BORDERCOLOR 3801
+#endif
+#ifndef BT_IMAGEFILE
+# define BT_IMAGEFILE 0
+#endif
+#ifndef BT_BORDERFILL
+# define BT_BORDERFILL 1
+#endif
+#ifndef BT_NONE
+# define BT_NONE 2
+#endif
+#ifndef TMT_FILLCOLOR
+# define TMT_FILLCOLOR 3802
+#endif
+#ifndef TMT_PROGRESSCHUNKSIZE
+# define TMT_PROGRESSCHUNKSIZE 2411
+#endif
+
+// TMT_TEXTSHADOWCOLOR is wrongly defined in mingw
+#if TMT_TEXTSHADOWCOLOR != 3818
+#undef TMT_TEXTSHADOWCOLOR
+#define TMT_TEXTSHADOWCOLOR 3818
+#endif
+#ifndef TST_NONE
+# define TST_NONE 0
+#endif
+
+#ifndef GT_NONE
+# define GT_NONE 0
+#endif
+#ifndef GT_IMAGEGLYPH
+# define GT_IMAGEGLYPH 1
+#endif
+
+// These defines are missing from the tmschema, but still exist as
+// states for their parts
+#ifndef MINBS_INACTIVE
+#define MINBS_INACTIVE 5
+#endif
+#ifndef MAXBS_INACTIVE
+#define MAXBS_INACTIVE 5
+#endif
+#ifndef RBS_INACTIVE
+#define RBS_INACTIVE 5
+#endif
+#ifndef HBS_INACTIVE
+#define HBS_INACTIVE 5
+#endif
+#ifndef CBS_INACTIVE
+#define CBS_INACTIVE 5
+#endif
+
+// Uncomment define below to build debug assisting code, and output
+// #define DEBUG_XP_STYLE
+
+#if !defined(QT_NO_STYLE_WINDOWSXP)
+
+// Declarations -----------------------------------------------------------------------------------
+class XPThemeData
+{
+public:
+ XPThemeData(const QWidget *w = 0, QPainter *p = 0, const QString &theme = QString(),
+ int part = 0, int state = 0, const QRect &r = QRect())
+ : widget(w), painter(p), name(theme), htheme(0), partId(part), stateId(state),
+ mirrorHorizontally(false), mirrorVertically(false), noBorder(false),
+ noContent(false), rotate(0), rect(r)
+ {}
+
+ HRGN mask();
+ HTHEME handle();
+
+ RECT toRECT(const QRect &qr);
+ bool isValid();
+
+ const QWidget *widget;
+ QPainter *painter;
+ QString name;
+ HTHEME htheme;
+ int partId;
+ int stateId;
+
+ uint mirrorHorizontally : 1;
+ uint mirrorVertically : 1;
+ uint noBorder : 1;
+ uint noContent : 1;
+ uint rotate;
+ QRect rect;
+};
+
+struct ThemeMapKey {
+ QString name;
+ int partId;
+ int stateId;
+ bool noBorder;
+ bool noContent;
+
+ ThemeMapKey() : partId(-1), stateId(-1) {}
+ ThemeMapKey(const XPThemeData &data)
+ : name(data.name), partId(data.partId), stateId(data.stateId),
+ noBorder(data.noBorder), noContent(data.noContent) {}
+
+};
+
+inline uint qHash(const ThemeMapKey &key)
+{ return qHash(key.name) ^ key.partId ^ key.stateId; }
+
+inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2)
+{
+ return k1.name == k2.name
+ && k1.partId == k2.partId
+ && k1.stateId == k2.stateId;
+}
+
+enum AlphaChannelType {
+ UnknownAlpha = -1, // Alpha of part & state not yet known
+ NoAlpha, // Totally opaque, no need to touch alpha (RGB)
+ MaskAlpha, // Alpha channel must be fixed (ARGB)
+ RealAlpha // Proper alpha values from Windows (ARGB_Premultiplied)
+};
+
+struct ThemeMapData {
+ AlphaChannelType alphaType; // Which type of alpha on part & state
+
+ bool dataValid : 1; // Only used to detect if hash value is ok
+ bool partIsTransparent : 1;
+ bool hasAnyData : 1; // False = part & state has not data, NOP
+ bool hasAlphaChannel : 1; // True = part & state has real Alpha
+ bool wasAlphaSwapped : 1; // True = alpha channel needs to be swapped
+ bool hadInvalidAlpha : 1; // True = alpha channel contained invalid alpha values
+
+ ThemeMapData() : dataValid(false), partIsTransparent(false), hasAnyData(false),
+ hasAlphaChannel(false), wasAlphaSwapped(false), hadInvalidAlpha(false) {}
+};
+
+class QWindowsXPStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsXPStyle)
+public:
+ QWindowsXPStylePrivate()
+ : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
+ bufferPixels(0), bufferW(0), bufferH(0)
+ { init(); }
+
+ ~QWindowsXPStylePrivate()
+ { cleanup(); }
+
+ static HWND winId(const QWidget *widget);
+
+ void init(bool force = false);
+ void cleanup(bool force = false);
+ void cleanupHandleMap();
+ const QPixmap *tabBody(QWidget *widget);
+
+ HBITMAP buffer(int w = 0, int h = 0);
+ HDC bufferHDC()
+ { return bufferDC;}
+
+ static bool resolveSymbols();
+ static bool useXP(bool update = false);
+
+ bool isTransparent(XPThemeData &themeData);
+ QRegion region(XPThemeData &themeData);
+
+ void setTransparency(QWidget *widget, XPThemeData &themeData);
+ void drawBackground(XPThemeData &themeData);
+ void drawBackgroundThruNativeBuffer(XPThemeData &themeData);
+ void drawBackgroundDirectly(XPThemeData &themeData);
+
+ bool hasAnyData(const QRect &rect);
+ bool hasAlphaChannel(const QRect &rect);
+ bool fixAlphaChannel(const QRect &rect);
+ bool swapAlphaChannel(const QRect &rect, bool allPixels = false);
+
+ QRgb groupBoxTextColor;
+ QRgb groupBoxTextColorDisabled;
+ QRgb sliderTickColor;
+ bool hasInitColors;
+
+ static QMap<QString,HTHEME> *handleMap;
+
+ QIcon dockFloat, dockClose;
+
+private:
+#ifdef DEBUG_XP_STYLE
+ void dumpNativeDIB(int w, int h);
+ void showProperties(XPThemeData &themeData);
+#endif
+
+ static QBasicAtomicInt ref;
+ static bool use_xp;
+ static QWidget *limboWidget;
+ static QPixmap *tabbody;
+
+ QHash<ThemeMapKey, ThemeMapData> alphaCache;
+ HDC bufferDC;
+ HBITMAP bufferBitmap;
+ HBITMAP nullBitmap;
+ uchar *bufferPixels;
+ int bufferW, bufferH;
+};
+
+#endif // QT_NO_STYLE_WINDOWS
+
+QT_END_NAMESPACE
+
+#endif //QWINDOWSXPSTYLE_P_H
diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri
new file mode 100644
index 0000000000..b20caf726e
--- /dev/null
+++ b/src/widgets/styles/styles.pri
@@ -0,0 +1,194 @@
+# Qt styles module
+
+HEADERS += \
+ styles/qdrawutil.h \
+ styles/qstyle.h \
+ styles/qstylefactory.h \
+ styles/qstyleoption.h \
+ styles/qstyleplugin.h \
+ styles/qcommonstylepixmaps_p.h \
+ styles/qcommonstyle.h \
+ styles/qstylehelper_p.h \
+ styles/qproxystyle.h \
+ styles/qproxystyle_p.h \
+ styles/qstylepainter.h \
+ styles/qstylesheetstyle_p.h
+
+SOURCES += \
+ styles/qdrawutil.cpp \
+ styles/qstyle.cpp \
+ styles/qstylefactory.cpp \
+ styles/qstyleoption.cpp \
+ styles/qstyleplugin.cpp \
+ styles/qstylehelper.cpp \
+ styles/qcommonstyle.cpp \
+ styles/qproxystyle.cpp \
+ styles/qstylepainter.cpp \
+ styles/qstylesheetstyle.cpp \
+ styles/qstylesheetstyle_default.cpp
+
+wince* {
+ RESOURCES += styles/qstyle_wince.qrc
+} else:symbian {
+ RESOURCES += styles/qstyle_s60.qrc
+} else {
+ RESOURCES += styles/qstyle.qrc
+}
+
+contains( styles, all ) {
+ styles = mac windows windowsxp windowsvista
+}
+
+x11|qpa|!macx-*:styles -= mac
+
+x11{
+ QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTKSTYLE
+ LIBS_PRIVATE += $$QT_LIBS_QGTKSTYLE
+ styles += gtk
+}
+
+contains( styles, mac ) {
+ HEADERS += \
+ styles/qmacstyle_mac.h \
+ styles/qmacstylepixmaps_mac_p.h \
+ styles/qmacstyle_mac_p.h
+ OBJECTIVE_SOURCES += styles/qmacstyle_mac.mm
+
+ !contains( styles, windows ) {
+ message( mac requires windows )
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_MAC
+}
+
+contains( styles, cde ) {
+ HEADERS += styles/qcdestyle.h
+ SOURCES += styles/qcdestyle.cpp
+
+ !contains( styles, motif ) {
+ message( cde requires motif )
+ styles += motif
+ DEFINES+= QT_STYLE_MOTIF
+ }
+} else {
+ DEFINES += QT_NO_STYLE_CDE
+}
+
+contains( styles, windowsvista ) {
+ HEADERS += styles/qwindowsvistastyle.h
+ HEADERS += styles/qwindowsvistastyle_p.h
+ SOURCES += styles/qwindowsvistastyle.cpp
+ !contains( styles, windowsxp ) {
+ message( windowsvista requires windowsxp )
+ styles += windowsxp
+ DEFINES+= QT_STYLE_WINDOWSXP
+ }
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSVISTA
+}
+
+contains( styles, windowsxp ) {
+ HEADERS += styles/qwindowsxpstyle.h
+ SOURCES += styles/qwindowsxpstyle.cpp
+ !contains( styles, windows ) {
+ message( windowsxp requires windows )
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSXP
+}
+
+contains( styles, plastique ) {
+ HEADERS += styles/qplastiquestyle.h
+ SOURCES += styles/qplastiquestyle.cpp
+ !contains( styles, windows ) {
+ message( plastique requires windows )
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_PLASTIQUE
+}
+
+contains( styles, gtk ) {
+ HEADERS += styles/qgtkstyle.h
+ HEADERS += styles/qgtkpainter_p.h
+ HEADERS += styles/qgtkstyle_p.h
+ SOURCES += styles/qgtkstyle.cpp
+ SOURCES += styles/qgtkpainter.cpp
+ SOURCES += styles/qgtkstyle_p.cpp
+ !contains( styles, cleanlooks ) {
+ styles += cleanlooks
+ DEFINES+= QT_STYLE_CLEANLOOKS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_GTK
+}
+
+contains( styles, cleanlooks ) {
+ HEADERS += styles/qcleanlooksstyle.h
+ HEADERS += styles/qcleanlooksstyle_p.h
+ SOURCES += styles/qcleanlooksstyle.cpp
+ !contains( styles, windows ) {
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_CLEANLOOKS
+}
+
+contains( styles, windows ) {
+ HEADERS += styles/qwindowsstyle.h
+ SOURCES += styles/qwindowsstyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWS
+}
+
+contains( styles, motif ) {
+ HEADERS += styles/qmotifstyle.h
+ SOURCES += styles/qmotifstyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_MOTIF
+}
+
+contains( styles, windowsce ) {
+ HEADERS += styles/qwindowscestyle.h
+ SOURCES += styles/qwindowscestyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSCE
+}
+
+contains( styles, windowsmobile ) {
+ HEADERS += styles/qwindowsmobilestyle.h
+ SOURCES += styles/qwindowsmobilestyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSMOBILE
+}
+
+contains( styles, s60 ):contains(QT_CONFIG, s60) {
+ HEADERS += \
+ styles/qs60style.h \
+ styles/qs60style_p.h
+ SOURCES += styles/qs60style.cpp
+ symbian {
+ SOURCES += styles/qs60style_s60.cpp
+ LIBS += -legul -lbmpanim
+ contains(CONFIG, is_using_gnupoc) {
+ LIBS += -laknicon -laknskins -laknskinsrv -lfontutils
+ } else {
+ LIBS += -lAknIcon -lAKNSKINS -lAKNSKINSRV -lFontUtils
+ }
+ } else {
+ SOURCES += styles/qs60style_simulated.cpp
+ RESOURCES += styles/qstyle_s60_simulated.qrc
+ }
+} else {
+ symbian {
+ HEADERS += styles/qs60style.h
+ SOURCES += styles/qs60style_stub.cpp
+ }
+ DEFINES += QT_NO_STYLE_S60
+}