1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 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 <QtTest/QtTest> |
31 | #include <qapplication.h> |
32 | #include <qsplitter.h> |
33 | #include <qstyle.h> |
34 | #include <qfile.h> |
35 | #include <qtextstream.h> |
36 | #include <qlayout.h> |
37 | #include <qabstractscrollarea.h> |
38 | #include <qgraphicsview.h> |
39 | #include <qmdiarea.h> |
40 | #include <qscrollarea.h> |
41 | #include <qtextedit.h> |
42 | #include <qtreeview.h> |
43 | #include <qlabel.h> |
44 | #include <qdialog.h> |
45 | #include <qscreen.h> |
46 | #include <qproxystyle.h> |
47 | #include <qdebug.h> // for file error messages |
48 | |
49 | QT_FORWARD_DECLARE_CLASS(QSplitter) |
50 | QT_FORWARD_DECLARE_CLASS(QWidget) |
51 | class tst_QSplitter : public QObject |
52 | { |
53 | Q_OBJECT |
54 | |
55 | public: |
56 | tst_QSplitter(); |
57 | virtual ~tst_QSplitter(); |
58 | |
59 | public slots: |
60 | void initTestCase(); |
61 | void cleanupTestCase(); |
62 | void init(); |
63 | private slots: |
64 | void getSetCheck(); |
65 | void setSizes(); |
66 | void setSizes_data(); |
67 | void saveAndRestoreState(); |
68 | void saveAndRestoreState_data(); |
69 | void saveState_data(); |
70 | void addWidget(); |
71 | void insertWidget(); |
72 | void setStretchFactor_data(); |
73 | void setStretchFactor(); |
74 | void testShowHide_data(); |
75 | void testShowHide(); |
76 | void testRemoval(); |
77 | void rubberBandNotInSplitter(); |
78 | void saveAndRestoreStateOfNotYetShownSplitter(); |
79 | void saveAndRestoreHandleWidth(); |
80 | void replaceWidget_data(); |
81 | void replaceWidget(); |
82 | void replaceWidgetWithSplitterChild_data(); |
83 | void replaceWidgetWithSplitterChild(); |
84 | void handleMinimumWidth(); |
85 | |
86 | // task-specific tests below me: |
87 | void task187373_addAbstractScrollAreas(); |
88 | void task187373_addAbstractScrollAreas_data(); |
89 | void task169702_sizes(); |
90 | void taskQTBUG_4101_ensureOneNonCollapsedWidget_data(); |
91 | void taskQTBUG_4101_ensureOneNonCollapsedWidget(); |
92 | void setLayout(); |
93 | void autoAdd(); |
94 | |
95 | private: |
96 | void removeThirdWidget(); |
97 | void addThirdWidget(); |
98 | QSplitter *splitter; |
99 | QWidget *w1; |
100 | QWidget *w2; |
101 | QWidget *w3; |
102 | }; |
103 | |
104 | // Testing get/set functions |
105 | void tst_QSplitter::getSetCheck() |
106 | { |
107 | QSplitter obj1; |
108 | // bool QSplitter::opaqueResize() |
109 | // void QSplitter::setOpaqueResize(bool) |
110 | bool styleHint = obj1.style()->styleHint(stylehint: QStyle::SH_Splitter_OpaqueResize); |
111 | QCOMPARE(styleHint, obj1.opaqueResize()); |
112 | obj1.setOpaqueResize(false); |
113 | QCOMPARE(false, obj1.opaqueResize()); |
114 | obj1.setOpaqueResize(true); |
115 | QCOMPARE(true, obj1.opaqueResize()); |
116 | } |
117 | |
118 | tst_QSplitter::tst_QSplitter() |
119 | : w1(0), w2(0), w3(0) |
120 | { |
121 | } |
122 | |
123 | tst_QSplitter::~tst_QSplitter() |
124 | { |
125 | } |
126 | |
127 | void tst_QSplitter::initTestCase() |
128 | { |
129 | splitter = new QSplitter(Qt::Horizontal); |
130 | w1 = new QWidget; |
131 | w2 = new QWidget; |
132 | splitter->addWidget(widget: w1); |
133 | splitter->addWidget(widget: w2); |
134 | } |
135 | |
136 | void tst_QSplitter::init() |
137 | { |
138 | removeThirdWidget(); |
139 | w1->show(); |
140 | w2->show(); |
141 | w1->setMinimumSize(minw: 0, minh: 0); |
142 | w2->setMinimumSize(minw: 0, minh: 0); |
143 | splitter->setSizes(QList<int>() << 200 << 200); |
144 | qApp->sendPostedEvents(); |
145 | } |
146 | |
147 | void tst_QSplitter::removeThirdWidget() |
148 | { |
149 | delete w3; |
150 | w3 = 0; |
151 | int handleWidth = splitter->style()->pixelMetric(metric: QStyle::PM_SplitterWidth); |
152 | splitter->setFixedSize(w: 400 + handleWidth, h: 400); |
153 | } |
154 | |
155 | void tst_QSplitter::addThirdWidget() |
156 | { |
157 | if (!w3) { |
158 | w3 = new QWidget; |
159 | splitter->addWidget(widget: w3); |
160 | int handleWidth = splitter->style()->pixelMetric(metric: QStyle::PM_SplitterWidth); |
161 | splitter->setFixedSize(w: 600 + 2 * handleWidth, h: 400); |
162 | } |
163 | } |
164 | |
165 | void tst_QSplitter::cleanupTestCase() |
166 | { |
167 | } |
168 | |
169 | |
170 | typedef QList<int> IntList; |
171 | |
172 | void tst_QSplitter::setSizes() |
173 | { |
174 | QFETCH(IntList, minimumSizes); |
175 | QFETCH(IntList, splitterSizes); |
176 | QFETCH(IntList, collapsibleStates); |
177 | QFETCH(bool, childrenCollapse); |
178 | |
179 | QCOMPARE(minimumSizes.size(), splitterSizes.size()); |
180 | if (minimumSizes.size() > 2) |
181 | addThirdWidget(); |
182 | for (int i = 0; i < minimumSizes.size(); ++i) { |
183 | QWidget *w = splitter->widget(index: i); |
184 | w->setMinimumWidth(minimumSizes.at(i)); |
185 | splitter->setCollapsible(index: splitter->indexOf(w), collapsibleStates.at(i)); |
186 | } |
187 | splitter->setChildrenCollapsible(childrenCollapse); |
188 | splitter->setSizes(splitterSizes); |
189 | QTEST(splitter->sizes(), "expectedSizes" ); |
190 | } |
191 | |
192 | void tst_QSplitter::setSizes_data() |
193 | { |
194 | QTest::addColumn<IntList>(name: "minimumSizes" ); |
195 | QTest::addColumn<IntList>(name: "splitterSizes" ); |
196 | QTest::addColumn<IntList>(name: "expectedSizes" ); |
197 | QTest::addColumn<IntList>(name: "collapsibleStates" ); |
198 | QTest::addColumn<bool>(name: "childrenCollapse" ); |
199 | |
200 | QFile file(QFINDTESTDATA("setSizes3.dat" )); |
201 | if (!file.open(flags: QIODevice::ReadOnly)) { |
202 | qDebug() << "Can't open file, reason:" << file.errorString(); |
203 | return; |
204 | } |
205 | QTextStream ts(&file); |
206 | ts.setIntegerBase(10); |
207 | |
208 | QString dataName; |
209 | IntList minimumSizes; |
210 | IntList splitterSizes; |
211 | IntList expectedSizes; |
212 | IntList collapsibleStates; |
213 | int childrenCollapse; |
214 | while (!ts.atEnd()) { |
215 | int i1, i2, i3; |
216 | minimumSizes.clear(); |
217 | splitterSizes.clear(); |
218 | expectedSizes.clear(); |
219 | collapsibleStates.clear(); |
220 | ts >> dataName; |
221 | ts >> i1 >> i2 >> i3; |
222 | minimumSizes << i1 << i2 << i3; |
223 | ts >> i1 >> i2 >> i3; |
224 | splitterSizes << i1 << i2 << i3; |
225 | ts >> i1 >> i2 >> i3; |
226 | expectedSizes << i1 << i2 << i3; |
227 | ts >> i1 >> i2 >> i3; |
228 | collapsibleStates << i1 << i2 << i3; |
229 | ts >> childrenCollapse; |
230 | QTest::newRow(dataTag: dataName.toLocal8Bit()) << minimumSizes << splitterSizes << expectedSizes << collapsibleStates << bool(childrenCollapse); |
231 | ts.skipWhiteSpace(); |
232 | } |
233 | } |
234 | |
235 | void tst_QSplitter::saveAndRestoreState_data() |
236 | { |
237 | saveState_data(); |
238 | } |
239 | |
240 | void tst_QSplitter::saveAndRestoreState() |
241 | { |
242 | QFETCH(IntList, initialSizes); |
243 | splitter->setSizes(initialSizes); |
244 | QApplication::instance()->sendPostedEvents(); |
245 | |
246 | QSplitter *splitter2 = new QSplitter(splitter->orientation() == Qt::Horizontal ? |
247 | Qt::Vertical : Qt::Horizontal); |
248 | for (int i = 0; i < splitter->count(); ++i) { |
249 | splitter2->addWidget(widget: new QWidget()); |
250 | } |
251 | splitter2->resize(splitter->size()); |
252 | splitter2->setChildrenCollapsible(!splitter->childrenCollapsible()); |
253 | splitter2->setOpaqueResize(!splitter->opaqueResize()); |
254 | splitter2->setHandleWidth(splitter->handleWidth()+3); |
255 | |
256 | QByteArray ba = splitter->saveState(); |
257 | QVERIFY(splitter2->restoreState(ba)); |
258 | |
259 | QCOMPARE(splitter2->orientation(), splitter->orientation()); |
260 | QCOMPARE(splitter2->handleWidth(), splitter->handleWidth()); |
261 | QCOMPARE(splitter2->opaqueResize(), splitter->opaqueResize()); |
262 | QCOMPARE(splitter2->childrenCollapsible(), splitter->childrenCollapsible()); |
263 | |
264 | QList<int> l1 = splitter->sizes(); |
265 | QList<int> l2 = splitter2->sizes(); |
266 | QCOMPARE(l1.size(), l2.size()); |
267 | for (int i = 0; i < splitter->sizes().size(); ++i) { |
268 | QCOMPARE(l2.at(i), l1.at(i)); |
269 | } |
270 | |
271 | // destroy version and magic number |
272 | for (int i = 0; i < ba.size(); ++i) |
273 | ba[i] = ~ba.at(i); |
274 | QVERIFY(!splitter2->restoreState(ba)); |
275 | |
276 | delete splitter2; |
277 | } |
278 | |
279 | void tst_QSplitter::saveAndRestoreStateOfNotYetShownSplitter() |
280 | { |
281 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
282 | QSKIP("Wayland: This fails. Figure out why." ); |
283 | |
284 | QSplitter *spl = new QSplitter; |
285 | QLabel *l1 = new QLabel; |
286 | QLabel *l2 = new QLabel; |
287 | spl->addWidget(widget: l1); |
288 | spl->addWidget(widget: l2); |
289 | |
290 | QByteArray ba = spl->saveState(); |
291 | spl->restoreState(state: ba); |
292 | spl->show(); |
293 | QVERIFY(QTest::qWaitForWindowActive(spl)); |
294 | |
295 | QCOMPARE(l1->geometry().isValid(), true); |
296 | QCOMPARE(l2->geometry().isValid(), true); |
297 | |
298 | delete spl; |
299 | } |
300 | |
301 | class TestSplitterStyle : public QProxyStyle |
302 | { |
303 | public: |
304 | TestSplitterStyle() : handleWidth(5) {} |
305 | int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const override |
306 | { |
307 | if (metric == QStyle::PM_SplitterWidth) |
308 | return handleWidth; |
309 | else |
310 | return QProxyStyle::pixelMetric(metric, option, widget); |
311 | } |
312 | int handleWidth; |
313 | }; |
314 | |
315 | void tst_QSplitter::saveAndRestoreHandleWidth() |
316 | { |
317 | TestSplitterStyle style; |
318 | style.handleWidth = 5; |
319 | QSplitter spl; |
320 | spl.setStyle(&style); |
321 | |
322 | QCOMPARE(spl.handleWidth(), style.handleWidth); |
323 | style.handleWidth = 10; |
324 | QCOMPARE(spl.handleWidth(), style.handleWidth); |
325 | QByteArray ba = spl.saveState(); |
326 | spl.setHandleWidth(20); |
327 | QCOMPARE(spl.handleWidth(), 20); |
328 | spl.setHandleWidth(-1); |
329 | QCOMPARE(spl.handleWidth(), style.handleWidth); |
330 | spl.setHandleWidth(15); |
331 | QCOMPARE(spl.handleWidth(), 15); |
332 | spl.restoreState(state: ba); |
333 | QCOMPARE(spl.handleWidth(), style.handleWidth); |
334 | } |
335 | |
336 | void tst_QSplitter::saveState_data() |
337 | { |
338 | QTest::addColumn<IntList>(name: "initialSizes" ); |
339 | QTest::addColumn<bool>(name: "hideWidget1" ); |
340 | QTest::addColumn<bool>(name: "hideWidget2" ); |
341 | QTest::addColumn<QByteArray>(name: "finalBa" ); |
342 | |
343 | QTest::newRow(dataTag: "ok0" ) << (IntList() << 200 << 200) << bool(false) << bool(false) << QByteArray("[200,200]" ); |
344 | QTest::newRow(dataTag: "ok1" ) << (IntList() << 300 << 100) << bool(false) << bool(false) << QByteArray("[300,100]" ); |
345 | QTest::newRow(dataTag: "ok2" ) << (IntList() << 100 << 300) << bool(false) << bool(false) << QByteArray("[100,300]" ); |
346 | QTest::newRow(dataTag: "ok3" ) << (IntList() << 200 << 200) << bool(false) << bool(true) << QByteArray("[200,H]" ); |
347 | QTest::newRow(dataTag: "ok4" ) << (IntList() << 200 << 200) << bool(true) << bool(false) << QByteArray("[H,200]" ); |
348 | QTest::newRow(dataTag: "ok5" ) << (IntList() << 200 << 200) << bool(false) << bool(false) << QByteArray("[200,200]" ); |
349 | QTest::newRow(dataTag: "ok6" ) << (IntList() << 200 << 200) << bool(false) << bool(false) << QByteArray("[200,200]" ); |
350 | QTest::newRow(dataTag: "ok7" ) << (IntList() << 200 << 200) << bool(false) << bool(false) << QByteArray("[200,200]" ); |
351 | QTest::newRow(dataTag: "ok8" ) << (IntList() << 200 << 200) << bool(true) << bool(true) << QByteArray("[H,H]" ); |
352 | } |
353 | |
354 | void tst_QSplitter::addWidget() |
355 | { |
356 | QSplitter split; |
357 | |
358 | // Simple case |
359 | QWidget *widget1 = new QWidget; |
360 | QWidget *widget2 = new QWidget; |
361 | split.addWidget(widget: widget1); |
362 | split.addWidget(widget: widget2); |
363 | QCOMPARE(split.count(), 2); |
364 | QCOMPARE(split.indexOf(widget1), 0); |
365 | QCOMPARE(split.indexOf(widget2), 1); |
366 | QCOMPARE(split.widget(0), widget1); |
367 | QCOMPARE(split.widget(1), widget2); |
368 | |
369 | |
370 | // Implicit Add |
371 | QWidget *widget3 = new QWidget(&split); |
372 | QCOMPARE(split.count(), 3); |
373 | QCOMPARE(split.indexOf(widget3), 2); |
374 | QCOMPARE(split.widget(2), widget3); |
375 | |
376 | // Try and add it again |
377 | split.addWidget(widget: widget3); |
378 | QCOMPARE(split.count(), 3); |
379 | QCOMPARE(split.indexOf(widget3), 2); |
380 | QCOMPARE(split.widget(2), widget3); |
381 | |
382 | // Add a widget that is already in the splitter |
383 | split.addWidget(widget: widget1); |
384 | QCOMPARE(split.count(), 3); |
385 | QCOMPARE(split.indexOf(widget1), 2); |
386 | QCOMPARE(split.widget(0), widget2); |
387 | QCOMPARE(split.widget(1), widget3); |
388 | QCOMPARE(split.widget(2), widget1); |
389 | |
390 | // Change a widget's parent |
391 | widget2->setParent(0); |
392 | QCOMPARE(split.count(), 2); |
393 | QCOMPARE(split.indexOf(widget2), -1); |
394 | |
395 | |
396 | // Add the widget in again. |
397 | split.addWidget(widget: widget2); |
398 | QCOMPARE(split.count(), 3); |
399 | QCOMPARE(split.indexOf(widget2), 2); |
400 | QCOMPARE(split.widget(0), widget3); |
401 | QCOMPARE(split.widget(1), widget1); |
402 | QCOMPARE(split.widget(2), widget2); |
403 | |
404 | // Delete a widget |
405 | delete widget1; |
406 | QCOMPARE(split.count(), 2); |
407 | QCOMPARE(split.indexOf(widget1), -1); // Nasty |
408 | QCOMPARE(split.widget(0), widget3); |
409 | QCOMPARE(split.widget(1), widget2); |
410 | |
411 | delete widget2; |
412 | } |
413 | |
414 | void tst_QSplitter::insertWidget() |
415 | { |
416 | QSplitter split; |
417 | QWidget *widget1 = new QWidget; |
418 | QWidget *widget2 = new QWidget; |
419 | QWidget *widget3 = new QWidget; |
420 | |
421 | split.insertWidget(index: 0, widget: widget1); |
422 | QCOMPARE(split.count(), 1); |
423 | QCOMPARE(split.indexOf(widget1), 0); |
424 | QCOMPARE(split.widget(0), widget1); |
425 | |
426 | split.insertWidget(index: 0, widget: widget2); |
427 | QCOMPARE(split.count(), 2); |
428 | QCOMPARE(split.indexOf(widget1), 1); |
429 | QCOMPARE(split.indexOf(widget2), 0); |
430 | QCOMPARE(split.widget(0), widget2); |
431 | QCOMPARE(split.widget(1), widget1); |
432 | |
433 | split.insertWidget(index: 1, widget: widget3); |
434 | QCOMPARE(split.count(), 3); |
435 | QCOMPARE(split.indexOf(widget1), 2); |
436 | QCOMPARE(split.indexOf(widget2), 0); |
437 | QCOMPARE(split.indexOf(widget3), 1); |
438 | QCOMPARE(split.widget(0), widget2); |
439 | QCOMPARE(split.widget(1), widget3); |
440 | QCOMPARE(split.widget(2), widget1); |
441 | |
442 | delete widget3; |
443 | QCOMPARE(split.count(), 2); |
444 | QCOMPARE(split.indexOf(widget1), 1); |
445 | QCOMPARE(split.indexOf(widget2), 0); |
446 | QCOMPARE(split.widget(0), widget2); |
447 | QCOMPARE(split.widget(1), widget1); |
448 | |
449 | widget3 = new QWidget; |
450 | split.insertWidget(index: split.count() + 1, widget: widget3); |
451 | QCOMPARE(split.count(), 3); |
452 | QCOMPARE(split.indexOf(widget1), 1); |
453 | QCOMPARE(split.indexOf(widget2), 0); |
454 | QCOMPARE(split.indexOf(widget3), 2); |
455 | QCOMPARE(split.widget(0), widget2); |
456 | QCOMPARE(split.widget(1), widget1); |
457 | QCOMPARE(split.widget(2), widget3); |
458 | |
459 | |
460 | // Try it again, |
461 | split.insertWidget(index: split.count() + 1, widget: widget3); |
462 | QCOMPARE(split.count(), 3); |
463 | QCOMPARE(split.indexOf(widget1), 1); |
464 | QCOMPARE(split.indexOf(widget2), 0); |
465 | QCOMPARE(split.indexOf(widget3), 2); |
466 | QCOMPARE(split.widget(0), widget2); |
467 | QCOMPARE(split.widget(1), widget1); |
468 | QCOMPARE(split.widget(2), widget3); |
469 | |
470 | // Try to move widget2 to a bad place |
471 | split.insertWidget(index: -1, widget: widget2); |
472 | QCOMPARE(split.count(), 3); |
473 | QCOMPARE(split.indexOf(widget1), 0); |
474 | QCOMPARE(split.indexOf(widget2), 2); |
475 | QCOMPARE(split.indexOf(widget3), 1); |
476 | QCOMPARE(split.widget(0), widget1); |
477 | QCOMPARE(split.widget(1), widget3); |
478 | QCOMPARE(split.widget(2), widget2); |
479 | |
480 | QWidget *widget4 = new QWidget(&split); |
481 | QCOMPARE(split.count(), 4); |
482 | QCOMPARE(split.indexOf(widget1), 0); |
483 | QCOMPARE(split.indexOf(widget2), 2); |
484 | QCOMPARE(split.indexOf(widget3), 1); |
485 | QCOMPARE(split.indexOf(widget4), 3); |
486 | QCOMPARE(split.widget(0), widget1); |
487 | QCOMPARE(split.widget(1), widget3); |
488 | QCOMPARE(split.widget(2), widget2); |
489 | QCOMPARE(split.widget(3), widget4); |
490 | |
491 | QWidget *widget5 = new QWidget(&split); |
492 | QCOMPARE(split.count(), 5); |
493 | QCOMPARE(split.indexOf(widget1), 0); |
494 | QCOMPARE(split.indexOf(widget2), 2); |
495 | QCOMPARE(split.indexOf(widget3), 1); |
496 | QCOMPARE(split.indexOf(widget4), 3); |
497 | QCOMPARE(split.indexOf(widget5), 4); |
498 | QCOMPARE(split.widget(0), widget1); |
499 | QCOMPARE(split.widget(1), widget3); |
500 | QCOMPARE(split.widget(2), widget2); |
501 | QCOMPARE(split.widget(3), widget4); |
502 | QCOMPARE(split.widget(4), widget5); |
503 | |
504 | split.insertWidget(index: 2, widget: widget4); |
505 | QCOMPARE(split.count(), 5); |
506 | QCOMPARE(split.indexOf(widget1), 0); |
507 | QCOMPARE(split.indexOf(widget2), 3); |
508 | QCOMPARE(split.indexOf(widget3), 1); |
509 | QCOMPARE(split.indexOf(widget4), 2); |
510 | QCOMPARE(split.indexOf(widget5), 4); |
511 | QCOMPARE(split.widget(0), widget1); |
512 | QCOMPARE(split.widget(1), widget3); |
513 | QCOMPARE(split.widget(2), widget4); |
514 | QCOMPARE(split.widget(3), widget2); |
515 | QCOMPARE(split.widget(4), widget5); |
516 | |
517 | split.insertWidget(index: 1, widget: widget5); |
518 | QCOMPARE(split.count(), 5); |
519 | QCOMPARE(split.indexOf(widget1), 0); |
520 | QCOMPARE(split.indexOf(widget2), 4); |
521 | QCOMPARE(split.indexOf(widget3), 2); |
522 | QCOMPARE(split.indexOf(widget4), 3); |
523 | QCOMPARE(split.indexOf(widget5), 1); |
524 | QCOMPARE(split.widget(0), widget1); |
525 | QCOMPARE(split.widget(1), widget5); |
526 | QCOMPARE(split.widget(2), widget3); |
527 | QCOMPARE(split.widget(3), widget4); |
528 | QCOMPARE(split.widget(4), widget2); |
529 | } |
530 | |
531 | void tst_QSplitter::setStretchFactor_data() |
532 | { |
533 | QTest::addColumn<int>(name: "orientation" ); |
534 | QTest::addColumn<int>(name: "widgetIndex" ); |
535 | QTest::addColumn<int>(name: "stretchFactor" ); |
536 | QTest::addColumn<int>(name: "expectedHStretch" ); |
537 | QTest::addColumn<int>(name: "expectedVStretch" ); |
538 | |
539 | QTest::newRow(dataTag: "ok01" ) << int(Qt::Horizontal) << 1 << 2 << 2 << 2; |
540 | QTest::newRow(dataTag: "ok02" ) << int(Qt::Horizontal) << 2 << 0 << 0 << 0; |
541 | QTest::newRow(dataTag: "ok03" ) << int(Qt::Horizontal) << 3 << 1 << 1 << 1; |
542 | QTest::newRow(dataTag: "ok04" ) << int(Qt::Horizontal) << 0 << 7 << 7 << 7; |
543 | QTest::newRow(dataTag: "ok05" ) << int(Qt::Vertical) << 0 << 0 << 0 << 0; |
544 | QTest::newRow(dataTag: "ok06" ) << int(Qt::Vertical) << 1 << 1 << 1 << 1; |
545 | QTest::newRow(dataTag: "ok07" ) << int(Qt::Vertical) << 2 << 2 << 2 << 2; |
546 | QTest::newRow(dataTag: "ok08" ) << int(Qt::Vertical) << 3 << 5 << 5 << 5; |
547 | QTest::newRow(dataTag: "ok09" ) << int(Qt::Vertical) << -1 << 5 << 0 << 0; |
548 | } |
549 | |
550 | void tst_QSplitter::setStretchFactor() |
551 | { |
552 | QFETCH(int, orientation); |
553 | Qt::Orientation orient = Qt::Orientation(orientation); |
554 | QSplitter split(orient); |
555 | QWidget *w = new QWidget; |
556 | split.addWidget(widget: w); |
557 | w = new QWidget; |
558 | split.addWidget(widget: w); |
559 | w = new QWidget; |
560 | split.addWidget(widget: w); |
561 | w = new QWidget; |
562 | split.addWidget(widget: w); |
563 | |
564 | QFETCH(int, widgetIndex); |
565 | QFETCH(int, stretchFactor); |
566 | w = split.widget(index: widgetIndex); |
567 | QSizePolicy sp; |
568 | if (w) { |
569 | QCOMPARE(sp.horizontalStretch(), 0); |
570 | QCOMPARE(sp.verticalStretch(), 0); |
571 | } |
572 | split.setStretchFactor(index: widgetIndex, stretch: stretchFactor); |
573 | if (w) |
574 | sp = w->sizePolicy(); |
575 | QTEST(sp.horizontalStretch(), "expectedHStretch" ); |
576 | QTEST(sp.verticalStretch(), "expectedVStretch" ); |
577 | } |
578 | |
579 | void tst_QSplitter::testShowHide_data() |
580 | { |
581 | QTest::addColumn<bool>(name: "hideWidget1" ); |
582 | QTest::addColumn<bool>(name: "hideWidget2" ); |
583 | QTest::addColumn<QList<int> >(name: "finalValues" ); |
584 | QTest::addColumn<bool>(name: "handleVisible" ); |
585 | |
586 | QSplitter *split = new QSplitter(Qt::Horizontal); |
587 | QTest::newRow(dataTag: "hideNone" ) << false << false << (QList<int>() << 200 << 200) << true; |
588 | QTest::newRow(dataTag: "hide2" ) << false << true << (QList<int>() << 400 + split->handleWidth() << 0) << false; |
589 | QTest::newRow(dataTag: "hide1" ) << true << false << (QList<int>() << 0 << 400 + split->handleWidth()) << false; |
590 | QTest::newRow(dataTag: "hideall" ) << true << true << (QList<int>() << 0 << 0) << false; |
591 | delete split; |
592 | } |
593 | |
594 | void tst_QSplitter::testShowHide() |
595 | { |
596 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
597 | QSKIP("Wayland: This fails. Figure out why." ); |
598 | |
599 | QFETCH(bool, hideWidget1); |
600 | QFETCH(bool, hideWidget2); |
601 | |
602 | QSplitter *split = new QSplitter(Qt::Horizontal); |
603 | |
604 | QWidget topLevel; |
605 | QWidget widget(&topLevel); |
606 | widget.resize(w: 400 + split->handleWidth(), h: 200); |
607 | QVBoxLayout *lay=new QVBoxLayout(&widget); |
608 | lay->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0); |
609 | lay->setSpacing(0); |
610 | split->addWidget(widget: new QWidget); |
611 | split->addWidget(widget: new QWidget); |
612 | split->setSizes(QList<int>() << 200 << 200); |
613 | lay->addWidget(split); |
614 | widget.setLayout(lay); |
615 | topLevel.show(); |
616 | QVERIFY(QTest::qWaitForWindowActive(&topLevel)); |
617 | |
618 | widget.hide(); |
619 | split->widget(index: 0)->setHidden(hideWidget1); |
620 | split->widget(index: 1)->setHidden(hideWidget2); |
621 | widget.show(); |
622 | QTest::qWait(ms: 100); |
623 | |
624 | QTEST(split->sizes(), "finalValues" ); |
625 | QTEST(split->handle(1)->isVisible(), "handleVisible" ); |
626 | } |
627 | |
628 | void tst_QSplitter::testRemoval() |
629 | { |
630 | |
631 | // This test relies on the internal structure of QSplitter That is, that |
632 | // there is a handle before every splitter, but sometimes that handle is |
633 | // hidden. But definiately when something is removed the front handle |
634 | // should not be visible. |
635 | |
636 | QSplitter split; |
637 | split.addWidget(widget: new QWidget); |
638 | split.addWidget(widget: new QWidget); |
639 | split.show(); |
640 | QTest::qWait(ms: 100); |
641 | |
642 | QCOMPARE(split.handle(0)->isVisible(), false); |
643 | QSplitterHandle *handle = split.handle(index: 1); |
644 | QCOMPARE(handle->isVisible(), true); |
645 | |
646 | delete split.widget(index: 0); |
647 | QSplitterHandle *sameHandle = split.handle(index: 0); |
648 | QCOMPARE(handle, sameHandle); |
649 | QCOMPARE(sameHandle->isVisible(), false); |
650 | } |
651 | |
652 | class MyFriendlySplitter : public QSplitter |
653 | { |
654 | public: |
655 | MyFriendlySplitter(QWidget *parent = 0) : QSplitter(parent) {} |
656 | void setRubberBand(int pos) { QSplitter::setRubberBand(pos); } |
657 | |
658 | void moveSplitter(int pos, int index) { QSplitter::moveSplitter(pos, index); } |
659 | |
660 | friend class tst_QSplitter; |
661 | }; |
662 | |
663 | class EventCounterSpy : public QObject |
664 | { |
665 | public: |
666 | EventCounterSpy(QWidget *obj) : objectToWatch(obj) |
667 | { } |
668 | |
669 | ~EventCounterSpy() |
670 | { |
671 | removeEventFilter(); |
672 | } |
673 | |
674 | void installEventFilter() |
675 | { |
676 | if (needRemoveEventFilter) |
677 | return; |
678 | needRemoveEventFilter = true; |
679 | qApp->installEventFilter(filterObj: this); |
680 | } |
681 | |
682 | void removeEventFilter() |
683 | { |
684 | if (!needRemoveEventFilter) |
685 | return; |
686 | needRemoveEventFilter = false; |
687 | qApp->removeEventFilter(obj: this); |
688 | } |
689 | |
690 | bool eventFilter(QObject *watched, QEvent *event) override |
691 | { |
692 | // Watch for events in the parent widget and all its children |
693 | if (watched == objectToWatch || watched->parent() == objectToWatch) { |
694 | if (event->type() == QEvent::Resize) |
695 | resizeCount++; |
696 | else if (event->type() == QEvent::Paint) |
697 | paintCount++; |
698 | } |
699 | |
700 | return QObject::eventFilter(watched, event); |
701 | } |
702 | |
703 | int resizeCount = 0; |
704 | int paintCount = 0; |
705 | bool needRemoveEventFilter = false; |
706 | QObject *objectToWatch; |
707 | }; |
708 | |
709 | void tst_QSplitter::replaceWidget_data() |
710 | { |
711 | QTest::addColumn<int>(name: "index" ); |
712 | QTest::addColumn<bool>(name: "visible" ); |
713 | QTest::addColumn<bool>(name: "collapsed" ); |
714 | |
715 | QTest::newRow(dataTag: "negative index" ) << -1 << true << false; |
716 | QTest::newRow(dataTag: "index too large" ) << 80 << true << false; |
717 | QTest::newRow(dataTag: "visible, not collapsed" ) << 3 << true << false; |
718 | QTest::newRow(dataTag: "visible, collapsed" ) << 3 << true << true; |
719 | QTest::newRow(dataTag: "not visible, not collapsed" ) << 3 << false << false; |
720 | QTest::newRow(dataTag: "not visible, collapsed" ) << 3 << false << true; |
721 | } |
722 | |
723 | void tst_QSplitter::replaceWidget() |
724 | { |
725 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
726 | QSKIP("Wayland: This fails. Figure out why." ); |
727 | |
728 | QFETCH(int, index); |
729 | QFETCH(bool, visible); |
730 | QFETCH(bool, collapsed); |
731 | |
732 | // Setup |
733 | MyFriendlySplitter sp; |
734 | const int count = 7; |
735 | for (int i = 0; i < count; i++) { |
736 | // We use labels instead of plain widgets to |
737 | // make it easier to fix eventual regressions. |
738 | QLabel *w = new QLabel(QString::asprintf(format: "WIDGET #%d" , i)); |
739 | sp.addWidget(widget: w); |
740 | } |
741 | sp.setWindowTitle(QString::asprintf(format: "index %d, visible %d, collapsed %d" , index, visible, collapsed)); |
742 | sp.show(); |
743 | QVERIFY(QTest::qWaitForWindowExposed(&sp)); |
744 | |
745 | // Configure splitter |
746 | QWidget *oldWidget = sp.widget(index); |
747 | QTest::qWait(ms: 100); // Make sure we record the right original size (after the window manager adds the frame) |
748 | const QRect oldGeom = oldWidget ? oldWidget->geometry() : QRect(); |
749 | if (oldWidget) { |
750 | // Collapse first, then hide, if necessary |
751 | if (collapsed) { |
752 | sp.setCollapsible(index, true); |
753 | sp.moveSplitter(pos: oldWidget->x() + 1, index: index + 1); |
754 | } |
755 | if (!visible) |
756 | oldWidget->hide(); |
757 | } |
758 | |
759 | // Replace widget |
760 | QTest::qWait(ms: 100); // Flush event queue |
761 | const QList<int> sizes = sp.sizes(); |
762 | // Shorter label: The important thing is to ensure we can set |
763 | // the same size on the new widget. Because of QLabel's sizing |
764 | // constraints (they can expand but not shrink) the easiest is |
765 | // to set a shorter label. |
766 | QLabel *newWidget = new QLabel(QLatin1String("<b>NEW</b>" )); |
767 | |
768 | EventCounterSpy ef(&sp); |
769 | ef.installEventFilter(); |
770 | const QWidget *res = sp.replaceWidget(index, widget: newWidget); |
771 | QTest::qWait(ms: 100); // Give visibility and resizing some time |
772 | |
773 | // Check |
774 | if (index < 0 || index >= count) { |
775 | QVERIFY(!res); |
776 | QVERIFY(!newWidget->parentWidget()); |
777 | QCOMPARE(ef.resizeCount, 0); |
778 | QCOMPARE(ef.paintCount, 0); |
779 | } else { |
780 | QCOMPARE(res, oldWidget); |
781 | QVERIFY(!res->parentWidget()); |
782 | QVERIFY(!res->isVisible()); |
783 | const int expectedResizeCount = visible ? 1 : 0; // new widget only |
784 | const int expectedPaintCount = visible && !collapsed ? 2 : 0; // splitter and new widget |
785 | QTRY_COMPARE(ef.resizeCount, expectedResizeCount); |
786 | #ifndef Q_OS_WINRT // QTBUG-68297 |
787 | QTRY_COMPARE(ef.paintCount, expectedPaintCount); |
788 | #endif |
789 | QCOMPARE(newWidget->parentWidget(), &sp); |
790 | QCOMPARE(newWidget->isVisible(), visible); |
791 | if (visible && !collapsed) |
792 | QCOMPARE(newWidget->geometry(), oldGeom); |
793 | #ifndef Q_OS_WINRT // QTBUG-68297 |
794 | QCOMPARE(newWidget->size().isEmpty(), !visible || collapsed); |
795 | #endif |
796 | delete res; |
797 | } |
798 | QCOMPARE(sp.count(), count); |
799 | QCOMPARE(sp.sizes(), sizes); |
800 | } |
801 | |
802 | void tst_QSplitter::replaceWidgetWithSplitterChild_data() |
803 | { |
804 | QTest::addColumn<int>(name: "srcIndex" ); |
805 | QTest::addColumn<int>(name: "dstIndex" ); |
806 | |
807 | QTest::newRow(dataTag: "replace with null widget" ) << -2 << 3; |
808 | QTest::newRow(dataTag: "replace with itself" ) << 3 << 3; |
809 | QTest::newRow(dataTag: "replace with sibling, after recalc" ) << 1 << 4; |
810 | QTest::newRow(dataTag: "replace with sibling, before recalc" ) << -1 << 4; |
811 | } |
812 | |
813 | void tst_QSplitter::replaceWidgetWithSplitterChild() |
814 | { |
815 | QFETCH(int, srcIndex); |
816 | QFETCH(int, dstIndex); |
817 | |
818 | // Setup |
819 | MyFriendlySplitter sp; |
820 | const int count = 7; |
821 | for (int i = 0; i < count; i++) { |
822 | // We use labels instead of plain widgets to |
823 | // make it easier to fix eventual regressions. |
824 | QLabel *w = new QLabel(QString::asprintf(format: "WIDGET #%d" , i)); |
825 | sp.addWidget(widget: w); |
826 | } |
827 | sp.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); |
828 | sp.show(); |
829 | QVERIFY(QTest::qWaitForWindowExposed(&sp)); |
830 | |
831 | QTest::qWait(ms: 100); // Flush event queue before new widget creation |
832 | const QList<int> sizes = sp.sizes(); |
833 | QWidget *sibling = srcIndex == -1 ? (new QLabel("<b>NEW</b>" , &sp)) : sp.widget(index: srcIndex); |
834 | |
835 | EventCounterSpy ef(&sp); |
836 | ef.installEventFilter(); |
837 | const QWidget *res = sp.replaceWidget(index: dstIndex, widget: sibling); |
838 | QTest::qWait(ms: 100); // Give visibility and resizing some time |
839 | |
840 | QVERIFY(!res); |
841 | if (srcIndex == -1) { |
842 | // Create and replace before recalc. The sibling is scheduled to be |
843 | // added after replaceWidget(), when QSplitter receives a child event. |
844 | QTRY_VERIFY(ef.resizeCount > 0); |
845 | QTRY_VERIFY(ef.paintCount > 0); |
846 | QCOMPARE(sp.count(), count + 1); |
847 | #ifndef Q_OS_WINRT // QTBUG-68297 |
848 | QCOMPARE(sp.sizes().mid(0, count), sizes); |
849 | #endif |
850 | QCOMPARE(sp.sizes().last(), sibling->width()); |
851 | } else { |
852 | // No-op for the rest |
853 | QCOMPARE(ef.resizeCount, 0); |
854 | QCOMPARE(ef.paintCount, 0); |
855 | QCOMPARE(sp.count(), count); |
856 | QCOMPARE(sp.sizes(), sizes); |
857 | } |
858 | } |
859 | |
860 | void tst_QSplitter::handleMinimumWidth() |
861 | { |
862 | MyFriendlySplitter split; |
863 | split.addWidget(widget: new QLabel("Number Wan" )); |
864 | split.addWidget(widget: new QLabel("Number Too" )); |
865 | |
866 | split.show(); |
867 | QVERIFY(QTest::qWaitForWindowExposed(&split)); |
868 | for (int i = 0; i < 10; i++) { |
869 | split.setHandleWidth(i); |
870 | QTest::qWait(ms: 100); // resizing |
871 | QCOMPARE(split.handle(1)->width(), qMax(4 + (i & 1), i)); |
872 | } |
873 | |
874 | split.setOrientation(Qt::Vertical); |
875 | QTest::qWait(ms: 100); |
876 | for (int i = 0; i < 10; i++) { |
877 | split.setHandleWidth(i); |
878 | QTest::qWait(ms: 100); // resizing |
879 | QCOMPARE(split.handle(1)->height(), qMax(4 + (i & 1), i)); |
880 | } |
881 | } |
882 | |
883 | void tst_QSplitter::rubberBandNotInSplitter() |
884 | { |
885 | MyFriendlySplitter split; |
886 | split.addWidget(widget: new QWidget); |
887 | split.addWidget(widget: new QWidget); |
888 | split.setOpaqueResize(false); |
889 | QCOMPARE(split.count(), 2); |
890 | split.setRubberBand(2); |
891 | QCOMPARE(split.count(), 2); |
892 | } |
893 | |
894 | void tst_QSplitter::task187373_addAbstractScrollAreas_data() |
895 | { |
896 | QTest::addColumn<QString>(name: "className" ); |
897 | QTest::addColumn<bool>(name: "addInConstructor" ); |
898 | QTest::addColumn<bool>(name: "addOutsideConstructor" ); |
899 | |
900 | QStringList classNames; |
901 | classNames << QLatin1String("QGraphicsView" ); |
902 | classNames << QLatin1String("QMdiArea" ); |
903 | classNames << QLatin1String("QScrollArea" ); |
904 | classNames << QLatin1String("QTextEdit" ); |
905 | classNames << QLatin1String("QTreeView" ); |
906 | |
907 | foreach (QString className, classNames) { |
908 | QTest::newRow(qPrintable(className + QLatin1String(" 1" ))) << className << false << true; |
909 | QTest::newRow(qPrintable(className + QLatin1String(" 2" ))) << className << true << false; |
910 | QTest::newRow(qPrintable(className + QLatin1String(" 3" ))) << className << true << true; |
911 | } |
912 | } |
913 | |
914 | static QAbstractScrollArea *task187373_createScrollArea( |
915 | QSplitter *splitter, const QString &className, bool addInConstructor) |
916 | { |
917 | if (className == QLatin1String("QGraphicsView" )) |
918 | return new QGraphicsView(addInConstructor ? splitter : 0); |
919 | if (className == QLatin1String("QMdiArea" )) |
920 | return new QMdiArea(addInConstructor ? splitter : 0); |
921 | if (className == QLatin1String("QScrollArea" )) |
922 | return new QScrollArea(addInConstructor ? splitter : 0); |
923 | if (className == QLatin1String("QTextEdit" )) |
924 | return new QTextEdit(addInConstructor ? splitter : 0); |
925 | if (className == QLatin1String("QTreeView" )) |
926 | return new QTreeView(addInConstructor ? splitter : 0); |
927 | return 0; |
928 | } |
929 | |
930 | void tst_QSplitter::task187373_addAbstractScrollAreas() |
931 | { |
932 | QFETCH(QString, className); |
933 | QFETCH(bool, addInConstructor); |
934 | QFETCH(bool, addOutsideConstructor); |
935 | QVERIFY(addInConstructor || addOutsideConstructor); |
936 | |
937 | QSplitter *splitter = new QSplitter; |
938 | splitter->show(); |
939 | QVERIFY(splitter->isVisible()); |
940 | |
941 | QAbstractScrollArea *w = task187373_createScrollArea(splitter, className, addInConstructor); |
942 | QVERIFY(w); |
943 | if (addOutsideConstructor) |
944 | splitter->addWidget(widget: w); |
945 | |
946 | QTRY_VERIFY(w->isVisible()); |
947 | QVERIFY(!w->isHidden()); |
948 | QVERIFY(w->viewport()->isVisible()); |
949 | QVERIFY(!w->viewport()->isHidden()); |
950 | } |
951 | |
952 | //! A simple QTextEdit which can switch between two different size states |
953 | class MyTextEdit : public QTextEdit |
954 | { |
955 | public: |
956 | MyTextEdit(const QString & text, QWidget* parent = NULL) |
957 | : QTextEdit(text, parent) , m_iFactor(1) |
958 | { |
959 | setSizePolicy(hor: QSizePolicy::Maximum, ver: QSizePolicy::Maximum); |
960 | } |
961 | virtual QSize minimumSizeHint () const |
962 | { |
963 | return QSize(200, 200) * m_iFactor; |
964 | } |
965 | virtual QSize sizeHint() const |
966 | { |
967 | return QSize(390, 390) * m_iFactor; |
968 | } |
969 | int m_iFactor; |
970 | }; |
971 | |
972 | void tst_QSplitter::task169702_sizes() |
973 | { |
974 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
975 | QSKIP("Wayland: This fails. Figure out why." ); |
976 | |
977 | QWidget topLevel; |
978 | // Create two nested (non-collapsible) splitters |
979 | QSplitter* outerSplitter = new QSplitter(Qt::Vertical, &topLevel); |
980 | outerSplitter->setChildrenCollapsible(false); |
981 | QSplitter* splitter = new QSplitter(Qt::Horizontal, outerSplitter); |
982 | splitter->setChildrenCollapsible(false); |
983 | |
984 | // populate the outer splitter |
985 | outerSplitter->addWidget(widget: new QTextEdit("Foo" )); |
986 | outerSplitter->addWidget(widget: splitter); |
987 | outerSplitter->setStretchFactor(index: 0, stretch: 1); |
988 | outerSplitter->setStretchFactor(index: 1, stretch: 0); |
989 | |
990 | // populate the inner splitter |
991 | MyTextEdit* testW = new MyTextEdit("TextEdit with size restriction" ); |
992 | splitter->addWidget(widget: testW); |
993 | splitter->addWidget(widget: new QTextEdit("Bar" )); |
994 | |
995 | outerSplitter->setGeometry(ax: 100, ay: 100, aw: 500, ah: 500); |
996 | topLevel.show(); |
997 | QVERIFY(QTest::qWaitForWindowActive(&topLevel)); |
998 | |
999 | testW->m_iFactor++; |
1000 | testW->updateGeometry(); |
1001 | |
1002 | //Make sure the minimimSizeHint is respected |
1003 | QTRY_COMPARE(testW->size().height(), testW->minimumSizeHint().height()); |
1004 | } |
1005 | |
1006 | void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget_data() |
1007 | { |
1008 | QTest::addColumn<bool>(name: "testingHide" ); |
1009 | |
1010 | QTest::newRow(dataTag: "last non collapsed hidden" ) << true; |
1011 | QTest::newRow(dataTag: "last non collapsed deleted" ) << false; |
1012 | } |
1013 | |
1014 | void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget() |
1015 | { |
1016 | QFETCH(bool, testingHide); |
1017 | |
1018 | MyFriendlySplitter s; |
1019 | QLabel *l; |
1020 | for (int i = 0; i < 5; ++i) { |
1021 | l = new QLabel(QString("Label " ) + QChar('A' + i)); |
1022 | l->setAlignment(Qt::AlignCenter); |
1023 | s.addWidget(widget: l); |
1024 | s.moveSplitter(pos: 0, index: i); // Collapse all the labels except the last one. |
1025 | } |
1026 | |
1027 | s.show(); |
1028 | if (testingHide) |
1029 | l->hide(); |
1030 | else |
1031 | delete l; |
1032 | QTRY_VERIFY(s.sizes().at(0) > 0); |
1033 | } |
1034 | |
1035 | void tst_QSplitter::setLayout() |
1036 | { |
1037 | QSplitter splitter; |
1038 | QVBoxLayout layout; |
1039 | QTest::ignoreMessage(type: QtWarningMsg, message: "Adding a QLayout to a QSplitter is not supported." ); |
1040 | splitter.setLayout(&layout); |
1041 | // It will work, but we don't recommend it... |
1042 | QCOMPARE(splitter.layout(), &layout); |
1043 | } |
1044 | |
1045 | void tst_QSplitter::autoAdd() |
1046 | { |
1047 | QSplitter splitter; |
1048 | splitter.setWindowTitle("autoAdd" ); |
1049 | splitter.setMinimumSize(QSize(200, 200)); |
1050 | splitter.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100)); |
1051 | splitter.show(); |
1052 | QVERIFY(QTest::qWaitForWindowExposed(&splitter)); |
1053 | // Constructing a child widget on the splitter should |
1054 | // automatically add and show it. |
1055 | QWidget *childWidget = new QWidget(&splitter); |
1056 | QCOMPARE(splitter.count(), 1); |
1057 | QTRY_VERIFY(childWidget->isVisible()); |
1058 | // Deleting should automatically remove it |
1059 | delete childWidget; |
1060 | QCOMPARE(splitter.count(), 0); |
1061 | // QTBUG-40132, top level windows should not be affected by this. |
1062 | QDialog *dialog = new QDialog(&splitter); |
1063 | QCOMPARE(splitter.count(), 0); |
1064 | QCoreApplication::processEvents(); |
1065 | QVERIFY(!dialog->isVisible()); |
1066 | } |
1067 | |
1068 | QTEST_MAIN(tst_QSplitter) |
1069 | #include "tst_qsplitter.moc" |
1070 | |