QtBase  v6.3.1
tst_qstyle.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 
30 #include <QTest>
31 #include <qlayout.h>
32 #include "qstyle.h"
33 #include <qevent.h>
34 #include <qpainter.h>
35 #include <qpixmap.h>
36 #include <qapplication.h>
37 #include <qwidget.h>
38 #include <qlabel.h>
39 #include <qstyleoption.h>
40 #include <qscrollbar.h>
41 #include <qprogressbar.h>
42 #include <qtoolbutton.h>
43 #include <qtoolbar.h>
44 
45 #include <qcommonstyle.h>
46 #include <qproxystyle.h>
47 #include <qstylefactory.h>
48 
49 #include <qimagereader.h>
50 #include <qimagewriter.h>
51 #include <qmenu.h>
52 #include <qpushbutton.h>
53 #include <qspinbox.h>
54 #include <qcombobox.h>
55 #include <qradiobutton.h>
56 #include <qlineedit.h>
57 #include <qmdiarea.h>
58 #include <qscrollarea.h>
59 #include <qwidget.h>
60 
61 #include <algorithm>
62 
63 #include <QtTest/private/qtesthelpers_p.h>
64 
65 using namespace QTestPrivate;
66 
67 class tst_QStyle : public QObject
68 {
69  Q_OBJECT
70 
71 private slots:
72  void drawItemPixmap();
73  void cleanup();
74 #ifndef QT_NO_STYLE_FUSION
75  void testFusionStyle();
76 #endif
77  void testWindowsStyle();
78 #if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA)
79  void testWindowsVistaStyle();
80 #endif
81 #ifdef Q_OS_MAC
82  void testMacStyle();
83 #endif
84  void testStyleFactory();
85  void testProxyStyle();
86 #if !defined(QT_NO_STYLE_WINDOWS) && !defined(QT_NO_STYLE_FUSION)
87  void progressBarChangeStyle();
88 #endif
89  void defaultFont();
90  void testDrawingShortcuts();
91  void testFrameOnlyAroundContents();
92 
93  void testProxyCalled();
94  void testStyleOptionInit();
95 
96  void sliderPositionFromValue_data();
97  void sliderPositionFromValue();
98  void sliderValueFromPosition_data();
99  void sliderValueFromPosition();
100 private:
101  bool testAllFunctions(QStyle *);
102  bool testScrollBarSubControls(const QStyle *style);
103  void testPainting(QStyle *style, const QString &platform);
104  void lineUpLayoutTest(QStyle *);
105 };
106 
107 class MyWidget : public QWidget
108 {
109 public:
110  using QWidget::QWidget;
111 
112 protected:
113  void paintEvent(QPaintEvent *) override;
114 };
115 
116 void tst_QStyle::cleanup()
117 {
119 }
120 
121 void tst_QStyle::testStyleFactory()
122 {
124 #ifndef QT_NO_STYLE_FUSION
125  QVERIFY(keys.contains("Fusion"));
126 #endif
127 #ifndef QT_NO_STYLE_WINDOWS
128  QVERIFY(keys.contains("Windows"));
129 #endif
130 
131  for (const QString &styleName : keys) {
133  QVERIFY2(!style.isNull(),
134  qPrintable(QString::fromLatin1("Fail to load style '%1'").arg(styleName)));
135  }
136 }
137 
138 class CustomProxy : public QProxyStyle
139 {
140  int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr,
141  const QWidget *widget = nullptr) const override
142  {
143  if (metric == QStyle::PM_ButtonIconSize)
144  return 13;
145  return QProxyStyle::pixelMetric(metric, option, widget);
146  }
147 };
148 
149 void tst_QStyle::testProxyStyle()
150 {
151  QProxyStyle *proxyStyle = new QProxyStyle();
152  QVERIFY(proxyStyle->baseStyle());
153  QStyle *style = QStyleFactory::create("Windows");
154  QCOMPARE(style->proxy(), style);
155 
156  proxyStyle->setBaseStyle(style);
157  QCOMPARE(style->proxy(), proxyStyle);
158  QCOMPARE(style->parent(), proxyStyle);
159  QCOMPARE(proxyStyle->baseStyle(), style);
160 
161  QVERIFY(testAllFunctions(proxyStyle));
162  proxyStyle->setBaseStyle(nullptr);
163  QVERIFY(proxyStyle->baseStyle());
164  QApplication::setStyle(proxyStyle);
165 
166  QProxyStyle* baseStyle = new QProxyStyle("Windows");
167  QCOMPARE(baseStyle->baseStyle()->objectName(), style->objectName());
168 
169  QProxyStyle doubleProxy(baseStyle);
170  QVERIFY(testAllFunctions(&doubleProxy));
171 
172  CustomProxy customStyle;
173  QLineEdit edit;
174  edit.setStyle(&customStyle);
175  QVERIFY(!customStyle.parent());
177 }
178 
179 void tst_QStyle::drawItemPixmap()
180 {
181  MyWidget testWidget;
182  testWidget.setObjectName("testObject");
183  testWidget.resize(300, 300);
184  testWidget.showNormal();
185 
186  QImage image = testWidget.grab().toImage();
187  const QRgb green = QColor(Qt::green).rgb();
188  QVERIFY(image.reinterpretAsFormat(QImage::Format_RGB32));
189  const QRgb *bits = reinterpret_cast<const QRgb *>(image.constBits());
190  const QRgb *end = bits + image.sizeInBytes() / sizeof(QRgb);
191  QVERIFY(std::all_of(bits, end, [green] (QRgb r) { return r == green; }));
192 }
193 
194 bool tst_QStyle::testAllFunctions(QStyle *style)
195 {
197  QWidget testWidget;
198  opt.initFrom(&testWidget);
199 
200  testWidget.setStyle(style);
201 
202  //Tests styleHint with default arguments for potential crashes
203  for ( int hint = 0 ; hint < int(QStyle::SH_Menu_Mask); ++hint) {
204  style->styleHint(QStyle::StyleHint(hint));
205  style->styleHint(QStyle::StyleHint(hint), &opt, &testWidget);
206  }
207 
208  //Tests pixelMetric with default arguments for potential crashes
209  for ( int pm = 0 ; pm < int(QStyle::PM_LayoutVerticalSpacing); ++pm) {
210  style->pixelMetric(QStyle::PixelMetric(pm));
211  style->pixelMetric(QStyle::PixelMetric(pm), &opt, &testWidget);
212  }
213 
214  //Tests drawControl with default arguments for potential crashes
215  for ( int control = 0 ; control < int(QStyle::CE_ColumnViewGrip); ++control) {
216  QPixmap surface(QSize(200, 200));
217  QPainter painter(&surface);
218  style->drawControl(QStyle::ControlElement(control), &opt, &painter, nullptr);
219  }
220 
221  //Tests drawComplexControl with default arguments for potential crashes
222  {
223  QPixmap surface(QSize(200, 200));
224  QPainter painter(&surface);
225  QStyleOptionComboBox copt1;
226  copt1.initFrom(&testWidget);
227 
228  QStyleOptionGroupBox copt2;
229  copt2.initFrom(&testWidget);
230  QStyleOptionSizeGrip copt3;
231  copt3.initFrom(&testWidget);
232  QStyleOptionSlider copt4;
233  copt4.initFrom(&testWidget);
234  copt4.minimum = 0;
235  copt4.maximum = 100;
236  copt4.tickInterval = 25;
237  copt4.sliderValue = 50;
238  QStyleOptionSpinBox copt5;
239  copt5.initFrom(&testWidget);
240  QStyleOptionTitleBar copt6;
241  copt6.initFrom(&testWidget);
243  copt7.initFrom(&testWidget);
244  QStyleOptionComplex copt9;
245  copt9.initFrom(&testWidget);
246 
247  style->drawComplexControl(QStyle::CC_SpinBox, &copt5, &painter, nullptr);
248  style->drawComplexControl(QStyle::CC_ComboBox, &copt1, &painter, nullptr);
249  style->drawComplexControl(QStyle::CC_ScrollBar, &copt4, &painter, nullptr);
250  style->drawComplexControl(QStyle::CC_Slider, &copt4, &painter, nullptr);
251  style->drawComplexControl(QStyle::CC_ToolButton, &copt7, &painter, nullptr);
252  style->drawComplexControl(QStyle::CC_TitleBar, &copt6, &painter, nullptr);
253  style->drawComplexControl(QStyle::CC_GroupBox, &copt2, &painter, nullptr);
254  style->drawComplexControl(QStyle::CC_Dial, &copt4, &painter, nullptr);
255  }
256 
257  //Check standard pixmaps/icons
258  for ( int i = 0 ; i < int(QStyle::SP_ToolBarVerticalExtensionButton); ++i) {
259  QPixmap pixmap = style->standardPixmap(QStyle::StandardPixmap(i));
260  if (pixmap.isNull()) {
261  qWarning("missing StandardPixmap: %d", i);
262  }
263  QIcon icn = style->standardIcon(QStyle::StandardPixmap(i));
264  if (icn.isNull()) {
265  qWarning("missing StandardIcon: %d", i);
266  }
267  }
268 
269  style->itemPixmapRect(QRect(0, 0, 100, 100), Qt::AlignHCenter, QPixmap(200, 200));
270  style->itemTextRect(QFontMetrics(QApplication::font()), QRect(0, 0, 100, 100),
271  Qt::AlignHCenter, true, QLatin1String("Test"));
272 
273  return testScrollBarSubControls(style);
274 }
275 
276 bool tst_QStyle::testScrollBarSubControls(const QStyle *style)
277 {
278  const bool isMacStyle = style->objectName().compare(QLatin1String("macos"),
279  Qt::CaseInsensitive) == 0;
281  setFrameless(&scrollBar);
282  scrollBar.show();
283  const QStyleOptionSlider opt = qt_qscrollbarStyleOption(&scrollBar);
284  for (int sc : {1, 2, 4, 8}) {
285  const auto subControl = static_cast<QStyle::SubControl>(sc);
286  const QRect sr = style->subControlRect(QStyle::CC_ScrollBar, &opt, subControl, &scrollBar);
287  if (sr.isNull()) {
288  // macOS scrollbars no longer have these, so there's no reason to fail
289  if (!(isMacStyle && (subControl == QStyle::SC_ScrollBarAddLine ||
290  subControl == QStyle::SC_ScrollBarSubLine))) {
291  qWarning() << "Unexpected null rect for subcontrol" << subControl;
292  return false;
293  }
294  }
295  }
296  return true;
297 }
298 
299 #ifndef QT_NO_STYLE_FUSION
300 void tst_QStyle::testFusionStyle()
301 {
303  QVERIFY(!fstyle.isNull());
304  QVERIFY(testAllFunctions(fstyle.data()));
305  lineUpLayoutTest(fstyle.data());
306 }
307 #endif
308 
309 void tst_QStyle::testWindowsStyle()
310 {
312  QVERIFY(!wstyle.isNull());
313  QVERIFY(testAllFunctions(wstyle.data()));
314  lineUpLayoutTest(wstyle.data());
315 
316  // Tests drawing indeterminate progress with 0 size: QTBUG-15973
318  pb.rect = QRect(0,0,-9,0);
319  QPixmap surface(QSize(200, 200));
320  QPainter painter(&surface);
321  wstyle->drawControl(QStyle::CE_ProgressBar, &pb, &painter, nullptr);
322 }
323 
324 #if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA)
325 void tst_QStyle::testWindowsVistaStyle()
326 {
327  QScopedPointer<QStyle> vistastyle(QStyleFactory::create("WindowsVista"));
328  QVERIFY(!vistastyle.isNull());
329  QVERIFY(testAllFunctions(vistastyle.data()));
330 }
331 #endif
332 
333 #ifdef Q_OS_MAC
334 void tst_QStyle::testMacStyle()
335 {
336  QStyle *mstyle = QStyleFactory::create("macos");
337  QVERIFY(testAllFunctions(mstyle));
338  delete mstyle;
339 }
340 #endif
341 
342 // Helper class...
344 {
345  QPainter p(this);
346  QPixmap big(400,400);
347  big.fill(Qt::green);
348  style()->drawItemPixmap(&p, rect(), Qt::AlignCenter, big);
349 }
350 
351 
352 #if !defined(QT_NO_STYLE_WINDOWS) && !defined(QT_NO_STYLE_FUSION)
353 void tst_QStyle::progressBarChangeStyle()
354 {
355  //test a crashing situation (task 143530)
356  //where changing the styles and deleting a progressbar would crash
357 
358  QStyle *style1 = QStyleFactory::create("Windows");
359  QStyle *style2 = QStyleFactory::create("Fusion");
360 
361  QProgressBar *progress=new QProgressBar;
362  progress->setStyle(style1);
363 
364  progress->show();
365 
366  progress->setStyle(style2);
367 
368  QTest::qWait(100);
369  delete progress;
370 
371  QTest::qWait(100);
372 
373  //before the correction, there would be a crash here
374  delete style1;
375  delete style2;
376 }
377 #endif
378 
379 void tst_QStyle::lineUpLayoutTest(QStyle *style)
380 {
381  QWidget widget;
382  setFrameless(&widget);
383  QHBoxLayout layout;
384  QFont font;
385  font.setPointSize(9); //Plastique is lined up for odd numbers...
387  QSpinBox spinbox(&widget);
388  QLineEdit lineedit(&widget);
389  QComboBox combo(&widget);
390  combo.setEditable(true);
391  layout.addWidget(&spinbox);
392  layout.addWidget(&lineedit);
393  layout.addWidget(&combo);
396  // propagate the style.
397  const auto children = widget.findChildren<QWidget *>();
398  for (QWidget *w : children)
399  w->setStyle(style);
400  widget.show();
402 
403 #ifdef Q_OS_WIN
404  const int limit = 2; // Aero style has larger margins
405 #else
406  const int limit = 1;
407 #endif
408  const int slDiff = qAbs(spinbox.height() - lineedit.height());
409  const int scDiff = qAbs(spinbox.height() - combo.height());
410  QVERIFY2(slDiff <= limit,
411  qPrintable(QString::fromLatin1("%1 exceeds %2 for %3")
412  .arg(slDiff).arg(limit).arg(style->objectName())));
413  QVERIFY2(scDiff <= limit,
414  qPrintable(QString::fromLatin1("%1 exceeds %2 for %3")
415  .arg(scDiff).arg(limit).arg(style->objectName())));
416 }
417 
418 void tst_QStyle::defaultFont()
419 {
420  QFont defaultFont = QApplication::font();
421  QFont pointFont = defaultFont;
422  pointFont.setPixelSize(9);
423  QApplication::setFont(pointFont);
425  setFrameless(&button);
426  button.show();
428  QApplication::setFont(defaultFont);
429 }
430 
432 {
433  Q_OBJECT
434 public:
436 
437  void drawItemText(QPainter *painter, const QRect &rect,
438  int flags, const QPalette &pal, bool enabled,
439  const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const override
440  {
441  alignment = flags;
443  }
444 
445  mutable int alignment = 0;
446 };
447 
448 
449 void tst_QStyle::testDrawingShortcuts()
450 {
451  {
452  QWidget w;
453  setFrameless(&w);
454  QToolButton *tb = new QToolButton(&w);
455  tb->setText("&abc");
457  w.show();
458  tb->setStyle(dts.data());
459  tb->grab();
461  sotb.initFrom(tb);
462  bool showMnemonic = dts->styleHint(QStyle::SH_UnderlineShortcut, &sotb, tb);
463  QVERIFY(dts->alignment & (showMnemonic ? Qt::TextShowMnemonic : Qt::TextHideMnemonic));
464  }
465  {
466  QToolBar w;
467  setFrameless(&w);
468  QToolButton *tb = new QToolButton(&w);
469  tb->setText("&abc");
471  w.addWidget(tb);
472  w.show();
473  tb->setStyle(dts.data());
474  tb->grab();
476  sotb.initFrom(tb);
477  bool showMnemonic = dts->styleHint(QStyle::SH_UnderlineShortcut, &sotb, tb);
478  QVERIFY(dts->alignment & (showMnemonic ? Qt::TextShowMnemonic : Qt::TextHideMnemonic));
479  }
480 }
481 
482 static const int SCROLLBAR_SPACING = 33;
483 
484 class FrameTestStyle : public QProxyStyle {
485 public:
486  FrameTestStyle() : QProxyStyle("Windows") { }
487 
488  int styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
489  QStyleHintReturn *returnData) const override
490  {
492  return 1;
493  return QProxyStyle ::styleHint(hint, opt, widget, returnData);
494  }
495 
496  int pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const override
497  {
499  return SCROLLBAR_SPACING;
501  }
502 };
503 
504 void tst_QStyle::testFrameOnlyAroundContents()
505 {
506  QScrollArea area;
507  area.setGeometry(0, 0, 200, 200);
508  QScopedPointer<QStyle> winStyle(QStyleFactory::create("Windows"));
509  FrameTestStyle frameStyle;
510  QWidget *widget = new QWidget(&area);
511  widget->setGeometry(0, 0, 400, 400);
512  area.setStyle(winStyle.data());
513  area.verticalScrollBar()->setStyle(winStyle.data());
514  area.setWidget(widget);
515  area.setVisible(true);
516  int viewPortWidth = area.viewport()->width();
517  area.verticalScrollBar()->setStyle(&frameStyle);
518  area.setStyle(&frameStyle);
519  // Test that we reserve space for scrollbar spacing
520  QCOMPARE(viewPortWidth, area.viewport()->width() + SCROLLBAR_SPACING);
521 }
522 
523 
524 class ProxyTest: public QProxyStyle
525 {
526  Q_OBJECT
527 public:
529 
530  void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
531  const QWidget *w) const override
532  {
533  called = true;
534  return QProxyStyle::drawPrimitive(pe, opt, p, w);
535  }
536 
537  mutable bool called = false;
538 };
539 
540 
541 void tst_QStyle::testProxyCalled()
542 {
543  QToolButton b;
544  b.setArrowType(Qt::DownArrow);
546  opt.initFrom(&b);
548  QPixmap surface(QSize(200, 200));
549  QPainter painter(&surface);
550 
552  QList<QStyle *> styles;
553  styles.reserve(keys.size() + 1);
554 
555  styles << new QCommonStyle();
556 
557  for (const QString &key : keys)
558  styles << QStyleFactory::create(key);
559 
560  for (QStyle *style : styles) {
561  ProxyTest testStyle;
562  testStyle.setBaseStyle(style);
563  style->drawControl(QStyle::CE_ToolButtonLabel, &opt, &painter, &b);
564  QVERIFY(testStyle.called);
565  delete style;
566  }
567 }
568 
569 
571 {
572  Q_OBJECT
573 public:
574  mutable bool invalidOptionsDetected = false;
575 
577 
578  void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const override {
579  checkStyleEnum<QStyle::PrimitiveElement>(pe, opt);
580  return QProxyStyle::drawPrimitive(pe, opt, p, w);
581  }
582 
583  void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const override {
584  checkStyleEnum<QStyle::ControlElement>(element, opt);
585  return QProxyStyle::drawControl(element, opt, p, w);
586  }
587 
588  QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget) const override {
589  checkStyleEnum<QStyle::SubElement>(subElement, option);
590  return QProxyStyle::subElementRect(subElement, option, widget);
591  }
592 
593  void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const override {
594  checkStyleEnum<QStyle::ComplexControl>(cc, opt);
596  }
597 
598  QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override {
599  checkStyleEnum<QStyle::ComplexControl>(cc, opt);
600  return QProxyStyle::subControlRect(cc, opt, sc, widget);
601  }
602 
603  int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override {
604  checkStyleEnum<QStyle::PixelMetric>(metric, option);
605  return QProxyStyle::pixelMetric(metric, option, widget);
606  }
607 
608  QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const override {
609  checkStyleEnum<QStyle::ContentsType>(ct, opt);
610  return QProxyStyle::sizeFromContents(ct, opt, contentsSize, w);
611  }
612 
613  int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const override {
614  checkStyleEnum<QStyle::StyleHint>(stylehint, opt);
615  return QProxyStyle::styleHint(stylehint, opt, widget, returnData);
616  }
617 
618  QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const override {
619  checkStyleEnum<QStyle::StandardPixmap>(standardPixmap, opt);
620  return QProxyStyle::standardPixmap(standardPixmap, opt, widget);
621  }
622 
623  QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const override {
624  checkStyleEnum<QStyle::StandardPixmap>(standardIcon, option);
625  return QProxyStyle::standardIcon(standardIcon, option, widget);
626  }
627 
628  QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override {
629  checkStyle(QString::asprintf("QIcon::Mode(%i)", iconMode).toLatin1(), opt);
630  return QProxyStyle::generatedIconPixmap(iconMode, pixmap, opt);
631  }
632 
633  int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const override {
634  checkStyle(QString::asprintf("QSizePolicy::ControlType(%i), QSizePolicy::ControlType(%i)", control1, control2).toLatin1(), option);
635  return QProxyStyle::layoutSpacing(control1, control2, orientation, option, widget);
636  }
637 
638 private:
639  void checkStyle(const QByteArray &info, const QStyleOption *opt) const {
640  if (opt && (opt->version == 0 || opt->styleObject == nullptr) ) {
641  invalidOptionsDetected = true;
642  qWarning() << baseStyle()->metaObject()->className()
643  << "Invalid QStyleOption found for"
644  << info;
645  qWarning() << "Version:" << opt->version << "StyleObject:" << opt->styleObject;
646  }
647  }
648 
649  template<typename MEnum>
650  void checkStyleEnum(MEnum element, const QStyleOption *opt) const {
651  static QMetaEnum _enum = QMetaEnum::fromType<MEnum>();
652  checkStyle(_enum.valueToKey(element), opt);
653  }
654 };
655 
656 void tst_QStyle::testStyleOptionInit()
657 {
659  keys.prepend(QString()); // QCommonStyle marker
660 
661  for (const QString &key : qAsConst(keys)) {
662  QStyle* style = key.isEmpty() ? new QCommonStyle : QStyleFactory::create(key);
663  TestStyleOptionInitProxy testStyle;
664  testStyle.setBaseStyle(style);
665  testAllFunctions(style);
666  QVERIFY(!testStyle.invalidOptionsDetected);
667  }
668 }
669 
670 void tst_QStyle::sliderPositionFromValue_data()
671 {
672  QTest::addColumn<int>("min");
673  QTest::addColumn<int>("max");
674  QTest::addColumn<int>("value");
675  QTest::addColumn<int>("span");
676  QTest::addColumn<bool>("upsideDown");
677  QTest::addColumn<int>("position");
678 
679  QTest::addRow("no span") << 12 << 56 << 34 << 0 << false << 0;
680  QTest::addRow("no span inverse") << 12 << 56 << 34 << 0 << true << 0;
681 
682  QTest::addRow("value too small") << 34 << 56 << 12 << 2000 << false << 0;
683 
684  QTest::addRow("no-range") << 12 << 12 << 12 << 2000 << false << 0;
685  QTest::addRow("no-range-inverse") << 12 << 12 << 12 << 2000 << true << 0;
686 
687  QTest::addRow("close-to-max") << 12 << 34 << 33 << 2000 << false << 1909;
688  QTest::addRow("at-max") << 12 << 34 << 34 << 2000 << false << 2000;
689  QTest::addRow("close-to-max-inverse") << 12 << 34 << 33 << 2000 << true << 91;
690  QTest::addRow("at-max-inverse") << 12 << 34 << 34 << 2000 << true << 0;
691 
692  QTest::addRow("big-range") << 100000 << 700000 << 250000 << 2000 << false << 500;
693  QTest::addRow("big-range-inverse") << 100000 << 700000 << 250000 << 2000 << true << 1500;
694 
695  QTest::addRow("across-zero") << -1000 << 1000 << -500 << 100 << false << 25;
696  QTest::addRow("across-zero-inverse") << -1000 << 1000 << -500 << 100 << true << 75;
697 
698  QTest::addRow("span>range") << 0 << 100 << 60 << 2000 << false << 1200;
699  QTest::addRow("span>range-inverse") << 0 << 100 << 60 << 2000 << true << 800;
700 
701  QTest::addRow("overflow1 (QTBUG-101581)") << -1 << INT_MAX << 235 << 891 << false << 0;
702  QTest::addRow("overflow2") << INT_MIN << INT_MAX << 10 << 100 << false << 50;
703  QTest::addRow("overflow2-inverse") << INT_MIN << INT_MAX << 10 << 100 << true << 49;
704  QTest::addRow("overflow3") << INT_MIN << INT_MAX << -10 << 100 << false << 49;
705  QTest::addRow("overflow3-inverse") << INT_MIN << INT_MAX << -10 << 100 << true << 50;
706 }
707 
708 void tst_QStyle::sliderPositionFromValue()
709 {
710  QFETCH(int, min);
711  QFETCH(int, max);
712  QFETCH(int, value);
713  QFETCH(int, span);
714  QFETCH(bool, upsideDown);
715  QFETCH(int, position);
716 
717  QCOMPARE(QStyle::sliderPositionFromValue(min, max, value, span, upsideDown), position);
718 }
719 
720 void tst_QStyle::sliderValueFromPosition_data()
721 {
722  QTest::addColumn<int>("min");
723  QTest::addColumn<int>("max");
724  QTest::addColumn<int>("position");
725  QTest::addColumn<int>("span");
726  QTest::addColumn<bool>("upsideDown");
727  QTest::addColumn<int>("value");
728 
729  QTest::addRow("position zero") << 0 << 100 << 0 << 2000 << false << 0;
730  QTest::addRow("position zero inverse") << 0 << 100 << 0 << 2000 << true << 100;
731 
732  QTest::addRow("span zero") << 0 << 100 << 1200 << 0 << false << 0;
733  QTest::addRow("span zero inverse") << 0 << 100 << 1200 << 0 << true << 100;
734 
735  QTest::addRow("position > span") << -300 << -200 << 2 << 1 << false << -200;
736  QTest::addRow("position > span inverse") << -300 << -200 << 2 << 1 << true << -300;
737 
738  QTest::addRow("large") << 0 << 100 << 1200 << 2000 << false << 60;
739  QTest::addRow("large-inverse") << 0 << 100 << 1200 << 2000 << true << 40;
740 
741  QTest::addRow("normal") << 0 << 100 << 12 << 20 << false << 60;
742  QTest::addRow("inverse") << 0 << 100 << 12 << 20 << true << 40;
743 
744  QTest::addRow("overflow1") << -1 << INT_MAX << 10 << 10 << false << INT_MAX;
745  QTest::addRow("overflow1-inverse") << -1 << INT_MAX << 10 << 10 << true << -1;
746  QTest::addRow("overflow2") << INT_MIN << INT_MAX << 5 << 10 << false << 0;
747  QTest::addRow("overflow2-inverse") << INT_MIN << INT_MAX << 5 << 10 << true << -1;
748  QTest::addRow("overflow3") << INT_MIN << 0 << 0 << 10 << false << INT_MIN;
749  QTest::addRow("overflow3-inverse") << INT_MIN << 0 << 0 << 10 << true << 0;
750 
751  QTest::addRow("overflow4") << 0 << INT_MAX << INT_MAX/2-6 << INT_MAX/2-5 << false << INT_MAX-2;
752  QTest::addRow("overflow4-inverse") << 0 << INT_MAX << INT_MAX/2-6 << INT_MAX/2-5 << true << 2;
753 
754  QTest::addRow("overflow5") << 0 << 4 << INT_MAX/4 << INT_MAX << false << 1;
755  QTest::addRow("overflow5-inverse") << 0 << 4 << INT_MAX/4 << INT_MAX << true << 3;
756 }
757 
758 void tst_QStyle::sliderValueFromPosition()
759 {
760  QFETCH(int, min);
761  QFETCH(int, max);
762  QFETCH(int, position);
763  QFETCH(int, span);
764  QFETCH(bool, upsideDown);
765  QFETCH(int, value);
766 
767  QCOMPARE(QStyle::sliderValueFromPosition(min, max, position, span, upsideDown), value);
768 }
769 
771 #include "tst_qstyle.moc"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
Arabic default style
Definition: afstyles.h:94
void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole=QPalette::NoRole) const override
Definition: tst_qstyle.cpp:437
int pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const override
Definition: tst_qstyle.cpp:496
int styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const override
Definition: tst_qstyle.cpp:488
QWidget(QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
void paintEvent(QPaintEvent *event) override
[0]
void paintEvent(QPaintEvent *) override
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const override
Definition: tst_qstyle.cpp:530
void setText(const QString &text)
static void setStyle(QStyle *)
static QWidgetList topLevelWidgets()
static QFont font()
static void setFont(const QFont &, const char *className=nullptr)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
The QCommonStyle class encapsulates the common Look and Feel of a GUI.
Definition: qcommonstyle.h:51
static void processEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:56
QGraphicsObject * parent
the parent of the item
Mode
Definition: qicon.h:58
@ Format_RGB32
Definition: qimage.h:82
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QLineEdit widget is a one-line text editor.
Definition: qlineedit.h:64
Definition: qlist.h:108
void reserve(qsizetype size)
Definition: qlist.h:757
The QMetaEnum class provides meta-data about an enumerator.
Definition: qmetaobject.h:220
const char * valueToKey(int value) const
QString objectName
the name of this object
Definition: qobject.h:129
friend class QWidget
Definition: qobject.h:445
QList< T > findChildren(const QString &aName, Qt::FindChildOptions options=Qt::FindChildrenRecursively) const
Definition: qobject.h:175
void setObjectName(const QString &name)
Definition: qobject.cpp:1261
The QPaintEvent class contains event parameters for paint events. \inmodule QtGui.
Definition: qevent.h:539
@ NoRole
Definition: qpalette.h:91
The QProgressBar widget provides a horizontal or vertical progress bar.
Definition: qprogressbar.h:54
The QProxyStyle class is a convenience class that simplifies dynamically overriding QStyle elements.
Definition: qproxystyle.h:53
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget=nullptr) const override
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget=nullptr) const override
int styleHint(StyleHint hint, const QStyleOption *option=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const override
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override
void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole=QPalette::NoRole) const override
int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const override
int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const override
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget=nullptr) const override
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override
void setBaseStyle(QStyle *style)
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget=nullptr) const override
QStyle * baseStyle() const
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const override
The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon dest...
T * data() const noexcept
The QScrollArea class provides a scrolling view onto another widget.
Definition: qscrollarea.h:53
void setWidget(QWidget *widget)
The QScrollBar widget provides a vertical or horizontal scroll bar.
Definition: qscrollbar.h:56
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
Definition: qstring.cpp:6759
The QStringList class provides a list of strings.
static QStringList keys()
static QStyle * create(const QString &)
the exposed rectangle, in item coordinates
Definition: qstyleoption.h:724
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition: qstyle.h:65
ContentsType
Definition: qstyle.h:580
StyleHint
Definition: qstyle.h:618
@ SH_ScrollView_FrameOnlyAroundContents
Definition: qstyle.h:636
@ SH_Menu_Mask
Definition: qstyle.h:699
@ SH_UnderlineShortcut
Definition: qstyle.h:660
StandardPixmap
Definition: qstyle.h:750
@ SP_ToolBarVerticalExtensionButton
Definition: qstyle.h:779
ControlElement
Definition: qstyle.h:206
@ CE_ColumnViewGrip
Definition: qstyle.h:264
@ CE_ToolButtonLabel
Definition: qstyle.h:236
@ CE_ProgressBar
Definition: qstyle.h:221
static int sliderPositionFromValue(int min, int max, int val, int space, bool upsideDown=false)
Definition: qstyle.cpp:2258
PixelMetric
Definition: qstyle.h:449
@ PM_LayoutVerticalSpacing
Definition: qstyle.h:551
@ PM_ScrollView_ScrollBarSpacing
Definition: qstyle.h:559
@ PM_ButtonIconSize
Definition: qstyle.h:541
static int sliderValueFromPosition(int min, int max, int pos, int space, bool upsideDown=false)
Definition: qstyle.cpp:2301
ComplexControl
Definition: qstyle.h:367
@ CC_ComboBox
Definition: qstyle.h:369
@ CC_GroupBox
Definition: qstyle.h:375
@ CC_Slider
Definition: qstyle.h:371
@ CC_Dial
Definition: qstyle.h:374
@ CC_ToolButton
Definition: qstyle.h:372
@ CC_TitleBar
Definition: qstyle.h:373
@ CC_SpinBox
Definition: qstyle.h:368
@ CC_ScrollBar
Definition: qstyle.h:370
PrimitiveElement
Definition: qstyle.h:138
friend class QProxyStyle
Definition: qstyle.h:873
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
SubElement
Definition: qstyle.h:278
SubControl
Definition: qstyle.h:383
@ SC_ScrollBarSubLine
Definition: qstyle.h:387
@ SC_ScrollBarAddLine
Definition: qstyle.h:386
ButtonFeatures features
Definition: qstyleoption.h:260
an OR combination of the tool button's features
Definition: qstyleoption.h:608
the type of menu item
Definition: qstyleoption.h:515
a bitwise OR of the features that describe this frame.
Definition: qstyleoption.h:649
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:75
void initFrom(const QWidget *w)
QObject * styleObject
Definition: qstyleoption.h:100
a bitwise OR of the features that describe this button
Definition: qstyleoption.h:346
the position of the selected tab in relation to this tab
Definition: qstyleoption.h:630
the title of the dock window
Definition: qstyleoption.h:579
The QToolBar class provides a movable panel that contains a set of controls.
Definition: qtoolbar.h:59
The QToolButton class provides a quick-access button to commands or options, usually used inside a QT...
Definition: qtoolbutton.h:56
void setLayout(QLayout *)
Definition: qwidget.cpp:10146
void setGeometry(int x, int y, int w, int h)
Definition: qwidget.h:919
Q_INVOKABLE QPixmap grab(const QRect &rectangle=QRect(QPoint(0, 0), QSize(-1, -1)))
Definition: qwidget.cpp:5218
void setStyle(QStyle *)
Definition: qwidget.cpp:2642
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:150
void show()
Definition: qwidget.cpp:7825
QStyle * style() const
Definition: qwidget.cpp:2612
void setFont(const QFont &)
Definition: qwidget.cpp:4673
void resize(int w, int h)
Definition: qwidget.h:916
void showNormal()
Definition: qwidget.cpp:3072
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const override
Definition: tst_qstyle.cpp:623
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const override
Definition: tst_qstyle.cpp:578
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const override
Definition: tst_qstyle.cpp:583
QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const override
Definition: tst_qstyle.cpp:608
int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const override
Definition: tst_qstyle.cpp:613
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const override
Definition: tst_qstyle.cpp:618
QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget) const override
Definition: tst_qstyle.cpp:588
int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override
Definition: tst_qstyle.cpp:603
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override
Definition: tst_qstyle.cpp:598
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override
Definition: tst_qstyle.cpp:628
int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const override
Definition: tst_qstyle.cpp:633
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const override
Definition: tst_qstyle.cpp:593
QPushButton
[1]
QOpenGLWidget * widget
[1]
QString text
[meta data]
QPushButton * button
[2]
QCOMPARE(spy.count(), 1)
rect
[4]
uint alignment
QStyleOptionButton opt
backing_store_ptr info
[4]
Definition: jmemsys.h:161
QHighDpiScaling::Point position(T, QHighDpiScaling::Point::Kind)
Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, int timeout=5000)
Q_TESTLIB_EXPORT QTestData & addRow(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
Definition: qtestcase.cpp:2690
Q_CORE_EXPORT void qWait(int ms)
@ AlignHCenter
Definition: qnamespace.h:173
@ AlignCenter
Definition: qnamespace.h:188
Orientation
Definition: qnamespace.h:123
@ DownArrow
Definition: qnamespace.h:1106
@ TextHideMnemonic
Definition: qnamespace.h:203
@ TextShowMnemonic
Definition: qnamespace.h:198
@ green
Definition: qnamespace.h:67
@ CaseInsensitive
Definition: qnamespace.h:1283
Definition: image.cpp:51
constexpr struct q20::ranges::@310 all_of
#define QString()
Definition: parse-defines.h:51
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld cleanup[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
EGLOutputLayerEXT EGLint EGLAttrib value
#define qWarning
Definition: qlogging.h:179
GLboolean GLboolean GLboolean b
GLuint64 key
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLuint GLuint end
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLbitfield flags
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: qopenglext.h:6904
GLint limit
Definition: qopenglext.h:9975
GLenum GLenum GLsizei void GLsizei void void * span
Definition: qopenglext.h:2747
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLuint GLenum option
Definition: qopenglext.h:5929
GLbyte green
Definition: qopenglext.h:385
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition: qrgb.h:49
Q_WIDGETS_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollbar)
Definition: qscrollbar.cpp:725
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
SSL_CTX int(*) void arg)
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define QVERIFY2(statement, description)
Definition: qtestcase.h:76
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define slots
Definition: qtmetamacros.h:76
QStringList keys
QVBoxLayout * layout
QScrollBar * scrollBar
widget render & pixmap
QPainter painter(this)
[7]
QCommandLinkButton * pb