From 9f1aa866bda7678261f2f441d4cfd5bb524c2411 Mon Sep 17 00:00:00 2001 From: Jo Asplin Date: Thu, 20 Oct 2011 13:17:26 +0200 Subject: Moved tests into integrationtests/ and widgets/ Task-number: QTBUG-19013 Change-Id: Ibb776f5967c0645ce6d22ef7afdc40657c575461 Reviewed-by: Holger Ihrig --- tests/auto/widgets/styles/qmacstyle/.gitignore | 1 + tests/auto/widgets/styles/qmacstyle/qmacstyle.pro | 6 + .../widgets/styles/qmacstyle/tst_qmacstyle.cpp | 413 +++++ tests/auto/widgets/styles/qstyle/.gitignore | 1 + .../widgets/styles/qstyle/images/mac/button.png | Bin 0 -> 1785 bytes .../widgets/styles/qstyle/images/mac/combobox.png | Bin 0 -> 1808 bytes .../widgets/styles/qstyle/images/mac/lineedit.png | Bin 0 -> 953 bytes .../auto/widgets/styles/qstyle/images/mac/mdi.png | Bin 0 -> 3092 bytes .../auto/widgets/styles/qstyle/images/mac/menu.png | Bin 0 -> 1139 bytes .../styles/qstyle/images/mac/radiobutton.png | Bin 0 -> 1498 bytes .../widgets/styles/qstyle/images/mac/slider.png | Bin 0 -> 1074 bytes .../widgets/styles/qstyle/images/mac/spinbox.png | Bin 0 -> 1299 bytes .../widgets/styles/qstyle/images/vista/button.png | Bin 0 -> 722 bytes .../styles/qstyle/images/vista/combobox.png | Bin 0 -> 809 bytes .../styles/qstyle/images/vista/lineedit.png | Bin 0 -> 530 bytes .../widgets/styles/qstyle/images/vista/menu.png | Bin 0 -> 646 bytes .../styles/qstyle/images/vista/radiobutton.png | Bin 0 -> 844 bytes .../widgets/styles/qstyle/images/vista/slider.png | Bin 0 -> 575 bytes .../widgets/styles/qstyle/images/vista/spinbox.png | Bin 0 -> 583 bytes tests/auto/widgets/styles/qstyle/qstyle.pro | 13 + tests/auto/widgets/styles/qstyle/task_25863.png | Bin 0 -> 910 bytes tests/auto/widgets/styles/qstyle/tst_qstyle.cpp | 794 ++++++++++ tests/auto/widgets/styles/qstyleoption/.gitignore | 1 + .../widgets/styles/qstyleoption/qstyleoption.pro | 11 + .../styles/qstyleoption/tst_qstyleoption.cpp | 161 ++ .../widgets/styles/qstylesheetstyle/.gitignore | 1 + .../styles/qstylesheetstyle/images/testimage.png | Bin 0 -> 299 bytes .../styles/qstylesheetstyle/qstylesheetstyle.pro | 7 + .../widgets/styles/qstylesheetstyle/resources.qrc | 6 + .../qstylesheetstyle/tst_qstylesheetstyle.cpp | 1644 ++++++++++++++++++++ tests/auto/widgets/styles/styles.pro | 13 + 31 files changed, 3072 insertions(+) create mode 100644 tests/auto/widgets/styles/qmacstyle/.gitignore create mode 100644 tests/auto/widgets/styles/qmacstyle/qmacstyle.pro create mode 100644 tests/auto/widgets/styles/qmacstyle/tst_qmacstyle.cpp create mode 100644 tests/auto/widgets/styles/qstyle/.gitignore create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/button.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/combobox.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/lineedit.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/mdi.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/menu.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/slider.png create mode 100644 tests/auto/widgets/styles/qstyle/images/mac/spinbox.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/button.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/combobox.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/lineedit.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/menu.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/slider.png create mode 100644 tests/auto/widgets/styles/qstyle/images/vista/spinbox.png create mode 100644 tests/auto/widgets/styles/qstyle/qstyle.pro create mode 100644 tests/auto/widgets/styles/qstyle/task_25863.png create mode 100644 tests/auto/widgets/styles/qstyle/tst_qstyle.cpp create mode 100644 tests/auto/widgets/styles/qstyleoption/.gitignore create mode 100644 tests/auto/widgets/styles/qstyleoption/qstyleoption.pro create mode 100644 tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp create mode 100644 tests/auto/widgets/styles/qstylesheetstyle/.gitignore create mode 100644 tests/auto/widgets/styles/qstylesheetstyle/images/testimage.png create mode 100644 tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro create mode 100644 tests/auto/widgets/styles/qstylesheetstyle/resources.qrc create mode 100644 tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp create mode 100644 tests/auto/widgets/styles/styles.pro (limited to 'tests/auto/widgets/styles') 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 +#include + +#include + +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"); } + +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"); + 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("size1"); + QTest::addColumn("size2"); + QTest::addColumn("size3"); + QTest::addColumn("expectedHeight1"); + QTest::addColumn("expectedHeight2"); + QTest::addColumn("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) <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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/button.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/combobox.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/mdi.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/menu.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/slider.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/button.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/combobox.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/menu.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/slider.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png 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 Binary files /dev/null and b/tests/auto/widgets/styles/qstyle/task_25863.png 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 +#include +#include "qstyle.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef Q_WS_MAC +#include +#endif + +#ifdef Q_WS_WIN +#include +#include +#endif + +#ifdef Q_OS_WINCE +#include +#endif + +#ifdef Q_OS_WINCE_WM +#include +#include + +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 (QString::fromLatin1("Smartphone").utf16()), tszPlatform)) + return true; + return false; +} +#endif + +#include + +//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(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() << 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(&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 +#include + + +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 +struct StyleOptionPointer: public StyleOptionPointerBase +{ + StyleOptionPointer(T *p = 0): StyleOptionPointerBase(p) {} + ~StyleOptionPointer() { delete static_cast(pointer); pointer = 0; } +}; + +Q_DECLARE_METATYPE(StyleOptionPointerBase*) + +template +inline StyleOptionPointerBase *stylePtr(T *ptr) { return new StyleOptionPointer(ptr); } + +void tst_QStyleOption::qstyleoptioncast_data() +{ + QTest::addColumn("testOption"); + QTest::addColumn("canCastToComplex"); + QTest::addColumn("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(testOption->pointer); + QVERIFY(castOption != 0); + + // Cast to complex base class + castOption = qstyleoption_cast(testOption->pointer); + QCOMPARE(canCastToComplex, (castOption != 0)); + + // Cast to combo box + castOption = qstyleoption_cast(testOption->pointer); + QCOMPARE((castOption != 0),(testOption->pointer->type == QStyleOption::SO_ComboBox)); + + // Cast to button + castOption = qstyleoption_cast(testOption->pointer); + QCOMPARE((castOption != 0),(testOption->pointer->type == QStyleOption::SO_Button)); + + // Cast to lower version + testOption->pointer->version += 1; + castOption = qstyleoption_cast(testOption->pointer); + QVERIFY(castOption); + + // Cast a null pointer + castOption = qstyleoption_cast((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 Binary files /dev/null and b/tests/auto/widgets/styles/qstylesheetstyle/images/testimage.png 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 @@ + + + + images/testimage.png + + \ 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 +#include +#include +#include +#include +#include + +#include +#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 pstyle1 = &style1; + QPointer 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(&style1), window1->style()); + + // Setting another style must not delete the older style + window1->setStyle(&style2); + QCOMPARE(static_cast(&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 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(&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(&style1)); // the same guy + + // Remove the stylesheet + proxy = (QStyleSheetStyle *)window1->style(); + window1->setStyleSheet(""); + QVERIFY(proxy.isNull()); // should have disappeared + QCOMPARE(window1->style(), static_cast(&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(&style1)); + + // Style Sheet propagation on a child widget with a custom style already set + window2->setStyleSheet(""); + QCOMPARE(window2->style(), static_cast(&style2)); + QCOMPARE(widget2->style(), static_cast(&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(newStyle)); // magic ;) the widget still follows the application + QCOMPARE(static_cast(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(&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 style1 = new QWindowsStyle; + QPointer 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 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(&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 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 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 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"); + + 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(&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(&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(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 widgets; + QList 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(); + 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(); + QVERIFY(embedded); + QTest::qWait(20); + QCOMPARE(box.font().pixelSize(), 32); + QCOMPARE(embedded->font().pixelSize(), 32); +} + +void tst_QStyleSheetStyle::opaquePaintEvent_data() +{ + QTest::addColumn("stylesheet"); + QTest::addColumn("transparent"); + QTest::addColumn("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 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 \ -- cgit v1.2.3