|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the test suite of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 |
|
43 #include <QtTest/QtTest> |
|
44 #include <QtGui> |
|
45 #include "../../shared/util.h" |
|
46 #include <private/qlayoutengine_p.h> // qSmartMin functions... |
|
47 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) |
|
48 #include <QMacStyle> |
|
49 #endif |
|
50 #ifdef Q_WS_X11 |
|
51 #include <private/qt_x11_p.h> |
|
52 #endif |
|
53 |
|
54 static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton) |
|
55 { |
|
56 QMouseEvent event(QEvent::MouseMove, point, widget->mapToGlobal(point), button, button, 0); |
|
57 QApplication::sendEvent(widget, &event); |
|
58 } |
|
59 |
|
60 |
|
61 #ifndef QT_NO_STYLE_CLEANLOOKS |
|
62 /* |
|
63 Notes: |
|
64 |
|
65 1) The proxy and the widget geometries are linked. |
|
66 proxy resize => widget resize => stop (no livelock) |
|
67 widget resize => proxy resize => stop (no livelock) |
|
68 |
|
69 2) As far as possible, the properties are linked. |
|
70 proxy enable => widget enable => stop |
|
71 widget disabled => proxy disabled => stop |
|
72 |
|
73 3) Windowed state is linked |
|
74 Windowed proxy state => windowed widget state => stop |
|
75 Windowed widget state => windowed proxy state => stop |
|
76 */ |
|
77 |
|
78 class EventSpy : public QObject |
|
79 { |
|
80 public: |
|
81 EventSpy(QObject *receiver) |
|
82 { |
|
83 receiver->installEventFilter(this); |
|
84 } |
|
85 |
|
86 QMap<QEvent::Type, int> counts; |
|
87 |
|
88 protected: |
|
89 bool eventFilter(QObject *, QEvent *event) |
|
90 { |
|
91 ++counts[event->type()]; |
|
92 return false; |
|
93 } |
|
94 }; |
|
95 |
|
96 class tst_QGraphicsProxyWidget : public QObject |
|
97 { |
|
98 Q_OBJECT |
|
99 |
|
100 public slots: |
|
101 void initTestCase(); |
|
102 void cleanupTestCase(); |
|
103 void init(); |
|
104 void cleanup(); |
|
105 |
|
106 private slots: |
|
107 void qgraphicsproxywidget_data(); |
|
108 void qgraphicsproxywidget(); |
|
109 void paint(); |
|
110 void paint_2(); |
|
111 void setWidget_data(); |
|
112 void setWidget(); |
|
113 void eventFilter_data(); |
|
114 void eventFilter(); |
|
115 void focusInEvent_data(); |
|
116 void focusInEvent(); |
|
117 void focusInEventNoWidget(); |
|
118 void focusNextPrevChild_data(); |
|
119 void focusNextPrevChild(); |
|
120 void focusOutEvent_data(); |
|
121 void focusOutEvent(); |
|
122 void hoverEnterLeaveEvent_data(); |
|
123 void hoverEnterLeaveEvent(); |
|
124 void hoverMoveEvent_data(); |
|
125 void hoverMoveEvent(); |
|
126 void keyPressEvent_data(); |
|
127 void keyPressEvent(); |
|
128 void keyReleaseEvent_data(); |
|
129 void keyReleaseEvent(); |
|
130 void mouseDoubleClickEvent_data(); |
|
131 void mouseDoubleClickEvent(); |
|
132 void mousePressReleaseEvent_data(); |
|
133 void mousePressReleaseEvent(); |
|
134 void resizeEvent_data(); |
|
135 void resizeEvent(); |
|
136 void paintEvent(); |
|
137 void wheelEvent(); |
|
138 void sizeHint_data(); |
|
139 void sizeHint(); |
|
140 void sizePolicy(); |
|
141 void minimumSize(); |
|
142 void maximumSize(); |
|
143 void scrollUpdate(); |
|
144 void setWidget_simple(); |
|
145 void setWidget_ownership(); |
|
146 void resize_simple_data(); |
|
147 void resize_simple(); |
|
148 void symmetricMove(); |
|
149 void symmetricResize(); |
|
150 void symmetricEnabled(); |
|
151 void symmetricVisible(); |
|
152 void tabFocus_simpleWidget(); |
|
153 void tabFocus_simpleTwoWidgets(); |
|
154 void tabFocus_complexWidget(); |
|
155 void tabFocus_complexTwoWidgets(); |
|
156 void setFocus_simpleWidget(); |
|
157 void setFocus_simpleTwoWidgets(); |
|
158 void setFocus_complexTwoWidgets(); |
|
159 void popup_basic(); |
|
160 void popup_subwidget(); |
|
161 void changingCursor_basic(); |
|
162 void tooltip_basic(); |
|
163 void childPos_data(); |
|
164 void childPos(); |
|
165 void autoShow(); |
|
166 void windowOpacity(); |
|
167 void stylePropagation(); |
|
168 void palettePropagation(); |
|
169 void fontPropagation(); |
|
170 void dontCrashWhenDie(); |
|
171 void createProxyForChildWidget(); |
|
172 void actionsContextMenu(); |
|
173 void actionsContextMenu_data(); |
|
174 void deleteProxyForChildWidget(); |
|
175 void bypassGraphicsProxyWidget_data(); |
|
176 void bypassGraphicsProxyWidget(); |
|
177 void dragDrop(); |
|
178 void windowFlags_data(); |
|
179 void windowFlags(); |
|
180 void comboboxWindowFlags(); |
|
181 void updateAndDelete(); |
|
182 void inputMethod(); |
|
183 void clickFocus(); |
|
184 }; |
|
185 |
|
186 // Subclass that exposes the protected functions. |
|
187 class SubQGraphicsProxyWidget : public QGraphicsProxyWidget |
|
188 { |
|
189 |
|
190 public: |
|
191 SubQGraphicsProxyWidget(QGraphicsItem *parent = 0) : QGraphicsProxyWidget(parent), |
|
192 paintCount(0), keyPress(0), focusOut(0) |
|
193 {} |
|
194 |
|
195 bool call_eventFilter(QObject* object, QEvent* event) |
|
196 { return SubQGraphicsProxyWidget::eventFilter(object, event); } |
|
197 |
|
198 void call_focusInEvent(QFocusEvent* event) |
|
199 { return SubQGraphicsProxyWidget::focusInEvent(event); } |
|
200 |
|
201 bool call_focusNextPrevChild(bool next) |
|
202 { return SubQGraphicsProxyWidget::focusNextPrevChild(next); } |
|
203 |
|
204 void call_focusOutEvent(QFocusEvent* event) |
|
205 { return SubQGraphicsProxyWidget::focusOutEvent(event); } |
|
206 |
|
207 void call_hideEvent(QHideEvent* event) |
|
208 { return SubQGraphicsProxyWidget::hideEvent(event); } |
|
209 |
|
210 void call_hoverEnterEvent(QGraphicsSceneHoverEvent* event) |
|
211 { return SubQGraphicsProxyWidget::hoverEnterEvent(event); } |
|
212 |
|
213 void call_hoverLeaveEvent(QGraphicsSceneHoverEvent* event) |
|
214 { return SubQGraphicsProxyWidget::hoverLeaveEvent(event); } |
|
215 |
|
216 void call_hoverMoveEvent(QGraphicsSceneHoverEvent* event) |
|
217 { return SubQGraphicsProxyWidget::hoverMoveEvent(event); } |
|
218 |
|
219 void call_keyPressEvent(QKeyEvent* event) |
|
220 { return SubQGraphicsProxyWidget::keyPressEvent(event); } |
|
221 |
|
222 void call_keyReleaseEvent(QKeyEvent* event) |
|
223 { return SubQGraphicsProxyWidget::keyReleaseEvent(event); } |
|
224 |
|
225 void call_mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) |
|
226 { return SubQGraphicsProxyWidget::mouseDoubleClickEvent(event); } |
|
227 |
|
228 void call_mouseMoveEvent(QGraphicsSceneMouseEvent* event) |
|
229 { return SubQGraphicsProxyWidget::mouseMoveEvent(event); } |
|
230 |
|
231 void call_mousePressEvent(QGraphicsSceneMouseEvent* event) |
|
232 { return SubQGraphicsProxyWidget::mousePressEvent(event); } |
|
233 |
|
234 void call_mouseReleaseEvent(QGraphicsSceneMouseEvent* event) |
|
235 { return SubQGraphicsProxyWidget::mouseReleaseEvent(event); } |
|
236 |
|
237 void call_resizeEvent(QGraphicsSceneResizeEvent* event) |
|
238 { return SubQGraphicsProxyWidget::resizeEvent(event); } |
|
239 |
|
240 QSizeF call_sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const |
|
241 { return SubQGraphicsProxyWidget::sizeHint(which, constraint); } |
|
242 |
|
243 void call_showEvent(QShowEvent* event) |
|
244 { return SubQGraphicsProxyWidget::showEvent(event); } |
|
245 |
|
246 void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) { |
|
247 paintCount++; |
|
248 QGraphicsProxyWidget::paint(painter, option, widget); |
|
249 } |
|
250 |
|
251 void focusOutEvent(QFocusEvent *event) |
|
252 { |
|
253 focusOut++; |
|
254 QGraphicsProxyWidget::focusOutEvent(event); |
|
255 } |
|
256 |
|
257 bool eventFilter(QObject *object, QEvent *event) { |
|
258 if (event->type() == QEvent::KeyPress && object == widget()) |
|
259 keyPress++; |
|
260 return QGraphicsProxyWidget::eventFilter(object, event); |
|
261 } |
|
262 int paintCount; |
|
263 int keyPress; |
|
264 int focusOut; |
|
265 }; |
|
266 |
|
267 class WheelWidget : public QWidget |
|
268 { |
|
269 public: |
|
270 WheelWidget() : wheelEventCalled(false) { setFocusPolicy(Qt::WheelFocus); } |
|
271 |
|
272 virtual void wheelEvent(QWheelEvent *event) { event->accept(); wheelEventCalled = true; } |
|
273 |
|
274 bool wheelEventCalled; |
|
275 }; |
|
276 |
|
277 // This will be called before the first test function is executed. |
|
278 // It is only called once. |
|
279 void tst_QGraphicsProxyWidget::initTestCase() |
|
280 { |
|
281 #ifdef Q_OS_WINCE //disable magic for WindowsCE |
|
282 qApp->setAutoMaximizeThreshold(-1); |
|
283 #endif |
|
284 } |
|
285 |
|
286 // This will be called after the last test function is executed. |
|
287 // It is only called once. |
|
288 void tst_QGraphicsProxyWidget::cleanupTestCase() |
|
289 { |
|
290 } |
|
291 |
|
292 // This will be called before each test function is executed. |
|
293 void tst_QGraphicsProxyWidget::init() |
|
294 { |
|
295 } |
|
296 |
|
297 // This will be called after every test function. |
|
298 void tst_QGraphicsProxyWidget::cleanup() |
|
299 { |
|
300 } |
|
301 |
|
302 void tst_QGraphicsProxyWidget::qgraphicsproxywidget_data() |
|
303 { |
|
304 } |
|
305 |
|
306 void tst_QGraphicsProxyWidget::qgraphicsproxywidget() |
|
307 { |
|
308 SubQGraphicsProxyWidget proxy; |
|
309 proxy.paint(0, 0, 0); |
|
310 proxy.setWidget(0); |
|
311 QVERIFY(proxy.type() == QGraphicsProxyWidget::Type); |
|
312 QVERIFY(!proxy.widget()); |
|
313 QEvent event(QEvent::None); |
|
314 proxy.call_eventFilter(0, &event); |
|
315 QFocusEvent focusEvent(QEvent::FocusIn); |
|
316 focusEvent.ignore(); |
|
317 proxy.call_focusInEvent(&focusEvent); |
|
318 QCOMPARE(focusEvent.isAccepted(), false); |
|
319 QCOMPARE(proxy.call_focusNextPrevChild(false), false); |
|
320 QCOMPARE(proxy.call_focusNextPrevChild(true), false); |
|
321 proxy.call_focusOutEvent(&focusEvent); |
|
322 QHideEvent hideEvent; |
|
323 proxy.call_hideEvent(&hideEvent); |
|
324 QGraphicsSceneHoverEvent hoverEvent; |
|
325 proxy.call_hoverEnterEvent(&hoverEvent); |
|
326 proxy.call_hoverLeaveEvent(&hoverEvent); |
|
327 proxy.call_hoverMoveEvent(&hoverEvent); |
|
328 QKeyEvent keyEvent(QEvent::KeyPress, 0, Qt::NoModifier); |
|
329 proxy.call_keyPressEvent(&keyEvent); |
|
330 proxy.call_keyReleaseEvent(&keyEvent); |
|
331 QGraphicsSceneMouseEvent mouseEvent; |
|
332 proxy.call_mouseDoubleClickEvent(&mouseEvent); |
|
333 proxy.call_mouseMoveEvent(&mouseEvent); |
|
334 proxy.call_mousePressEvent(&mouseEvent); |
|
335 proxy.call_mouseReleaseEvent(&mouseEvent); |
|
336 QGraphicsSceneResizeEvent resizeEvent; |
|
337 proxy.call_resizeEvent(&resizeEvent); |
|
338 QShowEvent showEvent; |
|
339 proxy.call_showEvent(&showEvent); |
|
340 proxy.call_sizeHint(Qt::PreferredSize, QSizeF()); |
|
341 } |
|
342 |
|
343 // public void paint(QPainter* painter, QStyleOptionGraphicsItem const* option, QWidget* widget) |
|
344 void tst_QGraphicsProxyWidget::paint() |
|
345 { |
|
346 SubQGraphicsProxyWidget proxy; |
|
347 proxy.paint(0, 0, 0); |
|
348 } |
|
349 |
|
350 class MyProxyWidget : public QGraphicsProxyWidget |
|
351 { |
|
352 public: |
|
353 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
354 { |
|
355 // Make sure QGraphicsProxyWidget::paint does not modify the render hints set on the painter. |
|
356 painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform |
|
357 | QPainter::NonCosmeticDefaultPen | QPainter::TextAntialiasing); |
|
358 const QPainter::RenderHints oldRenderHints = painter->renderHints(); |
|
359 QGraphicsProxyWidget::paint(painter, option, widget); |
|
360 QCOMPARE(painter->renderHints(), oldRenderHints); |
|
361 } |
|
362 }; |
|
363 |
|
364 void tst_QGraphicsProxyWidget::paint_2() |
|
365 { |
|
366 MyProxyWidget *proxyWidget = new MyProxyWidget; |
|
367 proxyWidget->setWidget(new QLineEdit); |
|
368 |
|
369 QGraphicsScene scene; |
|
370 scene.addItem(proxyWidget); |
|
371 scene.setSceneRect(scene.itemsBoundingRect()); |
|
372 |
|
373 // Trigger repaint. |
|
374 QPixmap pixmap(scene.sceneRect().toRect().size()); |
|
375 QPainter painter(&pixmap); |
|
376 scene.render(&painter); |
|
377 } |
|
378 |
|
379 void tst_QGraphicsProxyWidget::setWidget_data() |
|
380 { |
|
381 QTest::addColumn<bool>("widgetExists"); |
|
382 QTest::addColumn<bool>("insertWidget"); |
|
383 QTest::addColumn<bool>("hasParent"); |
|
384 QTest::addColumn<bool>("proxyHasParent"); |
|
385 |
|
386 QTest::newRow("setWidget(0)") << false << false << false << false; |
|
387 QTest::newRow("setWidget(widget)") << false << true << false << false; |
|
388 QTest::newRow("setWidget(widgetWParent)") << false << true << true << false; |
|
389 QTest::newRow("setWidget(1), setWidget(0)") << true << false << false << false; |
|
390 QTest::newRow("setWidget(1), setWidget(widget)") << true << true << false << false; |
|
391 QTest::newRow("setWidget(1), setWidget(widgetWParent)") << true << true << true << false; |
|
392 QTest::newRow("p setWidget(0)") << false << false << false << true; |
|
393 QTest::newRow("p setWidget(widget)") << false << true << false << true; |
|
394 QTest::newRow("p setWidget(widgetWParent)") << false << true << true << true; |
|
395 QTest::newRow("p setWidget(1), setWidget(0)") << true << false << false << true; |
|
396 QTest::newRow("p setWidget(1), setWidget(widget)") << true << true << false << true; |
|
397 QTest::newRow("p setWidget(1), setWidget(widgetWParent)") << true << true << true << true; |
|
398 } |
|
399 |
|
400 // public void setWidget(QWidget* widget) |
|
401 void tst_QGraphicsProxyWidget::setWidget() |
|
402 { |
|
403 QFETCH(bool, widgetExists); |
|
404 QFETCH(bool, insertWidget); |
|
405 QFETCH(bool, hasParent); |
|
406 QFETCH(bool, proxyHasParent); |
|
407 |
|
408 QGraphicsScene scene; |
|
409 QGraphicsView view(&scene); |
|
410 view.show(); |
|
411 #ifdef Q_WS_X11 |
|
412 qt_x11_wait_for_window_manager(&view); |
|
413 #endif |
|
414 QPointer<SubQGraphicsProxyWidget> proxy = new SubQGraphicsProxyWidget; |
|
415 SubQGraphicsProxyWidget parentProxy; |
|
416 scene.addItem(proxy); |
|
417 scene.addItem(&parentProxy); |
|
418 if (proxyHasParent) |
|
419 proxy->setParent(&parentProxy); |
|
420 QPointer<QWidget> existingSubWidget = new QWidget; |
|
421 proxy->setVisible(false); |
|
422 proxy->setEnabled(false); |
|
423 |
|
424 if (widgetExists) { |
|
425 existingSubWidget->setAttribute(Qt::WA_QuitOnClose, true); |
|
426 proxy->setWidget(existingSubWidget); |
|
427 } |
|
428 |
|
429 QWidget *widget = new QWidget; |
|
430 #ifndef QT_NO_CURSOR |
|
431 widget->setCursor(Qt::IBeamCursor); |
|
432 #endif |
|
433 widget->setPalette(QPalette(Qt::magenta)); |
|
434 widget->setLayoutDirection(Qt::RightToLeft); |
|
435 QCleanlooksStyle cleanlooksStyle; |
|
436 widget->setStyle(&cleanlooksStyle); |
|
437 widget->setFont(QFont("Times")); |
|
438 widget->setVisible(true); |
|
439 QApplication::setActiveWindow(widget); |
|
440 widget->activateWindow(); |
|
441 widget->setEnabled(true); |
|
442 widget->resize(325, 241); |
|
443 widget->setMinimumSize(100, 200); |
|
444 widget->setMaximumSize(1000, 2000); |
|
445 widget->setFocusPolicy(Qt::TabFocus); |
|
446 widget->setContentsMargins(10, 29, 19, 81); |
|
447 widget->setFocus(Qt::TabFocusReason); |
|
448 widget->setAcceptDrops(true); |
|
449 QTRY_VERIFY(widget->hasFocus()); |
|
450 QVERIFY(widget->isActiveWindow()); |
|
451 |
|
452 QWidget parentWidget; |
|
453 if (hasParent) |
|
454 widget->setParent(&parentWidget); |
|
455 |
|
456 QWidget *subWidget = insertWidget ? widget : 0; |
|
457 bool shouldBeInsertable = !hasParent && subWidget; |
|
458 if (shouldBeInsertable) |
|
459 subWidget->setAttribute(Qt::WA_QuitOnClose, true); |
|
460 |
|
461 proxy->setWidget(subWidget); |
|
462 |
|
463 if (shouldBeInsertable) { |
|
464 QCOMPARE(proxy->widget(), subWidget); |
|
465 QVERIFY(subWidget->testAttribute(Qt::WA_DontShowOnScreen)); |
|
466 QVERIFY(!subWidget->testAttribute(Qt::WA_QuitOnClose)); |
|
467 QCOMPARE(proxy->acceptHoverEvents(), true); |
|
468 #ifndef QT_NO_CURSOR |
|
469 QVERIFY(proxy->hasCursor()); |
|
470 |
|
471 // These should match |
|
472 QCOMPARE(proxy->cursor().shape(), widget->cursor().shape()); |
|
473 #endif |
|
474 //###QCOMPARE(proxy->palette(), widget->palette()); |
|
475 QCOMPARE(proxy->layoutDirection(), widget->layoutDirection()); |
|
476 QCOMPARE(proxy->style(), widget->style()); |
|
477 QCOMPARE(proxy->isVisible(), widget->isVisible()); |
|
478 QCOMPARE(proxy->isEnabled(), widget->isEnabled()); |
|
479 QVERIFY(proxy->flags() & QGraphicsItem::ItemIsFocusable); |
|
480 QCOMPARE(proxy->effectiveSizeHint(Qt::MinimumSize).toSize(), |
|
481 qSmartMinSize(widget)); |
|
482 QCOMPARE(proxy->minimumSize().toSize(), |
|
483 qSmartMinSize(widget) ); |
|
484 QCOMPARE(proxy->maximumSize().toSize(), QSize(1000, 2000)); |
|
485 QCOMPARE(proxy->effectiveSizeHint(Qt::PreferredSize).toSize(), |
|
486 qSmartMinSize(widget)); |
|
487 QCOMPARE(proxy->size().toSize(), widget->size()); |
|
488 QCOMPARE(proxy->rect().toRect(), widget->rect()); |
|
489 QCOMPARE(proxy->focusPolicy(), Qt::WheelFocus); |
|
490 QVERIFY(proxy->acceptDrops()); |
|
491 QCOMPARE(proxy->acceptsHoverEvents(), true); // to get widget enter events |
|
492 int left, top, right, bottom; |
|
493 widget->getContentsMargins(&left, &top, &right, &bottom); |
|
494 qreal rleft, rtop, rright, rbottom; |
|
495 proxy->getContentsMargins(&rleft, &rtop, &rright, &rbottom); |
|
496 QCOMPARE((qreal)left, rleft); |
|
497 QCOMPARE((qreal)top, rtop); |
|
498 QCOMPARE((qreal)right, rright); |
|
499 QCOMPARE((qreal)bottom, rbottom); |
|
500 } else { |
|
501 // proxy shouldn't mess with the widget if it can't insert it. |
|
502 QCOMPARE(proxy->widget(), (QWidget*)0); |
|
503 QCOMPARE(proxy->acceptHoverEvents(), false); |
|
504 if (subWidget) { |
|
505 QVERIFY(!subWidget->testAttribute(Qt::WA_DontShowOnScreen)); |
|
506 QVERIFY(subWidget->testAttribute(Qt::WA_QuitOnClose)); |
|
507 // reset |
|
508 subWidget->setAttribute(Qt::WA_QuitOnClose, false); |
|
509 } |
|
510 } |
|
511 |
|
512 if (widgetExists) { |
|
513 QCOMPARE(existingSubWidget->parent(), static_cast<QObject*>(0)); |
|
514 QVERIFY(!existingSubWidget->testAttribute(Qt::WA_DontShowOnScreen)); |
|
515 QVERIFY(!existingSubWidget->testAttribute(Qt::WA_QuitOnClose)); |
|
516 } |
|
517 |
|
518 if (hasParent) |
|
519 widget->setParent(0); |
|
520 |
|
521 delete widget; |
|
522 if (shouldBeInsertable) |
|
523 QVERIFY(!proxy); |
|
524 delete existingSubWidget; |
|
525 if (!shouldBeInsertable) { |
|
526 QVERIFY(proxy); |
|
527 delete proxy; |
|
528 } |
|
529 QVERIFY(!proxy); |
|
530 } |
|
531 |
|
532 Q_DECLARE_METATYPE(QEvent::Type) |
|
533 void tst_QGraphicsProxyWidget::eventFilter_data() |
|
534 { |
|
535 QTest::addColumn<QEvent::Type>("eventType"); |
|
536 QTest::addColumn<bool>("fromObject"); // big grin evil |
|
537 QTest::newRow("none") << QEvent::None << false; |
|
538 for (int i = 0; i < 2; ++i) { |
|
539 bool fromObject = (i == 0); |
|
540 QTest::newRow(QString("resize %1").arg(fromObject).toLatin1()) << QEvent::Resize << fromObject; |
|
541 QTest::newRow(QString("move %1").arg(fromObject).toLatin1()) << QEvent::Move << fromObject; |
|
542 QTest::newRow(QString("hide %1").arg(fromObject).toLatin1()) << QEvent::Hide << fromObject; |
|
543 QTest::newRow(QString("show %1").arg(fromObject).toLatin1()) << QEvent::Show << fromObject; |
|
544 QTest::newRow(QString("enabled %1").arg(fromObject).toLatin1()) << QEvent::EnabledChange << fromObject; |
|
545 QTest::newRow(QString("focusIn %1").arg(fromObject).toLatin1()) << QEvent::FocusIn << fromObject; |
|
546 QTest::newRow(QString("focusOut %1").arg(fromObject).toLatin1()) << QEvent::FocusOut << fromObject; |
|
547 QTest::newRow(QString("keyPress %1").arg(fromObject).toLatin1()) << QEvent::KeyPress << fromObject; |
|
548 } |
|
549 } |
|
550 |
|
551 // protected bool eventFilter(QObject* object, QEvent* event) |
|
552 void tst_QGraphicsProxyWidget::eventFilter() |
|
553 { |
|
554 QFETCH(QEvent::Type, eventType); |
|
555 QFETCH(bool, fromObject); |
|
556 |
|
557 QGraphicsScene scene; |
|
558 QEvent windowActivate(QEvent::WindowActivate); |
|
559 qApp->sendEvent(&scene, &windowActivate); |
|
560 |
|
561 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
562 scene.addItem(proxy); |
|
563 |
|
564 QWidget *widget = new QWidget(0, Qt::FramelessWindowHint); |
|
565 widget->setFocusPolicy(Qt::TabFocus); |
|
566 widget->resize(10, 10); |
|
567 widget->show(); |
|
568 proxy->setWidget(widget); |
|
569 proxy->show(); |
|
570 |
|
571 // mirror whatever is happening to the widget |
|
572 // don't get in a loop |
|
573 switch (eventType) { |
|
574 case QEvent::None: { |
|
575 QEvent event(QEvent::None); |
|
576 proxy->call_eventFilter(widget, &event); |
|
577 break; |
|
578 } |
|
579 case QEvent::Resize: { |
|
580 QSize oldSize = widget->size(); |
|
581 QSize newSize = QSize(100, 100); |
|
582 if (fromObject) { |
|
583 widget->resize(newSize); |
|
584 } else { |
|
585 proxy->resize(newSize); |
|
586 } |
|
587 QCOMPARE(proxy->size().toSize(), newSize); |
|
588 QCOMPARE(widget->size(), newSize); |
|
589 break; |
|
590 } |
|
591 case QEvent::Move: { |
|
592 QPoint oldPoint = widget->pos(); |
|
593 QPoint newPoint = QPoint(100, 100); |
|
594 if (fromObject) { |
|
595 widget->move(newPoint); |
|
596 } else { |
|
597 proxy->setPos(newPoint); |
|
598 } |
|
599 QCOMPARE(proxy->pos().toPoint(), newPoint); |
|
600 QCOMPARE(widget->pos(), newPoint); |
|
601 break; |
|
602 } |
|
603 case QEvent::Hide: { |
|
604 // A hide event can only come from a widget |
|
605 if (fromObject) { |
|
606 widget->setFocus(Qt::TabFocusReason); |
|
607 widget->hide(); |
|
608 } else { |
|
609 QHideEvent event; |
|
610 proxy->call_eventFilter(widget, &event); |
|
611 } |
|
612 QCOMPARE(proxy->isVisible(), false); |
|
613 break; |
|
614 } |
|
615 case QEvent::Show: { |
|
616 // A show event can either come from a widget or somewhere else |
|
617 widget->hide(); |
|
618 if (fromObject) { |
|
619 widget->show(); |
|
620 } else { |
|
621 QShowEvent event; |
|
622 proxy->call_eventFilter(widget, &event); |
|
623 } |
|
624 QCOMPARE(proxy->isVisible(), true); |
|
625 break; |
|
626 } |
|
627 case QEvent::EnabledChange: { |
|
628 widget->setEnabled(false); |
|
629 proxy->setEnabled(false); |
|
630 if (fromObject) { |
|
631 widget->setEnabled(true); |
|
632 QCOMPARE(proxy->isEnabled(), true); |
|
633 widget->setEnabled(false); |
|
634 QCOMPARE(proxy->isEnabled(), false); |
|
635 } else { |
|
636 QEvent event(QEvent::EnabledChange); |
|
637 proxy->call_eventFilter(widget, &event); |
|
638 // match the widget not the event |
|
639 QCOMPARE(proxy->isEnabled(), false); |
|
640 } |
|
641 break; |
|
642 } |
|
643 case QEvent::FocusIn: { |
|
644 if (fromObject) { |
|
645 widget->setFocus(Qt::TabFocusReason); |
|
646 QVERIFY(proxy->hasFocus()); |
|
647 } |
|
648 break; |
|
649 } |
|
650 case QEvent::FocusOut: { |
|
651 widget->setFocus(Qt::TabFocusReason); |
|
652 QVERIFY(proxy->hasFocus()); |
|
653 QVERIFY(widget->hasFocus()); |
|
654 if (fromObject) { |
|
655 widget->clearFocus(); |
|
656 QVERIFY(!proxy->hasFocus()); |
|
657 } |
|
658 break; |
|
659 } |
|
660 case QEvent::KeyPress: { |
|
661 if (fromObject) { |
|
662 QTest::keyPress(widget, Qt::Key_A, Qt::NoModifier); |
|
663 } else { |
|
664 QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier); |
|
665 proxy->call_eventFilter(widget, &event); |
|
666 } |
|
667 QCOMPARE(proxy->keyPress, 1); |
|
668 break; |
|
669 } |
|
670 default: |
|
671 break; |
|
672 } |
|
673 } |
|
674 |
|
675 void tst_QGraphicsProxyWidget::focusInEvent_data() |
|
676 { |
|
677 QTest::addColumn<bool>("widgetHasFocus"); |
|
678 QTest::addColumn<bool>("widgetCanHaveFocus"); |
|
679 QTest::newRow("no focus, can't get") << false << false; |
|
680 QTest::newRow("no focus, can get") << false << true; |
|
681 QTest::newRow("has focus, can't get") << true << false; |
|
682 QTest::newRow("has focus, can get") << true << true; |
|
683 // ### add test for widget having a focusNextPrevChild |
|
684 } |
|
685 |
|
686 // protected void focusInEvent(QFocusEvent* event) |
|
687 void tst_QGraphicsProxyWidget::focusInEvent() |
|
688 { |
|
689 // ### This test is just plain old broken |
|
690 QFETCH(bool, widgetHasFocus); |
|
691 QFETCH(bool, widgetCanHaveFocus); |
|
692 |
|
693 QGraphicsScene scene; |
|
694 QEvent windowActivate(QEvent::WindowActivate); |
|
695 qApp->sendEvent(&scene, &windowActivate); |
|
696 |
|
697 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
698 proxy->setEnabled(true); |
|
699 scene.addItem(proxy); |
|
700 proxy->setVisible(true); |
|
701 |
|
702 QWidget *widget = new QWidget; |
|
703 widget->resize(100, 100); |
|
704 if (widgetCanHaveFocus) |
|
705 widget->setFocusPolicy(Qt::WheelFocus); |
|
706 widget->show(); |
|
707 |
|
708 if (widgetHasFocus) |
|
709 widget->setFocus(Qt::TabFocusReason); |
|
710 |
|
711 proxy->setWidget(widget); |
|
712 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // <- shouldn't need to do this |
|
713 |
|
714 // ### This test is just plain old broken - sending a focus in event |
|
715 // does not cause items to gain input focus. The widget has focus |
|
716 // because the proxy has focus, not because it got this event. |
|
717 |
|
718 QFocusEvent event(QEvent::FocusIn, Qt::TabFocusReason); |
|
719 event.ignore(); |
|
720 proxy->call_focusInEvent(&event); |
|
721 QTRY_COMPARE(widget->hasFocus(), widgetCanHaveFocus); |
|
722 } |
|
723 |
|
724 void tst_QGraphicsProxyWidget::focusInEventNoWidget() |
|
725 { |
|
726 QGraphicsView view; |
|
727 QGraphicsScene scene(&view); |
|
728 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
729 proxy->setEnabled(true); |
|
730 scene.addItem(proxy); |
|
731 proxy->setVisible(true); |
|
732 view.show(); |
|
733 |
|
734 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // <- shouldn't need to do this |
|
735 QFocusEvent event(QEvent::FocusIn, Qt::TabFocusReason); |
|
736 event.ignore(); |
|
737 //should not crash |
|
738 proxy->call_focusInEvent(&event); |
|
739 } |
|
740 |
|
741 void tst_QGraphicsProxyWidget::focusNextPrevChild_data() |
|
742 { |
|
743 QTest::addColumn<bool>("hasWidget"); |
|
744 QTest::addColumn<bool>("hasScene"); |
|
745 QTest::addColumn<bool>("next"); |
|
746 QTest::addColumn<bool>("focusNextPrevChild"); |
|
747 |
|
748 for (int i = 0; i < 2; ++i) { |
|
749 for (int j = 0; j < 2; ++j) { |
|
750 for (int k = 0; k < 2; ++k) { |
|
751 bool next = (i == 0); |
|
752 bool hasWidget = (j == 0); |
|
753 bool hasScene = (k == 0); |
|
754 bool result = hasScene && hasWidget; |
|
755 QString name = QString("Forward: %1, hasWidget: %2, hasScene: %3, result: %4").arg(next).arg(hasWidget).arg(hasScene).arg(result); |
|
756 QTest::newRow(name.toLatin1()) << hasWidget << hasScene << next << result; |
|
757 } |
|
758 } |
|
759 } |
|
760 } |
|
761 |
|
762 // protected bool focusNextPrevChild(bool next) |
|
763 void tst_QGraphicsProxyWidget::focusNextPrevChild() |
|
764 { |
|
765 QFETCH(bool, next); |
|
766 QFETCH(bool, focusNextPrevChild); |
|
767 QFETCH(bool, hasWidget); |
|
768 QFETCH(bool, hasScene); |
|
769 |
|
770 // If a widget has its own focusNextPrevChild we need to respect it |
|
771 // otherwise respect the scene |
|
772 // Respect the widget over the scene! |
|
773 |
|
774 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
775 |
|
776 QLabel *widget = new QLabel; |
|
777 // I can't believe designer adds this much junk! |
|
778 widget->setText("<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\"> <p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.slashdot.org\"><span style=\" text-decoration: underline; color:#0000ff;\">old</span></a> foo <a href=\"http://www.reddit.org\"><span style=\" text-decoration: underline; color:#0000ff;\">new</span></a></p></body></html>"); |
|
779 widget->setTextInteractionFlags(Qt::TextBrowserInteraction); |
|
780 |
|
781 if (hasWidget) |
|
782 proxy->setWidget(widget); |
|
783 |
|
784 QGraphicsScene scene; |
|
785 QGraphicsView view(&scene); |
|
786 view.show(); |
|
787 QApplication::setActiveWindow(&view); |
|
788 QTest::qWaitForWindowShown(&view); |
|
789 QApplication::processEvents(); |
|
790 QTRY_COMPARE(QApplication::activeWindow(), &view); |
|
791 if (hasScene) { |
|
792 scene.addItem(proxy); |
|
793 proxy->show(); |
|
794 |
|
795 // widget should take precedence over scene so make scene.focusNextPrevChild return false |
|
796 // so we know that a true can only come from the widget |
|
797 if (!(hasWidget && hasScene)) { |
|
798 QGraphicsTextItem *item = new QGraphicsTextItem("Foo"); |
|
799 item->setTextInteractionFlags(Qt::TextBrowserInteraction); |
|
800 scene.addItem(item); |
|
801 item->setPos(50, 40); |
|
802 } |
|
803 scene.setFocusItem(proxy); |
|
804 QVERIFY(proxy->hasFocus()); |
|
805 } |
|
806 |
|
807 QCOMPARE(proxy->call_focusNextPrevChild(next), focusNextPrevChild); |
|
808 |
|
809 if (!hasScene) |
|
810 delete proxy; |
|
811 } |
|
812 |
|
813 void tst_QGraphicsProxyWidget::focusOutEvent_data() |
|
814 { |
|
815 QTest::addColumn<bool>("hasWidget"); |
|
816 QTest::addColumn<bool>("call"); |
|
817 QTest::newRow("no widget, focus to other widget") << false << false; |
|
818 QTest::newRow("no widget, focusOutCalled") << false << true; |
|
819 QTest::newRow("widget, focus to other widget") << true << false; |
|
820 QTest::newRow("widget, focusOutCalled") << true << true; |
|
821 } |
|
822 |
|
823 // protected void focusOutEvent(QFocusEvent* event) |
|
824 void tst_QGraphicsProxyWidget::focusOutEvent() |
|
825 { |
|
826 QFETCH(bool, hasWidget); |
|
827 QFETCH(bool, call); |
|
828 |
|
829 QGraphicsScene scene; |
|
830 QGraphicsView view(&scene); |
|
831 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
832 scene.addItem(proxy); |
|
833 view.show(); |
|
834 QApplication::setActiveWindow(&view); |
|
835 view.activateWindow(); |
|
836 view.setFocus(); |
|
837 QTest::qWaitForWindowShown(&view); |
|
838 QApplication::processEvents(); |
|
839 QTRY_VERIFY(view.isVisible()); |
|
840 QTRY_COMPARE(QApplication::activeWindow(), &view); |
|
841 |
|
842 QWidget *widget = new QWidget; |
|
843 widget->setFocusPolicy(Qt::WheelFocus); |
|
844 if (hasWidget) |
|
845 proxy->setWidget(widget); |
|
846 proxy->show(); |
|
847 proxy->setFocus(); |
|
848 QVERIFY(proxy->hasFocus()); |
|
849 QEXPECT_FAIL("widget, focus to other widget", "Widget should have focus but doesn't", Continue); |
|
850 QEXPECT_FAIL("widget, focusOutCalled", "Widget should have focus but doesn't", Continue); |
|
851 QCOMPARE(widget->hasFocus(), hasWidget); |
|
852 |
|
853 if (!call) { |
|
854 QWidget *other = new QLineEdit(&view); |
|
855 other->show(); |
|
856 QApplication::processEvents(); |
|
857 QTRY_VERIFY(other->isVisible()); |
|
858 other->setFocus(); |
|
859 QTRY_VERIFY(other->hasFocus()); |
|
860 qApp->processEvents(); |
|
861 QTRY_COMPARE(proxy->hasFocus(), false); |
|
862 QVERIFY(proxy->focusOut); |
|
863 QCOMPARE(widget->hasFocus(), false); |
|
864 } else { |
|
865 { |
|
866 /* |
|
867 ### Test doesn't make sense |
|
868 QFocusEvent focusEvent(QEvent::FocusOut); |
|
869 proxy->call_focusOutEvent(&focusEvent); |
|
870 QCOMPARE(focusEvent.isAccepted(), hasWidget); |
|
871 qApp->processEvents(); |
|
872 QCOMPARE(proxy->paintCount, hasWidget ? 1 : 0); |
|
873 */ |
|
874 } |
|
875 { |
|
876 /* |
|
877 ### Test doesn't make sense |
|
878 proxy->setFlag(QGraphicsItem::ItemIsFocusable, false); |
|
879 QFocusEvent focusEvent(QEvent::FocusOut); |
|
880 proxy->call_focusOutEvent(&focusEvent); |
|
881 QCOMPARE(focusEvent.isAccepted(), hasWidget); |
|
882 qApp->processEvents(); |
|
883 QCOMPARE(proxy->paintCount, 0); |
|
884 */ |
|
885 } |
|
886 } |
|
887 } |
|
888 |
|
889 class EventLogger : public QWidget |
|
890 { |
|
891 public: |
|
892 EventLogger() : QWidget(), enterCount(0), leaveCount(0), moveCount(0), |
|
893 hoverEnter(0), hoverLeave(0), hoverMove(0) |
|
894 { |
|
895 installEventFilter(this); |
|
896 } |
|
897 |
|
898 void enterEvent(QEvent *event) |
|
899 { |
|
900 enterCount++; |
|
901 QWidget::enterEvent(event); |
|
902 } |
|
903 |
|
904 void leaveEvent(QEvent *event ) |
|
905 { |
|
906 leaveCount++; |
|
907 QWidget::leaveEvent(event); |
|
908 } |
|
909 |
|
910 void mouseMoveEvent(QMouseEvent *event) |
|
911 { |
|
912 event->setAccepted(true); |
|
913 moveCount++; |
|
914 QWidget::mouseMoveEvent(event); |
|
915 } |
|
916 |
|
917 int enterCount; |
|
918 int leaveCount; |
|
919 int moveCount; |
|
920 |
|
921 int hoverEnter; |
|
922 int hoverLeave; |
|
923 int hoverMove; |
|
924 protected: |
|
925 bool eventFilter(QObject *object, QEvent *event) |
|
926 { |
|
927 switch (event->type()) { |
|
928 case QEvent::HoverEnter: |
|
929 hoverEnter++; |
|
930 break; |
|
931 case QEvent::HoverLeave: |
|
932 hoverLeave++; |
|
933 break; |
|
934 case QEvent::HoverMove: |
|
935 hoverMove++; |
|
936 break; |
|
937 default: |
|
938 break; |
|
939 } |
|
940 return QWidget::eventFilter(object, event); |
|
941 } |
|
942 }; |
|
943 |
|
944 void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent_data() |
|
945 { |
|
946 QTest::addColumn<bool>("hasWidget"); |
|
947 QTest::addColumn<bool>("hoverEnabled"); |
|
948 QTest::newRow("widget, no hover") << true << false; |
|
949 QTest::newRow("no widget, no hover") << false << false; |
|
950 QTest::newRow("widget, hover") << true << true; |
|
951 QTest::newRow("no widget, hover") << false << true; |
|
952 } |
|
953 |
|
954 // protected void hoverEnterEvent(QGraphicsSceneHoverEvent* event) |
|
955 void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent() |
|
956 { |
|
957 QFETCH(bool, hasWidget); |
|
958 QFETCH(bool, hoverEnabled); |
|
959 |
|
960 #if defined(Q_OS_WINCE) && (!defined(GWES_ICONCURS) || defined(QT_NO_CURSOR)) |
|
961 QSKIP("hover events not supported on this platform", SkipAll); |
|
962 #endif |
|
963 |
|
964 // proxy should translate this into events that the widget would expect |
|
965 |
|
966 QGraphicsScene scene; |
|
967 QGraphicsView view(&scene); |
|
968 //do not let the window manager move the window while we are moving the mouse on it |
|
969 view.setWindowFlags(Qt::X11BypassWindowManagerHint); |
|
970 view.show(); |
|
971 #ifdef Q_WS_X11 |
|
972 qt_x11_wait_for_window_manager(&view); |
|
973 #endif |
|
974 |
|
975 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
976 EventLogger *widget = new EventLogger; |
|
977 widget->resize(50, 50); |
|
978 widget->setAttribute(Qt::WA_Hover, hoverEnabled); |
|
979 widget->setMouseTracking(true); |
|
980 view.resize(100, 100); |
|
981 if (hasWidget) |
|
982 proxy->setWidget(widget); |
|
983 proxy->setPos(50, 0); |
|
984 scene.addItem(proxy); |
|
985 QTest::qWait(30); |
|
986 QTest::mouseMove(&view, QPoint(10, 10)); |
|
987 QTest::qWait(30); |
|
988 |
|
989 // in |
|
990 QTest::mouseMove(&view, QPoint(50, 50)); |
|
991 QTest::qWait(25); |
|
992 QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), hasWidget ? true : false); |
|
993 // ### this attribute isn't supported |
|
994 QCOMPARE(widget->enterCount, hasWidget ? 1 : 0); |
|
995 QCOMPARE(widget->hoverEnter, (hasWidget && hoverEnabled) ? 1 : 0); |
|
996 // does not work on all platforms |
|
997 //QCOMPARE(widget->moveCount, 0); |
|
998 |
|
999 // out |
|
1000 QTest::mouseMove(&view, QPoint(10, 10)); |
|
1001 QTest::qWait(25); |
|
1002 // QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), false); |
|
1003 // ### this attribute isn't supported |
|
1004 QCOMPARE(widget->leaveCount, hasWidget ? 1 : 0); |
|
1005 QCOMPARE(widget->hoverLeave, (hasWidget && hoverEnabled) ? 1 : 0); |
|
1006 // does not work on all platforms |
|
1007 //QCOMPARE(widget->moveCount, 0); |
|
1008 |
|
1009 if (!hasWidget) |
|
1010 delete widget; |
|
1011 } |
|
1012 |
|
1013 void tst_QGraphicsProxyWidget::hoverMoveEvent_data() |
|
1014 { |
|
1015 QTest::addColumn<bool>("hasWidget"); |
|
1016 QTest::addColumn<bool>("hoverEnabled"); |
|
1017 QTest::addColumn<bool>("mouseTracking"); |
|
1018 QTest::addColumn<bool>("mouseDown"); |
|
1019 for (int i = 0; i < 2; ++i) { |
|
1020 for (int j = 0; j < 2; ++j) { |
|
1021 for (int k = 0; k < 2; ++k) { |
|
1022 for (int l = 0; l < 2; ++l) { |
|
1023 bool hasWidget = (i == 0); |
|
1024 bool hoverEnabled = (j == 0); |
|
1025 bool mouseTracking = (k == 0); |
|
1026 bool mouseDown = (l == 0); |
|
1027 QString name = QString("hasWidget:%1, hover:%2, mouseTracking:%3, mouseDown: %4").arg(hasWidget).arg(hoverEnabled).arg(mouseTracking).arg(mouseDown); |
|
1028 QTest::newRow(name.toLatin1()) << hasWidget << hoverEnabled << mouseTracking << mouseDown; |
|
1029 } |
|
1030 } |
|
1031 } |
|
1032 } |
|
1033 } |
|
1034 |
|
1035 // protected void hoverMoveEvent(QGraphicsSceneHoverEvent* event) |
|
1036 void tst_QGraphicsProxyWidget::hoverMoveEvent() |
|
1037 { |
|
1038 QFETCH(bool, hasWidget); |
|
1039 QFETCH(bool, hoverEnabled); |
|
1040 QFETCH(bool, mouseTracking); |
|
1041 QFETCH(bool, mouseDown); |
|
1042 |
|
1043 QSKIP("Ambiguous test...", SkipAll); |
|
1044 |
|
1045 // proxy should translate the move events to what the widget would expect |
|
1046 |
|
1047 QGraphicsScene scene; |
|
1048 QGraphicsView view(&scene); |
|
1049 view.show(); |
|
1050 |
|
1051 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
1052 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!! |
|
1053 EventLogger *widget = new EventLogger; |
|
1054 widget->resize(50, 50); |
|
1055 widget->setAttribute(Qt::WA_Hover, hoverEnabled); |
|
1056 if (mouseTracking) |
|
1057 widget->setMouseTracking(true); |
|
1058 view.resize(100, 100); |
|
1059 if (hasWidget) |
|
1060 proxy->setWidget(widget); |
|
1061 proxy->setPos(50, 0); |
|
1062 scene.addItem(proxy); |
|
1063 |
|
1064 // in |
|
1065 QTest::mouseMove(&view, QPoint(50, 50)); |
|
1066 QTest::qWait(12); |
|
1067 |
|
1068 if (mouseDown) |
|
1069 QTest::mousePress(view.viewport(), Qt::LeftButton); |
|
1070 |
|
1071 // move a little bit |
|
1072 QTest::mouseMove(&view, QPoint(60, 60)); |
|
1073 QTest::qWait(12); |
|
1074 QTRY_COMPARE(widget->hoverEnter, (hasWidget && hoverEnabled) ? 1 : 0); |
|
1075 QCOMPARE(widget->moveCount, (hasWidget && mouseTracking) || (hasWidget && mouseDown) ? 1 : 0); |
|
1076 |
|
1077 if (!hasWidget) |
|
1078 delete widget; |
|
1079 } |
|
1080 |
|
1081 void tst_QGraphicsProxyWidget::keyPressEvent_data() |
|
1082 { |
|
1083 QTest::addColumn<bool>("hasWidget"); |
|
1084 QTest::newRow("widget") << true; |
|
1085 QTest::newRow("no widget") << false; |
|
1086 } |
|
1087 |
|
1088 // protected void keyPressEvent(QKeyEvent* event) |
|
1089 void tst_QGraphicsProxyWidget::keyPressEvent() |
|
1090 { |
|
1091 QFETCH(bool, hasWidget); |
|
1092 |
|
1093 QGraphicsScene scene; |
|
1094 QGraphicsView view(&scene); |
|
1095 view.show(); |
|
1096 view.viewport()->setFocus(); |
|
1097 QApplication::setActiveWindow(&view); |
|
1098 QTest::qWaitForWindowShown(&view); |
|
1099 QApplication::processEvents(); |
|
1100 QTRY_COMPARE(QApplication::activeWindow(), &view); |
|
1101 |
|
1102 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
1103 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!! |
|
1104 |
|
1105 QLineEdit *widget = new QLineEdit; |
|
1106 widget->resize(50, 50); |
|
1107 view.resize(100, 100); |
|
1108 if (hasWidget) { |
|
1109 proxy->setWidget(widget); |
|
1110 proxy->show(); |
|
1111 } |
|
1112 proxy->setPos(50, 0); |
|
1113 scene.addItem(proxy); |
|
1114 proxy->setFocus(); |
|
1115 |
|
1116 QTest::keyPress(view.viewport(), 'x'); |
|
1117 |
|
1118 QTRY_COMPARE(widget->text(), hasWidget ? QString("x") : QString()); |
|
1119 |
|
1120 if (!hasWidget) |
|
1121 delete widget; |
|
1122 } |
|
1123 |
|
1124 void tst_QGraphicsProxyWidget::keyReleaseEvent_data() |
|
1125 { |
|
1126 QTest::addColumn<bool>("hasWidget"); |
|
1127 QTest::newRow("widget") << true; |
|
1128 QTest::newRow("no widget") << false; |
|
1129 } |
|
1130 |
|
1131 // protected void keyReleaseEvent(QKeyEvent* event) |
|
1132 void tst_QGraphicsProxyWidget::keyReleaseEvent() |
|
1133 { |
|
1134 QFETCH(bool, hasWidget); |
|
1135 |
|
1136 QGraphicsScene scene; |
|
1137 QGraphicsView view(&scene); |
|
1138 view.show(); |
|
1139 QApplication::setActiveWindow(&view); |
|
1140 QTest::qWaitForWindowShown(&view); |
|
1141 QTRY_COMPARE(QApplication::activeWindow(), &view); |
|
1142 |
|
1143 |
|
1144 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
1145 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!! |
|
1146 QPushButton *widget = new QPushButton; |
|
1147 QSignalSpy spy(widget, SIGNAL(clicked())); |
|
1148 widget->resize(50, 50); |
|
1149 view.resize(100, 100); |
|
1150 if (hasWidget) { |
|
1151 proxy->setWidget(widget); |
|
1152 proxy->show(); |
|
1153 } |
|
1154 proxy->setPos(50, 0); |
|
1155 scene.addItem(proxy); |
|
1156 proxy->setFocus(); |
|
1157 |
|
1158 QTest::keyPress(view.viewport(), Qt::Key_Space); |
|
1159 QTRY_COMPARE(spy.count(), 0); |
|
1160 QTest::keyRelease(view.viewport(), Qt::Key_Space); |
|
1161 QTRY_COMPARE(spy.count(), (hasWidget) ? 1 : 0); |
|
1162 |
|
1163 if (!hasWidget) |
|
1164 delete widget; |
|
1165 } |
|
1166 |
|
1167 void tst_QGraphicsProxyWidget::mouseDoubleClickEvent_data() |
|
1168 { |
|
1169 QTest::addColumn<bool>("hasWidget"); |
|
1170 QTest::newRow("widget") << true; |
|
1171 QTest::newRow("no widget") << false; |
|
1172 } |
|
1173 |
|
1174 // protected void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) |
|
1175 void tst_QGraphicsProxyWidget::mouseDoubleClickEvent() |
|
1176 { |
|
1177 QFETCH(bool, hasWidget); |
|
1178 |
|
1179 QGraphicsScene scene; |
|
1180 QGraphicsView view(&scene); |
|
1181 view.show(); |
|
1182 |
|
1183 QApplication::setActiveWindow(&view); |
|
1184 QTest::qWaitForWindowShown(&view); |
|
1185 QTRY_COMPARE(QApplication::activeWindow(), &view); |
|
1186 |
|
1187 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
1188 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!! |
|
1189 QLineEdit *widget = new QLineEdit; |
|
1190 widget->setText("foo"); |
|
1191 widget->resize(50, 50); |
|
1192 view.resize(100, 100); |
|
1193 if (hasWidget) { |
|
1194 proxy->setWidget(widget); |
|
1195 proxy->show(); |
|
1196 } |
|
1197 proxy->setPos(50, 0); |
|
1198 scene.addItem(proxy); |
|
1199 proxy->setFocus(); |
|
1200 |
|
1201 QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()))); |
|
1202 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()))); |
|
1203 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()))); |
|
1204 QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()))); |
|
1205 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()))); |
|
1206 |
|
1207 QTRY_COMPARE(widget->selectedText(), hasWidget ? QString("foo") : QString()); |
|
1208 |
|
1209 if (!hasWidget) |
|
1210 delete widget; |
|
1211 } |
|
1212 |
|
1213 void tst_QGraphicsProxyWidget::mousePressReleaseEvent_data() |
|
1214 { |
|
1215 QTest::addColumn<bool>("hasWidget"); |
|
1216 QTest::newRow("widget") << true; |
|
1217 QTest::newRow("no widget") << false; |
|
1218 } |
|
1219 |
|
1220 // protected void mousePressEvent(QGraphicsSceneMouseEvent* event) |
|
1221 void tst_QGraphicsProxyWidget::mousePressReleaseEvent() |
|
1222 { |
|
1223 QFETCH(bool, hasWidget); |
|
1224 |
|
1225 QGraphicsScene scene; |
|
1226 QGraphicsView view(&scene); |
|
1227 view.show(); |
|
1228 QTest::qWaitForWindowShown(&view); |
|
1229 |
|
1230 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
1231 proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!! |
|
1232 QPushButton *widget = new QPushButton; |
|
1233 QSignalSpy spy(widget, SIGNAL(clicked())); |
|
1234 widget->resize(50, 50); |
|
1235 view.resize(100, 100); |
|
1236 if (hasWidget) { |
|
1237 proxy->setWidget(widget); |
|
1238 proxy->show(); |
|
1239 } |
|
1240 proxy->setPos(50, 0); |
|
1241 scene.addItem(proxy); |
|
1242 proxy->setFocus(); |
|
1243 |
|
1244 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, |
|
1245 view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); |
|
1246 QTRY_COMPARE(spy.count(), 0); |
|
1247 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, |
|
1248 view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); |
|
1249 QTRY_COMPARE(spy.count(), (hasWidget) ? 1 : 0); |
|
1250 |
|
1251 if (!hasWidget) |
|
1252 delete widget; |
|
1253 } |
|
1254 |
|
1255 void tst_QGraphicsProxyWidget::resizeEvent_data() |
|
1256 { |
|
1257 QTest::addColumn<bool>("hasWidget"); |
|
1258 QTest::newRow("widget") << true; |
|
1259 QTest::newRow("no widget") << false; |
|
1260 } |
|
1261 |
|
1262 // protected void resizeEvent(QGraphicsSceneResizeEvent* event) |
|
1263 void tst_QGraphicsProxyWidget::resizeEvent() |
|
1264 { |
|
1265 QFETCH(bool, hasWidget); |
|
1266 |
|
1267 SubQGraphicsProxyWidget proxy; |
|
1268 QWidget *widget = new QWidget; |
|
1269 if (hasWidget) |
|
1270 proxy.setWidget(widget); |
|
1271 |
|
1272 QSize newSize(100, 100); |
|
1273 QGraphicsSceneResizeEvent event; |
|
1274 event.setOldSize(QSize(10, 10)); |
|
1275 event.setNewSize(newSize); |
|
1276 proxy.call_resizeEvent(&event); |
|
1277 if (hasWidget) |
|
1278 QCOMPARE(widget->size(), newSize); |
|
1279 if (!hasWidget) |
|
1280 delete widget; |
|
1281 } |
|
1282 |
|
1283 void tst_QGraphicsProxyWidget::paintEvent() |
|
1284 { |
|
1285 //we test that calling update on a widget inside a QGraphicsView is triggering a repaint |
|
1286 QGraphicsScene scene; |
|
1287 QGraphicsView view(&scene); |
|
1288 view.show(); |
|
1289 QTest::qWaitForWindowShown(&view); |
|
1290 QTest::qWait(70); |
|
1291 |
|
1292 SubQGraphicsProxyWidget proxy; |
|
1293 |
|
1294 QWidget *w = new QWidget; |
|
1295 //showing the widget here seems to create a bug in Graphics View |
|
1296 //this bug prevents the widget from being updated |
|
1297 |
|
1298 w->show(); |
|
1299 QTest::qWaitForWindowShown(w); |
|
1300 QApplication::processEvents(); |
|
1301 QTest::qWait(100); |
|
1302 proxy.setWidget(w); |
|
1303 scene.addItem(&proxy); |
|
1304 |
|
1305 //make sure we flush all the paint events |
|
1306 QTest::qWait(70); |
|
1307 QTRY_VERIFY(proxy.paintCount > 1); |
|
1308 QTest::qWait(110); |
|
1309 proxy.paintCount = 0; |
|
1310 |
|
1311 w->update(); |
|
1312 QTest::qWait(30); |
|
1313 QTRY_COMPARE(proxy.paintCount, 1); //the widget should have been painted now |
|
1314 } |
|
1315 |
|
1316 |
|
1317 void tst_QGraphicsProxyWidget::wheelEvent() |
|
1318 { |
|
1319 QGraphicsScene scene; |
|
1320 QGraphicsView view(&scene); |
|
1321 view.show(); |
|
1322 #ifdef Q_WS_X11 |
|
1323 qt_x11_wait_for_window_manager(&view); |
|
1324 #endif |
|
1325 |
|
1326 WheelWidget *wheelWidget = new WheelWidget(); |
|
1327 wheelWidget->setFixedSize(400, 400); |
|
1328 |
|
1329 QGraphicsProxyWidget *proxy = scene.addWidget(wheelWidget); |
|
1330 proxy->setVisible(true); |
|
1331 |
|
1332 QGraphicsSceneWheelEvent event(QEvent::GraphicsSceneWheel); |
|
1333 event.setScenePos(QPoint(50, 50)); |
|
1334 event.setAccepted(false); |
|
1335 wheelWidget->wheelEventCalled = false; |
|
1336 |
|
1337 QApplication::sendEvent(&scene, &event); |
|
1338 |
|
1339 QVERIFY(event.isAccepted()); |
|
1340 QVERIFY(wheelWidget->wheelEventCalled); |
|
1341 } |
|
1342 |
|
1343 Q_DECLARE_METATYPE(Qt::SizeHint) |
|
1344 void tst_QGraphicsProxyWidget::sizeHint_data() |
|
1345 { |
|
1346 QTest::addColumn<Qt::SizeHint>("which"); |
|
1347 QTest::addColumn<QSizeF>("constraint"); |
|
1348 QTest::addColumn<QSizeF>("sizeHint"); |
|
1349 QTest::addColumn<bool>("hasWidget"); |
|
1350 |
|
1351 for (int i = 0; i < 2; ++i) { |
|
1352 bool hasWidget = (i == 0); |
|
1353 // ### What should these do? |
|
1354 QTest::newRow("min") << Qt::MinimumSize << QSizeF() << QSizeF() << hasWidget; |
|
1355 QTest::newRow("pre") << Qt::PreferredSize << QSizeF() << QSizeF() << hasWidget; |
|
1356 QTest::newRow("max") << Qt::MaximumSize << QSizeF() << QSizeF() << hasWidget; |
|
1357 QTest::newRow("mindes") << Qt::MinimumDescent << QSizeF() << QSizeF() << hasWidget; |
|
1358 QTest::newRow("nsize") << Qt::NSizeHints << QSizeF() << QSizeF() << hasWidget; |
|
1359 } |
|
1360 } |
|
1361 |
|
1362 // protected QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const |
|
1363 void tst_QGraphicsProxyWidget::sizeHint() |
|
1364 { |
|
1365 QFETCH(Qt::SizeHint, which); |
|
1366 QFETCH(QSizeF, constraint); |
|
1367 QFETCH(QSizeF, sizeHint); |
|
1368 QFETCH(bool, hasWidget); |
|
1369 QSKIP("Broken test", SkipAll); |
|
1370 SubQGraphicsProxyWidget proxy; |
|
1371 QWidget *widget = new QWidget; |
|
1372 if (hasWidget) |
|
1373 proxy.setWidget(widget); |
|
1374 QCOMPARE(proxy.call_sizeHint(which, constraint), sizeHint); |
|
1375 if (!hasWidget) |
|
1376 delete widget; |
|
1377 } |
|
1378 |
|
1379 void tst_QGraphicsProxyWidget::sizePolicy() |
|
1380 { |
|
1381 for (int p = 0; p < 2; ++p) { |
|
1382 bool hasWidget = (p == 0 ? true : false); |
|
1383 SubQGraphicsProxyWidget proxy; |
|
1384 QWidget *widget = new QWidget; |
|
1385 QSizePolicy proxyPol(QSizePolicy::Maximum, QSizePolicy::Expanding); |
|
1386 proxy.setSizePolicy(proxyPol); |
|
1387 QSizePolicy widgetPol(QSizePolicy::Fixed, QSizePolicy::Minimum); |
|
1388 widget->setSizePolicy(widgetPol); |
|
1389 |
|
1390 QCOMPARE(proxy.sizePolicy(), proxyPol); |
|
1391 QCOMPARE(widget->sizePolicy(), widgetPol); |
|
1392 if (hasWidget) { |
|
1393 proxy.setWidget(widget); |
|
1394 QCOMPARE(proxy.sizePolicy(), widgetPol); |
|
1395 } else { |
|
1396 QCOMPARE(proxy.sizePolicy(), proxyPol); |
|
1397 } |
|
1398 QCOMPARE(widget->sizePolicy(), widgetPol); |
|
1399 |
|
1400 proxy.setSizePolicy(widgetPol); |
|
1401 widget->setSizePolicy(proxyPol); |
|
1402 if (hasWidget) |
|
1403 QCOMPARE(proxy.sizePolicy(), proxyPol); |
|
1404 else |
|
1405 QCOMPARE(proxy.sizePolicy(), widgetPol); |
|
1406 } |
|
1407 } |
|
1408 |
|
1409 void tst_QGraphicsProxyWidget::minimumSize() |
|
1410 { |
|
1411 SubQGraphicsProxyWidget proxy; |
|
1412 QWidget *widget = new QWidget; |
|
1413 QSize minSize(50, 50); |
|
1414 widget->setMinimumSize(minSize); |
|
1415 proxy.resize(30, 30); |
|
1416 widget->resize(30,30); |
|
1417 QCOMPARE(proxy.size(), QSizeF(30, 30)); |
|
1418 proxy.setWidget(widget); |
|
1419 QCOMPARE(proxy.size().toSize(), minSize); |
|
1420 QCOMPARE(proxy.minimumSize().toSize(), minSize); |
|
1421 widget->setMinimumSize(70, 70); |
|
1422 QCOMPARE(proxy.minimumSize(), QSizeF(70, 70)); |
|
1423 QCOMPARE(proxy.size(), QSizeF(70, 70)); |
|
1424 } |
|
1425 |
|
1426 void tst_QGraphicsProxyWidget::maximumSize() |
|
1427 { |
|
1428 SubQGraphicsProxyWidget proxy; |
|
1429 QWidget *widget = new QWidget; |
|
1430 QSize maxSize(150, 150); |
|
1431 widget->setMaximumSize(maxSize); |
|
1432 proxy.resize(200, 200); |
|
1433 widget->resize(200,200); |
|
1434 QCOMPARE(proxy.size(), QSizeF(200, 200)); |
|
1435 proxy.setWidget(widget); |
|
1436 QCOMPARE(proxy.size().toSize(), maxSize); |
|
1437 QCOMPARE(proxy.maximumSize().toSize(), maxSize); |
|
1438 widget->setMaximumSize(70, 70); |
|
1439 QCOMPARE(proxy.maximumSize(), QSizeF(70, 70)); |
|
1440 QCOMPARE(proxy.size(), QSizeF(70, 70)); |
|
1441 } |
|
1442 |
|
1443 class View : public QGraphicsView |
|
1444 { |
|
1445 public: |
|
1446 View(QGraphicsScene *scene, QWidget *parent = 0) |
|
1447 : QGraphicsView(scene, parent), npaints(0) |
|
1448 { } |
|
1449 QRegion paintEventRegion; |
|
1450 int npaints; |
|
1451 protected: |
|
1452 void paintEvent(QPaintEvent *event) |
|
1453 { |
|
1454 ++npaints; |
|
1455 paintEventRegion += event->region(); |
|
1456 QGraphicsView::paintEvent(event); |
|
1457 } |
|
1458 }; |
|
1459 |
|
1460 class ScrollWidget : public QWidget |
|
1461 { |
|
1462 Q_OBJECT |
|
1463 public: |
|
1464 ScrollWidget() : npaints(0) |
|
1465 { |
|
1466 resize(200, 200); |
|
1467 } |
|
1468 QRegion paintEventRegion; |
|
1469 int npaints; |
|
1470 |
|
1471 public slots: |
|
1472 void updateScroll() |
|
1473 { |
|
1474 update(0, 0, 200, 10); |
|
1475 scroll(0, 10, QRect(0, 0, 100, 20)); |
|
1476 } |
|
1477 |
|
1478 protected: |
|
1479 void paintEvent(QPaintEvent *event) |
|
1480 { |
|
1481 ++npaints; |
|
1482 paintEventRegion += event->region(); |
|
1483 QPainter painter(this); |
|
1484 painter.fillRect(event->rect(), Qt::blue); |
|
1485 } |
|
1486 }; |
|
1487 |
|
1488 void tst_QGraphicsProxyWidget::scrollUpdate() |
|
1489 { |
|
1490 ScrollWidget *widget = new ScrollWidget; |
|
1491 |
|
1492 QGraphicsScene scene; |
|
1493 scene.addWidget(widget); |
|
1494 |
|
1495 View view(&scene); |
|
1496 view.show(); |
|
1497 QTest::qWaitForWindowShown(&view); |
|
1498 QTRY_VERIFY(view.npaints >= 1); |
|
1499 QTest::qWait(20); |
|
1500 widget->paintEventRegion = QRegion(); |
|
1501 widget->npaints = 0; |
|
1502 view.paintEventRegion = QRegion(); |
|
1503 view.npaints = 0; |
|
1504 QTimer::singleShot(0, widget, SLOT(updateScroll())); |
|
1505 QTest::qWait(50); |
|
1506 QTRY_COMPARE(view.npaints, 2); |
|
1507 // QRect(0, 0, 200, 12) is the first update, expanded (-2, -2, 2, 2) |
|
1508 // QRect(0, 12, 102, 10) is the scroll update, expanded (-2, -2, 2, 2), |
|
1509 // intersected with the above update. |
|
1510 QCOMPARE(view.paintEventRegion.rects(), |
|
1511 QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10)); |
|
1512 QCOMPARE(widget->npaints, 2); |
|
1513 QCOMPARE(widget->paintEventRegion.rects(), |
|
1514 QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10)); |
|
1515 } |
|
1516 |
|
1517 void tst_QGraphicsProxyWidget::setWidget_simple() |
|
1518 { |
|
1519 QGraphicsProxyWidget proxy; |
|
1520 QLineEdit *lineEdit = new QLineEdit; |
|
1521 proxy.setWidget(lineEdit); |
|
1522 |
|
1523 QVERIFY(lineEdit->testAttribute(Qt::WA_DontShowOnScreen)); |
|
1524 // Size hints |
|
1525 // ### size hints are tested in a different test |
|
1526 // QCOMPARE(proxy.effectiveSizeHint(Qt::MinimumSize).toSize(), lineEdit->minimumSizeHint()); |
|
1527 // QCOMPARE(proxy.effectiveSizeHint(Qt::MaximumSize).toSize(), lineEdit->maximumSize()); |
|
1528 // QCOMPARE(proxy.effectiveSizeHint(Qt::PreferredSize).toSize(), lineEdit->sizeHint()); |
|
1529 QCOMPARE(proxy.size().toSize(), lineEdit->minimumSizeHint().expandedTo(lineEdit->size())); |
|
1530 QRect rect = lineEdit->rect(); |
|
1531 rect.setSize(rect.size().expandedTo(lineEdit->minimumSizeHint())); |
|
1532 QCOMPARE(proxy.rect().toRect(), rect); |
|
1533 |
|
1534 // Properties |
|
1535 // QCOMPARE(proxy.focusPolicy(), lineEdit->focusPolicy()); |
|
1536 // QCOMPARE(proxy.palette(), lineEdit->palette()); |
|
1537 #ifndef QT_NO_CURSOR |
|
1538 QCOMPARE(proxy.cursor().shape(), lineEdit->cursor().shape()); |
|
1539 #endif |
|
1540 QCOMPARE(proxy.layoutDirection(), lineEdit->layoutDirection()); |
|
1541 QCOMPARE(proxy.style(), lineEdit->style()); |
|
1542 QCOMPARE(proxy.font(), lineEdit->font()); |
|
1543 QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled()); |
|
1544 QCOMPARE(proxy.isVisible(), lineEdit->isVisible()); |
|
1545 } |
|
1546 |
|
1547 void tst_QGraphicsProxyWidget::setWidget_ownership() |
|
1548 { |
|
1549 QPointer<QLineEdit> lineEdit = new QLineEdit; |
|
1550 QPointer<QLineEdit> lineEdit2 = new QLineEdit; |
|
1551 QVERIFY(lineEdit); |
|
1552 { |
|
1553 // Create a proxy and transfer ownership to it |
|
1554 QGraphicsProxyWidget proxy; |
|
1555 proxy.setWidget(lineEdit); |
|
1556 QCOMPARE(proxy.widget(), (QWidget *)lineEdit); |
|
1557 |
|
1558 // Remove the widget without destroying it. |
|
1559 proxy.setWidget(0); |
|
1560 QVERIFY(!proxy.widget()); |
|
1561 QVERIFY(lineEdit); |
|
1562 |
|
1563 // Assign the widget again and switch to another widget. |
|
1564 proxy.setWidget(lineEdit); |
|
1565 proxy.setWidget(lineEdit2); |
|
1566 QCOMPARE(proxy.widget(), (QWidget *)lineEdit2); |
|
1567 |
|
1568 // Assign the first widget, and destroy the proxy. |
|
1569 proxy.setWidget(lineEdit); |
|
1570 } |
|
1571 QVERIFY(!lineEdit); |
|
1572 QVERIFY(lineEdit2); |
|
1573 |
|
1574 QGraphicsScene scene; |
|
1575 QPointer<QGraphicsProxyWidget> proxy = scene.addWidget(lineEdit2); |
|
1576 |
|
1577 delete lineEdit2; |
|
1578 QVERIFY(!proxy); |
|
1579 } |
|
1580 |
|
1581 void tst_QGraphicsProxyWidget::resize_simple_data() |
|
1582 { |
|
1583 QTest::addColumn<QSizeF>("size"); |
|
1584 |
|
1585 QTest::newRow("200, 200") << QSizeF(200, 200); |
|
1586 #if !defined(QT_ARCH_ARM) && !defined(Q_OS_WINCE) |
|
1587 QTest::newRow("1000, 1000") << QSizeF(1000, 1000); |
|
1588 // Since 4.5, 10000x10000 runs out of memory. |
|
1589 // QTest::newRow("10000, 10000") << QSizeF(10000, 10000); |
|
1590 #endif |
|
1591 } |
|
1592 |
|
1593 void tst_QGraphicsProxyWidget::resize_simple() |
|
1594 { |
|
1595 QFETCH(QSizeF, size); |
|
1596 |
|
1597 QGraphicsProxyWidget proxy; |
|
1598 QWidget *widget = new QWidget; |
|
1599 widget->setGeometry(0, 0, (int)size.width(), (int)size.height()); |
|
1600 proxy.setWidget(widget); |
|
1601 widget->show(); |
|
1602 QCOMPARE(widget->pos(), QPoint()); |
|
1603 |
|
1604 // The proxy resizes itself, the line edit follows |
|
1605 proxy.resize(size); |
|
1606 QCOMPARE(proxy.size(), size); |
|
1607 QCOMPARE(proxy.size().toSize(), widget->size()); |
|
1608 |
|
1609 // The line edit resizes itself, the proxy follows (no loopback/live lock) |
|
1610 QSize doubleSize = size.toSize() * 2; |
|
1611 widget->resize(doubleSize); |
|
1612 QCOMPARE(widget->size(), doubleSize); |
|
1613 QCOMPARE(widget->size(), proxy.size().toSize()); |
|
1614 } |
|
1615 |
|
1616 void tst_QGraphicsProxyWidget::symmetricMove() |
|
1617 { |
|
1618 QGraphicsProxyWidget proxy; |
|
1619 QLineEdit *lineEdit = new QLineEdit; |
|
1620 proxy.setWidget(lineEdit); |
|
1621 lineEdit->show(); |
|
1622 |
|
1623 proxy.setPos(10, 10); |
|
1624 QCOMPARE(proxy.pos(), QPointF(10, 10)); |
|
1625 QCOMPARE(lineEdit->pos(), QPoint(10, 10)); |
|
1626 |
|
1627 lineEdit->move(5, 5); |
|
1628 QCOMPARE(proxy.pos(), QPointF(5, 5)); |
|
1629 QCOMPARE(lineEdit->pos(), QPoint(5, 5)); |
|
1630 } |
|
1631 |
|
1632 void tst_QGraphicsProxyWidget::symmetricResize() |
|
1633 { |
|
1634 QGraphicsProxyWidget proxy; |
|
1635 QLineEdit *lineEdit = new QLineEdit; |
|
1636 proxy.setWidget(lineEdit); |
|
1637 lineEdit->show(); |
|
1638 |
|
1639 proxy.resize(256, 256); |
|
1640 QCOMPARE(proxy.size(), QSizeF(256, 256)); |
|
1641 QCOMPARE(lineEdit->size(), QSize(256, 256)); |
|
1642 |
|
1643 lineEdit->resize(512, 512); |
|
1644 QCOMPARE(proxy.size(), QSizeF(512, 512)); |
|
1645 QCOMPARE(lineEdit->size(), QSize(512, 512)); |
|
1646 } |
|
1647 |
|
1648 void tst_QGraphicsProxyWidget::symmetricVisible() |
|
1649 { |
|
1650 QGraphicsProxyWidget proxy; |
|
1651 QLineEdit *lineEdit = new QLineEdit; |
|
1652 proxy.setWidget(lineEdit); |
|
1653 lineEdit->show(); |
|
1654 |
|
1655 QCOMPARE(proxy.isVisible(), lineEdit->isVisible()); |
|
1656 |
|
1657 proxy.hide(); |
|
1658 QCOMPARE(proxy.isVisible(), lineEdit->isVisible()); |
|
1659 proxy.show(); |
|
1660 QCOMPARE(proxy.isVisible(), lineEdit->isVisible()); |
|
1661 lineEdit->hide(); |
|
1662 QCOMPARE(proxy.isVisible(), lineEdit->isVisible()); |
|
1663 lineEdit->show(); |
|
1664 QCOMPARE(proxy.isVisible(), lineEdit->isVisible()); |
|
1665 } |
|
1666 |
|
1667 void tst_QGraphicsProxyWidget::symmetricEnabled() |
|
1668 { |
|
1669 QGraphicsProxyWidget proxy; |
|
1670 QLineEdit *lineEdit = new QLineEdit; |
|
1671 proxy.setWidget(lineEdit); |
|
1672 lineEdit->show(); |
|
1673 |
|
1674 QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled()); |
|
1675 proxy.setEnabled(false); |
|
1676 QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled()); |
|
1677 proxy.setEnabled(true); |
|
1678 QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled()); |
|
1679 lineEdit->setEnabled(false); |
|
1680 QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled()); |
|
1681 lineEdit->setEnabled(true); |
|
1682 QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled()); |
|
1683 } |
|
1684 |
|
1685 void tst_QGraphicsProxyWidget::tabFocus_simpleWidget() |
|
1686 { |
|
1687 QGraphicsScene scene; |
|
1688 QLineEdit *edit = new QLineEdit; |
|
1689 QGraphicsProxyWidget *editProxy = scene.addWidget(edit); |
|
1690 editProxy->show(); |
|
1691 |
|
1692 QDial *leftDial = new QDial; |
|
1693 QDial *rightDial = new QDial; |
|
1694 QGraphicsView *view = new QGraphicsView(&scene); |
|
1695 |
|
1696 QWidget window; |
|
1697 QHBoxLayout *layout = new QHBoxLayout; |
|
1698 layout->addWidget(leftDial); |
|
1699 layout->addWidget(view); |
|
1700 layout->addWidget(rightDial); |
|
1701 window.setLayout(layout); |
|
1702 |
|
1703 window.show(); |
|
1704 QApplication::setActiveWindow(&window); |
|
1705 window.activateWindow(); |
|
1706 QTest::qWaitForWindowShown(&window); |
|
1707 |
|
1708 leftDial->setFocus(); |
|
1709 QApplication::processEvents(); |
|
1710 QTRY_VERIFY(leftDial->hasFocus()); |
|
1711 |
|
1712 EventSpy eventSpy(edit); |
|
1713 |
|
1714 // Tab into line edit |
|
1715 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1716 QApplication::processEvents(); |
|
1717 QTRY_VERIFY(!leftDial->hasFocus()); |
|
1718 QTRY_VERIFY(view->hasFocus()); |
|
1719 QVERIFY(view->viewport()->hasFocus()); |
|
1720 QVERIFY(scene.hasFocus()); |
|
1721 QVERIFY(editProxy->hasFocus()); |
|
1722 QVERIFY(edit->hasFocus()); |
|
1723 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1724 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0); |
|
1725 |
|
1726 // Tab into right dial |
|
1727 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1728 QApplication::processEvents(); |
|
1729 QTRY_VERIFY(!view->hasFocus()); |
|
1730 QVERIFY(!view->viewport()->hasFocus()); |
|
1731 QVERIFY(!scene.hasFocus()); |
|
1732 QVERIFY(!editProxy->hasFocus()); |
|
1733 QVERIFY(!edit->hasFocus()); |
|
1734 QTRY_VERIFY(rightDial->hasFocus()); |
|
1735 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1736 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1737 |
|
1738 // Backtab into line edit |
|
1739 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1740 QApplication::processEvents(); |
|
1741 QTRY_VERIFY(view->hasFocus()); |
|
1742 QVERIFY(view->viewport()->hasFocus()); |
|
1743 QTRY_VERIFY(scene.hasFocus()); |
|
1744 QVERIFY(editProxy->hasFocus()); |
|
1745 QVERIFY(edit->hasFocus()); |
|
1746 QVERIFY(!rightDial->hasFocus()); |
|
1747 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2); |
|
1748 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1749 |
|
1750 // Backtab into left dial |
|
1751 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1752 QApplication::processEvents(); |
|
1753 QTRY_VERIFY(!view->hasFocus()); |
|
1754 QVERIFY(!view->viewport()->hasFocus()); |
|
1755 QVERIFY(!scene.hasFocus()); |
|
1756 QVERIFY(!editProxy->hasFocus()); |
|
1757 QVERIFY(!edit->hasFocus()); |
|
1758 QTRY_VERIFY(leftDial->hasFocus()); |
|
1759 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2); |
|
1760 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 2); |
|
1761 |
|
1762 delete view; |
|
1763 } |
|
1764 |
|
1765 void tst_QGraphicsProxyWidget::tabFocus_simpleTwoWidgets() |
|
1766 { |
|
1767 QGraphicsScene scene; |
|
1768 QLineEdit *edit = new QLineEdit; |
|
1769 QLineEdit *edit2 = new QLineEdit; |
|
1770 QGraphicsProxyWidget *editProxy = scene.addWidget(edit); |
|
1771 editProxy->show(); |
|
1772 QGraphicsProxyWidget *editProxy2 = scene.addWidget(edit2); |
|
1773 editProxy2->show(); |
|
1774 editProxy2->setPos(0, editProxy->rect().height() * 1.1); |
|
1775 |
|
1776 QDial *leftDial = new QDial; |
|
1777 QDial *rightDial = new QDial; |
|
1778 QGraphicsView *view = new QGraphicsView(&scene); |
|
1779 |
|
1780 QWidget window; |
|
1781 QHBoxLayout *layout = new QHBoxLayout; |
|
1782 layout->addWidget(leftDial); |
|
1783 layout->addWidget(view); |
|
1784 layout->addWidget(rightDial); |
|
1785 window.setLayout(layout); |
|
1786 |
|
1787 window.show(); |
|
1788 QApplication::setActiveWindow(&window); |
|
1789 window.activateWindow(); |
|
1790 QTest::qWaitForWindowShown(&window); |
|
1791 |
|
1792 leftDial->setFocus(); |
|
1793 QApplication::processEvents(); |
|
1794 QTRY_VERIFY(leftDial->hasFocus()); |
|
1795 |
|
1796 EventSpy eventSpy(edit); |
|
1797 EventSpy eventSpy2(edit2); |
|
1798 |
|
1799 // Tab into line edit |
|
1800 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1801 QApplication::processEvents(); |
|
1802 QVERIFY(!leftDial->hasFocus()); |
|
1803 QVERIFY(view->hasFocus()); |
|
1804 QVERIFY(view->viewport()->hasFocus()); |
|
1805 QVERIFY(scene.hasFocus()); |
|
1806 QVERIFY(editProxy->hasFocus()); |
|
1807 QVERIFY(edit->hasFocus()); |
|
1808 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1809 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0); |
|
1810 |
|
1811 // Tab into second line edit |
|
1812 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1813 QApplication::processEvents(); |
|
1814 QVERIFY(view->hasFocus()); |
|
1815 QVERIFY(view->viewport()->hasFocus()); |
|
1816 QVERIFY(scene.hasFocus()); |
|
1817 QVERIFY(!editProxy->hasFocus()); |
|
1818 QVERIFY(!edit->hasFocus()); |
|
1819 QVERIFY(editProxy2->hasFocus()); |
|
1820 QVERIFY(edit2->hasFocus()); |
|
1821 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1822 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1823 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1); |
|
1824 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 0); |
|
1825 |
|
1826 // Tab into right dial |
|
1827 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1828 QApplication::processEvents(); |
|
1829 QVERIFY(!view->hasFocus()); |
|
1830 QVERIFY(!view->viewport()->hasFocus()); |
|
1831 QVERIFY(!scene.hasFocus()); |
|
1832 QVERIFY(!editProxy->hasFocus()); |
|
1833 QVERIFY(!edit->hasFocus()); |
|
1834 QVERIFY(!editProxy2->hasFocus()); |
|
1835 QVERIFY(!edit2->hasFocus()); |
|
1836 QVERIFY(rightDial->hasFocus()); |
|
1837 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1838 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1839 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1); |
|
1840 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1); |
|
1841 |
|
1842 // Backtab into line edit 2 |
|
1843 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1844 QApplication::processEvents(); |
|
1845 QVERIFY(view->hasFocus()); |
|
1846 QVERIFY(view->viewport()->hasFocus()); |
|
1847 QVERIFY(scene.hasFocus()); |
|
1848 QVERIFY(!editProxy->hasFocus()); |
|
1849 QVERIFY(!edit->hasFocus()); |
|
1850 QVERIFY(editProxy2->hasFocus()); |
|
1851 QVERIFY(edit2->hasFocus()); |
|
1852 QVERIFY(!rightDial->hasFocus()); |
|
1853 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1854 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1855 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 2); |
|
1856 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1); |
|
1857 |
|
1858 // Backtab into line edit 1 |
|
1859 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1860 QApplication::processEvents(); |
|
1861 QVERIFY(view->hasFocus()); |
|
1862 QVERIFY(view->viewport()->hasFocus()); |
|
1863 QVERIFY(scene.hasFocus()); |
|
1864 QVERIFY(editProxy->hasFocus()); |
|
1865 QVERIFY(edit->hasFocus()); |
|
1866 QVERIFY(!editProxy2->hasFocus()); |
|
1867 QVERIFY(!edit2->hasFocus()); |
|
1868 QVERIFY(!rightDial->hasFocus()); |
|
1869 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2); |
|
1870 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1871 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 2); |
|
1872 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 2); |
|
1873 |
|
1874 // Backtab into left dial |
|
1875 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1876 QApplication::processEvents(); |
|
1877 QVERIFY(!view->hasFocus()); |
|
1878 QVERIFY(!view->viewport()->hasFocus()); |
|
1879 QVERIFY(!scene.hasFocus()); |
|
1880 QVERIFY(!editProxy->hasFocus()); |
|
1881 QVERIFY(!edit->hasFocus()); |
|
1882 QVERIFY(leftDial->hasFocus()); |
|
1883 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2); |
|
1884 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 2); |
|
1885 |
|
1886 delete view; |
|
1887 } |
|
1888 |
|
1889 void tst_QGraphicsProxyWidget::tabFocus_complexWidget() |
|
1890 { |
|
1891 QGraphicsScene scene; |
|
1892 |
|
1893 QLineEdit *edit1 = new QLineEdit; |
|
1894 edit1->setText("QLineEdit 1"); |
|
1895 QLineEdit *edit2 = new QLineEdit; |
|
1896 edit2->setText("QLineEdit 2"); |
|
1897 QVBoxLayout *vlayout = new QVBoxLayout; |
|
1898 vlayout->addWidget(edit1); |
|
1899 vlayout->addWidget(edit2); |
|
1900 |
|
1901 QGroupBox *box = new QGroupBox("QGroupBox"); |
|
1902 box->setCheckable(true); |
|
1903 box->setChecked(true); |
|
1904 box->setLayout(vlayout); |
|
1905 |
|
1906 QGraphicsProxyWidget *proxy = scene.addWidget(box); |
|
1907 proxy->show(); |
|
1908 |
|
1909 QDial *leftDial = new QDial; |
|
1910 QDial *rightDial = new QDial; |
|
1911 QGraphicsView *view = new QGraphicsView(&scene); |
|
1912 |
|
1913 QWidget window; |
|
1914 QHBoxLayout *layout = new QHBoxLayout; |
|
1915 layout->addWidget(leftDial); |
|
1916 layout->addWidget(view); |
|
1917 layout->addWidget(rightDial); |
|
1918 window.setLayout(layout); |
|
1919 |
|
1920 window.show(); |
|
1921 QApplication::setActiveWindow(&window); |
|
1922 window.activateWindow(); |
|
1923 QTest::qWaitForWindowShown(&window); |
|
1924 |
|
1925 leftDial->setFocus(); |
|
1926 QApplication::processEvents(); |
|
1927 QTRY_VERIFY(leftDial->hasFocus()); |
|
1928 |
|
1929 EventSpy eventSpy(edit1); |
|
1930 EventSpy eventSpy2(edit2); |
|
1931 EventSpy eventSpyBox(box); |
|
1932 |
|
1933 // Tab into group box |
|
1934 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1935 QApplication::processEvents(); |
|
1936 QVERIFY(!leftDial->hasFocus()); |
|
1937 QVERIFY(view->hasFocus()); |
|
1938 QVERIFY(view->viewport()->hasFocus()); |
|
1939 QVERIFY(scene.hasFocus()); |
|
1940 QVERIFY(proxy->hasFocus()); |
|
1941 QVERIFY(box->hasFocus()); |
|
1942 |
|
1943 // Tab into line edit |
|
1944 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1945 QApplication::processEvents(); |
|
1946 edit1->hasFocus(); |
|
1947 QVERIFY(!box->hasFocus()); |
|
1948 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1949 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0); |
|
1950 |
|
1951 // Tab into line edit 2 |
|
1952 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1953 QApplication::processEvents(); |
|
1954 edit2->hasFocus(); |
|
1955 QVERIFY(!edit1->hasFocus()); |
|
1956 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
1957 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
1958 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1); |
|
1959 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 0); |
|
1960 |
|
1961 // Tab into right dial |
|
1962 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
1963 QApplication::processEvents(); |
|
1964 QVERIFY(!edit2->hasFocus()); |
|
1965 rightDial->hasFocus(); |
|
1966 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1); |
|
1967 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1); |
|
1968 |
|
1969 // Backtab into line edit 2 |
|
1970 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1971 QApplication::processEvents(); |
|
1972 QVERIFY(!rightDial->hasFocus()); |
|
1973 edit2->hasFocus(); |
|
1974 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 2); |
|
1975 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1); |
|
1976 |
|
1977 // Backtab into line edit 1 |
|
1978 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1979 QApplication::processEvents(); |
|
1980 QVERIFY(!edit2->hasFocus()); |
|
1981 edit1->hasFocus(); |
|
1982 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 2); |
|
1983 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2); |
|
1984 |
|
1985 // Backtab into line box |
|
1986 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1987 QApplication::processEvents(); |
|
1988 QVERIFY(!edit1->hasFocus()); |
|
1989 box->hasFocus(); |
|
1990 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 2); |
|
1991 |
|
1992 // Backtab into left dial |
|
1993 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
1994 QApplication::processEvents(); |
|
1995 QVERIFY(!box->hasFocus()); |
|
1996 leftDial->hasFocus(); |
|
1997 |
|
1998 delete view; |
|
1999 } |
|
2000 |
|
2001 void tst_QGraphicsProxyWidget::tabFocus_complexTwoWidgets() |
|
2002 { |
|
2003 // ### add event spies to this test. |
|
2004 QGraphicsScene scene; |
|
2005 |
|
2006 QLineEdit *edit1 = new QLineEdit; |
|
2007 edit1->setText("QLineEdit 1"); |
|
2008 QLineEdit *edit2 = new QLineEdit; |
|
2009 edit2->setText("QLineEdit 2"); |
|
2010 QFontComboBox *fontComboBox = new QFontComboBox; |
|
2011 QVBoxLayout *vlayout = new QVBoxLayout; |
|
2012 vlayout->addWidget(edit1); |
|
2013 vlayout->addWidget(fontComboBox); |
|
2014 vlayout->addWidget(edit2); |
|
2015 |
|
2016 QGroupBox *box = new QGroupBox("QGroupBox"); |
|
2017 box->setCheckable(true); |
|
2018 box->setChecked(true); |
|
2019 box->setLayout(vlayout); |
|
2020 |
|
2021 QLineEdit *edit1_2 = new QLineEdit; |
|
2022 edit1_2->setText("QLineEdit 1_2"); |
|
2023 QLineEdit *edit2_2 = new QLineEdit; |
|
2024 edit2_2->setText("QLineEdit 2_2"); |
|
2025 QFontComboBox *fontComboBox2 = new QFontComboBox; |
|
2026 vlayout = new QVBoxLayout; |
|
2027 vlayout->addWidget(edit1_2); |
|
2028 vlayout->addWidget(fontComboBox2); |
|
2029 vlayout->addWidget(edit2_2); |
|
2030 |
|
2031 QGroupBox *box_2 = new QGroupBox("QGroupBox 2"); |
|
2032 box_2->setCheckable(true); |
|
2033 box_2->setChecked(true); |
|
2034 box_2->setLayout(vlayout); |
|
2035 |
|
2036 QGraphicsProxyWidget *proxy = scene.addWidget(box); |
|
2037 proxy->show(); |
|
2038 |
|
2039 QGraphicsProxyWidget *proxy_2 = scene.addWidget(box_2); |
|
2040 proxy_2->setPos(proxy->boundingRect().width() * 1.2, 0); |
|
2041 proxy_2->show(); |
|
2042 |
|
2043 QDial *leftDial = new QDial; |
|
2044 QDial *rightDial = new QDial; |
|
2045 QGraphicsView *view = new QGraphicsView(&scene); |
|
2046 view->setRenderHint(QPainter::Antialiasing); |
|
2047 view->rotate(45); |
|
2048 view->scale(0.5, 0.5); |
|
2049 |
|
2050 QWidget window; |
|
2051 QHBoxLayout *layout = new QHBoxLayout; |
|
2052 layout->addWidget(leftDial); |
|
2053 layout->addWidget(view); |
|
2054 layout->addWidget(rightDial); |
|
2055 window.setLayout(layout); |
|
2056 |
|
2057 window.show(); |
|
2058 QApplication::setActiveWindow(&window); |
|
2059 window.activateWindow(); |
|
2060 QTest::qWaitForWindowShown(&window); |
|
2061 QTRY_COMPARE(QApplication::activeWindow(), &window); |
|
2062 |
|
2063 leftDial->setFocus(); |
|
2064 QApplication::processEvents(); |
|
2065 QTRY_VERIFY(leftDial->hasFocus()); |
|
2066 |
|
2067 EventSpy eventSpy(edit1); |
|
2068 EventSpy eventSpy2(edit2); |
|
2069 EventSpy eventSpy3(fontComboBox); |
|
2070 EventSpy eventSpy1_2(edit1_2); |
|
2071 EventSpy eventSpy2_2(edit2_2); |
|
2072 EventSpy eventSpy2_3(fontComboBox2); |
|
2073 EventSpy eventSpyBox(box); |
|
2074 |
|
2075 // Tab into group box |
|
2076 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2077 QApplication::processEvents(); |
|
2078 QVERIFY(!leftDial->hasFocus()); |
|
2079 QVERIFY(view->hasFocus()); |
|
2080 QVERIFY(view->viewport()->hasFocus()); |
|
2081 QVERIFY(scene.hasFocus()); |
|
2082 QVERIFY(proxy->hasFocus()); |
|
2083 QVERIFY(box->hasFocus()); |
|
2084 |
|
2085 // Tab into line edit |
|
2086 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2087 QApplication::processEvents(); |
|
2088 edit1->hasFocus(); |
|
2089 QVERIFY(!box->hasFocus()); |
|
2090 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2091 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0); |
|
2092 |
|
2093 // Tab to the font combobox |
|
2094 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2095 QApplication::processEvents(); |
|
2096 fontComboBox->hasFocus(); |
|
2097 QVERIFY(!edit2->hasFocus()); |
|
2098 QCOMPARE(eventSpy3.counts[QEvent::FocusIn], 1); |
|
2099 QCOMPARE(eventSpy3.counts[QEvent::FocusOut], 0); |
|
2100 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2101 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
2102 |
|
2103 // Tab into line edit 2 |
|
2104 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2105 QApplication::processEvents(); |
|
2106 edit2->hasFocus(); |
|
2107 QVERIFY(!edit1->hasFocus()); |
|
2108 QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1); |
|
2109 QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 0); |
|
2110 QCOMPARE(eventSpy3.counts[QEvent::FocusOut], 1); |
|
2111 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2112 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
2113 |
|
2114 // Tab into right box |
|
2115 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2116 QApplication::processEvents(); |
|
2117 QVERIFY(!edit2->hasFocus()); |
|
2118 box_2->hasFocus(); |
|
2119 |
|
2120 // Tab into right top line edit |
|
2121 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2122 QApplication::processEvents(); |
|
2123 QVERIFY(!box_2->hasFocus()); |
|
2124 edit1_2->hasFocus(); |
|
2125 QCOMPARE(eventSpy1_2.counts[QEvent::FocusIn], 1); |
|
2126 QCOMPARE(eventSpy1_2.counts[QEvent::FocusOut], 0); |
|
2127 |
|
2128 // Tab into right font combobox |
|
2129 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2130 QApplication::processEvents(); |
|
2131 QVERIFY(!edit1_2->hasFocus()); |
|
2132 fontComboBox2->hasFocus(); |
|
2133 QCOMPARE(eventSpy1_2.counts[QEvent::FocusIn], 1); |
|
2134 QCOMPARE(eventSpy1_2.counts[QEvent::FocusOut], 1); |
|
2135 QCOMPARE(eventSpy2_3.counts[QEvent::FocusIn], 1); |
|
2136 QCOMPARE(eventSpy2_3.counts[QEvent::FocusOut], 0); |
|
2137 |
|
2138 // Tab into right bottom line edit |
|
2139 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2140 QApplication::processEvents(); |
|
2141 QVERIFY(!edit1_2->hasFocus()); |
|
2142 edit2_2->hasFocus(); |
|
2143 QCOMPARE(eventSpy1_2.counts[QEvent::FocusIn], 1); |
|
2144 QCOMPARE(eventSpy1_2.counts[QEvent::FocusOut], 1); |
|
2145 QCOMPARE(eventSpy2_3.counts[QEvent::FocusIn], 1); |
|
2146 QCOMPARE(eventSpy2_3.counts[QEvent::FocusOut], 1); |
|
2147 QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 1); |
|
2148 QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 0); |
|
2149 |
|
2150 // Tab into right dial |
|
2151 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
|
2152 QApplication::processEvents(); |
|
2153 QVERIFY(!edit2->hasFocus()); |
|
2154 rightDial->hasFocus(); |
|
2155 QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 1); |
|
2156 |
|
2157 // Backtab into line edit 2 |
|
2158 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2159 QApplication::processEvents(); |
|
2160 QVERIFY(!rightDial->hasFocus()); |
|
2161 edit2_2->hasFocus(); |
|
2162 |
|
2163 // Backtab into the right font combobox |
|
2164 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2165 QApplication::processEvents(); |
|
2166 QVERIFY(!edit2_2->hasFocus()); |
|
2167 fontComboBox2->hasFocus(); |
|
2168 |
|
2169 // Backtab into line edit 1 |
|
2170 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2171 QApplication::processEvents(); |
|
2172 QVERIFY(!edit2_2->hasFocus()); |
|
2173 edit1_2->hasFocus(); |
|
2174 |
|
2175 // Backtab into line box |
|
2176 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2177 QApplication::processEvents(); |
|
2178 QVERIFY(!edit1_2->hasFocus()); |
|
2179 box_2->hasFocus(); |
|
2180 |
|
2181 // Backtab into line edit 2 |
|
2182 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2183 QApplication::processEvents(); |
|
2184 QVERIFY(!rightDial->hasFocus()); |
|
2185 edit2->hasFocus(); |
|
2186 |
|
2187 // Backtab into the font combobox |
|
2188 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2189 QApplication::processEvents(); |
|
2190 QVERIFY(!edit2->hasFocus()); |
|
2191 fontComboBox->hasFocus(); |
|
2192 |
|
2193 // Backtab into line edit 1 |
|
2194 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2195 QApplication::processEvents(); |
|
2196 QVERIFY(!fontComboBox->hasFocus()); |
|
2197 edit1->hasFocus(); |
|
2198 |
|
2199 // Backtab into line box |
|
2200 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2201 QApplication::processEvents(); |
|
2202 QVERIFY(!edit1->hasFocus()); |
|
2203 box->hasFocus(); |
|
2204 |
|
2205 // Backtab into left dial |
|
2206 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
|
2207 QApplication::processEvents(); |
|
2208 QVERIFY(!box->hasFocus()); |
|
2209 leftDial->hasFocus(); |
|
2210 |
|
2211 delete view; |
|
2212 } |
|
2213 |
|
2214 void tst_QGraphicsProxyWidget::setFocus_simpleWidget() |
|
2215 { |
|
2216 QGraphicsScene scene; |
|
2217 QLineEdit *edit = new QLineEdit; |
|
2218 QGraphicsProxyWidget *editProxy = scene.addWidget(edit); |
|
2219 editProxy->show(); |
|
2220 |
|
2221 QDial *leftDial = new QDial; |
|
2222 QDial *rightDial = new QDial; |
|
2223 QGraphicsView *view = new QGraphicsView(&scene); |
|
2224 |
|
2225 QWidget window; |
|
2226 QHBoxLayout *layout = new QHBoxLayout; |
|
2227 layout->addWidget(leftDial); |
|
2228 layout->addWidget(view); |
|
2229 layout->addWidget(rightDial); |
|
2230 window.setLayout(layout); |
|
2231 |
|
2232 window.show(); |
|
2233 QApplication::setActiveWindow(&window); |
|
2234 window.activateWindow(); |
|
2235 QTest::qWaitForWindowShown(&window); |
|
2236 QTRY_COMPARE(QApplication::activeWindow(), &window); |
|
2237 |
|
2238 leftDial->setFocus(); |
|
2239 QApplication::processEvents(); |
|
2240 QTRY_VERIFY(leftDial->hasFocus()); |
|
2241 |
|
2242 EventSpy eventSpy(edit); |
|
2243 |
|
2244 // Calling setFocus for the line edit when the view doesn't have input |
|
2245 // focus does not steal focus from the dial. The edit, proxy and scene |
|
2246 // have focus but only in their own little space. |
|
2247 edit->setFocus(); |
|
2248 QVERIFY(scene.hasFocus()); |
|
2249 QVERIFY(edit->hasFocus()); |
|
2250 QVERIFY(!view->hasFocus()); |
|
2251 QVERIFY(!view->viewport()->hasFocus()); |
|
2252 QVERIFY(leftDial->hasFocus()); |
|
2253 |
|
2254 // Clearing focus is a local operation. |
|
2255 edit->clearFocus(); |
|
2256 QVERIFY(scene.hasFocus()); |
|
2257 QVERIFY(!edit->hasFocus()); |
|
2258 QVERIFY(!view->hasFocus()); |
|
2259 QVERIFY(leftDial->hasFocus()); |
|
2260 |
|
2261 view->setFocus(); |
|
2262 QVERIFY(scene.hasFocus()); |
|
2263 QVERIFY(view->hasFocus()); |
|
2264 QVERIFY(!leftDial->hasFocus()); |
|
2265 QVERIFY(!edit->hasFocus()); |
|
2266 |
|
2267 scene.clearFocus(); |
|
2268 QVERIFY(!scene.hasFocus()); |
|
2269 |
|
2270 edit->setFocus(); |
|
2271 QVERIFY(scene.hasFocus()); |
|
2272 QVERIFY(edit->hasFocus()); |
|
2273 QVERIFY(editProxy->hasFocus()); |
|
2274 |
|
2275 // Symmetry |
|
2276 editProxy->clearFocus(); |
|
2277 QVERIFY(!edit->hasFocus()); |
|
2278 |
|
2279 delete view; |
|
2280 } |
|
2281 |
|
2282 void tst_QGraphicsProxyWidget::setFocus_simpleTwoWidgets() |
|
2283 { |
|
2284 QGraphicsScene scene; |
|
2285 QLineEdit *edit = new QLineEdit; |
|
2286 QGraphicsProxyWidget *editProxy = scene.addWidget(edit); |
|
2287 editProxy->show(); |
|
2288 QLineEdit *edit2 = new QLineEdit; |
|
2289 QGraphicsProxyWidget *edit2Proxy = scene.addWidget(edit2); |
|
2290 edit2Proxy->show(); |
|
2291 edit2Proxy->setPos(editProxy->boundingRect().width() * 1.01, 0); |
|
2292 |
|
2293 QDial *leftDial = new QDial; |
|
2294 QDial *rightDial = new QDial; |
|
2295 QGraphicsView *view = new QGraphicsView(&scene); |
|
2296 |
|
2297 QWidget window; |
|
2298 QHBoxLayout *layout = new QHBoxLayout; |
|
2299 layout->addWidget(leftDial); |
|
2300 layout->addWidget(view); |
|
2301 layout->addWidget(rightDial); |
|
2302 window.setLayout(layout); |
|
2303 |
|
2304 window.show(); |
|
2305 QApplication::setActiveWindow(&window); |
|
2306 window.activateWindow(); |
|
2307 QTest::qWaitForWindowShown(&window); |
|
2308 QTRY_COMPARE(QApplication::activeWindow(), &window); |
|
2309 |
|
2310 leftDial->setFocus(); |
|
2311 QApplication::processEvents(); |
|
2312 QTRY_VERIFY(leftDial->hasFocus()); |
|
2313 |
|
2314 EventSpy eventSpy(edit); |
|
2315 |
|
2316 view->setFocus(); |
|
2317 QVERIFY(!edit->hasFocus()); |
|
2318 |
|
2319 edit->setFocus(); |
|
2320 QVERIFY(scene.hasFocus()); |
|
2321 QVERIFY(edit->hasFocus()); |
|
2322 QVERIFY(editProxy->hasFocus()); |
|
2323 |
|
2324 edit2->setFocus(); |
|
2325 QVERIFY(scene.hasFocus()); |
|
2326 QVERIFY(!edit->hasFocus()); |
|
2327 QVERIFY(!editProxy->hasFocus()); |
|
2328 QVERIFY(edit2->hasFocus()); |
|
2329 QVERIFY(edit2Proxy->hasFocus()); |
|
2330 |
|
2331 delete view; |
|
2332 } |
|
2333 |
|
2334 void tst_QGraphicsProxyWidget::setFocus_complexTwoWidgets() |
|
2335 { |
|
2336 // ### add event spies to this test. |
|
2337 QGraphicsScene scene; |
|
2338 |
|
2339 QLineEdit *edit1 = new QLineEdit; |
|
2340 edit1->setText("QLineEdit 1"); |
|
2341 QLineEdit *edit2 = new QLineEdit; |
|
2342 edit2->setText("QLineEdit 2"); |
|
2343 QVBoxLayout *vlayout = new QVBoxLayout; |
|
2344 vlayout->addWidget(edit1); |
|
2345 vlayout->addWidget(edit2); |
|
2346 |
|
2347 QGroupBox *box = new QGroupBox("QGroupBox"); |
|
2348 box->setCheckable(true); |
|
2349 box->setChecked(true); |
|
2350 box->setLayout(vlayout); |
|
2351 |
|
2352 QLineEdit *edit1_2 = new QLineEdit; |
|
2353 edit1_2->setText("QLineEdit 1_2"); |
|
2354 QLineEdit *edit2_2 = new QLineEdit; |
|
2355 edit2_2->setText("QLineEdit 2_2"); |
|
2356 vlayout = new QVBoxLayout; |
|
2357 vlayout->addWidget(edit1_2); |
|
2358 vlayout->addWidget(edit2_2); |
|
2359 |
|
2360 QGroupBox *box_2 = new QGroupBox("QGroupBox 2"); |
|
2361 box_2->setCheckable(true); |
|
2362 box_2->setChecked(true); |
|
2363 box_2->setLayout(vlayout); |
|
2364 |
|
2365 QGraphicsProxyWidget *proxy = scene.addWidget(box); |
|
2366 proxy->show(); |
|
2367 |
|
2368 QGraphicsProxyWidget *proxy_2 = scene.addWidget(box_2); |
|
2369 proxy_2->setPos(proxy->boundingRect().width() * 1.2, 0); |
|
2370 proxy_2->show(); |
|
2371 |
|
2372 QDial *leftDial = new QDial; |
|
2373 QDial *rightDial = new QDial; |
|
2374 QGraphicsView *view = new QGraphicsView(&scene); |
|
2375 |
|
2376 QWidget window; |
|
2377 QHBoxLayout *layout = new QHBoxLayout; |
|
2378 layout->addWidget(leftDial); |
|
2379 layout->addWidget(view); |
|
2380 layout->addWidget(rightDial); |
|
2381 window.setLayout(layout); |
|
2382 |
|
2383 window.show(); |
|
2384 QApplication::setActiveWindow(&window); |
|
2385 window.activateWindow(); |
|
2386 QTest::qWaitForWindowShown(&window); |
|
2387 QTRY_COMPARE(QApplication::activeWindow(), &window); |
|
2388 |
|
2389 leftDial->setFocus(); |
|
2390 QApplication::processEvents(); |
|
2391 QTRY_VERIFY(leftDial->hasFocus()); |
|
2392 |
|
2393 EventSpy eventSpy(edit1); |
|
2394 EventSpy eventSpy2(edit2); |
|
2395 EventSpy eventSpyBox(box); |
|
2396 EventSpy eventSpy_2(edit1_2); |
|
2397 EventSpy eventSpy2_2(edit2_2); |
|
2398 EventSpy eventSpyBox_2(box_2); |
|
2399 |
|
2400 view->setFocus(); |
|
2401 |
|
2402 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 0); |
|
2403 |
|
2404 edit1->setFocus(); |
|
2405 QApplication::processEvents(); |
|
2406 QVERIFY(scene.hasFocus()); |
|
2407 QVERIFY(edit1->hasFocus()); |
|
2408 QVERIFY(!box->hasFocus()); |
|
2409 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2410 QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 0); |
|
2411 |
|
2412 edit2_2->setFocus(); |
|
2413 QApplication::processEvents(); |
|
2414 QVERIFY(!edit1->hasFocus()); |
|
2415 QVERIFY(!box_2->hasFocus()); |
|
2416 QVERIFY(edit2_2->hasFocus()); |
|
2417 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2418 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
2419 QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 1); |
|
2420 QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 0); |
|
2421 QCOMPARE(eventSpyBox_2.counts[QEvent::FocusIn], 0); |
|
2422 |
|
2423 box->setFocus(); |
|
2424 QApplication::processEvents(); |
|
2425 QVERIFY(!edit2_2->hasFocus()); |
|
2426 QVERIFY(!edit1->hasFocus()); |
|
2427 QVERIFY(box->hasFocus()); |
|
2428 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2429 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
2430 QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 1); |
|
2431 QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 1); |
|
2432 QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 1); |
|
2433 QCOMPARE(eventSpyBox.counts[QEvent::FocusOut], 0); |
|
2434 QCOMPARE(eventSpyBox_2.counts[QEvent::FocusIn], 0); |
|
2435 QCOMPARE(eventSpyBox_2.counts[QEvent::FocusOut], 0); |
|
2436 |
|
2437 edit2_2->setFocus(); |
|
2438 QApplication::processEvents(); |
|
2439 QVERIFY(edit2_2->hasFocus()); |
|
2440 QVERIFY(!edit1->hasFocus()); |
|
2441 QVERIFY(!box->hasFocus()); |
|
2442 QVERIFY(!box_2->hasFocus()); |
|
2443 QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1); |
|
2444 QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1); |
|
2445 QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 2); |
|
2446 QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 1); |
|
2447 QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 1); |
|
2448 QCOMPARE(eventSpyBox.counts[QEvent::FocusOut], 1); |
|
2449 QCOMPARE(eventSpyBox_2.counts[QEvent::FocusIn], 0); |
|
2450 QCOMPARE(eventSpyBox_2.counts[QEvent::FocusOut], 0); |
|
2451 |
|
2452 delete view; |
|
2453 } |
|
2454 |
|
2455 void tst_QGraphicsProxyWidget::popup_basic() |
|
2456 { |
|
2457 // ProxyWidget should automatically create proxy's when the widget creates a child |
|
2458 QGraphicsScene *scene = new QGraphicsScene; |
|
2459 QGraphicsView view(scene); |
|
2460 view.setAlignment(Qt::AlignLeft | Qt::AlignTop); |
|
2461 view.setGeometry(0, 100, 480, 500); |
|
2462 view.show(); |
|
2463 |
|
2464 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
2465 QComboBox *box = new QComboBox; |
|
2466 box->setGeometry(0, 0, 320, 40); |
|
2467 box->addItems(QStringList() << "monday" << "tuesday" << "wednesday" |
|
2468 << "thursday" << "saturday" << "sunday"); |
|
2469 QCOMPARE(proxy->childItems().count(), 0); |
|
2470 proxy->setWidget(box); |
|
2471 proxy->show(); |
|
2472 scene->addItem(proxy); |
|
2473 |
|
2474 QCOMPARE(box->pos(), QPoint()); |
|
2475 QCOMPARE(proxy->pos(), QPointF()); |
|
2476 |
|
2477 QTest::qWaitForWindowShown(&view); |
|
2478 QTest::qWait(125); |
|
2479 QApplication::processEvents(); |
|
2480 |
|
2481 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, |
|
2482 view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); |
|
2483 |
|
2484 QTest::qWait(12); |
|
2485 |
|
2486 QCOMPARE(box->pos(), QPoint()); |
|
2487 |
|
2488 QCOMPARE(proxy->childItems().count(), 1); |
|
2489 QGraphicsProxyWidget *child = (QGraphicsProxyWidget*)(proxy->childItems())[0]; |
|
2490 QVERIFY(child->isWidget()); |
|
2491 QVERIFY(child->widget()); |
|
2492 QStyleOptionComboBox opt; |
|
2493 opt.initFrom(box); |
|
2494 opt.editable = box->isEditable(); |
|
2495 if (box->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt)) |
|
2496 QSKIP("Does not work due to SH_Combobox_Popup", SkipAll); |
|
2497 QCOMPARE(child->widget()->parent(), static_cast<QObject*>(box)); |
|
2498 |
|
2499 QTest::qWait(12); |
|
2500 QTRY_COMPARE(proxy->pos(), QPointF(box->pos())); |
|
2501 QCOMPARE(child->x(), qreal(box->x())); |
|
2502 QCOMPARE(child->y(), qreal(box->rect().bottom())); |
|
2503 #ifndef Q_OS_WIN |
|
2504 // The popup's coordinates on Windows are in global space, |
|
2505 // regardless. |
|
2506 QCOMPARE(child->widget()->x(), box->x()); |
|
2507 QCOMPARE(child->widget()->y(), box->rect().bottom()); |
|
2508 QCOMPARE(child->geometry().toRect(), child->widget()->geometry()); |
|
2509 #endif |
|
2510 QTest::qWait(12); |
|
2511 } |
|
2512 |
|
2513 void tst_QGraphicsProxyWidget::popup_subwidget() |
|
2514 { |
|
2515 QGroupBox *groupBox = new QGroupBox; |
|
2516 groupBox->setTitle("GroupBox"); |
|
2517 groupBox->setCheckable(true); |
|
2518 |
|
2519 QComboBox *box = new QComboBox; |
|
2520 box->addItems(QStringList() << "monday" << "tuesday" << "wednesday" |
|
2521 << "thursday" << "saturday" << "sunday"); |
|
2522 |
|
2523 QVBoxLayout *layout = new QVBoxLayout; |
|
2524 layout->addWidget(new QLineEdit("QLineEdit")); |
|
2525 layout->addWidget(box); |
|
2526 layout->addWidget(new QLineEdit("QLineEdit")); |
|
2527 groupBox->setLayout(layout); |
|
2528 |
|
2529 QGraphicsScene scene; |
|
2530 QGraphicsProxyWidget *groupBoxProxy = scene.addWidget(groupBox); |
|
2531 groupBox->show(); |
|
2532 groupBox->move(10000, 10000); |
|
2533 QCOMPARE(groupBox->pos(), QPoint(10000, 10000)); |
|
2534 QCOMPARE(groupBoxProxy->pos(), QPointF(10000, 10000)); |
|
2535 |
|
2536 QGraphicsView view(&scene); |
|
2537 view.show(); |
|
2538 #ifdef Q_WS_X11 |
|
2539 qt_x11_wait_for_window_manager(&view); |
|
2540 #endif |
|
2541 |
|
2542 box->showPopup(); |
|
2543 |
|
2544 QVERIFY(!groupBoxProxy->childItems().isEmpty()); |
|
2545 |
|
2546 QStyleOptionComboBox opt; |
|
2547 opt.initFrom(box); |
|
2548 opt.editable = box->isEditable(); |
|
2549 if (box->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt)) |
|
2550 QSKIP("Does not work due to SH_Combobox_Popup", SkipAll); |
|
2551 QGraphicsProxyWidget *child = (QGraphicsProxyWidget*)(groupBoxProxy->childItems())[0]; |
|
2552 QWidget *popup = child->widget(); |
|
2553 QCOMPARE(popup->parent(), static_cast<QObject*>(box)); |
|
2554 QCOMPARE(popup->x(), box->mapToGlobal(QPoint()).x()); |
|
2555 QCOMPARE(popup->y(), QRect(box->mapToGlobal(QPoint()), box->size()).bottom()); |
|
2556 QCOMPARE(popup->size(), child->size().toSize()); |
|
2557 } |
|
2558 |
|
2559 void tst_QGraphicsProxyWidget::changingCursor_basic() |
|
2560 { |
|
2561 #if defined(Q_OS_WINCE) && (!defined(GWES_ICONCURS) || defined(QT_NO_CURSOR)) |
|
2562 QSKIP("hover events not supported on this platform", SkipAll); |
|
2563 #endif |
|
2564 #ifndef QT_NO_CURSOR |
|
2565 // Confirm that mouse events are working properly by checking that |
|
2566 // when moving the mouse over a line edit it will change the cursor into the I |
|
2567 QGraphicsScene scene; |
|
2568 QGraphicsView view(&scene); |
|
2569 view.show(); |
|
2570 |
|
2571 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
2572 QLineEdit *widget = new QLineEdit; |
|
2573 proxy->setWidget(widget); |
|
2574 proxy->show(); |
|
2575 scene.addItem(proxy); |
|
2576 QTest::qWaitForWindowShown(&view); |
|
2577 QApplication::processEvents(); |
|
2578 |
|
2579 // in |
|
2580 QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); |
|
2581 sendMouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); |
|
2582 QTest::qWait(125); |
|
2583 QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor); |
|
2584 |
|
2585 // out |
|
2586 QTest::mouseMove(view.viewport(), QPoint(1, 1)); |
|
2587 sendMouseMove(view.viewport(), QPoint(1, 1)); |
|
2588 QTest::qWait(125); |
|
2589 QCOMPARE(view.viewport()->cursor().shape(), Qt::ArrowCursor); |
|
2590 #endif |
|
2591 } |
|
2592 |
|
2593 void tst_QGraphicsProxyWidget::tooltip_basic() |
|
2594 { |
|
2595 // Confirm that mouse events are working properly by checking that |
|
2596 // when moving the mouse over a label with a tooptip the tooltip appears |
|
2597 QGraphicsScene scene; |
|
2598 QGraphicsView view(&scene); |
|
2599 view.show(); |
|
2600 |
|
2601 QSKIP("Tooltips don't work yet", SkipAll); |
|
2602 |
|
2603 SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; |
|
2604 QLabel *widget = new QLabel; |
|
2605 widget->setText("If it ain't tested it's broken"); |
|
2606 widget->setToolTip("When in doubt, test"); |
|
2607 proxy->setWidget(widget); |
|
2608 widget->show(); |
|
2609 scene.addItem(proxy); |
|
2610 QTest::qWait(125); |
|
2611 |
|
2612 // in |
|
2613 QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); |
|
2614 QTest::qWait(3000); |
|
2615 |
|
2616 QCOMPARE(proxy->childItems().count(), 1); |
|
2617 QGraphicsProxyWidget *child = (QGraphicsProxyWidget*)(proxy->childItems())[0]; |
|
2618 QVERIFY(child->isWidget()); |
|
2619 QVERIFY(child->widget()); |
|
2620 QCOMPARE(child->widget()->parent(), static_cast<QObject*>(widget)); |
|
2621 QCOMPARE(child->widget()->x(), widget->x()); // ### ??? |
|
2622 QCOMPARE(child->widget()->y(), widget->y() + widget->height()); // ### ??? |
|
2623 } |
|
2624 |
|
2625 void tst_QGraphicsProxyWidget::childPos_data() |
|
2626 { |
|
2627 QTest::addColumn<bool>("moveCombo"); |
|
2628 QTest::addColumn<QPoint>("comboPos"); |
|
2629 QTest::addColumn<QPointF>("proxyPos"); |
|
2630 QTest::addColumn<QPointF>("menuPos"); |
|
2631 |
|
2632 QTest::newRow("0") << true << QPoint() << QPointF() << QPointF(); |
|
2633 QTest::newRow("1") << true << QPoint(10, 0) << QPointF(10, 0) << QPointF(); |
|
2634 QTest::newRow("2") << true << QPoint(100, 0) << QPointF(100, 0) << QPointF(); |
|
2635 QTest::newRow("3") << true << QPoint(1000, 0) << QPointF(1000, 0) << QPointF(); |
|
2636 QTest::newRow("4") << true << QPoint(10000, 0) << QPointF(10000, 0) << QPointF(); |
|
2637 QTest::newRow("5") << true << QPoint(-10000, 0) << QPointF(-10000, 0) << QPointF(); |
|
2638 QTest::newRow("6") << true << QPoint(-1000, 0) << QPointF(-1000, 0) << QPointF(); |
|
2639 QTest::newRow("7") << true << QPoint(-100, 0) << QPointF(-100, 0) << QPointF(); |
|
2640 QTest::newRow("8") << true << QPoint(-10, 0) << QPointF(-10, 0) << QPointF(); |
|
2641 QTest::newRow("0-") << false << QPoint() << QPointF() << QPointF(); |
|
2642 QTest::newRow("1-") << false << QPoint(10, 0) << QPointF(10, 0) << QPointF(); |
|
2643 QTest::newRow("2-") << false << QPoint(100, 0) << QPointF(100, 0) << QPointF(); |
|
2644 QTest::newRow("3-") << false << QPoint(1000, 0) << QPointF(1000, 0) << QPointF(); |
|
2645 QTest::newRow("4-") << false << QPoint(10000, 0) << QPointF(10000, 0) << QPointF(); |
|
2646 QTest::newRow("5-") << false << QPoint(-10000, 0) << QPointF(-10000, 0) << QPointF(); |
|
2647 QTest::newRow("6-") << false << QPoint(-1000, 0) << QPointF(-1000, 0) << QPointF(); |
|
2648 QTest::newRow("7-") << false << QPoint(-100, 0) << QPointF(-100, 0) << QPointF(); |
|
2649 QTest::newRow("8-") << false << QPoint(-10, 0) << QPointF(-10, 0) << QPointF(); |
|
2650 } |
|
2651 |
|
2652 void tst_QGraphicsProxyWidget::childPos() |
|
2653 { |
|
2654 #ifdef Q_OS_IRIX |
|
2655 QSKIP("This test is not reliable on IRIX.", SkipAll); |
|
2656 #endif |
|
2657 QFETCH(bool, moveCombo); |
|
2658 QFETCH(QPoint, comboPos); |
|
2659 QFETCH(QPointF, proxyPos); |
|
2660 QFETCH(QPointF, menuPos); |
|
2661 |
|
2662 QGraphicsScene scene; |
|
2663 |
|
2664 QComboBox *box = new QComboBox; |
|
2665 box->addItem("Item 1"); |
|
2666 box->addItem("Item 2"); |
|
2667 box->addItem("Item 3"); |
|
2668 box->addItem("Item 4"); |
|
2669 |
|
2670 if (moveCombo) |
|
2671 box->move(comboPos); |
|
2672 |
|
2673 QGraphicsProxyWidget *proxy = scene.addWidget(box); |
|
2674 proxy->show(); |
|
2675 QVERIFY(proxy->isVisible()); |
|
2676 QVERIFY(box->isVisible()); |
|
2677 |
|
2678 if (!moveCombo) |
|
2679 proxy->setPos(proxyPos); |
|
2680 |
|
2681 QCOMPARE(proxy->pos(), proxyPos); |
|
2682 QCOMPARE(box->pos(), comboPos); |
|
2683 |
|
2684 for (int i = 0; i < 2; ++i) { |
|
2685 box->showPopup(); |
|
2686 QApplication::processEvents(); |
|
2687 QApplication::processEvents(); |
|
2688 |
|
2689 QWidget *menu = 0; |
|
2690 foreach (QObject *child, box->children()) { |
|
2691 if ((menu = qobject_cast<QWidget *>(child))) |
|
2692 break; |
|
2693 } |
|
2694 QVERIFY(menu); |
|
2695 QVERIFY(menu->isVisible()); |
|
2696 QVERIFY(menu->testAttribute(Qt::WA_DontShowOnScreen)); |
|
2697 |
|
2698 QCOMPARE(proxy->childItems().size(), 1); |
|
2699 QGraphicsProxyWidget *proxyChild = 0; |
|
2700 foreach (QGraphicsItem *child, proxy->childItems()) { |
|
2701 if (child->isWidget() && (proxyChild = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child)))) |
|
2702 break; |
|
2703 } |
|
2704 QVERIFY(proxyChild); |
|
2705 QVERIFY(proxyChild->isVisible()); |
|
2706 qreal expectedXPosition = 0.0; |
|
2707 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) |
|
2708 // The Mac style wants the popup to show up at QPoint(4 - 11, 1). |
|
2709 // See QMacStyle::subControlRect SC_ComboBoxListBoxPopup. |
|
2710 if (qobject_cast<QMacStyle *>(QApplication::style())) |
|
2711 expectedXPosition = qreal(4 - 11); |
|
2712 #endif |
|
2713 QCOMPARE(proxyChild->pos().x(), expectedXPosition); |
|
2714 menu->hide(); |
|
2715 } |
|
2716 } |
|
2717 |
|
2718 void tst_QGraphicsProxyWidget::autoShow() |
|
2719 { |
|
2720 QGraphicsScene scene; |
|
2721 QGraphicsView view(&scene); |
|
2722 |
|
2723 QGraphicsProxyWidget *proxy1 = scene.addWidget(new QPushButton("Button1")); |
|
2724 |
|
2725 QPushButton *button2 = new QPushButton("Button2"); |
|
2726 button2->hide(); |
|
2727 QGraphicsProxyWidget *proxy2 = new QGraphicsProxyWidget(); |
|
2728 proxy2->setWidget(button2); |
|
2729 scene.addItem(proxy2); |
|
2730 |
|
2731 view.show(); |
|
2732 QApplication::processEvents(); |
|
2733 |
|
2734 QCOMPARE(proxy1->isVisible(), true); |
|
2735 QCOMPARE(proxy2->isVisible(), false); |
|
2736 |
|
2737 } |
|
2738 |
|
2739 Q_DECLARE_METATYPE(QList<QRectF>) |
|
2740 void tst_QGraphicsProxyWidget::windowOpacity() |
|
2741 { |
|
2742 QGraphicsScene scene; |
|
2743 QGraphicsView view(&scene); |
|
2744 |
|
2745 QWidget *widget = new QWidget; |
|
2746 widget->resize(100, 100); |
|
2747 QGraphicsProxyWidget *proxy = scene.addWidget(widget); |
|
2748 proxy->setCacheMode(QGraphicsItem::ItemCoordinateCache); |
|
2749 view.show(); |
|
2750 QTest::qWaitForWindowShown(&view); |
|
2751 QApplication::sendPostedEvents(); |
|
2752 QTest::qWait(150); |
|
2753 |
|
2754 qRegisterMetaType<QList<QRectF> >("QList<QRectF>"); |
|
2755 QSignalSpy signalSpy(&scene, SIGNAL(changed(const QList<QRectF> &))); |
|
2756 |
|
2757 EventSpy eventSpy(widget); |
|
2758 QVERIFY(widget->isVisible()); |
|
2759 |
|
2760 widget->setWindowOpacity(0.5); |
|
2761 QApplication::processEvents(); |
|
2762 |
|
2763 // Make sure setWindowOpacity triggers an update on the scene, |
|
2764 // and not on the widget or the proxy itself. The entire proxy needs an update |
|
2765 // in case it has a window decoration. Update: QGraphicsItem::CacheMode is |
|
2766 // disabled on platforms without alpha channel support in QPixmap (e.g., |
|
2767 // X11 without XRender). |
|
2768 int paints = 0; |
|
2769 #ifdef Q_WS_X11 |
|
2770 paints = !X11->use_xrender; |
|
2771 #endif |
|
2772 QTRY_COMPARE(eventSpy.counts[QEvent::UpdateRequest], 0); |
|
2773 QTRY_COMPARE(eventSpy.counts[QEvent::Paint], paints); |
|
2774 |
|
2775 QCOMPARE(signalSpy.count(), 1); |
|
2776 const QList<QVariant> arguments = signalSpy.takeFirst(); |
|
2777 const QList<QRectF> updateRects = qvariant_cast<QList<QRectF> >(arguments.at(0)); |
|
2778 QCOMPARE(updateRects.size(), 1); |
|
2779 QCOMPARE(updateRects.at(0), proxy->sceneBoundingRect()); |
|
2780 } |
|
2781 |
|
2782 void tst_QGraphicsProxyWidget::stylePropagation() |
|
2783 { |
|
2784 QPointer<QWindowsStyle> windowsStyle = new QWindowsStyle; |
|
2785 |
|
2786 QLineEdit *edit = new QLineEdit; |
|
2787 QGraphicsProxyWidget proxy; |
|
2788 proxy.setWidget(edit); |
|
2789 |
|
2790 EventSpy editSpy(edit); |
|
2791 EventSpy proxySpy(&proxy); |
|
2792 |
|
2793 // Widget to proxy |
|
2794 QCOMPARE(proxy.style(), QApplication::style()); |
|
2795 edit->setStyle(windowsStyle); |
|
2796 QCOMPARE(editSpy.counts[QEvent::StyleChange], 1); |
|
2797 QCOMPARE(proxySpy.counts[QEvent::StyleChange], 1); |
|
2798 QCOMPARE(proxy.style(), (QStyle *)windowsStyle); |
|
2799 edit->setStyle(0); |
|
2800 QCOMPARE(editSpy.counts[QEvent::StyleChange], 2); |
|
2801 QCOMPARE(proxySpy.counts[QEvent::StyleChange], 2); |
|
2802 QCOMPARE(proxy.style(), QApplication::style()); |
|
2803 QCOMPARE(edit->style(), QApplication::style()); |
|
2804 QVERIFY(windowsStyle); // not deleted |
|
2805 |
|
2806 // Proxy to widget |
|
2807 proxy.setStyle(windowsStyle); |
|
2808 QCOMPARE(editSpy.counts[QEvent::StyleChange], 3); |
|
2809 QCOMPARE(proxySpy.counts[QEvent::StyleChange], 3); |
|
2810 QCOMPARE(edit->style(), (QStyle *)windowsStyle); |
|
2811 proxy.setStyle(0); |
|
2812 QCOMPARE(editSpy.counts[QEvent::StyleChange], 4); |
|
2813 QCOMPARE(proxySpy.counts[QEvent::StyleChange], 4); |
|
2814 QCOMPARE(proxy.style(), QApplication::style()); |
|
2815 QCOMPARE(edit->style(), QApplication::style()); |
|
2816 QVERIFY(windowsStyle); // not deleted |
|
2817 |
|
2818 delete windowsStyle; |
|
2819 } |
|
2820 |
|
2821 void tst_QGraphicsProxyWidget::palettePropagation() |
|
2822 { |
|
2823 // Construct a palette with an unlikely setup |
|
2824 QPalette lineEditPalette = QApplication::palette("QLineEdit"); |
|
2825 QPalette palette = lineEditPalette; |
|
2826 palette.setBrush(QPalette::Text, Qt::red); |
|
2827 |
|
2828 QLineEdit *edit = new QLineEdit; |
|
2829 QGraphicsProxyWidget proxy; |
|
2830 proxy.setWidget(edit); |
|
2831 |
|
2832 EventSpy editSpy(edit); |
|
2833 EventSpy proxySpy(&proxy); |
|
2834 |
|
2835 // Widget to proxy (no change) |
|
2836 QVERIFY(!edit->testAttribute(Qt::WA_SetPalette)); |
|
2837 edit->setPalette(palette); |
|
2838 QCOMPARE(editSpy.counts[QEvent::PaletteChange], 1); |
|
2839 QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 0); |
|
2840 QVERIFY(edit->testAttribute(Qt::WA_SetPalette)); |
|
2841 QVERIFY(!proxy.testAttribute(Qt::WA_SetPalette)); |
|
2842 QCOMPARE(proxy.palette(), QPalette()); |
|
2843 edit->setPalette(QPalette()); |
|
2844 QCOMPARE(editSpy.counts[QEvent::PaletteChange], 2); |
|
2845 QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 0); |
|
2846 QVERIFY(!edit->testAttribute(Qt::WA_SetPalette)); |
|
2847 QVERIFY(!proxy.testAttribute(Qt::WA_SetPalette)); |
|
2848 QCOMPARE(proxy.palette(), QPalette()); |
|
2849 |
|
2850 // Proxy to widget |
|
2851 proxy.setPalette(palette); |
|
2852 QVERIFY(proxy.testAttribute(Qt::WA_SetPalette)); |
|
2853 QCOMPARE(editSpy.counts[QEvent::PaletteChange], 3); |
|
2854 QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 1); |
|
2855 QVERIFY(!edit->testAttribute(Qt::WA_SetPalette)); |
|
2856 QCOMPARE(edit->palette(), palette); |
|
2857 QCOMPARE(edit->palette(), proxy.palette()); |
|
2858 QCOMPARE(edit->palette().color(QPalette::Text), QColor(Qt::red)); |
|
2859 proxy.setPalette(QPalette()); |
|
2860 QVERIFY(!proxy.testAttribute(Qt::WA_SetPalette)); |
|
2861 QVERIFY(!edit->testAttribute(Qt::WA_SetPalette)); |
|
2862 QCOMPARE(editSpy.counts[QEvent::PaletteChange], 4); |
|
2863 QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 2); |
|
2864 QCOMPARE(edit->palette(), lineEditPalette); |
|
2865 } |
|
2866 |
|
2867 void tst_QGraphicsProxyWidget::fontPropagation() |
|
2868 { |
|
2869 // Construct a font with an unlikely setup |
|
2870 QGraphicsScene scene; |
|
2871 QFont lineEditFont = QApplication::font("QLineEdit"); |
|
2872 QFont font = lineEditFont; |
|
2873 font.setPointSize(43); |
|
2874 |
|
2875 QLineEdit *edit = new QLineEdit; |
|
2876 QGraphicsProxyWidget proxy; |
|
2877 proxy.setWidget(edit); |
|
2878 |
|
2879 scene.addItem(&proxy); |
|
2880 EventSpy editSpy(edit); |
|
2881 EventSpy proxySpy(&proxy); |
|
2882 |
|
2883 // Widget to proxy (no change) |
|
2884 QVERIFY(!edit->testAttribute(Qt::WA_SetFont)); |
|
2885 edit->setFont(font); |
|
2886 QCOMPARE(editSpy.counts[QEvent::FontChange], 1); |
|
2887 QCOMPARE(proxySpy.counts[QEvent::FontChange], 0); |
|
2888 QVERIFY(edit->testAttribute(Qt::WA_SetFont)); |
|
2889 QVERIFY(!proxy.testAttribute(Qt::WA_SetFont)); |
|
2890 QCOMPARE(proxy.font(), lineEditFont); |
|
2891 edit->setFont(QFont()); |
|
2892 QCOMPARE(editSpy.counts[QEvent::FontChange], 2); |
|
2893 QCOMPARE(proxySpy.counts[QEvent::FontChange], 0); |
|
2894 QVERIFY(!edit->testAttribute(Qt::WA_SetFont)); |
|
2895 QVERIFY(!proxy.testAttribute(Qt::WA_SetFont)); |
|
2896 QCOMPARE(proxy.font(), lineEditFont); |
|
2897 |
|
2898 // Proxy to widget |
|
2899 proxy.setFont(font); |
|
2900 QApplication::processEvents(); // wait for QEvent::Polish |
|
2901 QVERIFY(proxy.testAttribute(Qt::WA_SetFont)); |
|
2902 QCOMPARE(editSpy.counts[QEvent::FontChange], 3); |
|
2903 QCOMPARE(proxySpy.counts[QEvent::FontChange], 1); |
|
2904 QVERIFY(!edit->testAttribute(Qt::WA_SetFont)); |
|
2905 QCOMPARE(edit->font(), font); |
|
2906 QCOMPARE(edit->font(), proxy.font()); |
|
2907 QCOMPARE(edit->font().pointSize(), 43); |
|
2908 proxy.setFont(QFont()); |
|
2909 QVERIFY(!proxy.testAttribute(Qt::WA_SetFont)); |
|
2910 QVERIFY(!edit->testAttribute(Qt::WA_SetFont)); |
|
2911 QCOMPARE(editSpy.counts[QEvent::FontChange], 4); |
|
2912 QCOMPARE(proxySpy.counts[QEvent::FontChange], 2); |
|
2913 QCOMPARE(edit->font(), lineEditFont); |
|
2914 |
|
2915 proxy.setFont(font); |
|
2916 QLineEdit *edit2 = new QLineEdit; |
|
2917 proxy.setWidget(edit2); |
|
2918 delete edit; |
|
2919 QCOMPARE(edit2->font().pointSize(), 43); |
|
2920 } |
|
2921 |
|
2922 class MainWidget : public QMainWindow |
|
2923 { |
|
2924 Q_OBJECT |
|
2925 public: |
|
2926 MainWidget() : QMainWindow() { |
|
2927 view = new QGraphicsView(this); |
|
2928 scene = new QGraphicsScene(this); |
|
2929 item = new QGraphicsWidget(); |
|
2930 widget = new QGraphicsProxyWidget(item); |
|
2931 layout = new QGraphicsLinearLayout(item); |
|
2932 layout->addItem(widget); |
|
2933 item->setLayout(layout); |
|
2934 button = new QPushButton("Push me"); |
|
2935 widget->setWidget(button); |
|
2936 setCentralWidget(view); |
|
2937 scene->addItem(item); |
|
2938 view->setScene(scene); |
|
2939 scene->setFocusItem(item); |
|
2940 layout->activate(); |
|
2941 } |
|
2942 QGraphicsView* view; |
|
2943 QGraphicsScene* scene; |
|
2944 QGraphicsWidget * item; |
|
2945 QGraphicsLinearLayout * layout; |
|
2946 QGraphicsProxyWidget * widget; |
|
2947 QPushButton * button; |
|
2948 }; |
|
2949 |
|
2950 void tst_QGraphicsProxyWidget::dontCrashWhenDie() |
|
2951 { |
|
2952 MainWidget *w = new MainWidget(); |
|
2953 w->show(); |
|
2954 QTest::qWaitForWindowShown(w); |
|
2955 QTest::qWait(100); |
|
2956 QTest::mouseMove(w->view->viewport(), w->view->mapFromScene(w->widget->mapToScene(w->widget->boundingRect().center()))); |
|
2957 delete w->item; |
|
2958 |
|
2959 QApplication::processEvents(); |
|
2960 delete w; |
|
2961 } |
|
2962 |
|
2963 void tst_QGraphicsProxyWidget::createProxyForChildWidget() |
|
2964 { |
|
2965 QGraphicsScene scene; |
|
2966 |
|
2967 QLineEdit *edit1 = new QLineEdit; |
|
2968 edit1->setText("QLineEdit 1"); |
|
2969 QLineEdit *edit2 = new QLineEdit; |
|
2970 edit2->setText("QLineEdit 2"); |
|
2971 QCheckBox *checkbox = new QCheckBox("QCheckBox"); |
|
2972 QVBoxLayout *vlayout = new QVBoxLayout; |
|
2973 |
|
2974 vlayout->addWidget(edit1); |
|
2975 vlayout->addWidget(edit2); |
|
2976 vlayout->addWidget(checkbox); |
|
2977 vlayout->insertStretch(-1); |
|
2978 |
|
2979 QGroupBox *box = new QGroupBox("QGroupBox"); |
|
2980 box->setCheckable(true); |
|
2981 box->setChecked(true); |
|
2982 box->setLayout(vlayout); |
|
2983 |
|
2984 QDial *leftDial = new QDial; |
|
2985 QDial *rightDial = new QDial; |
|
2986 |
|
2987 QWidget window; |
|
2988 QHBoxLayout *layout = new QHBoxLayout; |
|
2989 layout->addWidget(leftDial); |
|
2990 layout->addWidget(box); |
|
2991 layout->addWidget(rightDial); |
|
2992 window.setLayout(layout); |
|
2993 |
|
2994 QVERIFY(window.graphicsProxyWidget() == 0); |
|
2995 QVERIFY(checkbox->graphicsProxyWidget() == 0); |
|
2996 |
|
2997 QGraphicsProxyWidget *windowProxy = scene.addWidget(&window); |
|
2998 QGraphicsView view(&scene); |
|
2999 view.show(); |
|
3000 view.resize(500,500); |
|
3001 |
|
3002 QVERIFY(window.graphicsProxyWidget() == windowProxy); |
|
3003 QVERIFY(box->graphicsProxyWidget() == 0); |
|
3004 QVERIFY(checkbox->graphicsProxyWidget() == 0); |
|
3005 |
|
3006 QPointer<QGraphicsProxyWidget> checkboxProxy = windowProxy->createProxyForChildWidget(checkbox); |
|
3007 |
|
3008 QGraphicsProxyWidget *boxProxy = box->graphicsProxyWidget(); |
|
3009 |
|
3010 QVERIFY(boxProxy); |
|
3011 QVERIFY(checkbox->graphicsProxyWidget() == checkboxProxy); |
|
3012 QVERIFY(checkboxProxy->parentItem() == boxProxy); |
|
3013 QVERIFY(boxProxy->parentItem() == windowProxy); |
|
3014 |
|
3015 QVERIFY(checkboxProxy->mapToScene(QPointF()) == checkbox->mapTo(&window, QPoint())); |
|
3016 QVERIFY(checkboxProxy->size() == checkbox->size()); |
|
3017 QVERIFY(boxProxy->size() == box->size()); |
|
3018 |
|
3019 window.resize(500,500); |
|
3020 QVERIFY(windowProxy->size() == QSize(500,500)); |
|
3021 QVERIFY(checkboxProxy->mapToScene(QPointF()) == checkbox->mapTo(&window, QPoint())); |
|
3022 QVERIFY(checkboxProxy->size() == checkbox->size()); |
|
3023 QVERIFY(boxProxy->size() == box->size()); |
|
3024 |
|
3025 QTest::qWait(10); |
|
3026 |
|
3027 |
|
3028 QSignalSpy spy(checkbox, SIGNAL(clicked())); |
|
3029 |
|
3030 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, |
|
3031 view.mapFromScene(checkboxProxy->mapToScene(QPointF(8,8)))); |
|
3032 QTRY_COMPARE(spy.count(), 0); |
|
3033 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, |
|
3034 view.mapFromScene(checkboxProxy->mapToScene(QPointF(8,8)))); |
|
3035 QTRY_COMPARE(spy.count(), 1); |
|
3036 |
|
3037 |
|
3038 |
|
3039 boxProxy->setWidget(0); |
|
3040 |
|
3041 QVERIFY(checkbox->graphicsProxyWidget() == 0); |
|
3042 QVERIFY(box->graphicsProxyWidget() == 0); |
|
3043 QVERIFY(checkboxProxy == 0); |
|
3044 |
|
3045 delete boxProxy; |
|
3046 } |
|
3047 |
|
3048 class ContextMenuWidget : public QWidget |
|
3049 { |
|
3050 Q_OBJECT |
|
3051 public: |
|
3052 ContextMenuWidget() |
|
3053 : embeddedPopup(false), |
|
3054 gotContextMenuEvent(false) |
|
3055 { } |
|
3056 bool embeddedPopup; |
|
3057 bool gotContextMenuEvent; |
|
3058 protected: |
|
3059 bool event(QEvent *event) |
|
3060 { |
|
3061 if (event->type() == QEvent::ContextMenu) |
|
3062 QTimer::singleShot(0, this, SLOT(checkMenu())); |
|
3063 return QWidget::event(event); |
|
3064 } |
|
3065 void contextMenuEvent(QContextMenuEvent *) |
|
3066 { |
|
3067 gotContextMenuEvent = true; |
|
3068 } |
|
3069 |
|
3070 private slots: |
|
3071 void checkMenu() |
|
3072 { |
|
3073 if (qFindChild<QMenu *>(this)) |
|
3074 embeddedPopup = true; |
|
3075 hide(); |
|
3076 } |
|
3077 }; |
|
3078 |
|
3079 void tst_QGraphicsProxyWidget::actionsContextMenu_data() |
|
3080 { |
|
3081 QTest::addColumn<bool>("actionsContextMenu"); |
|
3082 QTest::addColumn<bool>("hasFocus"); |
|
3083 |
|
3084 QTest::newRow("without actionsContextMenu and with focus") << false << true; |
|
3085 QTest::newRow("without actionsContextMenu and without focus") << false << false; |
|
3086 QTest::newRow("with actionsContextMenu and focus") << true << true; |
|
3087 QTest::newRow("with actionsContextMenu without focus") << true << false; |
|
3088 } |
|
3089 |
|
3090 void tst_QGraphicsProxyWidget::actionsContextMenu() |
|
3091 { |
|
3092 QFETCH(bool, hasFocus); |
|
3093 QFETCH(bool, actionsContextMenu); |
|
3094 |
|
3095 ContextMenuWidget *widget = new ContextMenuWidget; |
|
3096 if (actionsContextMenu) { |
|
3097 widget->addAction(new QAction("item 1", widget)); |
|
3098 widget->addAction(new QAction("item 2", widget)); |
|
3099 widget->addAction(new QAction("item 3", widget)); |
|
3100 widget->setContextMenuPolicy(Qt::ActionsContextMenu); |
|
3101 } |
|
3102 QGraphicsScene scene; |
|
3103 |
|
3104 QGraphicsView view(&scene); |
|
3105 view.show(); |
|
3106 QApplication::setActiveWindow(&view); |
|
3107 QTest::qWaitForWindowShown(&view); |
|
3108 view.setFocus(); |
|
3109 QTRY_VERIFY(view.hasFocus()); |
|
3110 |
|
3111 if (hasFocus) |
|
3112 scene.addWidget(widget)->setFocus(); |
|
3113 else |
|
3114 scene.addWidget(widget)->clearFocus(); |
|
3115 |
|
3116 QApplication::processEvents(); |
|
3117 |
|
3118 QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, |
|
3119 view.viewport()->rect().center(), |
|
3120 view.viewport()->mapToGlobal(view.viewport()->rect().center())); |
|
3121 contextMenuEvent.accept(); |
|
3122 qApp->sendEvent(view.viewport(), &contextMenuEvent); |
|
3123 |
|
3124 if (hasFocus) { |
|
3125 if (actionsContextMenu) { |
|
3126 //actionsContextMenu embedded popup but no contextMenuEvent (widget has focus) |
|
3127 QVERIFY(widget->embeddedPopup); |
|
3128 QVERIFY(!widget->gotContextMenuEvent); |
|
3129 } else { |
|
3130 //no embedded popup but contextMenuEvent (widget has focus) |
|
3131 QVERIFY(!widget->embeddedPopup); |
|
3132 QVERIFY(widget->gotContextMenuEvent); |
|
3133 } |
|
3134 } else { |
|
3135 //qgraphicsproxywidget doesn't have the focus, the widget must not receive any contextMenuEvent and must not create any QMenu |
|
3136 QVERIFY(!widget->embeddedPopup); |
|
3137 QVERIFY(!widget->gotContextMenuEvent); |
|
3138 } |
|
3139 |
|
3140 } |
|
3141 |
|
3142 |
|
3143 void tst_QGraphicsProxyWidget::deleteProxyForChildWidget() |
|
3144 { |
|
3145 QDialog dialog; |
|
3146 dialog.resize(320, 120); |
|
3147 dialog.move(80, 40); |
|
3148 |
|
3149 QGraphicsScene scene; |
|
3150 scene.setSceneRect(QRectF(0, 0, 640, 480)); |
|
3151 QGraphicsView view(&scene); |
|
3152 QComboBox *combo = new QComboBox; |
|
3153 combo->addItems(QStringList() << "red" << "green" << "blue" << "white" << "black" << "yellow" << "cyan" << "magenta"); |
|
3154 dialog.setLayout(new QVBoxLayout); |
|
3155 dialog.layout()->addWidget(combo); |
|
3156 |
|
3157 QGraphicsProxyWidget *proxy = scene.addWidget(&dialog); |
|
3158 view.show(); |
|
3159 |
|
3160 proxy->setWidget(0); |
|
3161 //just don't crash |
|
3162 QApplication::processEvents(); |
|
3163 delete combo; |
|
3164 } |
|
3165 |
|
3166 void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget_data() |
|
3167 { |
|
3168 QTest::addColumn<bool>("bypass"); |
|
3169 |
|
3170 QTest::newRow("autoembed") << false; |
|
3171 QTest::newRow("bypass") << true; |
|
3172 } |
|
3173 |
|
3174 void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget() |
|
3175 { |
|
3176 QFETCH(bool, bypass); |
|
3177 |
|
3178 QWidget *widget = new QWidget; |
|
3179 widget->resize(100, 100); |
|
3180 |
|
3181 QGraphicsScene scene; |
|
3182 QGraphicsView view(&scene); |
|
3183 view.show(); |
|
3184 |
|
3185 QGraphicsProxyWidget *proxy = scene.addWidget(widget); |
|
3186 |
|
3187 QCOMPARE(proxy->widget(), widget); |
|
3188 QVERIFY(proxy->childItems().isEmpty()); |
|
3189 |
|
3190 Qt::WindowFlags flags; |
|
3191 flags |= Qt::Dialog; |
|
3192 if (bypass) |
|
3193 flags |= Qt::BypassGraphicsProxyWidget; |
|
3194 QFileDialog *dialog = new QFileDialog(widget, flags); |
|
3195 dialog->setOption(QFileDialog::DontUseNativeDialog, true); |
|
3196 dialog->show(); |
|
3197 |
|
3198 QCOMPARE(proxy->childItems().size(), bypass ? 0 : 1); |
|
3199 if (!bypass) |
|
3200 QCOMPARE(((QGraphicsProxyWidget *)proxy->childItems().first())->widget(), (QWidget *)dialog); |
|
3201 |
|
3202 dialog->hide(); |
|
3203 QApplication::processEvents(); |
|
3204 delete dialog; |
|
3205 delete widget; |
|
3206 } |
|
3207 |
|
3208 static void makeDndEvent(QGraphicsSceneDragDropEvent *event, QGraphicsView *view, const QPointF &pos) |
|
3209 { |
|
3210 event->setScenePos(pos); |
|
3211 event->setScreenPos(view->mapToGlobal(view->mapFromScene(pos))); |
|
3212 event->setButtons(Qt::LeftButton); |
|
3213 event->setModifiers(0); |
|
3214 event->setPossibleActions(Qt::CopyAction); |
|
3215 event->setProposedAction(Qt::CopyAction); |
|
3216 event->setDropAction(Qt::CopyAction); |
|
3217 event->setWidget(view->viewport()); |
|
3218 event->setSource(view->viewport()); |
|
3219 event->ignore(); |
|
3220 } |
|
3221 |
|
3222 void tst_QGraphicsProxyWidget::dragDrop() |
|
3223 { |
|
3224 QPushButton *button = new QPushButton; // acceptDrops(false) |
|
3225 QLineEdit *edit = new QLineEdit; // acceptDrops(true) |
|
3226 |
|
3227 QGraphicsScene scene; |
|
3228 QGraphicsProxyWidget *buttonProxy = scene.addWidget(button); |
|
3229 QGraphicsProxyWidget *editProxy = scene.addWidget(edit); |
|
3230 QVERIFY(buttonProxy->acceptDrops()); |
|
3231 QVERIFY(editProxy->acceptDrops()); |
|
3232 |
|
3233 button->setGeometry(0, 0, 100, 50); |
|
3234 edit->setGeometry(0, 60, 100, 50); |
|
3235 |
|
3236 QGraphicsView view(&scene); |
|
3237 view.show(); |
|
3238 #ifdef Q_WS_X11 |
|
3239 qt_x11_wait_for_window_manager(&view); |
|
3240 #endif |
|
3241 |
|
3242 QMimeData data; |
|
3243 data.setText("hei"); |
|
3244 { |
|
3245 QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragEnter); |
|
3246 makeDndEvent(&event, &view, QPointF(50, 25)); |
|
3247 event.setMimeData(&data); |
|
3248 qApp->sendEvent(&scene, &event); |
|
3249 QVERIFY(event.isAccepted()); |
|
3250 } |
|
3251 { |
|
3252 QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragMove); |
|
3253 makeDndEvent(&event, &view, QPointF(50, 25)); |
|
3254 event.setMimeData(&data); |
|
3255 qApp->sendEvent(&scene, &event); |
|
3256 QVERIFY(!event.isAccepted()); |
|
3257 } |
|
3258 { |
|
3259 QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragMove); |
|
3260 makeDndEvent(&event, &view, QPointF(50, 75)); |
|
3261 event.setMimeData(&data); |
|
3262 qApp->sendEvent(&scene, &event); |
|
3263 QVERIFY(event.isAccepted()); |
|
3264 } |
|
3265 { |
|
3266 QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDrop); |
|
3267 makeDndEvent(&event, &view, QPointF(50, 75)); |
|
3268 event.setMimeData(&data); |
|
3269 qApp->sendEvent(&scene, &event); |
|
3270 QVERIFY(event.isAccepted()); |
|
3271 } |
|
3272 QCOMPARE(edit->text(), QString("hei")); |
|
3273 } |
|
3274 |
|
3275 void tst_QGraphicsProxyWidget::windowFlags_data() |
|
3276 { |
|
3277 QTest::addColumn<int>("proxyFlags"); |
|
3278 QTest::addColumn<int>("widgetFlags"); |
|
3279 QTest::addColumn<int>("resultingProxyFlags"); |
|
3280 QTest::addColumn<int>("resultingWidgetFlags"); |
|
3281 |
|
3282 QTest::newRow("proxy(0) widget(0)") << 0 << 0 << 0 << int(Qt::Window); |
|
3283 QTest::newRow("proxy(window)") << int(Qt::Window) << 0 << int(Qt::Window) << int(Qt::Window); |
|
3284 QTest::newRow("proxy(window) widget(window)") << int(Qt::Window) << int(Qt::Window) << int(Qt::Window) << int(Qt::Window); |
|
3285 QTest::newRow("proxy(0) widget(window)") << int(0) << int(Qt::Window) << int(0) << int(Qt::Window); |
|
3286 } |
|
3287 |
|
3288 void tst_QGraphicsProxyWidget::windowFlags() |
|
3289 { |
|
3290 QFETCH(int, proxyFlags); |
|
3291 QFETCH(int, widgetFlags); |
|
3292 QFETCH(int, resultingProxyFlags); |
|
3293 QFETCH(int, resultingWidgetFlags); |
|
3294 Qt::WindowFlags proxyWFlags = Qt::WindowFlags(proxyFlags); |
|
3295 Qt::WindowFlags widgetWFlags = Qt::WindowFlags(widgetFlags); |
|
3296 Qt::WindowFlags resultingProxyWFlags = Qt::WindowFlags(resultingProxyFlags); |
|
3297 Qt::WindowFlags resultingWidgetWFlags = Qt::WindowFlags(resultingWidgetFlags); |
|
3298 |
|
3299 QGraphicsProxyWidget proxy(0, proxyWFlags); |
|
3300 QVERIFY((proxy.windowFlags() & proxyWFlags) == proxyWFlags); |
|
3301 |
|
3302 QWidget *widget = new QWidget(0, widgetWFlags); |
|
3303 QVERIFY((widget->windowFlags() & widgetWFlags) == widgetWFlags); |
|
3304 |
|
3305 proxy.setWidget(widget); |
|
3306 |
|
3307 if (resultingProxyFlags == 0) |
|
3308 QVERIFY(!proxy.windowFlags()); |
|
3309 else |
|
3310 QVERIFY((proxy.windowFlags() & resultingProxyWFlags) == resultingProxyWFlags); |
|
3311 QVERIFY((widget->windowFlags() & resultingWidgetWFlags) == resultingWidgetWFlags); |
|
3312 } |
|
3313 |
|
3314 void tst_QGraphicsProxyWidget::comboboxWindowFlags() |
|
3315 { |
|
3316 QComboBox *comboBox = new QComboBox; |
|
3317 comboBox->addItem("Item 1"); |
|
3318 comboBox->addItem("Item 2"); |
|
3319 comboBox->addItem("Item 3"); |
|
3320 QWidget *embedWidget = comboBox; |
|
3321 |
|
3322 QGraphicsScene scene; |
|
3323 QGraphicsProxyWidget *proxy = scene.addWidget(embedWidget); |
|
3324 proxy->setWindowFlags(Qt::Window); |
|
3325 QVERIFY(embedWidget->isWindow()); |
|
3326 QVERIFY(proxy->isWindow()); |
|
3327 |
|
3328 comboBox->showPopup(); |
|
3329 |
|
3330 QCOMPARE(proxy->childItems().size(), 1); |
|
3331 QGraphicsItem *popupProxy = proxy->childItems().first(); |
|
3332 QVERIFY(popupProxy->isWindow()); |
|
3333 QVERIFY((static_cast<QGraphicsWidget *>(popupProxy)->windowFlags() & Qt::Popup) == Qt::Popup); |
|
3334 } |
|
3335 |
|
3336 void tst_QGraphicsProxyWidget::updateAndDelete() |
|
3337 { |
|
3338 QGraphicsScene scene; |
|
3339 QGraphicsProxyWidget *proxy = scene.addWidget(new QPushButton("Hello World")); |
|
3340 View view(&scene); |
|
3341 view.show(); |
|
3342 #ifdef Q_WS_X11 |
|
3343 qt_x11_wait_for_window_manager(&view); |
|
3344 #endif |
|
3345 QTest::qWait(20); |
|
3346 QTRY_VERIFY(view.npaints > 0); |
|
3347 |
|
3348 const QRect itemDeviceBoundingRect = proxy->deviceTransform(view.viewportTransform()) |
|
3349 .mapRect(proxy->boundingRect()).toRect(); |
|
3350 const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); |
|
3351 |
|
3352 view.npaints = 0; |
|
3353 view.paintEventRegion = QRegion(); |
|
3354 |
|
3355 // Update and hide. |
|
3356 proxy->update(); |
|
3357 proxy->hide(); |
|
3358 QTest::qWait(50); |
|
3359 QCOMPARE(view.npaints, 1); |
|
3360 QCOMPARE(view.paintEventRegion, expectedRegion); |
|
3361 |
|
3362 proxy->show(); |
|
3363 QTest::qWait(50); |
|
3364 view.npaints = 0; |
|
3365 view.paintEventRegion = QRegion(); |
|
3366 |
|
3367 // Update and delete. |
|
3368 proxy->update(); |
|
3369 delete proxy; |
|
3370 QTest::qWait(50); |
|
3371 QCOMPARE(view.npaints, 1); |
|
3372 QCOMPARE(view.paintEventRegion, expectedRegion); |
|
3373 } |
|
3374 |
|
3375 class InputMethod_LineEdit : public QLineEdit |
|
3376 { |
|
3377 bool event(QEvent *e) |
|
3378 { |
|
3379 if (e->type() == QEvent::InputMethod) |
|
3380 ++inputMethodEvents; |
|
3381 return QLineEdit::event(e); |
|
3382 } |
|
3383 public: |
|
3384 int inputMethodEvents; |
|
3385 }; |
|
3386 |
|
3387 void tst_QGraphicsProxyWidget::inputMethod() |
|
3388 { |
|
3389 QGraphicsScene scene; |
|
3390 |
|
3391 // check that the proxy is initialized with the correct input method sensitivity |
|
3392 for (int i = 0; i < 2; ++i) |
|
3393 { |
|
3394 QLineEdit *lineEdit = new QLineEdit; |
|
3395 lineEdit->setAttribute(Qt::WA_InputMethodEnabled, !!i); |
|
3396 QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit); |
|
3397 QCOMPARE(!!(proxy->flags() & QGraphicsItem::ItemAcceptsInputMethod), !!i); |
|
3398 } |
|
3399 |
|
3400 // check that input method events are only forwarded to widgets with focus |
|
3401 for (int i = 0; i < 2; ++i) |
|
3402 { |
|
3403 InputMethod_LineEdit *lineEdit = new InputMethod_LineEdit; |
|
3404 lineEdit->setAttribute(Qt::WA_InputMethodEnabled, true); |
|
3405 QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit); |
|
3406 |
|
3407 if (i) |
|
3408 lineEdit->setFocus(); |
|
3409 |
|
3410 lineEdit->inputMethodEvents = 0; |
|
3411 QInputMethodEvent event; |
|
3412 qApp->sendEvent(proxy, &event); |
|
3413 QCOMPARE(lineEdit->inputMethodEvents, i); |
|
3414 } |
|
3415 } |
|
3416 |
|
3417 void tst_QGraphicsProxyWidget::clickFocus() |
|
3418 { |
|
3419 QGraphicsScene scene; |
|
3420 scene.setItemIndexMethod(QGraphicsScene::NoIndex); |
|
3421 QGraphicsProxyWidget *proxy = scene.addWidget(new QLineEdit); |
|
3422 |
|
3423 EventSpy proxySpy(proxy); |
|
3424 EventSpy widgetSpy(proxy->widget()); |
|
3425 |
|
3426 QGraphicsView view(&scene); |
|
3427 view.setFrameStyle(0); |
|
3428 view.resize(300, 300); |
|
3429 view.show(); |
|
3430 #ifdef Q_WS_X11 |
|
3431 qt_x11_wait_for_window_manager(&view); |
|
3432 #endif |
|
3433 QApplication::setActiveWindow(&view); |
|
3434 QTest::qWait(25); |
|
3435 QTRY_COMPARE(QApplication::activeWindow(), &view); |
|
3436 |
|
3437 QVERIFY(!proxy->hasFocus()); |
|
3438 QVERIFY(!proxy->widget()->hasFocus()); |
|
3439 |
|
3440 QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0); |
|
3441 QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0); |
|
3442 QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0); |
|
3443 QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0); |
|
3444 |
|
3445 QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center()); |
|
3446 // Spontaneous mouse click sets focus on a clickable widget. |
|
3447 for (int retry = 0; retry < 50 && !proxy->hasFocus(); retry++) |
|
3448 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); |
|
3449 QVERIFY(proxy->hasFocus()); |
|
3450 QVERIFY(proxy->widget()->hasFocus()); |
|
3451 QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1); |
|
3452 QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1); |
|
3453 |
|
3454 scene.setFocusItem(0); |
|
3455 QVERIFY(!proxy->hasFocus()); |
|
3456 QVERIFY(!proxy->widget()->hasFocus()); |
|
3457 QCOMPARE(proxySpy.counts[QEvent::FocusOut], 1); |
|
3458 QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 1); |
|
3459 |
|
3460 // Non-spontaneous mouse click sets focus if the widget has been clicked before |
|
3461 { |
|
3462 QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); |
|
3463 event.setScenePos(lineEditCenter); |
|
3464 event.setButton(Qt::LeftButton); |
|
3465 qApp->sendEvent(&scene, &event); |
|
3466 QVERIFY(proxy->hasFocus()); |
|
3467 QVERIFY(proxy->widget()->hasFocus()); |
|
3468 QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); |
|
3469 QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); |
|
3470 } |
|
3471 |
|
3472 scene.setFocusItem(0); |
|
3473 proxy->setWidget(new QLineEdit); // resets focusWidget |
|
3474 QVERIFY(!proxy->hasFocus()); |
|
3475 QVERIFY(!proxy->widget()->hasFocus()); |
|
3476 QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2); |
|
3477 QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2); |
|
3478 |
|
3479 // Non-spontaneous mouse click does not set focus on the embedded widget. |
|
3480 { |
|
3481 QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); |
|
3482 event.setScenePos(lineEditCenter); |
|
3483 event.setButton(Qt::LeftButton); |
|
3484 qApp->sendEvent(&scene, &event); |
|
3485 QVERIFY(!proxy->hasFocus()); |
|
3486 QVERIFY(!proxy->widget()->hasFocus()); |
|
3487 QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); |
|
3488 QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); |
|
3489 } |
|
3490 |
|
3491 scene.setFocusItem(0); |
|
3492 QVERIFY(!proxy->hasFocus()); |
|
3493 QVERIFY(!proxy->widget()->hasFocus()); |
|
3494 QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2); |
|
3495 QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2); |
|
3496 |
|
3497 // Spontaneous click on non-clickable widget does not give focus. |
|
3498 proxy->widget()->setFocusPolicy(Qt::NoFocus); |
|
3499 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); |
|
3500 QVERIFY(!proxy->hasFocus()); |
|
3501 QVERIFY(!proxy->widget()->hasFocus()); |
|
3502 } |
|
3503 |
|
3504 QTEST_MAIN(tst_QGraphicsProxyWidget) |
|
3505 #include "tst_qgraphicsproxywidget.moc" |
|
3506 |
|
3507 #else // QT_NO_STYLE_CLEANLOOKS |
|
3508 QTEST_NOOP_MAIN |
|
3509 #endif |