summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/styles
diff options
context:
space:
mode:
authorJo Asplin <jo.asplin@nokia.com>2011-10-20 13:17:26 +0200
committerQt by Nokia <qt-info@nokia.com>2011-10-20 19:45:41 +0200
commit9f1aa866bda7678261f2f441d4cfd5bb524c2411 (patch)
tree5028f578122e7feb9200d571405494c73d96db89 /tests/auto/widgets/styles
parent78d02e93aca5325fc5be9bfd275862795207abaa (diff)
Moved tests into integrationtests/ and widgets/
Task-number: QTBUG-19013 Change-Id: Ibb776f5967c0645ce6d22ef7afdc40657c575461 Reviewed-by: Holger Ihrig <holger.ihrig@nokia.com>
Diffstat (limited to 'tests/auto/widgets/styles')
-rw-r--r--tests/auto/widgets/styles/qmacstyle/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qmacstyle/qmacstyle.pro6
-rw-r--r--tests/auto/widgets/styles/qmacstyle/tst_qmacstyle.cpp413
-rw-r--r--tests/auto/widgets/styles/qstyle/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/button.pngbin0 -> 1785 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/combobox.pngbin0 -> 1808 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/lineedit.pngbin0 -> 953 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/mdi.pngbin0 -> 3092 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/menu.pngbin0 -> 1139 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/radiobutton.pngbin0 -> 1498 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/slider.pngbin0 -> 1074 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/spinbox.pngbin0 -> 1299 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/button.pngbin0 -> 722 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/combobox.pngbin0 -> 809 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/lineedit.pngbin0 -> 530 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/menu.pngbin0 -> 646 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/radiobutton.pngbin0 -> 844 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/slider.pngbin0 -> 575 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/spinbox.pngbin0 -> 583 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/qstyle.pro13
-rw-r--r--tests/auto/widgets/styles/qstyle/task_25863.pngbin0 -> 910 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/tst_qstyle.cpp794
-rw-r--r--tests/auto/widgets/styles/qstyleoption/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qstyleoption/qstyleoption.pro11
-rw-r--r--tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp161
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/images/testimage.pngbin0 -> 299 bytes
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro7
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/resources.qrc6
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp1644
-rw-r--r--tests/auto/widgets/styles/styles.pro13
31 files changed, 3072 insertions, 0 deletions
diff --git a/tests/auto/widgets/styles/qmacstyle/.gitignore b/tests/auto/widgets/styles/qmacstyle/.gitignore
new file mode 100644
index 0000000000..9abe0ad6ab
--- /dev/null
+++ b/tests/auto/widgets/styles/qmacstyle/.gitignore
@@ -0,0 +1 @@
+tst_qmacstyle
diff --git a/tests/auto/widgets/styles/qmacstyle/qmacstyle.pro b/tests/auto/widgets/styles/qmacstyle/qmacstyle.pro
new file mode 100644
index 0000000000..5aad7368c6
--- /dev/null
+++ b/tests/auto/widgets/styles/qmacstyle/qmacstyle.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qmacstyle.cpp
+
+
+mac*:CONFIG+=insignificant_test
diff --git a/tests/auto/widgets/styles/qmacstyle/tst_qmacstyle.cpp b/tests/auto/widgets/styles/qmacstyle/tst_qmacstyle.cpp
new file mode 100644
index 0000000000..a262712abc
--- /dev/null
+++ b/tests/auto/widgets/styles/qmacstyle/tst_qmacstyle.cpp
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** 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 test suite 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 <QtTest/QtTest>
+#include <QtWidgets>
+
+#include <qmacstyle_mac.h>
+
+const int N = 1;
+
+//TESTED_CLASS=
+//TESTED_FILES=gui/styles/qmacstyle_mac.h gui/styles/qmacstyle_mac.cpp
+
+enum Size { Normal, Small, Mini };
+
+Q_DECLARE_METATYPE(Size);
+
+#define CT(E) \
+ static const ControlType E = QSizePolicy::E;
+
+typedef QSizePolicy::ControlType ControlType;
+
+CT(DefaultType)
+CT(ButtonBox)
+CT(CheckBox)
+CT(ComboBox)
+CT(Frame)
+CT(GroupBox)
+CT(Label)
+CT(Line)
+CT(LineEdit)
+CT(PushButton)
+CT(RadioButton)
+CT(Slider)
+CT(SpinBox)
+CT(TabWidget)
+CT(ToolButton)
+
+
+class tst_QMacStyle : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QMacStyle() { qRegisterMetaType<Size>("Size"); }
+
+private slots:
+ void sizeHints_data();
+ void sizeHints();
+ void layoutMargins_data();
+ void layoutMargins();
+ void layoutSpacings_data();
+ void layoutSpacings();
+ void smallMiniNormalExclusivity_data();
+ void smallMiniNormalExclusivity();
+
+private:
+ static QSize msh(QWidget *widget);
+ static QSize sh(QWidget *widget);
+ static QRect geo(QWidget *widget);
+ static QPoint pos(QWidget *widget) { return geo(widget).topLeft(); }
+ static QSize size(QWidget *widget) { return geo(widget).size(); }
+ static QSize gap(QWidget *widget1, QWidget *widget2);
+ static int hgap(QWidget *widget1, QWidget *widget2) { return gap(widget1, widget2).width(); }
+ static int vgap(QWidget *widget1, QWidget *widget2) { return gap(widget1, widget2).height(); }
+ static void setSize(QWidget *widget, Size size);
+ static int spacing(ControlType control1, ControlType control2, Qt::Orientation orientation,
+ QStyleOption *option = 0, QWidget *widget = 0);
+ static int hspacing(ControlType control1, ControlType control2, Size size = Normal);
+ static int vspacing(ControlType control1, ControlType control2, Size size = Normal);
+};
+
+#define SIZE(x, y, z) \
+ ((size == Normal) ? (x) : (size == Small) ? (y) : (z))
+
+void tst_QMacStyle::sizeHints_data()
+{
+ QTest::addColumn<Size>("size");
+ QTest::newRow("normal") << Normal;
+// QTest::newRow("small") << Small;
+// QTest::newRow("mini") << Mini;
+}
+
+void tst_QMacStyle::sizeHints()
+{
+ QFETCH(Size, size);
+ QDialog w;
+ setSize(&w, size);
+
+ QLineEdit lineEdit1(&w);
+ QCOMPARE(sh(&lineEdit1).height(), SIZE(22, 19, 16)); // 16 in Builder, 15 in AHIG
+
+ QProgressBar progress1(&w);
+ progress1.setOrientation(Qt::Horizontal);
+ qDebug() << "sh" << progress1.sizeHint();
+ QCOMPARE(sh(&progress1).height(), SIZE(16, 10, 10)); // Builder
+
+ progress1.setOrientation(Qt::Vertical);
+ QCOMPARE(sh(&progress1).width(), SIZE(16, 10, 10)); // Builder
+
+ QRadioButton radio1("Radio", &w);
+ QCOMPARE(sh(&radio1).height(), SIZE(15, 12, 10)); // Builder
+
+ QCheckBox checkBox1("Switch", &w);
+ QCOMPARE(sh(&checkBox1).height(), SIZE(14, 12, 10)); // Builder
+
+ QComboBox comboBox1(&w);
+ comboBox1.setEditable(false);
+ comboBox1.addItem("Foo");
+ QCOMPARE(sh(&comboBox1).height(), SIZE(20, 17, 15));
+
+ QComboBox comboBox2(&w);
+ comboBox2.setEditable(true);
+ comboBox2.addItem("Foo");
+ QCOMPARE(sh(&comboBox2).height(), SIZE(20, 17, 15));
+
+ // Combos in toolbars use the actual widget rect to
+ // avoid faulty clipping:
+ QToolBar tb;
+ setSize(&tb, size);
+ QComboBox comboBox3(&tb);
+ comboBox3.addItem("Foo");
+ QCOMPARE(sh(&comboBox3).height(), SIZE(26, -1, -1));
+
+ QSlider slider1(Qt::Horizontal, &w);
+ QCOMPARE(sh(&slider1).height(), SIZE(15, 12, 10));
+
+ slider1.setTickPosition(QSlider::TicksAbove);
+ QCOMPARE(sh(&slider1).height(), SIZE(24, 17, 16)); // Builder
+
+ slider1.setTickPosition(QSlider::TicksBelow);
+ QCOMPARE(sh(&slider1).height(), SIZE(24, 17, 16)); // Builder
+
+ slider1.setTickPosition(QSlider::TicksBothSides);
+ QVERIFY(sh(&slider1).height() > SIZE(15, 12, 10)); // common sense
+
+ QPushButton ok1("OK", &w);
+ QPushButton cancel1("Cancel", &w);
+
+ QSize s1 = sh(&ok1);
+ if (size == Normal) {
+ // AHIG says 68, Builder does 70, and Qt seems to do 69
+ QVERIFY(s1.width() >= 68 && s1.width() <= 70);
+ }
+ QCOMPARE(s1.height(), SIZE(20, 17, 14)); // 14 in Builder, 15 in AHIG
+
+ // Cancel should be identical to OK, no matter what
+ QCOMPARE(s1, sh(&cancel1));
+
+ // Play with auto-default and default
+ cancel1.setAutoDefault(false);
+ QCOMPARE(s1, sh(&cancel1));
+ cancel1.setAutoDefault(true);
+ QCOMPARE(s1, sh(&cancel1));
+ cancel1.setDefault(true);
+ QCOMPARE(s1, sh(&cancel1));
+
+ QDialogButtonBox bbox(&w);
+ bbox.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ QCOMPARE(s1, sh(bbox.button(QDialogButtonBox::Ok)));
+ QCOMPARE(s1, sh(bbox.button(QDialogButtonBox::Cancel)));
+
+ QMessageBox mbox(&w);
+ mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ QCOMPARE(s1, sh(mbox.button(QMessageBox::Ok)));
+ QCOMPARE(s1, sh(mbox.button(QMessageBox::Cancel)));
+
+ /*
+ QSpinBox spinBox1(&w);
+ int h1 = sh(&spinBox1).height();
+ QCOMPARE(h1, SIZE(22, 19, 15));
+
+ QDateEdit date1(&w);
+ QCOMPARE(sh(&date1).height(), h1);
+
+ QTimeEdit time1(&w);
+ QCOMPARE(sh(&time1).height(), h1);
+
+ QDateTimeEdit dateTime1(&w);
+ QCOMPARE(sh(&dateTime1).height(), h1);
+
+ ok1.setAttribute(Qt::WA_MacMetalStyle, true);
+ QSize s2 = sh(&ok1);
+ if (size == Normal) {
+ QVERIFY(s2.height() >= 21 && s2.height() <= 32);
+ } else {
+ QVERIFY(s2.height() >= 18 && s2.height() <= 24);
+ }
+ */
+
+ // QMacStyle bug: label doesn't react to Small and Mini
+ QLabel label1("Blah", &w);
+ QCOMPARE(sh(&label1).height(), SIZE(17, 14, 11));
+}
+
+void tst_QMacStyle::layoutMargins_data()
+{
+ tst_QMacStyle::sizeHints_data();
+}
+
+void tst_QMacStyle::layoutMargins()
+{
+ QFETCH(Size, size);
+ QWidget w;
+ setSize(&w, size);
+
+}
+
+void tst_QMacStyle::layoutSpacings_data()
+{
+ tst_QMacStyle::sizeHints_data();
+}
+
+void tst_QMacStyle::layoutSpacings()
+{
+ QFETCH(Size, size);
+
+ /*
+ Constraints specified by AHIG.
+ */
+
+ for (int i = 0; i < 4; ++i) {
+ ControlType c1 = (i % 2 == 0) ? PushButton : ButtonBox;
+ ControlType c2 = (i / 2 == 0) ? PushButton : ButtonBox;
+ QCOMPARE(hspacing(c1, c2, size), SIZE(14, 8, 8));
+ QCOMPARE(vspacing(c1, c2, size), SIZE(14, 8, 8));
+ }
+
+ QCOMPARE(hspacing(Label, RadioButton, size), SIZE(8, 6, 5));
+ QCOMPARE(vspacing(RadioButton, RadioButton, size), SIZE(5, 5, 5)); // Builder, guess, AHIG
+
+ QCOMPARE(hspacing(Label, CheckBox, size), SIZE(8, 6, 5));
+ QCOMPARE(vspacing(CheckBox, CheckBox, size), SIZE(8, 8, 7));
+
+ QCOMPARE(hspacing(Label, ComboBox, size), SIZE(8, 6, 5));
+
+ QCOMPARE(hspacing(LineEdit, LineEdit, size), SIZE(10, 8, 8));
+
+ /*
+ Common sense constraints, for when AHIG seems to make no sense (e.g., disagrees
+ too much with Builder or looks improper).
+ */
+
+ // Comboboxes are a special pain, because AHIG and Builder can't agree,
+ // and because they can be editable or not, with two totally different looks
+ QVERIFY(vspacing(ComboBox, ComboBox, size) >= SIZE(8, 6, 5));
+ QVERIFY(vspacing(ComboBox, ComboBox, size) <= SIZE(12, 10, 8));
+
+ // Make sure button boxes get the respect they deserve, when they occur
+ // in the bottom or right side of a dialog
+ QCOMPARE(hspacing(ButtonBox, LineEdit), SIZE(20, 8, 8));
+ QCOMPARE(vspacing(ButtonBox, LineEdit), SIZE(20, 7, 7));
+
+ QCOMPARE(hspacing(LineEdit, ButtonBox), SIZE(8, 8, 8));
+ QCOMPARE(vspacing(LineEdit, ButtonBox), SIZE(8, 8, 8));
+}
+
+// helper functions
+
+QSize tst_QMacStyle::msh(QWidget *widget)
+{
+ QWidgetItem item(widget);
+ return item.sizeHint();
+}
+
+QSize tst_QMacStyle::sh(QWidget *widget)
+{
+ QWidgetItem item(widget);
+ return item.sizeHint();
+}
+
+QRect tst_QMacStyle::geo(QWidget *widget)
+{
+ QWidgetItem item(widget);
+ return item.geometry();
+}
+
+QSize tst_QMacStyle::gap(QWidget *widget1, QWidget *widget2)
+{
+ QPoint d = pos(widget2) - pos(widget1);
+ QSize s = size(widget1);
+ return s + QSize(d.x(), d.y());
+}
+
+void tst_QMacStyle::setSize(QWidget *widget, Size size)
+{
+ switch (size) {
+ case Normal:
+ QMacStyle::setWidgetSizePolicy(widget, QMacStyle::SizeDefault);
+ break;
+ case Small:
+ QMacStyle::setWidgetSizePolicy(widget, QMacStyle::SizeSmall);
+ break;
+ case Mini:
+ QMacStyle::setWidgetSizePolicy(widget, QMacStyle::SizeMini);
+ }
+}
+
+int tst_QMacStyle::spacing(ControlType control1, ControlType control2, Qt::Orientation orientation,
+ QStyleOption *option, QWidget *widget)
+{
+ return QApplication::style()->layoutSpacing(control1, control2, orientation, option, widget);
+}
+
+int tst_QMacStyle::hspacing(ControlType control1, ControlType control2, Size size)
+{
+ QWidget w;
+ setSize(&w, size);
+
+ QStyleOption opt;
+ opt.initFrom(&w);
+
+ return spacing(control1, control2, Qt::Horizontal, &opt);
+}
+
+int tst_QMacStyle::vspacing(ControlType control1, ControlType control2, Size size)
+{
+ QWidget w;
+ setSize(&w, size);
+
+ QStyleOption opt;
+ opt.initFrom(&w);
+
+ return spacing(control1, control2, Qt::Vertical, &opt);
+}
+
+
+void tst_QMacStyle::smallMiniNormalExclusivity_data()
+{
+
+ QTest::addColumn<int>("size1");
+ QTest::addColumn<int>("size2");
+ QTest::addColumn<int>("size3");
+ QTest::addColumn<int>("expectedHeight1");
+ QTest::addColumn<int>("expectedHeight2");
+ QTest::addColumn<int>("expectedHeight3");
+
+ QTest::newRow("normal small mini") << int(Qt::WA_MacNormalSize) << int(Qt::WA_MacSmallSize) << int(Qt::WA_MacMiniSize) << 32 << 16 << 24;
+ QTest::newRow("normal mini small") << int(Qt::WA_MacNormalSize) <<int(Qt::WA_MacMiniSize) << int(Qt::WA_MacSmallSize) << 32 << 24 << 16;
+ QTest::newRow("small normal mini") << int(Qt::WA_MacSmallSize) << int(Qt::WA_MacNormalSize) << int(Qt::WA_MacMiniSize) << 16 << 32 << 24;
+ QTest::newRow("small mini normal") << int(Qt::WA_MacSmallSize) << int(Qt::WA_MacMiniSize) << int(Qt::WA_MacNormalSize) << 16 << 24 << 32;
+ QTest::newRow("mini small normal") << int(Qt::WA_MacMiniSize) << int(Qt::WA_MacSmallSize) << int(Qt::WA_MacNormalSize) << 24 << 16 << 32;
+ QTest::newRow("mini normal small") << int(Qt::WA_MacMiniSize) << int(Qt::WA_MacNormalSize) << int(Qt::WA_MacSmallSize) << 24 << 32 << 16;
+}
+
+void tst_QMacStyle::smallMiniNormalExclusivity()
+{
+
+ QFETCH(int, size1);
+ QFETCH(int, size2);
+ QFETCH(int, size3);
+ QFETCH(int, expectedHeight1);
+ QFETCH(int, expectedHeight2);
+ QFETCH(int, expectedHeight3);
+
+ static const int TotalSizes = 3;
+ int attrs[TotalSizes] = { size1, size2, size3 };
+ int expected[TotalSizes] = { expectedHeight1, expectedHeight2, expectedHeight3 };
+
+ QPushButton dummyWidget;
+ QStyleOptionButton opt;
+
+ for (int i = 0; i < TotalSizes; ++i) {
+ dummyWidget.setAttribute(Qt::WidgetAttribute(attrs[i]));
+ opt.initFrom(&dummyWidget);
+ QSize size = dummyWidget.style()->sizeFromContents(QStyle::CT_PushButton, &opt,
+ QSize(0, 0), &dummyWidget);
+ QCOMPARE(size.height(), expected[i]);
+ }
+}
+
+QTEST_MAIN(tst_QMacStyle)
+#include "tst_qmacstyle.moc"
+
diff --git a/tests/auto/widgets/styles/qstyle/.gitignore b/tests/auto/widgets/styles/qstyle/.gitignore
new file mode 100644
index 0000000000..64709f11f7
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/.gitignore
@@ -0,0 +1 @@
+tst_qstyle
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/button.png b/tests/auto/widgets/styles/qstyle/images/mac/button.png
new file mode 100644
index 0000000000..7b11325e87
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/button.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/combobox.png b/tests/auto/widgets/styles/qstyle/images/mac/combobox.png
new file mode 100644
index 0000000000..ded0b11f29
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/combobox.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png b/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png
new file mode 100644
index 0000000000..8d2861b65b
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/mdi.png b/tests/auto/widgets/styles/qstyle/images/mac/mdi.png
new file mode 100644
index 0000000000..8c09ae4338
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/mdi.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/menu.png b/tests/auto/widgets/styles/qstyle/images/mac/menu.png
new file mode 100644
index 0000000000..5dd9111d69
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/menu.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png b/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png
new file mode 100644
index 0000000000..8828e220a2
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/slider.png b/tests/auto/widgets/styles/qstyle/images/mac/slider.png
new file mode 100644
index 0000000000..fc65035631
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/slider.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png b/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png
new file mode 100644
index 0000000000..ee88441ecb
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/button.png b/tests/auto/widgets/styles/qstyle/images/vista/button.png
new file mode 100644
index 0000000000..a6c45276ca
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/button.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/combobox.png b/tests/auto/widgets/styles/qstyle/images/vista/combobox.png
new file mode 100644
index 0000000000..9b82f64d32
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/combobox.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png b/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png
new file mode 100644
index 0000000000..b2c6ac1ae4
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/menu.png b/tests/auto/widgets/styles/qstyle/images/vista/menu.png
new file mode 100644
index 0000000000..b114099cc3
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/menu.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png b/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png
new file mode 100644
index 0000000000..c8aa7864df
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/slider.png b/tests/auto/widgets/styles/qstyle/images/vista/slider.png
new file mode 100644
index 0000000000..7c156ded9d
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/slider.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png b/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png
new file mode 100644
index 0000000000..b8d0823ab2
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/qstyle.pro b/tests/auto/widgets/styles/qstyle/qstyle.pro
new file mode 100644
index 0000000000..2016316737
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/qstyle.pro
@@ -0,0 +1,13 @@
+load(qttest_p4)
+TARGET.EPOCHEAPSIZE = 0x200000 0x800000
+QT += widgets
+SOURCES += tst_qstyle.cpp
+
+wince* {
+ DEFINES += SRCDIR=\\\".\\\"
+ addPixmap.files = task_25863.png
+ addPixmap.path = .
+ DEPLOYMENT += addPixmap
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
diff --git a/tests/auto/widgets/styles/qstyle/task_25863.png b/tests/auto/widgets/styles/qstyle/task_25863.png
new file mode 100644
index 0000000000..a2de8d6f78
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/task_25863.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
new file mode 100644
index 0000000000..0045dbbb52
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
@@ -0,0 +1,794 @@
+/****************************************************************************
+**
+** 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 test suite 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 <QtTest/QtTest>
+#include <qlayout.h>
+#include "qstyle.h"
+#include <qevent.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qapplication.h>
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qstyleoption.h>
+#include <qscrollbar.h>
+#include <qprogressbar.h>
+#include <qtoolbutton.h>
+#include <qtoolbar.h>
+
+#include <qplastiquestyle.h>
+#include <qwindowsstyle.h>
+#include <qcdestyle.h>
+#include <qmotifstyle.h>
+#include <qcommonstyle.h>
+#include <qproxystyle.h>
+#include <qstylefactory.h>
+
+#include <qimagereader.h>
+#include <qimagewriter.h>
+#include <qmenu.h>
+#include <qpushbutton.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qradiobutton.h>
+#include <qlineedit.h>
+#include <qmdiarea.h>
+
+#include <QCleanlooksStyle>
+
+#ifdef Q_WS_MAC
+#include <QMacStyle>
+#endif
+
+#ifdef Q_WS_WIN
+#include <QWindowsXPStyle>
+#include <QWindowsVistaStyle>
+#endif
+
+#ifdef Q_OS_WINCE
+#include <QWindowsCEStyle>
+#endif
+
+#ifdef Q_OS_WINCE_WM
+#include <QWindowsMobileStyle>
+#include <windows.h>
+
+static bool qt_wince_is_smartphone() {
+ wchar_t tszPlatform[64];
+ if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
+ sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
+ if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (QString::fromLatin1("Smartphone").utf16()), tszPlatform))
+ return true;
+ return false;
+}
+#endif
+
+#include <qwidget.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=gui/styles/qstyle.h gui/styles/qstyle.cpp gui/styles/qplastiquestyle.cpp gui/styles/qwindowsstyle.cpp gui/styles/qwindowsxpstyle.cpp gui/styles/qwindowsvistastyle.cpp gui/styles/qmotifstyle.cpp
+
+class tst_QStyle : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QStyle();
+ virtual ~tst_QStyle();
+private:
+ void testAllFunctions(QStyle *);
+ void testScrollBarSubControls(QStyle *);
+ void testPainting(QStyle *style, const QString &platform);
+private slots:
+ void drawItemPixmap();
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+#ifndef QT_NO_STYLE_MOTIF
+ void testMotifStyle();
+#endif
+#ifndef QT_NO_STYLE_PLASTIQUE
+ void testPlastiqueStyle();
+#endif
+ void testWindowsStyle();
+#ifndef QT_NO_STYLE_CDE
+ void testCDEStyle();
+#endif
+#if defined(Q_WS_WIN) && !defined(QT_NO_STYLE_WINDOWSXP)
+ void testWindowsXPStyle();
+#endif
+ void testWindowsVistaStyle();
+#ifndef QT_NO_STYLE_CLEANLOOKS
+ void testCleanlooksStyle();
+#endif
+ void testMacStyle();
+#ifdef Q_OS_WINCE
+ void testWindowsCEStyle();
+#endif
+#ifdef Q_OS_WINCE_WM
+ void testWindowsMobileStyle();
+#endif
+ void testStyleFactory();
+ void testProxyStyle();
+ void pixelMetric();
+#if !defined(QT_NO_STYLE_PLASTIQUE) && !defined(QT_NO_STYLE_WINDOWS)
+ void progressBarChangeStyle();
+#endif
+ void defaultFont();
+ void testDrawingShortcuts();
+private:
+ void lineUpLayoutTest(QStyle *);
+ QWidget *testWidget;
+};
+
+
+tst_QStyle::tst_QStyle()
+{
+ testWidget = 0;
+}
+
+tst_QStyle::~tst_QStyle()
+{
+}
+
+class MyWidget : public QWidget
+{
+public:
+ MyWidget( QWidget* QWidget=0, const char* name=0 );
+protected:
+ void paintEvent( QPaintEvent* );
+};
+
+void tst_QStyle::init()
+{
+ testWidget = new MyWidget( 0, "testObject");
+}
+
+void tst_QStyle::cleanup()
+{
+ delete testWidget;
+ testWidget = 0;
+}
+
+void tst_QStyle::initTestCase()
+{
+}
+
+void tst_QStyle::cleanupTestCase()
+{
+}
+
+void tst_QStyle::testStyleFactory()
+{
+ QStringList keys = QStyleFactory::keys();
+#ifndef QT_NO_STYLE_MOTIF
+ QVERIFY(keys.contains("Motif"));
+#endif
+#ifndef QT_NO_STYLE_CLEANLOOKS
+ QVERIFY(keys.contains("Cleanlooks"));
+#endif
+#ifndef QT_NO_STYLE_PLASTIQUE
+ QVERIFY(keys.contains("Plastique"));
+#endif
+#ifndef QT_NO_STYLE_CDE
+ QVERIFY(keys.contains("CDE"));
+#endif
+#ifndef QT_NO_STYLE_WINDOWS
+ QVERIFY(keys.contains("Windows"));
+#endif
+#ifndef QT_NO_STYLE_MOTIF
+ QVERIFY(keys.contains("Motif"));
+#endif
+#ifdef Q_WS_WIN
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP &&
+ QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QVERIFY(keys.contains("WindowsXP"));
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA &&
+ QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QVERIFY(keys.contains("WindowsVista"));
+#endif
+
+ foreach (QString styleName , keys) {
+ QStyle *style = QStyleFactory::create(styleName);
+ QVERIFY2(style != 0, qPrintable(QString::fromLatin1("Fail to load style '%1'").arg(styleName)));
+ delete style;
+ }
+}
+
+class CustomProxy : public QProxyStyle
+{
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const
+ {
+ if (metric == QStyle::PM_ButtonIconSize)
+ return 13;
+ return QProxyStyle::pixelMetric(metric, option, widget);
+ }
+};
+
+void tst_QStyle::testProxyStyle()
+{
+ QProxyStyle *proxyStyle = new QProxyStyle();
+ QVERIFY(proxyStyle->baseStyle());
+ QStyle *style = new QWindowsStyle;
+ QVERIFY(style->proxy() == style);
+
+ proxyStyle->setBaseStyle(style);
+ QVERIFY(style->proxy() == proxyStyle);
+ QVERIFY(style->parent() == proxyStyle);
+ QVERIFY(proxyStyle->baseStyle() == style);
+
+ testAllFunctions(proxyStyle);
+ proxyStyle->setBaseStyle(0);
+ QVERIFY(proxyStyle->baseStyle());
+ qApp->setStyle(proxyStyle);
+
+ QProxyStyle doubleProxy(new QProxyStyle(new QWindowsStyle()));
+ testAllFunctions(&doubleProxy);
+
+ CustomProxy customStyle;
+ QLineEdit edit;
+ edit.setStyle(&customStyle);
+ QVERIFY(!customStyle.parent());
+ QVERIFY(edit.style()->pixelMetric(QStyle::PM_ButtonIconSize) == 13);
+}
+
+void tst_QStyle::drawItemPixmap()
+{
+ testWidget->resize(300, 300);
+ testWidget->show();
+
+ QPixmap p(QString(SRCDIR) + "/task_25863.png", "PNG");
+ QPixmap actualPix = QPixmap::grabWidget(testWidget);
+
+ QVERIFY(pixmapsAreEqual(&actualPix,&p));
+ testWidget->hide();
+}
+
+void tst_QStyle::testAllFunctions(QStyle *style)
+{
+ QStyleOption opt;
+ opt.init(testWidget);
+
+ testWidget->setStyle(style);
+
+ //Tests styleHint with default arguments for potential crashes
+ for ( int hint = 0 ; hint < int(QStyle::SH_Menu_Mask); ++hint) {
+ style->styleHint(QStyle::StyleHint(hint));
+ style->styleHint(QStyle::StyleHint(hint), &opt, testWidget);
+ }
+
+ //Tests pixelMetric with default arguments for potential crashes
+ for ( int pm = 0 ; pm < int(QStyle::PM_LayoutVerticalSpacing); ++pm) {
+ style->pixelMetric(QStyle::PixelMetric(pm));
+ style->pixelMetric(QStyle::PixelMetric(pm), &opt, testWidget);
+ }
+
+ //Tests drawControl with default arguments for potential crashes
+ for ( int control = 0 ; control < int(QStyle::CE_ColumnViewGrip); ++control) {
+ QPixmap surface(QSize(200, 200));
+ QPainter painter(&surface);
+ style->drawControl(QStyle::ControlElement(control), &opt, &painter, 0);
+ }
+
+ //Tests drawComplexControl with default arguments for potential crashes
+ {
+ QPixmap surface(QSize(200, 200));
+ QPainter painter(&surface);
+ QStyleOptionComboBox copt1;
+ copt1.init(testWidget);
+
+ QStyleOptionGroupBox copt2;
+ copt2.init(testWidget);
+ QStyleOptionSizeGrip copt3;
+ copt3.init(testWidget);
+ QStyleOptionSlider copt4;
+ copt4.init(testWidget);
+ copt4.minimum = 0;
+ copt4.maximum = 100;
+ copt4.tickInterval = 25;
+ copt4.sliderValue = 50;
+ QStyleOptionSpinBox copt5;
+ copt5.init(testWidget);
+ QStyleOptionTitleBar copt6;
+ copt6.init(testWidget);
+ QStyleOptionToolButton copt7;
+ copt7.init(testWidget);
+ QStyleOptionComplex copt9;
+ copt9.initFrom(testWidget);
+
+ style->drawComplexControl(QStyle::CC_SpinBox, &copt5, &painter, 0);
+ style->drawComplexControl(QStyle::CC_ComboBox, &copt1, &painter, 0);
+ style->drawComplexControl(QStyle::CC_ScrollBar, &copt4, &painter, 0);
+ style->drawComplexControl(QStyle::CC_Slider, &copt4, &painter, 0);
+ style->drawComplexControl(QStyle::CC_ToolButton, &copt7, &painter, 0);
+ style->drawComplexControl(QStyle::CC_TitleBar, &copt6, &painter, 0);
+ style->drawComplexControl(QStyle::CC_GroupBox, &copt2, &painter, 0);
+ style->drawComplexControl(QStyle::CC_Dial, &copt4, &painter, 0);
+ }
+
+ //Check standard pixmaps/icons
+ for ( int i = 0 ; i < int(QStyle::SP_ToolBarVerticalExtensionButton); ++i) {
+ QPixmap pixmap = style->standardPixmap(QStyle::StandardPixmap(i));
+ if (pixmap.isNull()) {
+ qWarning("missing StandardPixmap: %d", i);
+ }
+ QIcon icn = style->standardIcon(QStyle::StandardPixmap(i));
+ if (icn.isNull()) {
+ qWarning("missing StandardIcon: %d", i);
+ }
+ }
+
+ style->itemPixmapRect(QRect(0, 0, 100, 100), Qt::AlignHCenter, QPixmap(200, 200));
+ style->itemTextRect(QFontMetrics(qApp->font()), QRect(0, 0, 100, 100), Qt::AlignHCenter, true, QString("Test"));
+
+ testScrollBarSubControls(style);
+}
+
+void tst_QStyle::testScrollBarSubControls(QStyle* style)
+{
+#ifdef Q_OS_WINCE_WM
+ if (qobject_cast<QWindowsMobileStyle*>(style) && qt_wince_is_smartphone())
+ QSKIP("SmartPhone doesn't have scrollbar subcontrols.", SkipAll);
+#else
+ Q_UNUSED(style);
+#endif
+
+ QScrollBar scrollBar;
+ scrollBar.show();
+ const QStyleOptionSlider opt = qt_qscrollbarStyleOption(&scrollBar);
+ foreach (int subControl, QList<int>() << 1 << 2 << 4 << 8) {
+ QRect sr = testWidget->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
+ QStyle::SubControl(subControl), &scrollBar);
+ QVERIFY(sr.isNull() == false);
+ }
+}
+
+#ifndef QT_NO_STYLE_PLASTIQUE
+void tst_QStyle::testPlastiqueStyle()
+{
+ QPlastiqueStyle pstyle;
+ testAllFunctions(&pstyle);
+ lineUpLayoutTest(&pstyle);
+}
+#endif
+
+#ifndef QT_NO_STYLE_CLEANLOOKS
+void tst_QStyle::testCleanlooksStyle()
+{
+ QCleanlooksStyle cstyle;
+ testAllFunctions(&cstyle);
+ lineUpLayoutTest(&cstyle);
+}
+#endif
+
+void tst_QStyle::testWindowsStyle()
+{
+ QWindowsStyle wstyle;
+ testAllFunctions(&wstyle);
+ lineUpLayoutTest(&wstyle);
+
+ // Tests drawing indeterminate progress with 0 size: QTBUG-15973
+ QStyleOptionProgressBar pb;
+ pb.rect = QRect(0,0,-9,0);
+ QPixmap surface(QSize(200, 200));
+ QPainter painter(&surface);
+ wstyle.drawControl(QStyle::CE_ProgressBar, &pb, &painter, 0);
+}
+
+#if defined(Q_WS_WIN) && !defined(QT_NO_STYLE_WINDOWSXP)
+void tst_QStyle::testWindowsXPStyle()
+{
+ QWindowsXPStyle xpstyle;
+ testAllFunctions(&xpstyle);
+ lineUpLayoutTest(&xpstyle);
+}
+#endif
+
+void writeImage(const QString &fileName, QImage image)
+{
+ QImageWriter imageWriter(fileName);
+ imageWriter.setFormat("png");
+ qDebug() << "result " << imageWriter.write(image);
+}
+
+QImage readImage(const QString &fileName)
+{
+ QImageReader reader(fileName);
+ return reader.read();
+}
+
+
+void tst_QStyle::testWindowsVistaStyle()
+{
+#if defined(Q_WS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA)
+ QWindowsVistaStyle vistastyle;
+ testAllFunctions(&vistastyle);
+
+ if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA)
+ testPainting(&vistastyle, "vista");
+ else if (QSysInfo::WindowsVersion == QSysInfo::WV_XP)
+ testPainting(&vistastyle, "xp");
+#endif
+}
+
+void comparePixmap(const QString &filename, const QPixmap &pixmap)
+{
+ QImage oldFile = readImage(filename);
+ QPixmap oldPixmap = QPixmap::fromImage(oldFile);
+ if (!oldFile.isNull())
+ QVERIFY(pixmapsAreEqual(&pixmap, &oldPixmap));
+ else
+ writeImage(filename, pixmap.toImage());
+}
+
+void tst_QStyle::testPainting(QStyle *style, const QString &platform)
+{
+qDebug("TEST PAINTING");
+ //Test Menu
+ QString fileName = "images/" + platform + "/menu.png";
+ QMenu menu;
+ menu.setStyle(style);
+ menu.show();
+ menu.addAction(new QAction("Test 1", &menu));
+ menu.addAction(new QAction("Test 2", &menu));
+ QPixmap pixmap = QPixmap::grabWidget(&menu);
+ comparePixmap(fileName, pixmap);
+
+ //Push button
+ fileName = "images/" + platform + "/button.png";
+ QPushButton button("OK");
+ button.setStyle(style);
+ button.show();
+ pixmap = QPixmap::grabWidget(&button);
+ button.hide();
+ comparePixmap(fileName, pixmap);
+
+ //Push button
+ fileName = "images/" + platform + "/radiobutton.png";
+ QRadioButton radiobutton("Check");
+ radiobutton.setStyle(style);
+ radiobutton.show();
+ pixmap = QPixmap::grabWidget(&radiobutton);
+ radiobutton.hide();
+ comparePixmap(fileName, pixmap);
+
+ //Combo box
+ fileName = "images/" + platform + "/combobox.png";
+ QComboBox combobox;
+ combobox.setStyle(style);
+ combobox.addItem("Test 1");
+ combobox.addItem("Test 2");
+ combobox.show();
+ pixmap = QPixmap::grabWidget(&combobox);
+ combobox.hide();
+ comparePixmap(fileName, pixmap);
+
+ //Spin box
+ fileName = "images/" + platform + "/spinbox.png";
+ QDoubleSpinBox spinbox;
+ spinbox.setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
+ spinbox.setStyle(style);
+ spinbox.show();
+ pixmap = QPixmap::grabWidget(&spinbox);
+ spinbox.hide();
+ comparePixmap(fileName, pixmap);
+ QLocale::setDefault(QLocale::system());
+
+ //Slider
+ fileName = "images/" + platform + "/slider.png";
+ QSlider slider;
+ slider.setStyle(style);
+ slider.show();
+ pixmap = QPixmap::grabWidget(&slider);
+ slider.hide();
+ comparePixmap(fileName, pixmap);
+
+ //Line edit
+ fileName = "images/" + platform + "/lineedit.png";
+ QLineEdit lineedit("Test text");
+ lineedit.setStyle(style);
+ lineedit.show();
+ pixmap = QPixmap::grabWidget(&lineedit);
+ lineedit.hide();
+ comparePixmap(fileName, pixmap);
+
+ //MDI
+ fileName = "images/" + platform + "/mdi.png";
+ QMdiArea mdiArea;
+ mdiArea.addSubWindow(new QWidget(&mdiArea));
+ mdiArea.resize(200, 200);
+ mdiArea.setStyle(style);
+ mdiArea.show();
+ pixmap = QPixmap::grabWidget(&mdiArea);
+ mdiArea.hide();
+ comparePixmap(fileName, pixmap);
+
+ // QToolButton
+ fileName = "images/" + platform + "/toolbutton.png";
+ QToolButton tb;
+ tb.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+ tb.setText("AaQqPpXx");
+ tb.setIcon(style->standardPixmap(QStyle::SP_DirHomeIcon));
+ tb.setStyle(style);
+ tb.show();
+ pixmap = QPixmap::grabWidget(&tb);
+ tb.hide();
+ comparePixmap(fileName, pixmap);
+
+}
+
+void tst_QStyle::testMacStyle()
+{
+#ifdef Q_WS_MAC
+ QMacStyle mstyle;
+ testAllFunctions(&mstyle);
+#endif
+}
+
+#ifndef QT_NO_STYLE_MOTIF
+void tst_QStyle::testMotifStyle()
+{
+ QMotifStyle mstyle;
+ testAllFunctions(&mstyle);
+}
+#endif
+
+#ifndef QT_NO_STYLE_CDE
+void tst_QStyle::testCDEStyle()
+{
+ QCDEStyle cstyle;
+ testAllFunctions(&cstyle);
+}
+#endif
+
+#ifdef Q_OS_WINCE
+void tst_QStyle::testWindowsCEStyle()
+{
+ QWindowsCEStyle cstyle;
+ testAllFunctions(&cstyle);
+}
+#endif
+
+#ifdef Q_OS_WINCE_WM
+void tst_QStyle::testWindowsMobileStyle()
+{
+ QWindowsMobileStyle cstyle;
+ testAllFunctions(&cstyle);
+}
+#endif
+
+// Helper class...
+
+MyWidget::MyWidget( QWidget* parent, const char* name )
+ : QWidget( parent )
+{
+ setObjectName(name);
+}
+
+void MyWidget::paintEvent( QPaintEvent* )
+{
+ QPainter p(this);
+ QPixmap big(400,400);
+ big.fill(Qt::green);
+ style()->drawItemPixmap(&p, rect(), Qt::AlignCenter, big);
+}
+
+
+class Qt42Style : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ Qt42Style() : QWindowsStyle()
+ {
+ margin_toplevel = 10;
+ margin = 5;
+ spacing = 0;
+ }
+
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0,
+ const QWidget * widget = 0 ) const;
+
+ int margin_toplevel;
+ int margin;
+ int spacing;
+
+};
+
+int Qt42Style::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/,
+ const QWidget * widget /*= 0*/ ) const
+{
+ switch (metric) {
+ case QStyle::PM_DefaultTopLevelMargin:
+ return margin_toplevel;
+ break;
+ case QStyle::PM_DefaultChildMargin:
+ return margin;
+ break;
+ case QStyle::PM_DefaultLayoutSpacing:
+ return spacing;
+ break;
+ default:
+ break;
+ }
+ return QWindowsStyle::pixelMetric(metric, option, widget);
+}
+
+
+void tst_QStyle::pixelMetric()
+{
+ Qt42Style *style = new Qt42Style();
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultTopLevelMargin), 10);
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultChildMargin), 5);
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultLayoutSpacing), 0);
+
+ style->margin_toplevel = 0;
+ style->margin = 0;
+ style->spacing = 0;
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultTopLevelMargin), 0);
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultChildMargin), 0);
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultLayoutSpacing), 0);
+
+ style->margin_toplevel = -1;
+ style->margin = -1;
+ style->spacing = -1;
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultTopLevelMargin), -1);
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultChildMargin), -1);
+ QCOMPARE(style->pixelMetric(QStyle::PM_DefaultLayoutSpacing), -1);
+
+ delete style;
+}
+
+#if !defined(QT_NO_STYLE_PLASTIQUE) && !defined(QT_NO_STYLE_WINDOWS)
+void tst_QStyle::progressBarChangeStyle()
+{
+ //test a crashing situation (task 143530)
+ //where changing the styles and deleting a progressbar would crash
+
+ QWindowsStyle style1;
+ QPlastiqueStyle style2;
+
+ QProgressBar *progress=new QProgressBar;
+ progress->setStyle(&style1);
+
+ progress->show();
+
+ progress->setStyle(&style2);
+
+ QTest::qWait(100);
+ delete progress;
+
+ QTest::qWait(100);
+
+ //before the correction, there would be a crash here
+}
+#endif
+
+void tst_QStyle::lineUpLayoutTest(QStyle *style)
+{
+ QWidget widget;
+ QHBoxLayout layout;
+ QFont font;
+ font.setPointSize(9); //Plastique is lined up for odd numbers...
+ widget.setFont(font);
+ QSpinBox spinbox(&widget);
+ QLineEdit lineedit(&widget);
+ QComboBox combo(&widget);
+ combo.setEditable(true);
+ layout.addWidget(&spinbox);
+ layout.addWidget(&lineedit);
+ layout.addWidget(&combo);
+ widget.setLayout(&layout);
+ widget.setStyle(style);
+ // propagate the style.
+ foreach (QWidget *w, qFindChildren<QWidget *>(&widget))
+ w->setStyle(style);
+ widget.show();
+ QTest::qWait( 500 );
+
+ QVERIFY(qAbs(spinbox.height() - lineedit.height()) <= 1);
+ QVERIFY(qAbs(spinbox.height() - combo.height()) <= 1);
+}
+
+void tst_QStyle::defaultFont()
+{
+ QFont defaultFont = qApp->font();
+ QFont pointFont = defaultFont;
+ pointFont.setPixelSize(9);
+ qApp->setFont(pointFont);
+ QPushButton button;
+ button.show();
+ qApp->processEvents();
+ qApp->setFont(defaultFont);
+}
+
+class DrawTextStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ DrawTextStyle(QStyle *base = 0) : QProxyStyle(), alignment(0) { setBaseStyle(base); }
+ void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const
+ {
+ DrawTextStyle *that = (DrawTextStyle *)this;
+ that->alignment = flags;
+ QProxyStyle::drawItemText(painter, rect, flags, pal, enabled, text, textRole);
+ }
+ int alignment;
+};
+
+void tst_QStyle::testDrawingShortcuts()
+{
+ {
+ QWidget w;
+ QToolButton *tb = new QToolButton(&w);
+ tb->setText("&abc");
+ DrawTextStyle *dts = new DrawTextStyle;
+ w.show();
+ tb->setStyle(dts);
+ QPixmap::grabWidget(tb);
+ QStyleOptionToolButton sotb;
+ sotb.initFrom(tb);
+ bool showMnemonic = dts->styleHint(QStyle::SH_UnderlineShortcut, &sotb, tb);
+ QVERIFY(dts->alignment & (showMnemonic ? Qt::TextShowMnemonic : Qt::TextHideMnemonic));
+ delete dts;
+ }
+ {
+ QToolBar w;
+ QToolButton *tb = new QToolButton(&w);
+ tb->setText("&abc");
+ DrawTextStyle *dts = new DrawTextStyle;
+ w.addWidget(tb);
+ w.show();
+ tb->setStyle(dts);
+ QPixmap::grabWidget(tb);
+ QStyleOptionToolButton sotb;
+ sotb.initFrom(tb);
+ bool showMnemonic = dts->styleHint(QStyle::SH_UnderlineShortcut, &sotb, tb);
+ QVERIFY(dts->alignment & (showMnemonic ? Qt::TextShowMnemonic : Qt::TextHideMnemonic));
+ delete dts;
+ }
+}
+
+QTEST_MAIN(tst_QStyle)
+#include "tst_qstyle.moc"
diff --git a/tests/auto/widgets/styles/qstyleoption/.gitignore b/tests/auto/widgets/styles/qstyleoption/.gitignore
new file mode 100644
index 0000000000..70bf7781ce
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyleoption/.gitignore
@@ -0,0 +1 @@
+tst_qstyleoption
diff --git a/tests/auto/widgets/styles/qstyleoption/qstyleoption.pro b/tests/auto/widgets/styles/qstyleoption/qstyleoption.pro
new file mode 100644
index 0000000000..ccbb39d55b
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyleoption/qstyleoption.pro
@@ -0,0 +1,11 @@
+######################################################################
+# Automatically generated by qmake (2.00a) ti 8. mar 16:20:21 2005
+######################################################################
+
+load(qttest_p4)
+TEMPLATE = app
+QT += widgets
+# Input
+SOURCES += tst_qstyleoption.cpp
+
+
diff --git a/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp b/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp
new file mode 100644
index 0000000000..c1d4bd8166
--- /dev/null
+++ b/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** 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 test suite 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 <QtTest/QtTest>
+#include <QStyleOption>
+
+
+class tst_QStyleOption: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void qstyleoptioncast_data();
+ void qstyleoptioncast();
+ void copyconstructors();
+};
+
+// Just a simple container for QStyleOption-pointer
+struct StyleOptionPointerBase
+{
+ QStyleOption *pointer;
+
+ StyleOptionPointerBase(QStyleOption *p = 0) : pointer(p) { }
+
+ virtual ~StyleOptionPointerBase() { pointer = 0; }
+};
+
+template <typename T>
+struct StyleOptionPointer: public StyleOptionPointerBase
+{
+ StyleOptionPointer(T *p = 0): StyleOptionPointerBase(p) {}
+ ~StyleOptionPointer() { delete static_cast<T *>(pointer); pointer = 0; }
+};
+
+Q_DECLARE_METATYPE(StyleOptionPointerBase*)
+
+template <typename T>
+inline StyleOptionPointerBase *stylePtr(T *ptr) { return new StyleOptionPointer<T>(ptr); }
+
+void tst_QStyleOption::qstyleoptioncast_data()
+{
+ QTest::addColumn<StyleOptionPointerBase *>("testOption");
+ QTest::addColumn<bool>("canCastToComplex");
+ QTest::addColumn<int>("type");
+
+ QTest::newRow("optionDefault") << stylePtr(new QStyleOption) << false << int(QStyleOption::SO_Default);
+ QTest::newRow("optionButton") << stylePtr(new QStyleOptionButton) << false << int(QStyleOption::SO_Button);
+ QTest::newRow("optionComboBox") << stylePtr(new QStyleOptionComboBox) << true << int(QStyleOption::SO_ComboBox);
+ QTest::newRow("optionComplex") << stylePtr(new QStyleOptionComplex) << true << int(QStyleOption::SO_Complex);
+ QTest::newRow("optionDockWidget") << stylePtr(new QStyleOptionDockWidget) << false << int(QStyleOption::SO_DockWidget);
+ QTest::newRow("optionFocusRect") << stylePtr(new QStyleOptionFocusRect) << false << int(QStyleOption::SO_FocusRect);
+ QTest::newRow("optionFrame") << stylePtr(new QStyleOptionFrame) << false << int(QStyleOption::SO_Frame);
+ QTest::newRow("optionHeader") << stylePtr(new QStyleOptionHeader) << false << int(QStyleOption::SO_Header);
+ QTest::newRow("optionMenuItem") << stylePtr(new QStyleOptionMenuItem) << false << int(QStyleOption::SO_MenuItem);
+ QTest::newRow("optionProgressBar") << stylePtr(new QStyleOptionProgressBar) << false << int(QStyleOption::SO_ProgressBar);
+ QTest::newRow("optionSlider") << stylePtr(new QStyleOptionSlider) << true << int(QStyleOption::SO_Slider);
+ QTest::newRow("optionSpinBox") << stylePtr(new QStyleOptionSpinBox) << true << int(QStyleOption::SO_SpinBox);
+ QTest::newRow("optionTab") << stylePtr(new QStyleOptionTab) << false << int(QStyleOption::SO_Tab);
+ QTest::newRow("optionTitleBar") << stylePtr(new QStyleOptionTitleBar) << true << int(QStyleOption::SO_TitleBar);
+ QTest::newRow("optionToolBox") << stylePtr(new QStyleOptionToolBox) << false << int(QStyleOption::SO_ToolBox);
+ QTest::newRow("optionToolButton") << stylePtr(new QStyleOptionToolButton) << true << int(QStyleOption::SO_ToolButton);
+ QTest::newRow("optionViewItem") << stylePtr(new QStyleOptionViewItem) << false << int(QStyleOption::SO_ViewItem);
+ QTest::newRow("optionGraphicsItem") << stylePtr(new QStyleOptionGraphicsItem) << false << int(QStyleOption::SO_GraphicsItem);
+}
+
+void tst_QStyleOption::qstyleoptioncast()
+{
+ QFETCH(StyleOptionPointerBase *, testOption);
+ QFETCH(bool, canCastToComplex);
+ QFETCH(int, type);
+
+ QVERIFY(testOption->pointer != 0);
+
+ QCOMPARE(testOption->pointer->type, type);
+
+ // Cast to common base class
+ QStyleOption *castOption = qstyleoption_cast<QStyleOption*>(testOption->pointer);
+ QVERIFY(castOption != 0);
+
+ // Cast to complex base class
+ castOption = qstyleoption_cast<QStyleOptionComplex*>(testOption->pointer);
+ QCOMPARE(canCastToComplex, (castOption != 0));
+
+ // Cast to combo box
+ castOption = qstyleoption_cast<QStyleOptionComboBox*>(testOption->pointer);
+ QCOMPARE((castOption != 0),(testOption->pointer->type == QStyleOption::SO_ComboBox));
+
+ // Cast to button
+ castOption = qstyleoption_cast<QStyleOptionButton*>(testOption->pointer);
+ QCOMPARE((castOption != 0),(testOption->pointer->type == QStyleOption::SO_Button));
+
+ // Cast to lower version
+ testOption->pointer->version += 1;
+ castOption = qstyleoption_cast<QStyleOption*>(testOption->pointer);
+ QVERIFY(castOption);
+
+ // Cast a null pointer
+ castOption = qstyleoption_cast<QStyleOption*>((QStyleOption*)0);
+ QCOMPARE(castOption,(QStyleOption*)0);
+
+ // Deallocate
+ delete testOption;
+}
+
+void tst_QStyleOption::copyconstructors()
+{
+ QStyleOptionFrame frame;
+ QStyleOptionFrameV2 frame2(frame);
+ QCOMPARE(frame2.version, int(QStyleOptionFrameV2::Version));
+ frame2 = frame;
+ QCOMPARE(frame2.version, int(QStyleOptionFrameV2::Version));
+
+ QStyleOptionProgressBar bar;
+ QStyleOptionProgressBarV2 bar2(bar);
+ QCOMPARE(bar2.version, int(QStyleOptionProgressBarV2::Version));
+ bar2 = bar;
+ QCOMPARE(bar2.version, int(QStyleOptionProgressBarV2::Version));
+}
+
+QTEST_MAIN(tst_QStyleOption)
+#include "tst_qstyleoption.moc"
+
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/.gitignore b/tests/auto/widgets/styles/qstylesheetstyle/.gitignore
new file mode 100644
index 0000000000..df0251385e
--- /dev/null
+++ b/tests/auto/widgets/styles/qstylesheetstyle/.gitignore
@@ -0,0 +1 @@
+tst_qstylesheetstyle
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/images/testimage.png b/tests/auto/widgets/styles/qstylesheetstyle/images/testimage.png
new file mode 100644
index 0000000000..06fb34f0d6
--- /dev/null
+++ b/tests/auto/widgets/styles/qstylesheetstyle/images/testimage.png
Binary files differ
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro b/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro
new file mode 100644
index 0000000000..9dc296a51c
--- /dev/null
+++ b/tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+QT += widgets widgets-private
+QT += gui-private
+# Input
+SOURCES += tst_qstylesheetstyle.cpp
+RESOURCES += resources.qrc
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/resources.qrc b/tests/auto/widgets/styles/qstylesheetstyle/resources.qrc
new file mode 100644
index 0000000000..248bf80f50
--- /dev/null
+++ b/tests/auto/widgets/styles/qstylesheetstyle/resources.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>images/testimage.png</file>
+ </qresource>
+</RCC> \ No newline at end of file
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
new file mode 100644
index 0000000000..c5591c48ab
--- /dev/null
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -0,0 +1,1644 @@
+/****************************************************************************
+**
+** 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 test suite 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>
+#include <QtGui>
+#include <QtWidgets>
+#include <QtTest/QtTest>
+#include <QtDebug>
+#include <QMetaObject>
+
+#include <private/qstylesheetstyle_p.h>
+#include "../../../platformquirks.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QStyleSheetStyle : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QStyleSheetStyle();
+ ~tst_QStyleSheetStyle();
+
+private slots:
+ void repolish();
+ void numinstances();
+ void widgetsBeforeAppStyleSheet();
+ void widgetsAfterAppStyleSheet();
+ void applicationStyleSheet();
+ void windowStyleSheet();
+ void widgetStyleSheet();
+ void reparentWithNoChildStyleSheet();
+ void reparentWithChildStyleSheet();
+ void dynamicProperty();
+ // NB! Invoking this slot after layoutSpacing crashes on Mac.
+ void namespaces();
+#ifdef Q_OS_MAC
+ void layoutSpacing();
+#endif
+ void qproperty();
+ void palettePropagation();
+ void fontPropagation();
+ void onWidgetDestroyed();
+ void fontPrecedence();
+#if defined(Q_OS_WIN32) || defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL))
+ void focusColors();
+#endif
+ void hoverColors();
+ void background();
+ void tabAlignement();
+ void attributesList();
+ void minmaxSizes();
+ void task206238_twice();
+ void transparent();
+ void proxyStyle();
+ void dialogButtonBox();
+ void emptyStyleSheet();
+ void toolTip();
+ void embeddedFonts();
+ void opaquePaintEvent_data();
+ void opaquePaintEvent();
+ void complexWidgetFocus();
+ void task188195_baseBackground();
+ void task232085_spinBoxLineEditBg();
+ void changeStyleInChangeEvent();
+ void QTBUG15910_crashNullWidget();
+
+ //at the end because it mess with the style.
+ void widgetStyle();
+ void appStyle();
+ void QTBUG11658_cachecrash();
+private:
+ QColor COLOR(const QWidget& w) {
+ w.ensurePolished();
+ return w.palette().color(w.foregroundRole());
+ }
+ QColor APPCOLOR(const QWidget& w) {
+ w.ensurePolished();
+ return qApp->palette(&w).color(w.foregroundRole());
+ }
+ QColor BACKGROUND(const QWidget& w) {
+ w.ensurePolished();
+ return w.palette().color(w.backgroundRole());
+ }
+ QColor APPBACKGROUND(const QWidget& w) {
+ w.ensurePolished();
+ return qApp->palette(&w).color(w.backgroundRole());
+ }
+ int FONTSIZE(const QWidget &w) {
+ w.ensurePolished();
+ return w.font().pointSize();
+ }
+ int APPFONTSIZE(const QWidget &w) {
+ return qApp->font(&w).pointSize();
+ }
+};
+
+tst_QStyleSheetStyle::tst_QStyleSheetStyle()
+{
+}
+
+tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
+{
+}
+
+void tst_QStyleSheetStyle::numinstances()
+{
+ QWidget w;
+ QCommonStyle *style = new QCommonStyle;
+ style->setParent(&w);
+ QWidget c(&w);
+ w.show();
+
+ // set and unset application stylesheet
+ QCOMPARE(QStyleSheetStyle::numinstances, 0);
+ qApp->setStyleSheet("* { color: red; }");
+ QCOMPARE(QStyleSheetStyle::numinstances, 1);
+ qApp->setStyleSheet("");
+ QCOMPARE(QStyleSheetStyle::numinstances, 0);
+
+ // set and unset application stylesheet+widget
+ qApp->setStyleSheet("* { color: red; }");
+ w.setStyleSheet("color: red;");
+ QCOMPARE(QStyleSheetStyle::numinstances, 2);
+ w.setStyle(style);
+ QCOMPARE(QStyleSheetStyle::numinstances, 2);
+ qApp->setStyleSheet("");
+ QCOMPARE(QStyleSheetStyle::numinstances, 1);
+ w.setStyleSheet("");
+ QCOMPARE(QStyleSheetStyle::numinstances, 0);
+
+ // set and unset widget stylesheet
+ w.setStyle(0);
+ w.setStyleSheet("color: red");
+ QCOMPARE(QStyleSheetStyle::numinstances, 1);
+ c.setStyle(style);
+ QCOMPARE(QStyleSheetStyle::numinstances, 2);
+ w.setStyleSheet("");
+ QCOMPARE(QStyleSheetStyle::numinstances, 0);
+}
+
+void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet()
+{
+ QPushButton w1; // widget with no stylesheet
+ qApp->setStyleSheet("* { color: red; }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+ w1.setStyleSheet("color: white");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ qApp->setStyleSheet("");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ w1.setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+}
+
+class FriendlySpinBox : public QSpinBox { friend class tst_QStyleSheetStyle; };
+
+void tst_QStyleSheetStyle::widgetsAfterAppStyleSheet()
+{
+ qApp->setStyleSheet("* { color: red; font-size: 32pt; }");
+ QPushButton w1;
+ FriendlySpinBox spin;
+ QVERIFY(COLOR(w1) == QColor("red"));
+ QVERIFY(COLOR(spin) == QColor("red"));
+ QVERIFY(COLOR(*spin.lineEdit()) == QColor("red"));
+ QCOMPARE(FONTSIZE(w1), 32);
+ QCOMPARE(FONTSIZE(spin), 32);
+ QCOMPARE(FONTSIZE(*spin.lineEdit()), 32);
+ w1.setStyleSheet("color: white");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ QVERIFY(COLOR(spin) == QColor("red"));
+ QVERIFY(COLOR(*spin.lineEdit()) == QColor("red"));
+ w1.setStyleSheet("");
+ QVERIFY(COLOR(w1) == QColor("red"));
+ QVERIFY(COLOR(spin) == QColor("red"));
+ QVERIFY(COLOR(*spin.lineEdit()) == QColor("red"));
+ w1.setStyleSheet("color: white");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ qApp->setStyleSheet("");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ QVERIFY(COLOR(spin) == APPCOLOR(spin));
+ QVERIFY(COLOR(*spin.lineEdit()) == APPCOLOR(*spin.lineEdit()));
+ w1.setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+ // QCOMPARE(FONTSIZE(w1), APPFONTSIZE(w1)); //### task 244261
+ QCOMPARE(FONTSIZE(spin), APPFONTSIZE(spin));
+ //QCOMPARE(FONTSIZE(*spin.lineEdit()), APPFONTSIZE(*spin.lineEdit())); //### task 244261
+}
+
+void tst_QStyleSheetStyle::applicationStyleSheet()
+{
+ QPushButton w1;
+ qApp->setStyleSheet("* { color: red; }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+ qApp->setStyleSheet("* { color: white; }");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ qApp->setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+ qApp->setStyleSheet("* { color: red }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+}
+
+void tst_QStyleSheetStyle::windowStyleSheet()
+{
+ QPushButton w1;
+ qApp->setStyleSheet("");
+ w1.setStyleSheet("* { color: red; }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+ w1.setStyleSheet("* { color: white; }");
+ QVERIFY(COLOR(w1) == QColor("white"));
+ w1.setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+ w1.setStyleSheet("* { color: red }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+
+ qApp->setStyleSheet("* { color: green }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+ w1.setStyleSheet("");
+ QVERIFY(COLOR(w1) == QColor("green"));
+ qApp->setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+}
+
+void tst_QStyleSheetStyle::widgetStyleSheet()
+{
+ QPushButton w1;
+ QPushButton *pb = new QPushButton(&w1);
+ QPushButton &w2 = *pb;
+
+ qApp->setStyleSheet("");
+ w1.setStyleSheet("* { color: red }");
+ QVERIFY(COLOR(w1) == QColor("red"));
+ QVERIFY(COLOR(w2) == QColor("red"));
+
+ w2.setStyleSheet("* { color: white }");
+ QVERIFY(COLOR(w2) == QColor("white"));
+
+ w1.setStyleSheet("* { color: blue }");
+ QVERIFY(COLOR(w1) == QColor("blue"));
+ QVERIFY(COLOR(w2) == QColor("white"));
+
+ w1.setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+ QVERIFY(COLOR(w2) == QColor("white"));
+
+ w2.setStyleSheet("");
+ QVERIFY(COLOR(w1) == APPCOLOR(w1));
+ QVERIFY(COLOR(w2) == APPCOLOR(w2));
+}
+
+void tst_QStyleSheetStyle::reparentWithNoChildStyleSheet()
+{
+ QPushButton p1, p2;
+ QPushButton *pb = new QPushButton(&p1);
+ QPushButton &c1 = *pb; // child with no stylesheet
+
+ qApp->setStyleSheet("");
+ p1.setStyleSheet("* { color: red }");
+ QVERIFY(COLOR(c1) == QColor("red"));
+ c1.setParent(&p2);
+ QVERIFY(COLOR(c1) == APPCOLOR(c1));
+
+ p2.setStyleSheet("* { color: white }");
+ QVERIFY(COLOR(c1) == QColor("white"));
+
+ c1.setParent(&p1);
+ QVERIFY(COLOR(c1) == QColor("red"));
+
+ qApp->setStyleSheet("* { color: blue }");
+ c1.setParent(0);
+ QVERIFY(COLOR(c1) == QColor("blue"));
+ delete pb;
+}
+
+void tst_QStyleSheetStyle::reparentWithChildStyleSheet()
+{
+ qApp->setStyleSheet("");
+ QPushButton p1, p2;
+ QPushButton *pb = new QPushButton(&p1);
+ QPushButton &c1 = *pb;
+
+ c1.setStyleSheet("background: gray");
+ QVERIFY(BACKGROUND(c1) == QColor("gray"));
+ c1.setParent(&p2);
+ QVERIFY(BACKGROUND(c1) == QColor("gray"));
+
+ qApp->setStyleSheet("* { color: white }");
+ c1.setParent(&p1);
+ QVERIFY(BACKGROUND(c1) == QColor("gray"));
+ QVERIFY(COLOR(c1) == QColor("white"));
+}
+
+void tst_QStyleSheetStyle::repolish()
+{
+ qApp->setStyleSheet("");
+ QPushButton p1;
+ p1.setStyleSheet("color: red; background: white");
+ QVERIFY(BACKGROUND(p1) == QColor("white"));
+ p1.setStyleSheet("background: white");
+ QVERIFY(COLOR(p1) == APPCOLOR(p1));
+ p1.setStyleSheet("color: red");
+ QVERIFY(COLOR(p1) == QColor("red"));
+ QVERIFY(BACKGROUND(p1) == APPBACKGROUND(p1));
+ p1.setStyleSheet("");
+ QVERIFY(COLOR(p1) == APPCOLOR(p1));
+ QVERIFY(BACKGROUND(p1) == APPBACKGROUND(p1));
+}
+
+void tst_QStyleSheetStyle::widgetStyle()
+{
+ qApp->setStyleSheet("");
+
+ QWidget *window1 = new QWidget;
+ window1->setObjectName("window1");
+ QWidget *widget1 = new QWidget(window1);
+ widget1->setObjectName("widget1");
+ QWidget *widget2 = new QWidget;
+ widget2->setObjectName("widget2");
+ QWidget *window2 = new QWidget;
+ window2->setObjectName("window2");
+ window1->ensurePolished();
+ window2->ensurePolished();
+ widget1->ensurePolished();
+ widget2->ensurePolished();
+
+ QWindowsStyle style1, style2;
+ QPointer<QStyle> pstyle1 = &style1;
+ QPointer<QStyle> pstyle2 = &style2;
+
+ QStyle *appStyle = qApp->style();
+
+ // Sanity: By default, a window inherits the application style
+ QCOMPARE(appStyle, window1->style());
+
+ // Setting a custom style on a widget
+ window1->setStyle(&style1);
+ QCOMPARE(static_cast<QStyle *>(&style1), window1->style());
+
+ // Setting another style must not delete the older style
+ window1->setStyle(&style2);
+ QCOMPARE(static_cast<QStyle *>(&style2), window1->style());
+ QVERIFY(!pstyle1.isNull()); // case we have not already crashed
+
+ // Setting null style must make it follow the qApp style
+ window1->setStyle(0);
+ QCOMPARE(window1->style(), appStyle);
+ QVERIFY(!pstyle2.isNull()); // case we have not already crashed
+ QVERIFY(!pstyle2.isNull()); // case we have not already crashed
+
+ // Sanity: Set the stylesheet
+ window1->setStyleSheet(":x { }");
+
+ QPointer<QStyleSheetStyle> proxy = (QStyleSheetStyle *)window1->style();
+ QVERIFY(!proxy.isNull());
+ QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle"); // must be our proxy
+ QVERIFY(proxy->base == 0); // and follows the application
+
+ // Set the stylesheet
+ window1->setStyle(&style1);
+ QVERIFY(proxy.isNull()); // we create a new one each time
+ proxy = (QStyleSheetStyle *)window1->style();
+ QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle"); // it is a proxy
+ QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(&style1)); // must have been replaced with the new one
+
+ // Update the stylesheet and check nothing changes
+ window1->setStyleSheet(":y { }");
+ QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // it is a proxy
+ QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(&style1)); // the same guy
+
+ // Remove the stylesheet
+ proxy = (QStyleSheetStyle *)window1->style();
+ window1->setStyleSheet("");
+ QVERIFY(proxy.isNull()); // should have disappeared
+ QCOMPARE(window1->style(), static_cast<QStyle *>(&style1)); // its restored
+
+ // Style Sheet existing children propagation
+ window1->setStyleSheet(":z { }");
+ proxy = (QStyleSheetStyle *)window1->style();
+ QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle");
+ QCOMPARE(window1->style(), widget1->style()); // proxy must have propagated
+ QCOMPARE(widget2->style(), appStyle); // widget2 is following the app style
+
+ // Style Sheet automatic propagation to new children
+ widget2->setParent(window1); // reparent in!
+ QCOMPARE(window1->style(), widget2->style()); // proxy must have propagated
+
+ // Style Sheet automatic removal from children who abandoned their parents
+ window2->setStyle(&style2);
+ widget2->setParent(window2); // reparent
+ QCOMPARE(widget2->style(), appStyle); // widget2 is following the app style
+
+ // Style Sheet propagation on a child widget with a custom style
+ widget2->setStyle(&style1);
+ window2->setStyleSheet(":x { }");
+ proxy = (QStyleSheetStyle *)widget2->style();
+ QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle");
+ QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(&style1));
+
+ // Style Sheet propagation on a child widget with a custom style already set
+ window2->setStyleSheet("");
+ QCOMPARE(window2->style(), static_cast<QStyle *>(&style2));
+ QCOMPARE(widget2->style(), static_cast<QStyle *>(&style1));
+ widget2->setStyle(0);
+ window2->setStyleSheet(":x { }");
+ widget2->setStyle(&style1);
+ proxy = (QStyleSheetStyle *)widget2->style();
+ QCOMPARE(proxy->metaObject()->className(), "QStyleSheetStyle");
+
+ // QApplication, QWidget both having a style sheet
+
+ // clean everything out
+ window1->setStyle(0);
+ window1->setStyleSheet("");
+ window2->setStyle(0);
+ window2->setStyleSheet("");
+ qApp->setStyle(0);
+
+ qApp->setStyleSheet("may_insanity_prevail { }"); // app has stylesheet
+ QCOMPARE(window1->style(), qApp->style());
+ QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle");
+ QCOMPARE(widget1->style()->metaObject()->className(), "QStyleSheetStyle"); // check the child
+ window1->setStyleSheet("may_more_insanity_prevail { }"); // window has stylesheet
+ QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // a new one
+ QCOMPARE(widget1->style(), window1->style()); // child follows...
+ proxy = (QStyleSheetStyle *) window1->style();
+ QWindowsStyle *newStyle = new QWindowsStyle;
+ qApp->setStyle(newStyle); // set a custom style on app
+ proxy = (QStyleSheetStyle *) window1->style();
+ QCOMPARE(proxy->baseStyle(), static_cast<QStyle *>(newStyle)); // magic ;) the widget still follows the application
+ QCOMPARE(static_cast<QStyle *>(proxy), widget1->style()); // child still follows...
+
+ window1->setStyleSheet(""); // remove stylesheet
+ QCOMPARE(window1->style(), qApp->style()); // is this cool or what
+ QCOMPARE(widget1->style(), qApp->style()); // annoying child follows...
+ QWindowsStyle wndStyle;
+ window1->setStyle(&wndStyle);
+ QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // auto wraps it
+ QCOMPARE(widget1->style(), window1->style()); // and auto propagates to child
+ qApp->setStyleSheet(""); // remove the app stylesheet
+ QCOMPARE(window1->style(), static_cast<QStyle *>(&wndStyle)); // auto dewrap
+ QCOMPARE(widget1->style(), qApp->style()); // and child state is restored
+ window1->setStyle(0); // let sanity prevail
+ qApp->setStyle(0);
+
+ delete window1;
+ delete widget2;
+ delete window2;
+}
+
+void tst_QStyleSheetStyle::appStyle()
+{
+ qApp->setStyleSheet("");
+ // qApp style can never be 0
+ QVERIFY(QApplication::style() != 0);
+ QPointer<QStyle> style1 = new QWindowsStyle;
+ QPointer<QStyle> style2 = new QWindowsStyle;
+ qApp->setStyle(style1);
+ // Basic sanity
+ QVERIFY(qApp->style() == style1);
+ qApp->setStyle(style2);
+ QVERIFY(style1.isNull()); // qApp must have taken ownership and deleted it
+ // Setting null should not crash
+ qApp->setStyle(0);
+ QVERIFY(qApp->style() == style2);
+
+ // Set the stylesheet
+ qApp->setStyleSheet("whatever");
+ QPointer<QStyleSheetStyle> sss = (QStyleSheetStyle *)qApp->style();
+ QVERIFY(!sss.isNull());
+ QCOMPARE(sss->metaObject()->className(), "QStyleSheetStyle"); // must be our proxy now
+ QVERIFY(!style2.isNull()); // this should exist as it is the base of the proxy
+ QVERIFY(sss->baseStyle() == style2);
+ style1 = new QWindowsStyle;
+ qApp->setStyle(style1);
+ QVERIFY(style2.isNull()); // should disappear automatically
+ QVERIFY(sss.isNull()); // should disappear automatically
+
+ // Update the stylesheet and check nothing changes
+ sss = (QStyleSheetStyle *)qApp->style();
+ qApp->setStyleSheet("whatever2");
+ QVERIFY(qApp->style() == sss);
+ QVERIFY(sss->baseStyle() == style1);
+
+ // Revert the stylesheet
+ qApp->setStyleSheet("");
+ QVERIFY(sss.isNull()); // should have disappeared
+ QVERIFY(qApp->style() == style1);
+
+ qApp->setStyleSheet("");
+ QVERIFY(qApp->style() == style1);
+}
+
+void tst_QStyleSheetStyle::dynamicProperty()
+{
+ qApp->setStyleSheet(QString());
+
+ QString appStyle = qApp->style()->metaObject()->className();
+ QPushButton pb1, pb2;
+ pb1.setProperty("type", "critical");
+ qApp->setStyleSheet("*[class~=\"QPushButton\"] { color: red; } *[type=\"critical\"] { background: white; }");
+ QVERIFY(COLOR(pb1) == Qt::red);
+ QVERIFY(BACKGROUND(pb1) == Qt::white);
+
+ pb2.setProperty("class", "critical"); // dynamic class
+ pb2.setStyleSheet(QLatin1String(".critical[style~=\"") + appStyle + "\"] { color: blue }");
+ pb2.show();
+
+ QVERIFY(COLOR(pb2) == Qt::blue);
+}
+
+#ifdef Q_OS_MAC
+void tst_QStyleSheetStyle::layoutSpacing()
+{
+ qApp->setStyleSheet("* { color: red }");
+ QCheckBox ck1;
+ QCheckBox ck2;
+ QWidget window;
+ int spacing_widgetstyle = window.style()->layoutSpacing(ck1.sizePolicy().controlType(), ck2.sizePolicy().controlType(), Qt::Vertical);
+ int spacing_style = window.style()->layoutSpacing(ck1.sizePolicy().controlType(), ck2.sizePolicy().controlType(), Qt::Vertical);
+ QCOMPARE(spacing_widgetstyle, spacing_style);
+}
+#endif
+
+void tst_QStyleSheetStyle::qproperty()
+{
+ QPushButton pb;
+ pb.setStyleSheet("QPushButton { qproperty-text: hello; qproperty-checkable: true; qproperty-checked: 1}");
+ pb.ensurePolished();
+ QCOMPARE(pb.text(), QString("hello"));
+ QCOMPARE(pb.isCheckable(), true);
+ QCOMPARE(pb.isChecked(), true);
+}
+
+namespace ns {
+ class PushButton1 : public QPushButton {
+ Q_OBJECT
+ public:
+ PushButton1() { }
+ };
+ class PushButton2 : public PushButton1 {
+ Q_OBJECT
+ public:
+ PushButton2() { setProperty("class", "PushButtonTwo PushButtonDuo"); }
+ };
+}
+
+void tst_QStyleSheetStyle::namespaces()
+{
+ ns::PushButton1 pb1;
+ qApp->setStyleSheet("ns--PushButton1 { background: white }");
+ QVERIFY(BACKGROUND(pb1) == QColor("white"));
+ qApp->setStyleSheet(".ns--PushButton1 { background: red }");
+ QVERIFY(BACKGROUND(pb1) == QColor("red"));
+
+ ns::PushButton2 pb2;
+ qApp->setStyleSheet("ns--PushButton1 { background: blue}");
+ QVERIFY(BACKGROUND(pb2) == QColor("blue"));
+ qApp->setStyleSheet("ns--PushButton2 { background: magenta }");
+ QVERIFY(BACKGROUND(pb2) == QColor("magenta"));
+ qApp->setStyleSheet(".PushButtonTwo { background: white; }");
+ QVERIFY(BACKGROUND(pb2) == QColor("white"));
+ qApp->setStyleSheet(".PushButtonDuo { background: red; }");
+ QVERIFY(BACKGROUND(pb2) == QColor("red"));
+}
+
+void tst_QStyleSheetStyle::palettePropagation()
+{
+ qApp->setStyleSheet("");
+ QGroupBox gb;
+ QPushButton *push = new QPushButton(&gb);
+ QPushButton &pb = *push;
+ push->setText("AsdF");
+
+ gb.setStyleSheet("QGroupBox { color: red }");
+ QVERIFY(COLOR(gb) == Qt::red);
+ QVERIFY(COLOR(pb) == APPCOLOR(pb)); // palette shouldn't propagate
+ gb.setStyleSheet("QGroupBox * { color: red }");
+
+ QVERIFY(COLOR(pb) == Qt::red);
+ QVERIFY(COLOR(gb) == APPCOLOR(gb));
+
+ QWidget window;
+ window.setStyleSheet("* { color: white; }");
+ pb.setParent(&window);
+ QVERIFY(COLOR(pb) == Qt::white);
+}
+
+void tst_QStyleSheetStyle::fontPropagation()
+{
+ qApp->setStyleSheet("");
+ QComboBox cb;
+ cb.addItem("item1");
+ cb.addItem("item2");
+
+ QAbstractItemView *popup = cb.view();
+ int viewFontSize = FONTSIZE(*popup);
+
+ cb.setStyleSheet("QComboBox { font-size: 20pt; }");
+ QVERIFY(FONTSIZE(cb) == 20);
+ QVERIFY(FONTSIZE(*popup) == viewFontSize);
+ QGroupBox gb;
+ QPushButton *push = new QPushButton(&gb);
+ QPushButton &pb = *push;
+ int buttonFontSize = FONTSIZE(pb);
+ int gbFontSize = FONTSIZE(gb);
+
+ gb.setStyleSheet("QGroupBox { font-size: 20pt }");
+ QVERIFY(FONTSIZE(gb) == 20);
+ QVERIFY(FONTSIZE(pb) == buttonFontSize); // font does not propagate
+ gb.setStyleSheet("QGroupBox * { font-size: 20pt; }");
+ QVERIFY(FONTSIZE(gb) == gbFontSize);
+ QVERIFY(FONTSIZE(pb) == 20);
+
+ QWidget window;
+ window.setStyleSheet("* { font-size: 10pt }");
+ pb.setParent(&window);
+ QCOMPARE(FONTSIZE(pb), 10);
+ window.setStyleSheet("");
+ QVERIFY(FONTSIZE(pb) == buttonFontSize);
+
+ QTabWidget tw;
+ tw.setStyleSheet("QTabWidget { font-size: 20pt; }");
+ QVERIFY(FONTSIZE(tw) == 20);
+ QWidget *child = qFindChild<QWidget *>(&tw, "qt_tabwidget_tabbar");
+ QVERIFY2(child, "QTabWidget did not contain a widget named \"qt_tabwidget_tabbar\"");
+ QVERIFY(FONTSIZE(*child) == 20);
+}
+
+void tst_QStyleSheetStyle::onWidgetDestroyed()
+{
+ qApp->setStyleSheet("");
+ QLabel *l = new QLabel;
+ l->setStyleSheet("QLabel { color: red }");
+ QPointer<QStyleSheetStyle> ss = (QStyleSheetStyle *) l->style();
+ delete l;
+ QVERIFY(ss.isNull());
+}
+
+void tst_QStyleSheetStyle::fontPrecedence()
+{
+ QLineEdit edit;
+ edit.show();
+ QFont font;
+ QVERIFY(FONTSIZE(edit) != 22); // Sanity check to make sure this test makes sense.
+ edit.setStyleSheet("QLineEdit { font-size: 22pt; }");
+ QCOMPARE(FONTSIZE(edit), 22);
+ font.setPointSize(16);
+ edit.setFont(font);
+ QCOMPARE(FONTSIZE(edit), 22);
+ edit.setStyleSheet("");
+ QCOMPARE(FONTSIZE(edit), 16);
+ font.setPointSize(18);
+ edit.setFont(font);
+ QCOMPARE(FONTSIZE(edit), 18);
+ edit.setStyleSheet("QLineEdit { font-size: 20pt; }");
+ QCOMPARE(FONTSIZE(edit), 20);
+ edit.setStyleSheet("");
+ QCOMPARE(FONTSIZE(edit), 18);
+ edit.hide();
+
+ QLineEdit edit2;
+ edit2.setReadOnly(true);
+ edit2.setStyleSheet("QLineEdit { font-size: 24pt; } QLineEdit:read-only { font-size: 26pt; }");
+ QCOMPARE(FONTSIZE(edit2), 26);
+}
+
+// Ensure primary will only return true if the color covers more than 50% of pixels
+static bool testForColors(const QImage& image, const QColor& color, bool ensurePrimary=false)
+{
+ int count = 0;
+ QRgb rgb = color.rgba();
+ int totalCount = image.height()*image.width();
+ for (int y = 0; y < image.height(); ++y) {
+ for (int x = 0; x < image.width(); ++x) {
+ // Because of antialiasing we allow a certain range of errors here.
+ QRgb pixel = image.pixel(x, y);
+
+ if (qAbs((int)(pixel & 0xff) - (int)(rgb & 0xff)) +
+ qAbs((int)((pixel & 0xff00) >> 8) - (int)((rgb & 0xff00) >> 8)) +
+ qAbs((int)((pixel & 0xff0000) >> 16) - (int)((rgb & 0xff0000) >> 16)) <= 50) {
+ count++;
+ if (!ensurePrimary && count >=10 )
+ return true;
+ else if (count > totalCount/2)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+// This is a fragile test which fails on many esoteric platforms
+// because of focus problems. Test only on Windows, Mac, and Linux/gcc.
+#if defined(Q_OS_WIN32) || defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL))
+void tst_QStyleSheetStyle::focusColors()
+{
+ // Tests if colors can be changed by altering the focus of the widget.
+ // To avoid messy pixel-by-pixel comparison, we assume that the goal
+ // is reached if at least ten pixels of the right color can be found in
+ // the image.
+ // For this reason, we use unusual and extremely ugly colors! :-)
+ QList<QWidget *> widgets;
+ widgets << new QPushButton("TESTING");
+ widgets << new QLineEdit("TESTING");
+ widgets << new QLabel("TESTING");
+ QSpinBox *spinbox = new QSpinBox;
+ spinbox->setValue(8888);
+ widgets << spinbox;
+ QComboBox *combobox = new QComboBox;
+ combobox->setEditable(true);
+ combobox->addItems(QStringList() << "TESTING");
+ widgets << combobox;
+ widgets << new QLabel("TESTING");
+
+#ifdef Q_WS_QWS
+ // QWS has its own special focus logic which is slightly different
+ // and I don't dare change it at this point, because someone will
+ // be relying on it. It means that setFocus() on a NoFocus widget (i.e.
+ // a QLabel) will not work before the window is activated.
+ widgets[2]->setFocusPolicy(Qt::StrongFocus);
+#endif
+
+ foreach (QWidget *widget, widgets) {
+ QDialog frame;
+ QLayout* layout = new QGridLayout;
+
+ QLineEdit* dummy = new QLineEdit; // Avoids initial focus.
+
+ widget->setStyleSheet("*:focus { border:none; background: #e8ff66; color: #ff0084 }");
+
+ layout->addWidget(dummy);
+ layout->addWidget(widget);
+ frame.setLayout(layout);
+
+ frame.show();
+ QTest::qWaitForWindowShown(&frame);
+ QApplication::setActiveWindow(&frame);
+ widget->setFocus();
+ QApplication::processEvents();
+
+ QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
+ frame.render(&image);
+ if (image.depth() < 24) {
+ QSKIP("Test doesn't support color depth < 24", SkipAll);
+ }
+
+ QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain background color #e8ff66, using style "
+ + QString::fromLatin1(qApp->style()->metaObject()->className()))
+ .toLocal8Bit().constData());
+ QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain text color #ff0084, using style "
+ + QString::fromLatin1(qApp->style()->metaObject()->className()))
+ .toLocal8Bit().constData());
+ }
+}
+#endif
+
+void tst_QStyleSheetStyle::hoverColors()
+{
+ if (!PlatformQuirks::haveMouseCursor())
+ QSKIP("No mouse Cursor on this platform",SkipAll);
+ QList<QWidget *> widgets;
+ widgets << new QPushButton("TESTING");
+ widgets << new QLineEdit("TESTING");
+ widgets << new QLabel("TESTING");
+ QSpinBox *spinbox = new QSpinBox;
+ spinbox->setValue(8888);
+ widgets << spinbox;
+ QComboBox *combobox = new QComboBox;
+ combobox->setEditable(true);
+ combobox->addItems(QStringList() << "TESTING");
+ widgets << combobox;
+ widgets << new QLabel("<b>TESTING</b>");
+
+ foreach (QWidget *widget, widgets) {
+ //without Qt::X11BypassWindowManagerHint the window manager may move the window after we moved the cursor
+ QDialog frame(0, Qt::X11BypassWindowManagerHint);
+ QLayout* layout = new QGridLayout;
+
+ QLineEdit* dummy = new QLineEdit;
+
+ widget->setStyleSheet("*:hover { border:none; background: #e8ff66; color: #ff0084 }");
+
+ layout->addWidget(dummy);
+ layout->addWidget(widget);
+ frame.setLayout(layout);
+
+ frame.show();
+#ifdef Q_WS_QWS
+//QWS does not implement enter/leave when windows are shown underneath the cursor
+ QCursor::setPos(QPoint(0,0));
+#endif
+
+ QTest::qWaitForWindowShown(&frame);
+ QApplication::setActiveWindow(&frame);
+ QTest::qWait(60);
+ //move the mouse inside the widget, it should be colored
+ QTest::mouseMove ( widget, QPoint(6,6));
+ QTest::qWait(60);
+
+ QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
+
+ QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
+ frame.render(&image);
+
+ QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain background color #e8ff66").toLocal8Bit().constData());
+ QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain text color #ff0084").toLocal8Bit().constData());
+
+ //move the mouse outside the widget, it should NOT be colored
+ QTest::mouseMove ( dummy, QPoint(5,5));
+ QTest::qWait(60);
+
+ frame.render(&image);
+
+ QVERIFY2(!testForColors(image, QColor(0xe8, 0xff, 0x66)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did contain background color #e8ff66").toLocal8Bit().constData());
+ QVERIFY2(!testForColors(image, QColor(0xff, 0x00, 0x84)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did contain text color #ff0084").toLocal8Bit().constData());
+
+ //move the mouse again inside the widget, it should be colored
+ QTest::mouseMove (widget, QPoint(5,5));
+ QTest::qWait(60);
+
+ QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
+
+ frame.render(&image);
+
+ QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain background color #e8ff66").toLocal8Bit().constData());
+ QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain text color #ff0084").toLocal8Bit().constData());
+ }
+
+}
+
+class SingleInheritanceDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ SingleInheritanceDialog(QWidget *w = 0) :
+ QDialog(w)
+ {
+ }
+};
+
+class DoubleInheritanceDialog : public SingleInheritanceDialog
+{
+ Q_OBJECT
+public:
+ DoubleInheritanceDialog(QWidget *w = 0) :
+ SingleInheritanceDialog(w)
+ {
+ }
+};
+
+void tst_QStyleSheetStyle::background()
+{
+ const int number = 4;
+ QWidget* widgets[number];
+ // Testing inheritance styling of QDialog.
+ widgets[0] = new SingleInheritanceDialog;
+ widgets[0]->setStyleSheet("* { background-color: #e8ff66; }");
+ widgets[1] = new DoubleInheritanceDialog;
+ widgets[1]->setStyleSheet("* { background-color: #e8ff66; }");
+
+ // Testing gradients in QComboBox.
+ QLayout* layout;
+ QComboBox* cb;
+ // First color
+ widgets[2] = new QDialog;
+ layout = new QGridLayout;
+ cb = new QComboBox;
+ cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
+ layout->addWidget(cb);
+ widgets[2]->setLayout(layout);
+ // Second color
+ widgets[3] = new QDialog;
+ layout = new QGridLayout;
+ cb = new QComboBox;
+ cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
+ layout->addWidget(cb);
+ widgets[3]->setLayout(layout);
+
+ for (int c = 0; c < number; ++c) {
+ QWidget* widget = widgets[c];
+
+ widget->show();
+ QTest::qWaitForWindowShown(widget);
+
+ QImage image(widget->width(), widget->height(), QImage::Format_ARGB32);
+ widget->render(&image);
+ if (image.depth() < 24) {
+ QSKIP("Test doesn't support color depth < 24", SkipAll);
+ }
+
+ QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain background image with color #e8ff66")
+ .toLocal8Bit().constData());
+
+ delete widget;
+ }
+}
+
+void tst_QStyleSheetStyle::tabAlignement()
+{
+ QWidget topLevel;
+ QTabWidget tabWidget(&topLevel);
+ tabWidget.addTab(new QLabel("tab1"),"tab1");
+ tabWidget.resize(QSize(400,400));
+ topLevel.show();
+ QTest::qWaitForWindowShown(&tabWidget);
+ QTest::qWait(50);
+ QTabBar *bar = qFindChild<QTabBar*>(&tabWidget);
+ QVERIFY(bar);
+ //check the tab is on the right
+ tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: right ; }");
+ qApp->processEvents();
+ QVERIFY(bar->geometry().right() > 380);
+ QVERIFY(bar->geometry().left() > 200);
+ //check the tab is on the middle
+ tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: center ; }");
+ QVERIFY(bar->geometry().right() < 300);
+ QVERIFY(bar->geometry().left() > 100);
+ //check the tab is on the left
+ tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: left ; }");
+ QVERIFY(bar->geometry().left() < 20);
+ QVERIFY(bar->geometry().right() < 200);
+
+ tabWidget.setTabPosition(QTabWidget::West);
+ //check the tab is on the top
+ QVERIFY(bar->geometry().top() < 20);
+ QVERIFY(bar->geometry().bottom() < 200);
+ //check the tab is on the bottom
+ tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: right ; }");
+ QVERIFY(bar->geometry().bottom() > 380);
+ QVERIFY(bar->geometry().top() > 200);
+ //check the tab is on the middle
+ tabWidget.setStyleSheet("QTabWidget::tab-bar { alignment: center ; }");
+ QVERIFY(bar->geometry().bottom() < 300);
+ QVERIFY(bar->geometry().top() > 100);
+}
+
+void tst_QStyleSheetStyle::attributesList()
+{
+ QWidget w;
+ QPushButton *p1=new QPushButton(&w);
+ QPushButton *p2=new QPushButton(&w);
+ QPushButton *p3=new QPushButton(&w);
+ QPushButton *p4=new QPushButton(&w);
+ p1->setProperty("prop", QStringList() << "red");
+ p2->setProperty("prop", QStringList() << "foo" << "red");
+ p3->setProperty("prop", QStringList() << "foo" << "bar");
+
+ w.setStyleSheet(" QPushButton{ background-color:blue; } QPushButton[prop~=red] { background-color:red; }");
+ QCOMPARE(BACKGROUND(*p1) , QColor("red"));
+ QCOMPARE(BACKGROUND(*p2) , QColor("red"));
+ QCOMPARE(BACKGROUND(*p3) , QColor("blue"));
+ QCOMPARE(BACKGROUND(*p4) , QColor("blue"));
+}
+
+void tst_QStyleSheetStyle::minmaxSizes()
+{
+ QTabWidget tabWidget;
+ tabWidget.setObjectName("tabWidget");
+ int index1 = tabWidget.addTab(new QLabel("Tab1"),"a");
+
+ QWidget *page2=new QLabel("page2");
+ page2->setObjectName("page2");
+ page2->setStyleSheet("* {background-color: white; min-width: 250px; max-width:500px }");
+ tabWidget.addTab(page2,"Tab2");
+ QWidget *page3=new QLabel("plop");
+ page3->setObjectName("Page3");
+ page3->setStyleSheet("* {background-color: yellow; min-height: 250px; max-height:500px }");
+ int index3 = tabWidget.addTab(page3,"very_long_long_long_long_caption");
+
+ tabWidget.setStyleSheet("QTabBar::tab { min-width:100px; max-width:130px; }");
+
+ tabWidget.show();
+ QTest::qWait(50);
+ //i allow 4px additional border from the native style (hence the -2, <=2)
+ QVERIFY(qAbs(page2->maximumSize().width() - 500 - 2) <= 2);
+ QVERIFY(qAbs(page2->minimumSize().width() - 250 - 2) <= 2);
+ QVERIFY(qAbs(page3->maximumSize().height() - 500 - 2) <= 2);
+ QVERIFY(qAbs(page3->minimumSize().height() - 250 - 2) <= 2);
+ QVERIFY(qAbs(page3->minimumSize().height() - 250 - 2) <= 2);
+ QTabBar *bar = qFindChild<QTabBar*>(&tabWidget);
+ QVERIFY(bar);
+ QVERIFY(qAbs(bar->tabRect(index1).width() - 100 - 2) <= 2);
+ QVERIFY(qAbs(bar->tabRect(index3).width() - 130 - 2) <= 2);
+}
+
+void tst_QStyleSheetStyle::task206238_twice()
+{
+ QMainWindow w;
+ QTabWidget* tw = new QTabWidget;
+ tw->addTab(new QLabel("foo"), "test");
+ w.setCentralWidget(tw);
+ w.setStyleSheet("background: red;");
+ w.show();
+ QTest::qWait(20);
+ QCOMPARE(BACKGROUND(w) , QColor("red"));
+ QCOMPARE(BACKGROUND(*tw), QColor("red"));
+ w.setStyleSheet("background: red;");
+ QTest::qWait(20);
+ QCOMPARE(BACKGROUND(w) , QColor("red"));
+ QCOMPARE(BACKGROUND(*tw), QColor("red"));
+}
+
+void tst_QStyleSheetStyle::transparent()
+{
+ QWidget w;
+ QPushButton *p1=new QPushButton(&w);
+ QPushButton *p2=new QPushButton(&w);
+ QPushButton *p3=new QPushButton(&w);
+ p1->setStyleSheet("background:transparent");
+ p2->setStyleSheet("background-color:transparent");
+ p3->setStyleSheet("background:rgb(0,0,0,0)");
+ QCOMPARE(BACKGROUND(*p1) , QColor(0,0,0,0));
+ QCOMPARE(BACKGROUND(*p2) , QColor(0,0,0,0));
+ QCOMPARE(BACKGROUND(*p3) , QColor(0,0,0,0));
+}
+
+
+
+class ProxyStyle : public QStyle
+{
+ public:
+ ProxyStyle(QStyle *s)
+ {
+ style = s;
+ }
+
+ void drawControl(ControlElement ce, const QStyleOption *opt,
+ QPainter *painter, const QWidget *widget = 0) const;
+
+ void drawPrimitive(QStyle::PrimitiveElement pe,
+ const QStyleOption* opt,
+ QPainter* p ,
+ const QWidget* w) const
+ {
+ style->drawPrimitive(pe, opt, p, w);
+ }
+
+ QRect subElementRect(QStyle::SubElement se,
+ const QStyleOption* opt,
+ const QWidget* w) const
+ {
+ Q_UNUSED(se);
+ Q_UNUSED(opt);
+ Q_UNUSED(w);
+ return QRect(0, 0, 3, 3);
+ }
+
+ void drawComplexControl(QStyle::ComplexControl cc,
+ const QStyleOptionComplex* opt,
+ QPainter* p,
+ const QWidget* w) const
+ {
+ style->drawComplexControl(cc, opt, p, w);
+ }
+
+
+ SubControl hitTestComplexControl(QStyle::ComplexControl cc,
+ const QStyleOptionComplex* opt,
+ const QPoint& pt,
+ const QWidget* w) const
+ {
+ return style->hitTestComplexControl(cc, opt, pt, w);
+ }
+
+ QRect subControlRect(QStyle::ComplexControl cc,
+ const QStyleOptionComplex* opt,
+ QStyle::SubControl sc,
+ const QWidget* w) const
+ {
+ return style->subControlRect(cc, opt, sc, w);
+ }
+
+ int pixelMetric(QStyle::PixelMetric pm,
+ const QStyleOption* opt,
+ const QWidget* w) const
+ {
+ return style->pixelMetric(pm, opt, w);
+ }
+
+
+ QSize sizeFromContents(QStyle::ContentsType ct,
+ const QStyleOption* opt,
+ const QSize& size,
+ const QWidget* w) const
+ {
+ return style->sizeFromContents(ct, opt, size, w);
+ }
+
+ int styleHint(QStyle::StyleHint sh,
+ const QStyleOption* opt,
+ const QWidget* w,
+ QStyleHintReturn* shr) const
+ {
+ return style->styleHint(sh, opt, w, shr);
+ }
+
+ QPixmap standardPixmap(QStyle::StandardPixmap spix,
+ const QStyleOption* opt,
+ const QWidget* w) const
+ {
+ return style->standardPixmap(spix, opt, w);
+ }
+
+ QPixmap generatedIconPixmap(QIcon::Mode mode,
+ const QPixmap& pix,
+ const QStyleOption* opt) const
+ {
+ return style->generatedIconPixmap(mode, pix, opt);
+ }
+
+ private:
+ QStyle *style;
+};
+
+void ProxyStyle::drawControl(ControlElement ce, const QStyleOption *opt,
+ QPainter *painter, const QWidget *widget) const
+{
+ if(ce == CE_PushButton)
+ {
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt))
+ {
+ QRect r = btn->rect;
+ painter->fillRect(r, Qt::green);
+
+ if(btn->state & QStyle::State_HasFocus)
+ painter->fillRect(r.adjusted(5, 5, -5, -5), Qt::yellow);
+
+
+ painter->drawText(r, Qt::AlignCenter, btn->text);
+ }
+ }
+ else
+ {
+ style->drawControl(ce, opt, painter, widget);
+ }
+}
+
+void tst_QStyleSheetStyle::proxyStyle()
+{
+ //Should not crash; task 158984
+
+ ProxyStyle *proxy = new ProxyStyle(qApp->style());
+ QString styleSheet("QPushButton {background-color: red; }");
+
+ QWidget *w = new QWidget;
+ QVBoxLayout *layout = new QVBoxLayout(w);
+
+ QPushButton *pb1 = new QPushButton(qApp->style()->objectName(), w);
+ layout->addWidget(pb1);
+
+ QPushButton *pb2 = new QPushButton("ProxyStyle", w);
+ pb2->setStyle(proxy);
+ layout->addWidget(pb2);
+
+ QPushButton *pb3 = new QPushButton("StyleSheet", w);
+ pb3->setStyleSheet(styleSheet);
+ layout->addWidget(pb3);
+
+ QPushButton *pb4 = new QPushButton("StyleSheet then ProxyStyle ", w);
+ pb4->setStyleSheet(styleSheet);
+
+ // We are creating our Proxy based on current style...
+ // In this case it would be the QStyleSheetStyle that is deleted
+ // later on. We need to get access to the "real" QStyle to be able to
+ // draw correctly.
+ ProxyStyle* newProxy = new ProxyStyle(qApp->style());
+ pb4->setStyle(newProxy);
+
+ layout->addWidget(pb4);
+
+ QPushButton *pb5 = new QPushButton("ProxyStyle then StyleSheet ", w);
+ pb5->setStyle(proxy);
+ pb5->setStyleSheet(styleSheet);
+ layout->addWidget(pb5);
+
+ w->show();
+
+ QTest::qWait(100);
+
+ // Test for QTBUG-7198 - style sheet overrides custom element size
+ QStyleOptionViewItemV4 opt;
+ opt.initFrom(w);
+ opt.features |= QStyleOptionViewItemV2::HasCheckIndicator;
+ QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator,
+ &opt, pb5).width() == 3);
+ delete w;
+ delete proxy;
+ delete newProxy;
+}
+
+void tst_QStyleSheetStyle::dialogButtonBox()
+{
+ QDialogButtonBox box;
+ box.addButton(QDialogButtonBox::Ok);
+ box.addButton(QDialogButtonBox::Cancel);
+ box.setStyleSheet("/** */ ");
+ box.setStyleSheet(QString()); //should not crash
+}
+
+void tst_QStyleSheetStyle::emptyStyleSheet()
+{
+ //empty stylesheet should not change anything
+ qApp->setStyleSheet(QString());
+ QWidget w;
+ QHBoxLayout layout(&w);
+ w.setLayout(&layout);
+ layout.addWidget(new QPushButton("push", &w));
+ layout.addWidget(new QToolButton(&w));
+ QLabel label("toto", &w);
+ label.setFrameShape(QLabel::Panel);
+ label.setFrameShadow(QLabel::Sunken);
+ layout.addWidget(&label); //task 231137
+ layout.addWidget(new QTableWidget(200,200, &w));
+ layout.addWidget(new QProgressBar(&w));
+ layout.addWidget(new QLineEdit(&w));
+ layout.addWidget(new QSpinBox(&w));
+ layout.addWidget(new QComboBox(&w));
+ layout.addWidget(new QDateEdit(&w));
+ layout.addWidget(new QGroupBox("some text", &w));
+
+ w.show();
+ QTest::qWaitForWindowShown(&w);
+ //workaround the fact that the label sizehint is one pixel different the first time.
+ label.setIndent(0); //force to recompute the sizeHint:
+ w.setFocus();
+ QTest::qWait(100);
+
+ QImage img1(w.size(), QImage::Format_ARGB32);
+ w.render(&img1);
+
+ w.setStyleSheet("/* */");
+ QTest::qWait(100);
+
+ QImage img2(w.size(), QImage::Format_ARGB32);
+ w.render(&img2);
+
+ if(img1 != img2) {
+ img1.save("emptyStyleSheet_img1.png");
+ img2.save("emptyStyleSheet_img2.png");
+ }
+
+ QCOMPARE(img1,img2);
+}
+
+void tst_QStyleSheetStyle::toolTip()
+{
+ qApp->setStyleSheet(QString());
+ QWidget w;
+ QHBoxLayout layout(&w);
+ w.setLayout(&layout);
+
+ QWidget *wid1 = new QGroupBox(&w);
+ layout.addWidget(wid1);
+ wid1->setStyleSheet("QToolTip { background: #ae2; } #wid3 > QToolTip { background: #0b8; } ");
+ QVBoxLayout *layout1 = new QVBoxLayout(wid1);
+ wid1->setLayout(layout1);
+ wid1->setToolTip("this is wid1");
+ wid1->setObjectName("wid1");
+
+ QWidget *wid2 = new QPushButton("wid2", wid1);
+ layout1->addWidget(wid2);
+ wid2->setStyleSheet("QToolTip { background: #f81; } ");
+ wid2->setToolTip("this is wid2");
+ wid2->setObjectName("wid2");
+
+ QWidget *wid3 = new QPushButton("wid3", wid1);
+ layout1->addWidget(wid3);
+ wid3->setToolTip("this is wid3");
+ wid3->setObjectName("wid3");
+
+ QWidget *wid4 = new QPushButton("wid4", &w);
+ layout.addWidget(wid4);
+ wid4->setToolTip("this is wid4");
+ wid4->setObjectName("wid4");
+
+ w.show();
+ QTest::qWait(100);
+
+ QColor normalToolTip = qApp->palette().toolTipBase().color();
+ QList<QWidget *> widgets;
+ QList<QColor> colors;
+
+
+ //tooltip on the widget without stylesheet, then to othes widget, including one without stylesheet
+ //(the tooltip will be reused but his colour must change)
+ widgets << wid4 << wid1 << wid2 << wid3 << wid4;
+ colors << normalToolTip << "#ae2" << "#f81" << "#0b8" << normalToolTip;
+
+ for (int i = 0; i < widgets.count() ; i++)
+ {
+ QWidget *wid = widgets.at(i);
+ QColor col = colors.at(i);
+
+ QToolTip::showText( QPoint(0,0) , "This is " + wid->objectName(), wid);
+
+ QWidget *tooltip = 0;
+ foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ if (widget->inherits("QTipLabel") && widget->isVisible()) {
+ tooltip = widget;
+ break;
+ }
+ }
+ QVERIFY(tooltip);
+ QCOMPARE(tooltip->palette().color(tooltip->backgroundRole()), col);
+ }
+
+ QToolTip::showText( QPoint(0,0) , "This is " + wid3->objectName(), wid3);
+ QTest::qWait(100);
+ delete wid3; //should not crash;
+ QTest::qWait(10);
+ foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ widget->update(); //should not crash either
+ }
+}
+
+void tst_QStyleSheetStyle::embeddedFonts()
+{
+ //task 235622 and 210551
+ QSpinBox spin;
+ spin.show();
+ spin.setStyleSheet("QSpinBox { font-size: 32px; }");
+ QTest::qWait(20);
+ QLineEdit *embedded = spin.findChild<QLineEdit *>();
+ QVERIFY(embedded);
+ QCOMPARE(spin.font().pixelSize(), 32);
+ QCOMPARE(embedded->font().pixelSize(), 32);
+
+ QMenu *menu = embedded->createStandardContextMenu();
+ menu->show();
+ QTest::qWait(20);
+ QVERIFY(menu);
+ QVERIFY(menu->font().pixelSize() != 32);
+ QCOMPARE(menu->font().pixelSize(), qApp->font(menu).pixelSize());
+
+ //task 242556
+ QComboBox box;
+ box.setEditable(true);
+ box.addItems(QStringList() << "First" << "Second" << "Third");
+ box.setStyleSheet("QComboBox { font-size: 32px; }");
+ box.show();
+ embedded = box.findChild<QLineEdit *>();
+ QVERIFY(embedded);
+ QTest::qWait(20);
+ QCOMPARE(box.font().pixelSize(), 32);
+ QCOMPARE(embedded->font().pixelSize(), 32);
+}
+
+void tst_QStyleSheetStyle::opaquePaintEvent_data()
+{
+ QTest::addColumn<QString>("stylesheet");
+ QTest::addColumn<bool>("transparent");
+ QTest::addColumn<bool>("styled");
+
+ QTest::newRow("none") << QString::fromLatin1("/* */") << false << false;
+ QTest::newRow("background black ") << QString::fromLatin1("background: black;") << false << true;
+ QTest::newRow("background qrgba") << QString::fromLatin1("background: rgba(125,0,0,125);") << true << true;
+ QTest::newRow("background transparent") << QString::fromLatin1("background: transparent;") << true << true;
+ QTest::newRow("border native") << QString::fromLatin1("border: native;") << false << false;
+ QTest::newRow("border solid") << QString::fromLatin1("border: 2px solid black;") << true << true;
+ QTest::newRow("border transparent") << QString::fromLatin1("background: black; border: 2px solid rgba(125,0,0,125);") << true << true;
+ QTest::newRow("margin") << QString::fromLatin1("margin: 25px;") << true << true;
+ QTest::newRow("focus") << QString::fromLatin1("*:focus { background: rgba(125,0,0,125) }") << true << true;
+}
+
+void tst_QStyleSheetStyle::opaquePaintEvent()
+{
+ QFETCH(QString, stylesheet);
+ QFETCH(bool, transparent);
+ QFETCH(bool, styled);
+
+ QWidget tl;
+ QWidget cl(&tl);
+ cl.setAttribute(Qt::WA_OpaquePaintEvent, true);
+ cl.setAutoFillBackground(true);
+ cl.setStyleSheet(stylesheet);
+ cl.ensurePolished();
+ QCOMPARE(cl.testAttribute(Qt::WA_OpaquePaintEvent), !transparent);
+ QCOMPARE(cl.testAttribute(Qt::WA_StyledBackground), styled);
+ QCOMPARE(cl.autoFillBackground(), !styled );
+}
+
+void tst_QStyleSheetStyle::complexWidgetFocus()
+{
+ // This test is a simplified version of the focusColors() test above.
+
+ // Tests if colors can be changed by altering the focus of the widget.
+ // To avoid messy pixel-by-pixel comparison, we assume that the goal
+ // is reached if at least ten pixels of the right color can be found in
+ // the image.
+ // For this reason, we use unusual and extremely ugly colors! :-)
+
+ QDialog frame;
+ frame.setStyleSheet("*:focus { background: black; color: black } "
+ "QSpinBox::up-arrow:focus, QSpinBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 } "
+ "QComboBox::down-arrow:focus { width: 7px; height: 7px; background: #ff0084 }"
+ "QSlider::handle:horizontal:focus { width: 7px; height: 7px; background: #ff0084 } ");
+
+ QList<QWidget *> widgets;
+ widgets << new QSpinBox;
+ widgets << new QComboBox;
+ widgets << new QSlider(Qt::Horizontal);
+
+ QLayout* layout = new QGridLayout;
+ layout->addWidget(new QLineEdit); // Avoids initial focus.
+ foreach (QWidget *widget, widgets)
+ layout->addWidget(widget);
+ frame.setLayout(layout);
+
+ frame.show();
+ QTest::qWaitForWindowShown(&frame);
+ QApplication::setActiveWindow(&frame);
+ foreach (QWidget *widget, widgets) {
+ widget->setFocus();
+ QApplication::processEvents();
+
+ QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
+ frame.render(&image);
+ if (image.depth() < 24) {
+ QSKIP("Test doesn't support color depth < 24", SkipAll);
+ }
+
+ QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
+ (QString::fromLatin1(widget->metaObject()->className())
+ + " did not contain text color #ff0084, using style "
+ + QString::fromLatin1(qApp->style()->metaObject()->className()))
+ .toLocal8Bit().constData());
+ }
+}
+
+void tst_QStyleSheetStyle::task188195_baseBackground()
+{
+ QTreeView tree;
+ tree.setStyleSheet( "QTreeView:disabled { background-color:#ab1251; }" );
+ tree.show();
+ QTest::qWait(20);
+ QImage image(tree.width(), tree.height(), QImage::Format_ARGB32);
+
+ tree.render(&image);
+ QVERIFY(testForColors(image, tree.palette().base().color()));
+ QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51)));
+
+ tree.setEnabled(false);
+ tree.render(&image);
+ QVERIFY(testForColors(image, QColor(0xab, 0x12, 0x51)));
+
+ tree.setEnabled(true);
+ tree.render(&image);
+ QVERIFY(testForColors(image, tree.palette().base().color()));
+ QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51)));
+
+ QTableWidget table(12, 12);
+ table.setItem(0, 0, new QTableWidgetItem());
+ table.setStyleSheet( "QTableView {background-color: #ff0000}" );
+ table.show();
+ QTest::qWait(20);
+ image = QImage(table.width(), table.height(), QImage::Format_ARGB32);
+ table.render(&image);
+ QVERIFY(testForColors(image, Qt::red, true));
+}
+
+void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg()
+{
+ // This test is a simplified version of the focusColors() test above.
+
+ // Tests if colors can be changed by altering the focus of the widget.
+ // To avoid messy pixel-by-pixel comparison, we assume that the goal
+ // is reached if at least ten pixels of the right color can be found in
+ // the image.
+ // For this reason, we use unusual and extremely ugly colors! :-)
+
+ QSpinBox *spinbox = new QSpinBox;
+ spinbox->setValue(8888);
+
+ QDialog frame;
+ QLayout* layout = new QGridLayout;
+
+ QLineEdit* dummy = new QLineEdit; // Avoids initial focus.
+
+ // We only want to test the line edit colors.
+ spinbox->setStyleSheet("QSpinBox:focus { background: #e8ff66; color: #ff0084 } "
+ "QSpinBox::up-button, QSpinBox::down-button { background: black; }");
+
+ layout->addWidget(dummy);
+ layout->addWidget(spinbox);
+ frame.setLayout(layout);
+
+ frame.show();
+ QTest::qWaitForWindowShown(&frame);
+ QApplication::setActiveWindow(&frame);
+ spinbox->setFocus();
+ QApplication::processEvents();
+
+ QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
+ frame.render(&image);
+ if (image.depth() < 24) {
+ QSKIP("Test doesn't support color depth < 24", SkipAll);
+ }
+
+ QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
+ (QString::fromLatin1(spinbox->metaObject()->className())
+ + " did not contain background color #e8ff66, using style "
+ + QString::fromLatin1(qApp->style()->metaObject()->className()))
+ .toLocal8Bit().constData());
+ QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
+ (QString::fromLatin1(spinbox->metaObject()->className())
+ + " did not contain text color #ff0084, using style "
+ + QString::fromLatin1(qApp->style()->metaObject()->className()))
+ .toLocal8Bit().constData());
+}
+
+class ChangeEventWidget : public QWidget
+{ public:
+ void changeEvent(QEvent * event)
+ {
+ if(event->type() == QEvent::StyleChange) {
+ static bool recurse = false;
+ if (!recurse) {
+ recurse = true;
+ QStyle *style = new QMotifStyle;
+ style->setParent(this);
+ setStyle(style);
+ recurse = false;
+ }
+ }
+ QWidget::changeEvent(event);
+ }
+};
+
+void tst_QStyleSheetStyle::changeStyleInChangeEvent()
+{ //must not crash;
+ ChangeEventWidget wid;
+ wid.ensurePolished();
+ wid.setStyleSheet(" /* */ ");
+ wid.ensurePolished();
+ wid.setStyleSheet(" /* ** */ ");
+ wid.ensurePolished();
+}
+
+void tst_QStyleSheetStyle::QTBUG11658_cachecrash()
+{
+ //should not crash
+ class Widget : public QWidget
+ {
+ public:
+ Widget(QWidget *parent = 0)
+ : QWidget(parent)
+ {
+ QVBoxLayout* pLayout = new QVBoxLayout(this);
+ QCheckBox* pCheckBox = new QCheckBox(this);
+ pLayout->addWidget(pCheckBox);
+ setLayout(pLayout);
+
+ QString szStyleSheet = QLatin1String("* { color: red; }");
+ qApp->setStyleSheet(szStyleSheet);
+ qApp->setStyle(QStyleFactory::create(QLatin1String("Windows")));
+ }
+ };
+
+ Widget *w = new Widget();
+ delete w;
+ w = new Widget();
+ w->show();
+
+ QTest::qWaitForWindowShown(w);
+ delete w;
+ qApp->setStyleSheet(QString());
+}
+
+void tst_QStyleSheetStyle::QTBUG15910_crashNullWidget()
+{
+ struct Widget : QWidget {
+ virtual void paintEvent(QPaintEvent* ) {
+ QStyleOption opt;
+ opt.init(this);
+ QPainter p(this);
+ style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, 0);
+ style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, 0);
+ style()->drawControl(QStyle::CE_PushButton, &opt, &p, 0);
+ }
+ } w;
+ w.setStyleSheet("* { background-color: white; color:black; border 3px solid yellow }");
+ w.show();
+ QTest::qWaitForWindowShown(&w);
+}
+
+
+QTEST_MAIN(tst_QStyleSheetStyle)
+#include "tst_qstylesheetstyle.moc"
+
diff --git a/tests/auto/widgets/styles/styles.pro b/tests/auto/widgets/styles/styles.pro
new file mode 100644
index 0000000000..7e931582db
--- /dev/null
+++ b/tests/auto/widgets/styles/styles.pro
@@ -0,0 +1,13 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qmacstyle \
+ qstyle \
+ qstyleoption \
+ qstylesheetstyle \
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qstylesheetstyle \
+
+# This test can only be run on Mac OS:
+!mac:SUBDIRS -= \
+ qmacstyle \