qgraphicsproxywidget.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/graphicsview/qgraphicsproxywidget.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qglobal.h"-
41-
42#ifndef QT_NO_GRAPHICSVIEW-
43-
44#include "qgraphicslayout.h"-
45#include "qgraphicsproxywidget.h"-
46#include "private/qgraphicsproxywidget_p.h"-
47#include "private/qwidget_p.h"-
48#include "private/qapplication_p.h"-
49-
50#include <QtCore/qdebug.h>-
51#include <QtGui/qevent.h>-
52#include <QtWidgets/qgraphicsscene.h>-
53#include <QtWidgets/qgraphicssceneevent.h>-
54#include <QtWidgets/qlayout.h>-
55#include <QtGui/qpainter.h>-
56#include <QtWidgets/qstyleoption.h>-
57#include <QtWidgets/qgraphicsview.h>-
58#include <QtWidgets/qlistview.h>-
59#include <QtWidgets/qlineedit.h>-
60#include <QtWidgets/qtextedit.h>-
61-
62QT_BEGIN_NAMESPACE-
63-
64//#define GRAPHICSPROXYWIDGET_DEBUG-
65-
66/*!-
67 \class QGraphicsProxyWidget-
68 \brief The QGraphicsProxyWidget class provides a proxy layer for embedding-
69 a QWidget in a QGraphicsScene.-
70 \since 4.4-
71 \ingroup graphicsview-api-
72 \inmodule QtWidgets-
73-
74 QGraphicsProxyWidget embeds QWidget-based widgets, for example, a-
75 QPushButton, QFontComboBox, or even QFileDialog, into-
76 QGraphicsScene. It forwards events between the two objects and-
77 translates between QWidget's integer-based geometry and-
78 QGraphicsWidget's qreal-based geometry. QGraphicsProxyWidget-
79 supports all core features of QWidget, including tab focus,-
80 keyboard input, Drag & Drop, and popups. You can also embed-
81 complex widgets, e.g., widgets with subwidgets.-
82-
83 Example:-
84-
85 \snippet code/src_gui_graphicsview_qgraphicsproxywidget.cpp 0-
86-
87 QGraphicsProxyWidget takes care of automatically embedding popup children-
88 of embedded widgets through creating a child proxy for each popup. This-
89 means that when an embedded QComboBox shows its popup list, a new-
90 QGraphicsProxyWidget is created automatically, embedding the popup, and-
91 positioning it correctly. This only works if the popup is child of the-
92 embedded widget (for example QToolButton::setMenu() requires the QMenu instance-
93 to be child of the QToolButton).-
94-
95 \section1 Embedding a Widget with QGraphicsProxyWidget-
96-
97 There are two ways to embed a widget using QGraphicsProxyWidget. The most-
98 common way is to pass a widget pointer to QGraphicsScene::addWidget()-
99 together with any relevant \l Qt::WindowFlags. This function returns a-
100 pointer to a QGraphicsProxyWidget. You can then choose to reparent or-
101 position either the proxy, or the embedded widget itself.-
102-
103 For example, in the code snippet below, we embed a group box into the proxy:-
104-
105 \snippet code/src_gui_graphicsview_qgraphicsproxywidget.cpp 1-
106-
107 The image below is the output obtained with its contents margin and-
108 contents rect labeled.-
109-
110 \image qgraphicsproxywidget-embed.png-
111-
112 Alternatively, you can start by creating a new QGraphicsProxyWidget item,-
113 and then call setWidget() to embed a QWidget later. The widget() function-
114 returns a pointer to the embedded widget. QGraphicsProxyWidget shares-
115 ownership with QWidget, so if either of the two widgets are destroyed, the-
116 other widget will be automatically destroyed as well.-
117-
118 \section1 Synchronizing Widget States-
119-
120 QGraphicsProxyWidget keeps its state in sync with the embedded widget. For-
121 example, if the proxy is hidden or disabled, the embedded widget will be-
122 hidden or disabled as well, and vice versa. When the widget is embedded by-
123 calling addWidget(), QGraphicsProxyWidget copies the state from the widget-
124 into the proxy, and after that, the two will stay synchronized where-
125 possible. By default, when you embed a widget into a proxy, both the widget-
126 and the proxy will be visible because a QGraphicsWidget is visible when-
127 created (you do not have to call show()). If you explicitly hide the-
128 embedded widget, the proxy will also become invisible.-
129-
130 Example:-
131-
132 \snippet code/src_gui_graphicsview_qgraphicsproxywidget.cpp 2-
133-
134 QGraphicsProxyWidget maintains symmetry for the following states:-
135-
136 \table-
137 \header \li QWidget state \li QGraphicsProxyWidget state \li Notes-
138 \row \li QWidget::enabled-
139 \li QGraphicsProxyWidget::enabled-
140 \li-
141 \row \li QWidget::visible-
142 \li QGraphicsProxyWidget::visible-
143 \li The explicit state is also symmetric.-
144 \row \li QWidget::geometry-
145 \li QGraphicsProxyWidget::geometry-
146 \li Geometry is only guaranteed to be symmetric while-
147 the embedded widget is visible.-
148 \row \li QWidget::layoutDirection-
149 \li QGraphicsProxyWidget::layoutDirection-
150 \li-
151 \row \li QWidget::style-
152 \li QGraphicsProxyWidget::style-
153 \li-
154 \row \li QWidget::palette-
155 \li QGraphicsProxyWidget::palette-
156 \li-
157 \row \li QWidget::font-
158 \li QGraphicsProxyWidget::font-
159 \li-
160 \row \li QWidget::cursor-
161 \li QGraphicsProxyWidget::cursor-
162 \li The embedded widget overrides the proxy widget-
163 cursor. The proxy cursor changes depending on-
164 which embedded subwidget is currently under the-
165 mouse.-
166 \row \li QWidget::sizeHint()-
167 \li QGraphicsProxyWidget::sizeHint()-
168 \li All size hint functionality from the embedded-
169 widget is forwarded by the proxy.-
170 \row \li QWidget::getContentsMargins()-
171 \li QGraphicsProxyWidget::getContentsMargins()-
172 \li Updated once by setWidget().-
173 \row \li QWidget::windowTitle-
174 \li QGraphicsProxyWidget::windowTitle-
175 \li Updated once by setWidget().-
176 \endtable-
177-
178 \note QGraphicsScene keeps the embedded widget in a special state that-
179 prevents it from disturbing other widgets (both embedded and not embedded)-
180 while the widget is embedded. In this state, the widget may differ slightly-
181 in behavior from when it is not embedded.-
182-
183 \warning This class is provided for convenience when bridging-
184 QWidgets and QGraphicsItems, it should not be used for-
185 high-performance scenarios.-
186-
187 \sa QGraphicsScene::addWidget(), QGraphicsWidget-
188*/-
189-
190extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);-
191Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets();-
192-
193/*!-
194 \internal-
195*/-
196QGraphicsProxyWidgetPrivate::QGraphicsProxyWidgetPrivate()-
197 : QGraphicsWidgetPrivate(),-
198 dragDropWidget(nullptr),-
199 posChangeMode(NoMode),-
200 sizeChangeMode(NoMode),-
201 visibleChangeMode(NoMode),-
202 enabledChangeMode(NoMode),-
203 styleChangeMode(NoMode),-
204 paletteChangeMode(NoMode),-
205 tooltipChangeMode(NoMode),-
206 focusFromWidgetToProxy(false),-
207 proxyIsGivingFocus(false)-
208{-
209}
never executed: end of block
0
210-
211/*!-
212 \internal-
213*/-
214QGraphicsProxyWidgetPrivate::~QGraphicsProxyWidgetPrivate()-
215{-
216}-
217-
218/*!-
219 \internal-
220*/-
221void QGraphicsProxyWidgetPrivate::init()-
222{-
223 Q_Q(QGraphicsProxyWidget);-
224 q->setFocusPolicy(Qt::WheelFocus);-
225 q->setAcceptDrops(true);-
226}-
227-
228/*!-
229 \internal-
230*/-
231void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)-
232{-
233 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);-
234 mouseEvent.setPos(event->pos());-
235 mouseEvent.setScreenPos(event->screenPos());-
236 mouseEvent.setButton(Qt::NoButton);-
237 mouseEvent.setButtons(0);-
238 mouseEvent.setModifiers(event->modifiers());-
239 sendWidgetMouseEvent(&mouseEvent);-
240 event->setAccepted(mouseEvent.isAccepted());-
241}-
242-
243/*!-
244 \internal-
245*/-
246void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent *event)-
247{-
248 if (!event || !widget || !widget->isVisible())-
249 return;-
250 Q_Q(QGraphicsProxyWidget);-
251-
252 // Find widget position and receiver.-
253 QPointF pos = event->pos();-
254 QPointer<QWidget> alienWidget = widget->childAt(pos.toPoint());-
255 QPointer<QWidget> receiver = alienWidget ? alienWidget : widget;-
256-
257 if (QWidgetPrivate::nearestGraphicsProxyWidget(receiver) != q)-
258 return; //another proxywidget will handle the events-
259-
260 // Translate QGraphicsSceneMouse events to QMouseEvents.-
261 QEvent::Type type = QEvent::None;-
262 switch (event->type()) {-
263 case QEvent::GraphicsSceneMousePress:-
264 type = QEvent::MouseButtonPress;-
265 if (!embeddedMouseGrabber)-
266 embeddedMouseGrabber = receiver;-
267 else-
268 receiver = embeddedMouseGrabber;-
269 break;-
270 case QEvent::GraphicsSceneMouseRelease:-
271 type = QEvent::MouseButtonRelease;-
272 if (embeddedMouseGrabber)-
273 receiver = embeddedMouseGrabber;-
274 break;-
275 case QEvent::GraphicsSceneMouseDoubleClick:-
276 type = QEvent::MouseButtonDblClick;-
277 if (!embeddedMouseGrabber)-
278 embeddedMouseGrabber = receiver;-
279 else-
280 receiver = embeddedMouseGrabber;-
281 break;-
282 case QEvent::GraphicsSceneMouseMove:-
283 type = QEvent::MouseMove;-
284 if (embeddedMouseGrabber)-
285 receiver = embeddedMouseGrabber;-
286 break;-
287 default:-
288 Q_ASSERT_X(false, "QGraphicsProxyWidget", "internal error");-
289 break;-
290 }-
291-
292 if (!lastWidgetUnderMouse) {-
293 QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, 0, event->screenPos());-
294 lastWidgetUnderMouse = receiver;-
295 }-
296-
297 // Map event position from us to the receiver-
298 pos = mapToReceiver(pos, receiver);-
299-
300 // Send mouse event.-
301 QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()),-
302 receiver->mapToGlobal(pos.toPoint()),-
303 event->button(), event->buttons(), event->modifiers(), event->source());-
304-
305 QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber;-
306 QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget,-
307 &embeddedMouseGrabberPtr, lastWidgetUnderMouse, event->spontaneous());-
308 embeddedMouseGrabber = embeddedMouseGrabberPtr;-
309-
310 // Handle enter/leave events when last button is released from mouse-
311 // grabber child widget.-
312 if (embeddedMouseGrabber && type == QEvent::MouseButtonRelease && !event->buttons()) {-
313 Q_Q(QGraphicsProxyWidget);-
314 if (q->rect().contains(event->pos()) && q->acceptHoverEvents())-
315 lastWidgetUnderMouse = alienWidget ? alienWidget : widget;-
316 else // released on the frame our outside the item, or doesn't accept hover events.-
317 lastWidgetUnderMouse = 0;-
318-
319 QApplicationPrivate::dispatchEnterLeave(lastWidgetUnderMouse, embeddedMouseGrabber, event->screenPos());-
320 embeddedMouseGrabber = 0;-
321-
322#ifndef QT_NO_CURSOR-
323 // ### Restore the cursor, don't override it.-
324 if (!lastWidgetUnderMouse)-
325 q->unsetCursor();-
326#endif-
327 }-
328-
329 event->setAccepted(mouseEvent.isAccepted());-
330}-
331-
332void QGraphicsProxyWidgetPrivate::sendWidgetKeyEvent(QKeyEvent *event)-
333{-
334 Q_Q(QGraphicsProxyWidget);-
335 if (!event || !widget || !widget->isVisible())-
336 return;-
337-
338 QPointer<QWidget> receiver = widget->focusWidget();-
339 if (!receiver)-
340 receiver = widget;-
341 Q_ASSERT(receiver);-
342-
343 do {-
344 bool res = QApplication::sendEvent(receiver, event);-
345 if ((res && event->isAccepted()) || (q->isWindow() && receiver == widget))-
346 break;-
347 receiver = receiver->parentWidget();-
348 } while (receiver);-
349}-
350-
351/*!-
352 \internal-
353*/-
354void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::FocusReason reason)-
355{-
356 QFocusEvent event(QEvent::FocusOut, reason);-
357 QPointer<QWidget> widgetGuard = widget;-
358 QApplication::sendEvent(widget, &event);-
359 if (widgetGuard && event.isAccepted())-
360 QApplication::sendEvent(widget->style(), &event);-
361}-
362-
363/*!-
364 \internal-
365 Some of the logic is shared with QApplicationPrivate::focusNextPrevChild_helper-
366*/-
367QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) const-
368{-
369 if (!widget)-
370 return 0;-
371-
372 // Run around the focus chain until we find a widget that can take tab focus.-
373 if (!child) {-
374 child = next ? (QWidget *)widget : widget->d_func()->focus_prev;-
375 } else {-
376 child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;-
377 if ((next && child == widget) || (!next && child == widget->d_func()->focus_prev)) {-
378 return 0;-
379 }-
380 }-
381-
382 if (!child)-
383 return 0;-
384-
385 QWidget *oldChild = child;-
386 uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;-
387 do {-
388 if (child->isEnabled()-
389 && child->isVisibleTo(widget)-
390 && ((child->focusPolicy() & focus_flag) == focus_flag)-
391 && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {-
392 return child;-
393 }-
394 child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;-
395 } while (child != oldChild && !(next && child == widget) && !(!next && child == widget->d_func()->focus_prev));-
396 return 0;-
397}-
398-
399/*!-
400 \internal-
401*/-
402void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()-
403{-
404 Q_Q(QGraphicsProxyWidget);-
405 if (!widget.isNull()) {-
406 if (QWExtra *extra = widget->d_func()->extra)-
407 extra->proxyWidget = 0;-
408 }-
409 widget = 0;-
410 delete q;-
411}-
412-
413/*!-
414 \internal-
415*/-
416void QGraphicsProxyWidgetPrivate::updateWidgetGeometryFromProxy()-
417{-
418}-
419-
420/*!-
421 \internal-
422*/-
423void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget()-
424{-
425 Q_Q(QGraphicsProxyWidget);-
426 if (!widget)-
427 return;-
428-
429 QRectF widgetGeometry = widget->geometry();-
430 QWidget *parentWidget = widget->parentWidget();-
431 if (widget->isWindow()) {-
432 QGraphicsProxyWidget *proxyParent = 0;-
433 if (parentWidget && (proxyParent = qobject_cast<QGraphicsProxyWidget *>(q->parentWidget()))) {-
434 // Nested window proxy (e.g., combobox popup), map widget to the-
435 // parent widget's global coordinates, and map that to the parent-
436 // proxy's child coordinates.-
437 widgetGeometry.moveTo(proxyParent->subWidgetRect(parentWidget).topLeft()-
438 + parentWidget->mapFromGlobal(widget->pos()));-
439 }-
440 }-
441-
442 // Adjust to size hint if the widget has never been resized.-
443 if (!widget->size().isValid())-
444 widgetGeometry.setSize(widget->sizeHint());-
445-
446 // Assign new geometry.-
447 posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
448 sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
449 q->setGeometry(widgetGeometry);-
450 posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
451 sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
452}-
453-
454/*!-
455 \internal-
456*/-
457void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()-
458{-
459 Q_Q(QGraphicsProxyWidget);-
460 if (!widget)-
461 return;-
462-
463 QWidget *focusWidget = widget->focusWidget();-
464 if (!focusWidget)-
465 focusWidget = widget;-
466 q->setFlag(QGraphicsItem::ItemAcceptsInputMethod,-
467 focusWidget->testAttribute(Qt::WA_InputMethodEnabled));-
468}-
469-
470/*!-
471 \internal-
472-
473 Embeds \a subWin as a subwindow of this proxy widget. \a subWin must be a top-level-
474 widget and a descendant of the widget managed by this proxy. A separate subproxy-
475 will be created as a child of this proxy widget to manage \a subWin.-
476*/-
477void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)-
478{-
479 QWExtra *extra;-
480 if (!((extra = subWin->d_func()->extra) && extra->proxyWidget)) {-
481 QGraphicsProxyWidget *subProxy = new QGraphicsProxyWidget(q_func(), subWin->windowFlags());-
482 subProxy->d_func()->setWidget_helper(subWin, false);-
483 }-
484}-
485-
486/*!-
487 \internal-
488-
489 Removes ("unembeds") \a subWin and deletes the proxy holder item. This can-
490 happen when QWidget::setParent() reparents the embedded window out of-
491 "embedded space".-
492*/-
493void QGraphicsProxyWidgetPrivate::unembedSubWindow(QWidget *subWin)-
494{-
495 foreach (QGraphicsItem *child, children) {-
496 if (child->isWidget()) {-
497 if (QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child))) {-
498 if (proxy->widget() == subWin) {-
499 proxy->setWidget(0);-
500 scene->removeItem(proxy);-
501 delete proxy;-
502 return;-
503 }-
504 }-
505 }-
506 }-
507}-
508-
509bool QGraphicsProxyWidgetPrivate::isProxyWidget() const-
510{-
511 return true;-
512}-
513-
514/*!-
515 \internal-
516*/-
517QPointF QGraphicsProxyWidgetPrivate::mapToReceiver(const QPointF &pos, const QWidget *receiver) const-
518{-
519 QPointF p = pos;-
520 // Map event position from us to the receiver, preserving its-
521 // precision (don't use QWidget::mapFrom here).-
522 while (receiver && receiver != widget) {-
523 p -= QPointF(receiver->pos());-
524 receiver = receiver->parentWidget();-
525 }-
526 return p;-
527}-
528-
529/*!-
530 Constructs a new QGraphicsProxy widget. \a parent and \a wFlags are passed-
531 to QGraphicsItem's constructor.-
532*/-
533QGraphicsProxyWidget::QGraphicsProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)-
534 : QGraphicsWidget(*new QGraphicsProxyWidgetPrivate, parent, wFlags)-
535{-
536 Q_D(QGraphicsProxyWidget);-
537 d->init();-
538}-
539-
540/*!-
541 Destroys the proxy widget and any embedded widget.-
542*/-
543QGraphicsProxyWidget::~QGraphicsProxyWidget()-
544{-
545 Q_D(QGraphicsProxyWidget);-
546 if (d->widget) {-
547 d->widget->removeEventFilter(this);-
548 QObject::disconnect(d->widget, SIGNAL(destroyed()), this, SLOT(_q_removeWidgetSlot()));-
549 delete d->widget;-
550 }-
551}-
552-
553/*!-
554 Embeds \a widget into this proxy widget. The embedded widget must reside-
555 exclusively either inside or outside of Graphics View. You cannot embed a-
556 widget as long as it is is visible elsewhere in the UI, at the same time.-
557-
558 \a widget must be a top-level widget whose parent is 0.-
559-
560 When the widget is embedded, its state (e.g., visible, enabled, geometry,-
561 size hints) is copied into the proxy widget. If the embedded widget is-
562 explicitly hidden or disabled, the proxy widget will become explicitly-
563 hidden or disabled after embedding is complete. The class documentation-
564 has a full overview over the shared state.-
565-
566 QGraphicsProxyWidget's window flags determine whether the widget, after-
567 embedding, will be given window decorations or not.-
568-
569 After this function returns, QGraphicsProxyWidget will keep its state-
570 synchronized with that of \a widget whenever possible.-
571-
572 If a widget is already embedded by this proxy when this function is-
573 called, that widget will first be automatically unembedded. Passing 0 for-
574 the \a widget argument will only unembed the widget, and the ownership of-
575 the currently embedded widget will be passed on to the caller.-
576 Every child widget that are embedded will also be embedded and their proxy-
577 widget destroyed.-
578-
579 Note that widgets with the Qt::WA_PaintOnScreen widget attribute-
580 set and widgets that wrap an external application or controller-
581 cannot be embedded. Examples are QGLWidget and QAxWidget.-
582-
583 \sa widget()-
584*/-
585void QGraphicsProxyWidget::setWidget(QWidget *widget)-
586{-
587 Q_D(QGraphicsProxyWidget);-
588 d->setWidget_helper(widget, true);-
589}-
590-
591void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool autoShow)-
592{-
593 Q_Q(QGraphicsProxyWidget);-
594 if (newWidget == widget)
newWidget == widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
595 return;
never executed: return;
0
596 if (widget) {
widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
597 QObject::disconnect(widget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));-
598 widget->removeEventFilter(q);-
599 widget->setAttribute(Qt::WA_DontShowOnScreen, false);-
600 widget->d_func()->extra->proxyWidget = 0;-
601 resolveFont(inheritedFontResolveMask);-
602 resolvePalette(inheritedPaletteResolveMask);-
603 widget->update();-
604-
605 foreachconst auto childItems = q->childItems();-
606 for (QGraphicsItem *child , q->: childItems())) {-
607 if (child->d_ptr->isProxyWidget()) {
child->d_ptr->isProxyWidget()Description
TRUEnever evaluated
FALSEnever evaluated
0
608 QGraphicsProxyWidget *childProxy = static_cast<QGraphicsProxyWidget *>(child);-
609 QWidget * parent = childProxy->widget();-
610 while (parent->parentWidget() != 0) {
parent->parentWidget() != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
611 if (parent == widget)
parent == widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
612 break;
never executed: break;
0
613 parent = parent->parentWidget();-
614 }
never executed: end of block
0
615 if (!childProxy->widget() || parent != widget)
!childProxy->widget()Description
TRUEnever evaluated
FALSEnever evaluated
parent != widgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
616 continue;
never executed: continue;
0
617 childProxy->setWidget(0);-
618 delete childProxy;-
619 }
never executed: end of block
0
620 }
never executed: end of block
0
621-
622 widget = 0;-
623#ifndef QT_NO_CURSOR-
624 q->unsetCursor();-
625#endif-
626 q->setAcceptHoverEvents(false);-
627 if (!newWidget)
!newWidgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
628 q->update();
never executed: q->update();
0
629 }
never executed: end of block
0
630 if (!newWidget)
!newWidgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
631 return;
never executed: return;
0
632 if (!newWidget->isWindow()) {
!newWidget->isWindow()Description
TRUEnever evaluated
FALSEnever evaluated
0
633 QWExtra *extra = newWidget->parentWidget()->d_func()->extra;-
634 if (!extra || !extra->proxyWidget) {
!extraDescription
TRUEnever evaluated
FALSEnever evaluated
!extra->proxyWidgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
635 qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p "-
636 "which is not a toplevel widget, and is not a child of an embedded widget", newWidget);-
637 return;
never executed: return;
0
638 }-
639 }
never executed: end of block
0
640-
641 // Register this proxy within the widget's private.-
642 // ### This is a bit backdoorish-
643 QWExtra *extra = newWidget->d_func()->extra;-
644 if (!extra) {
!extraDescription
TRUEnever evaluated
FALSEnever evaluated
0
645 newWidget->d_func()->createExtra();-
646 extra = newWidget->d_func()->extra;-
647 }
never executed: end of block
0
648 QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;-
649 if (*proxyWidget) {
*proxyWidgetDescription
TRUEnever evaluated
FALSEnever evaluated
0
650 if (*proxyWidget != q) {
*proxyWidget != qDescription
TRUEnever evaluated
FALSEnever evaluated
0
651 qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p"-
652 "; already embedded", newWidget);-
653 }
never executed: end of block
0
654 return;
never executed: return;
0
655 }-
656 *proxyWidget = q;-
657-
658 newWidget->setAttribute(Qt::WA_DontShowOnScreen);-
659 newWidget->ensurePolished();-
660 // Do not wait for this widget to close before the app closes ###-
661 // shouldn't this widget inherit the attribute?-
662 newWidget->setAttribute(Qt::WA_QuitOnClose, false);-
663 q->setAcceptHoverEvents(true);-
664-
665 if (newWidget->testAttribute(Qt::WA_NoSystemBackground))
newWidget->tes...temBackground)Description
TRUEnever evaluated
FALSEnever evaluated
0
666 q->setAttribute(Qt::WA_NoSystemBackground);
never executed: q->setAttribute(Qt::WA_NoSystemBackground);
0
667 if (newWidget->testAttribute(Qt::WA_OpaquePaintEvent))
newWidget->tes...quePaintEvent)Description
TRUEnever evaluated
FALSEnever evaluated
0
668 q->setAttribute(Qt::WA_OpaquePaintEvent);
never executed: q->setAttribute(Qt::WA_OpaquePaintEvent);
0
669-
670 widget = newWidget;-
671-
672 // Changes only go from the widget to the proxy.-
673 enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
674 visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
675 posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
676 sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
677-
678 if ((autoShow && !newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide)) || !newWidget->testAttribute(Qt::WA_WState_Hidden)) {
autoShowDescription
TRUEnever evaluated
FALSEnever evaluated
!newWidget->te...licitShowHide)Description
TRUEnever evaluated
FALSEnever evaluated
!newWidget->te...WState_Hidden)Description
TRUEnever evaluated
FALSEnever evaluated
0
679 newWidget->show();-
680 }
never executed: end of block
0
681-
682 // Copy the state from the widget onto the proxy.-
683#ifndef QT_NO_CURSOR-
684 if (newWidget->testAttribute(Qt::WA_SetCursor))
newWidget->tes...:WA_SetCursor)Description
TRUEnever evaluated
FALSEnever evaluated
0
685 q->setCursor(widget->cursor());
never executed: q->setCursor(widget->cursor());
0
686#endif-
687 q->setEnabled(newWidget->isEnabled());-
688 q->setVisible(newWidget->isVisible());-
689 q->setLayoutDirection(newWidget->layoutDirection());-
690 if (newWidget->testAttribute(Qt::WA_SetStyle))
newWidget->tes...::WA_SetStyle)Description
TRUEnever evaluated
FALSEnever evaluated
0
691 q->setStyle(widget->style());
never executed: q->setStyle(widget->style());
0
692-
693 resolveFont(inheritedFontResolveMask);-
694 resolvePalette(inheritedPaletteResolveMask);-
695-
696 if (!newWidget->testAttribute(Qt::WA_Resized))
!newWidget->te...t::WA_Resized)Description
TRUEnever evaluated
FALSEnever evaluated
0
697 newWidget->adjustSize();
never executed: newWidget->adjustSize();
0
698-
699 int left, top, right, bottom;-
700 newWidget->getContentsMargins(&left, &top, &right, &bottom);-
701 q->setContentsMargins(left, top, right, bottom);-
702 q->setWindowTitle(newWidget->windowTitle());-
703-
704 // size policies and constraints..-
705 q->setSizePolicy(newWidget->sizePolicy());-
706 QSize sz = newWidget->minimumSize();-
707 q->setMinimumSize(sz.isNull() ? QSizeF() : QSizeF(sz));-
708 sz = newWidget->maximumSize();-
709 q->setMaximumSize(sz.isNull() ? QSizeF() : QSizeF(sz));-
710-
711 updateProxyGeometryFromWidget();-
712-
713 updateProxyInputMethodAcceptanceFromWidget();-
714-
715 // Hook up the event filter to keep the state up to date.-
716 newWidget->installEventFilter(q);-
717 QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));-
718-
719 // Changes no longer go only from the widget to the proxy.-
720 enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
721 visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
722 posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
723 sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
724}
never executed: end of block
0
725-
726/*!-
727 Returns a pointer to the embedded widget.-
728-
729 \sa setWidget()-
730*/-
731QWidget *QGraphicsProxyWidget::widget() const-
732{-
733 Q_D(const QGraphicsProxyWidget);-
734 return d->widget;-
735}-
736-
737/*!-
738 Returns the rectangle for \a widget, which must be a descendant of-
739 widget(), or widget() itself, in this proxy item's local coordinates.-
740-
741 If no widget is embedded, \a widget is 0, or \a widget is not a-
742 descendant of the embedded widget, this function returns an empty QRectF.-
743-
744 \sa widget()-
745*/-
746QRectF QGraphicsProxyWidget::subWidgetRect(const QWidget *widget) const-
747{-
748 Q_D(const QGraphicsProxyWidget);-
749 if (!widget || !d->widget)-
750 return QRectF();-
751 if (d->widget == widget || d->widget->isAncestorOf(widget))-
752 return QRectF(widget->mapTo(d->widget, QPoint(0, 0)), widget->size());-
753 return QRectF();-
754}-
755-
756/*!-
757 \reimp-
758*/-
759void QGraphicsProxyWidget::setGeometry(const QRectF &rect)-
760{-
761 Q_D(QGraphicsProxyWidget);-
762 bool proxyResizesWidget = !d->posChangeMode && !d->sizeChangeMode;-
763 if (proxyResizesWidget) {-
764 d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
765 d->sizeChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
766 }-
767 QGraphicsWidget::setGeometry(rect);-
768 if (proxyResizesWidget) {-
769 d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
770 d->sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
771 }-
772}-
773-
774/*!-
775 \reimp-
776*/-
777QVariant QGraphicsProxyWidget::itemChange(GraphicsItemChange change,-
778 const QVariant &value)-
779{-
780 Q_D(QGraphicsProxyWidget);-
781-
782 switch (change) {-
783 case ItemPositionChange:-
784 // The item's position is either changed directly on the proxy, in-
785 // which case the position change should propagate to the widget,-
786 // otherwise it happens as a side effect when filtering QEvent::Move.-
787 if (!d->posChangeMode)-
788 d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
789 break;-
790 case ItemPositionHasChanged:-
791 // Move the internal widget if we're in widget-to-proxy-
792 // mode. Otherwise the widget has already moved.-
793 if (d->widget && d->posChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)-
794 d->widget->move(value.toPoint());-
795 if (d->posChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)-
796 d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
797 break;-
798 case ItemVisibleChange:-
799 if (!d->visibleChangeMode)-
800 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
801 break;-
802 case ItemVisibleHasChanged:-
803 if (d->widget && d->visibleChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)-
804 d->widget->setVisible(isVisible());-
805 if (d->visibleChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)-
806 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
807 break;-
808 case ItemEnabledChange:-
809 if (!d->enabledChangeMode)-
810 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
811 break;-
812 case ItemEnabledHasChanged:-
813 if (d->widget && d->enabledChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)-
814 d->widget->setEnabled(isEnabled());-
815 if (d->enabledChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)-
816 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
817 break;-
818 default:-
819 break;-
820 }-
821 return QGraphicsWidget::itemChange(change, value);-
822}-
823-
824/*!-
825 \reimp-
826*/-
827bool QGraphicsProxyWidget::event(QEvent *event)-
828{-
829 Q_D(QGraphicsProxyWidget);-
830 if (!d->widget)-
831 return QGraphicsWidget::event(event);-
832-
833 switch (event->type()) {-
834 case QEvent::StyleChange:-
835 // Propagate style changes to the embedded widget.-
836 if (!d->styleChangeMode) {-
837 d->styleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
838 d->widget->setStyle(style());-
839 d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
840 }-
841 break;-
842 case QEvent::FontChange: {-
843 // Propagate to widget.-
844 QWidgetPrivate *wd = d->widget->d_func();-
845 int mask = d->font.resolve() | d->inheritedFontResolveMask;-
846 wd->inheritedFontResolveMask = mask;-
847 wd->resolveFont();-
848 break;-
849 }-
850 case QEvent::PaletteChange: {-
851 // Propagate to widget.-
852 QWidgetPrivate *wd = d->widget->d_func();-
853 int mask = d->palette.resolve() | d->inheritedPaletteResolveMask;-
854 wd->inheritedPaletteResolveMask = mask;-
855 wd->resolvePalette();-
856 break;-
857 }-
858 case QEvent::InputMethod: {-
859 inputMethodEvent(static_cast<QInputMethodEvent *>(event));-
860 if (event->isAccepted())-
861 return true;-
862 return false;-
863 }-
864 case QEvent::ShortcutOverride: {-
865 QWidget *focusWidget = d->widget->focusWidget();-
866 while (focusWidget) {-
867 QApplication::sendEvent(focusWidget, event);-
868 if (event->isAccepted())-
869 return true;-
870 focusWidget = focusWidget->parentWidget();-
871 }-
872 return false;-
873 }-
874 case QEvent::KeyPress: {-
875 QKeyEvent *k = static_cast<QKeyEvent *>(event);-
876 if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {-
877 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?-
878 QWidget *focusWidget = d->widget->focusWidget();-
879 while (focusWidget) {-
880 bool res = QApplication::sendEvent(focusWidget, event);-
881 if ((res && event->isAccepted()) || (isWindow() && focusWidget == d->widget)) {-
882 event->accept();-
883 break;-
884 }-
885 focusWidget = focusWidget->parentWidget();-
886 }-
887 return true;-
888 }-
889 }-
890 break;-
891 }-
892#ifndef QT_NO_TOOLTIP-
893 case QEvent::GraphicsSceneHelp: {-
894 // Propagate the help event (for tooltip) to the widget under mouse-
895 if (d->lastWidgetUnderMouse) {-
896 QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event);-
897 QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();-
898 QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());-
899 QApplication::sendEvent(d->lastWidgetUnderMouse, &e);-
900 event->setAccepted(e.isAccepted());-
901 return e.isAccepted();-
902 }-
903 break;-
904 }-
905 case QEvent::ToolTipChange: {-
906 // Propagate tooltip change to the widget-
907 if (!d->tooltipChangeMode) {-
908 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;-
909 d->widget->setToolTip(toolTip());-
910 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
911 }-
912 break;-
913 }-
914#endif-
915 case QEvent::TouchBegin:-
916 case QEvent::TouchUpdate:-
917 case QEvent::TouchEnd: {-
918 if (event->spontaneous())-
919 qt_sendSpontaneousEvent(d->widget, event);-
920 else-
921 QApplication::sendEvent(d->widget, event);-
922-
923 if (event->isAccepted())-
924 return true;-
925-
926 break;-
927 }-
928 default:-
929 break;-
930 }-
931 return QGraphicsWidget::event(event);-
932}-
933-
934/*!-
935 \reimp-
936*/-
937bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)-
938{-
939 Q_D(QGraphicsProxyWidget);-
940-
941 if (object == d->widget) {-
942 switch (event->type()) {-
943 case QEvent::LayoutRequest:-
944 updateGeometry();-
945 break;-
946 case QEvent::Resize:-
947 // If the widget resizes itself, we resize the proxy too.-
948 // Prevent feed-back by checking the geometry change mode.-
949 if (!d->sizeChangeMode)-
950 d->updateProxyGeometryFromWidget();-
951 break;-
952 case QEvent::Move:-
953 // If the widget moves itself, we move the proxy too. Prevent-
954 // feed-back by checking the geometry change mode.-
955 if (!d->posChangeMode)-
956 d->updateProxyGeometryFromWidget();-
957 break;-
958 case QEvent::Hide:-
959 case QEvent::Show:-
960 // If the widget toggles its visible state, the proxy will follow.-
961 if (!d->visibleChangeMode) {-
962 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
963 setVisible(event->type() == QEvent::Show);-
964 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
965 }-
966 break;-
967 case QEvent::EnabledChange:-
968 // If the widget toggles its enabled state, the proxy will follow.-
969 if (!d->enabledChangeMode) {-
970 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
971 setEnabled(d->widget->isEnabled());-
972 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
973 }-
974 break;-
975 case QEvent::StyleChange:-
976 // Propagate style changes to the proxy.-
977 if (!d->styleChangeMode) {-
978 d->styleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
979 setStyle(d->widget->style());-
980 d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
981 }-
982 break;-
983#ifndef QT_NO_TOOLTIP-
984 case QEvent::ToolTipChange:-
985 // Propagate tooltip change to the proxy.-
986 if (!d->tooltipChangeMode) {-
987 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;-
988 setToolTip(d->widget->toolTip());-
989 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;-
990 }-
991 break;-
992#endif-
993 default:-
994 break;-
995 }-
996 }-
997 return QGraphicsWidget::eventFilter(object, event);-
998}-
999-
1000/*!-
1001 \reimp-
1002*/-
1003void QGraphicsProxyWidget::showEvent(QShowEvent *event)-
1004{-
1005 Q_UNUSED(event);-
1006}-
1007-
1008/*!-
1009 \reimp-
1010*/-
1011void QGraphicsProxyWidget::hideEvent(QHideEvent *event)-
1012{-
1013 Q_UNUSED(event);-
1014}-
1015-
1016#ifndef QT_NO_CONTEXTMENU-
1017/*!-
1018 \reimp-
1019*/-
1020void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)-
1021{-
1022 Q_D(QGraphicsProxyWidget);-
1023 if (!event || !d->widget || !d->widget->isVisible() || !hasFocus())-
1024 return;-
1025-
1026 // Find widget position and receiver.-
1027 QPointF pos = event->pos();-
1028 QPointer<QWidget> alienWidget = d->widget->childAt(pos.toPoint());-
1029 QPointer<QWidget> receiver = alienWidget ? alienWidget : d->widget;-
1030-
1031 // Map event position from us to the receiver-
1032 pos = d->mapToReceiver(pos, receiver);-
1033-
1034 QPoint globalPos = receiver->mapToGlobal(pos.toPoint());-
1035 //If the receiver by-pass the proxy its popups-
1036 //will be top level QWidgets therefore they need-
1037 //the screen position. mapToGlobal expect the widget to-
1038 //have proper coordinates in regards of the windowing system-
1039 //but it's not true because the widget is embedded.-
1040 if (bypassGraphicsProxyWidget(receiver))-
1041 globalPos = event->screenPos();-
1042-
1043 // Send mouse event. ### Doesn't propagate the event.-
1044 QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),-
1045 pos.toPoint(), globalPos, event->modifiers());-
1046 QApplication::sendEvent(receiver, &contextMenuEvent);-
1047-
1048 event->setAccepted(contextMenuEvent.isAccepted());-
1049}-
1050#endif // QT_NO_CONTEXTMENU-
1051-
1052#ifndef QT_NO_DRAGANDDROP-
1053/*!-
1054 \reimp-
1055*/-
1056void QGraphicsProxyWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)-
1057{-
1058#ifdef QT_NO_DRAGANDDROP-
1059 Q_UNUSED(event);-
1060#else-
1061 Q_D(QGraphicsProxyWidget);-
1062 if (!d->widget)-
1063 return;-
1064-
1065 QDragEnterEvent proxyDragEnter(event->pos().toPoint(), event->dropAction(), event->mimeData(), event->buttons(), event->modifiers());-
1066 proxyDragEnter.setAccepted(event->isAccepted());-
1067 QApplication::sendEvent(d->widget, &proxyDragEnter);-
1068 event->setAccepted(proxyDragEnter.isAccepted());-
1069 if (proxyDragEnter.isAccepted()) // we discard answerRect-
1070 event->setDropAction(proxyDragEnter.dropAction());-
1071#endif-
1072}-
1073/*!-
1074 \reimp-
1075*/-
1076void QGraphicsProxyWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)-
1077{-
1078 Q_UNUSED(event);-
1079#ifndef QT_NO_DRAGANDDROP-
1080 Q_D(QGraphicsProxyWidget);-
1081 if (!d->widget || !d->dragDropWidget)-
1082 return;-
1083 QDragLeaveEvent proxyDragLeave;-
1084 QApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);-
1085 d->dragDropWidget = 0;-
1086#endif-
1087}-
1088-
1089/*!-
1090 \reimp-
1091*/-
1092void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)-
1093{-
1094#ifdef QT_NO_DRAGANDDROP-
1095 Q_UNUSED(event);-
1096#else-
1097 Q_D(QGraphicsProxyWidget);-
1098 if (!d->widget)-
1099 return;-
1100 QPointF p = event->pos();-
1101 event->ignore();-
1102 QPointer<QWidget> subWidget = d->widget->childAt(p.toPoint());-
1103 QPointer<QWidget> receiver = subWidget ? subWidget : d->widget;-
1104 bool eventDelivered = false;-
1105 for (; receiver; receiver = receiver->parentWidget()) {-
1106 if (!receiver->isEnabled() || !receiver->acceptDrops())-
1107 continue;-
1108 // Map event position from us to the receiver-
1109 QPoint receiverPos = d->mapToReceiver(p, receiver).toPoint();-
1110 if (receiver != d->dragDropWidget) {-
1111 // Try to enter before we leave-
1112 QDragEnterEvent dragEnter(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());-
1113 dragEnter.setDropAction(event->proposedAction());-
1114 QApplication::sendEvent(receiver, &dragEnter);-
1115 event->setAccepted(dragEnter.isAccepted());-
1116 event->setDropAction(dragEnter.dropAction());-
1117 if (!event->isAccepted()) {-
1118 // propagate to the parent widget-
1119 continue;-
1120 }-
1121-
1122 d->lastDropAction = event->dropAction();-
1123-
1124 if (d->dragDropWidget) {-
1125 QDragLeaveEvent dragLeave;-
1126 QApplication::sendEvent(d->dragDropWidget, &dragLeave);-
1127 }-
1128 d->dragDropWidget = receiver;-
1129 }-
1130-
1131 QDragMoveEvent dragMove(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());-
1132 event->setDropAction(d->lastDropAction);-
1133 QApplication::sendEvent(receiver, &dragMove);-
1134 event->setAccepted(dragMove.isAccepted());-
1135 event->setDropAction(dragMove.dropAction());-
1136 if (event->isAccepted())-
1137 d->lastDropAction = event->dropAction();-
1138 eventDelivered = true;-
1139 break;-
1140 }-
1141-
1142 if (!eventDelivered) {-
1143 if (d->dragDropWidget) {-
1144 // Leave the last drag drop item-
1145 QDragLeaveEvent dragLeave;-
1146 QApplication::sendEvent(d->dragDropWidget, &dragLeave);-
1147 d->dragDropWidget = 0;-
1148 }-
1149 // Propagate-
1150 event->setDropAction(Qt::IgnoreAction);-
1151 }-
1152#endif-
1153}-
1154-
1155/*!-
1156 \reimp-
1157*/-
1158void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event)-
1159{-
1160#ifdef QT_NO_DRAGANDDROP-
1161 Q_UNUSED(event);-
1162#else-
1163 Q_D(QGraphicsProxyWidget);-
1164 if (d->widget && d->dragDropWidget) {-
1165 QPoint widgetPos = d->mapToReceiver(event->pos(), d->dragDropWidget).toPoint();-
1166 QDropEvent dropEvent(widgetPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());-
1167 QApplication::sendEvent(d->dragDropWidget, &dropEvent);-
1168 event->setAccepted(dropEvent.isAccepted());-
1169 d->dragDropWidget = 0;-
1170 }-
1171#endif-
1172}-
1173#endif-
1174-
1175/*!-
1176 \reimp-
1177*/-
1178void QGraphicsProxyWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)-
1179{-
1180 Q_UNUSED(event);-
1181}-
1182-
1183/*!-
1184 \reimp-
1185*/-
1186void QGraphicsProxyWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)-
1187{-
1188 Q_UNUSED(event);-
1189 Q_D(QGraphicsProxyWidget);-
1190 // If hoverMove was compressed away, make sure we update properly here.-
1191 if (d->lastWidgetUnderMouse) {-
1192 QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse, event->screenPos());-
1193 d->lastWidgetUnderMouse = 0;-
1194 }-
1195}-
1196-
1197/*!-
1198 \reimp-
1199*/-
1200void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)-
1201{-
1202 Q_D(QGraphicsProxyWidget);-
1203#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1204 qDebug("QGraphicsProxyWidget::hoverMoveEvent");-
1205#endif-
1206 // Ignore events on the window frame.-
1207 if (!d->widget || !rect().contains(event->pos())) {-
1208 if (d->lastWidgetUnderMouse) {-
1209 QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse, event->screenPos());-
1210 d->lastWidgetUnderMouse = 0;-
1211 }-
1212 return;-
1213 }-
1214-
1215 d->embeddedMouseGrabber = 0;-
1216 d->sendWidgetMouseEvent(event);-
1217}-
1218-
1219/*!-
1220 \reimp-
1221*/-
1222void QGraphicsProxyWidget::grabMouseEvent(QEvent *event)-
1223{-
1224 Q_UNUSED(event);-
1225}-
1226-
1227/*!-
1228 \reimp-
1229*/-
1230void QGraphicsProxyWidget::ungrabMouseEvent(QEvent *event)-
1231{-
1232 Q_D(QGraphicsProxyWidget);-
1233 Q_UNUSED(event);-
1234 d->embeddedMouseGrabber = 0;-
1235}-
1236-
1237/*!-
1238 \reimp-
1239*/-
1240void QGraphicsProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)-
1241{-
1242 Q_D(QGraphicsProxyWidget);-
1243#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1244 qDebug("QGraphicsProxyWidget::mouseMoveEvent");-
1245#endif-
1246 d->sendWidgetMouseEvent(event);-
1247}-
1248-
1249/*!-
1250 \reimp-
1251*/-
1252void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)-
1253{-
1254 Q_D(QGraphicsProxyWidget);-
1255#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1256 qDebug("QGraphicsProxyWidget::mousePressEvent");-
1257#endif-
1258 d->sendWidgetMouseEvent(event);-
1259}-
1260-
1261/*!-
1262 \reimp-
1263*/-
1264void QGraphicsProxyWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)-
1265{-
1266 Q_D(QGraphicsProxyWidget);-
1267#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1268 qDebug("QGraphicsProxyWidget::mouseDoubleClickEvent");-
1269#endif-
1270 d->sendWidgetMouseEvent(event);-
1271}-
1272-
1273/*!-
1274 \reimp-
1275*/-
1276#ifndef QT_NO_WHEELEVENT-
1277void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)-
1278{-
1279 Q_D(QGraphicsProxyWidget);-
1280#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1281 qDebug("QGraphicsProxyWidget::wheelEvent");-
1282#endif-
1283 if (!d->widget)-
1284 return;-
1285-
1286 QPointF pos = event->pos();-
1287 QPointer<QWidget> receiver = d->widget->childAt(pos.toPoint());-
1288 if (!receiver)-
1289 receiver = d->widget;-
1290-
1291 // Map event position from us to the receiver-
1292 pos = d->mapToReceiver(pos, receiver);-
1293-
1294 // Send mouse event.-
1295 QWheelEvent wheelEvent(pos.toPoint(), event->screenPos(), event->delta(),-
1296 event->buttons(), event->modifiers(), event->orientation());-
1297 QPointer<QWidget> focusWidget = d->widget->focusWidget();-
1298 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);-
1299 qt_sendSpontaneousEvent(receiver, &wheelEvent);-
1300 event->setAccepted(wheelEvent.isAccepted());-
1301-
1302 // ### Remove, this should be done by proper focusIn/focusOut events.-
1303 if (focusWidget && !focusWidget->hasFocus()) {-
1304 focusWidget->update();-
1305 focusWidget = d->widget->focusWidget();-
1306 if (focusWidget && focusWidget->hasFocus())-
1307 focusWidget->update();-
1308 }-
1309}-
1310#endif-
1311-
1312/*!-
1313 \reimp-
1314*/-
1315void QGraphicsProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)-
1316{-
1317 Q_D(QGraphicsProxyWidget);-
1318#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1319 qDebug("QGraphicsProxyWidget::mouseReleaseEvent");-
1320#endif-
1321 d->sendWidgetMouseEvent(event);-
1322}-
1323-
1324/*!-
1325 \reimp-
1326*/-
1327void QGraphicsProxyWidget::keyPressEvent(QKeyEvent *event)-
1328{-
1329 Q_D(QGraphicsProxyWidget);-
1330#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1331 qDebug("QGraphicsProxyWidget::keyPressEvent");-
1332#endif-
1333 d->sendWidgetKeyEvent(event);-
1334}-
1335-
1336/*!-
1337 \reimp-
1338*/-
1339void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event)-
1340{-
1341 Q_D(QGraphicsProxyWidget);-
1342#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1343 qDebug("QGraphicsProxyWidget::keyReleaseEvent");-
1344#endif-
1345 d->sendWidgetKeyEvent(event);-
1346}-
1347-
1348/*!-
1349 \reimp-
1350*/-
1351void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)-
1352{-
1353#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1354 qDebug("QGraphicsProxyWidget::focusInEvent");-
1355#endif-
1356 Q_D(QGraphicsProxyWidget);-
1357-
1358 if (d->focusFromWidgetToProxy) {-
1359 // Prevent recursion when the proxy autogains focus through the-
1360 // embedded widget calling setFocus(). ### Could be done with event-
1361 // filter on FocusIn instead?-
1362 return;-
1363 }-
1364-
1365 d->proxyIsGivingFocus = true;-
1366-
1367 switch (event->reason()) {-
1368 case Qt::TabFocusReason: {-
1369 if (QWidget *focusChild = d->findFocusChild(0, true))-
1370 focusChild->setFocus(event->reason());-
1371 break;-
1372 }-
1373 case Qt::BacktabFocusReason:-
1374 if (QWidget *focusChild = d->findFocusChild(0, false))-
1375 focusChild->setFocus(event->reason());-
1376 break;-
1377 default:-
1378 if (d->widget && d->widget->focusWidget()) {-
1379 d->widget->focusWidget()->setFocus(event->reason());-
1380 }-
1381 break;-
1382 }-
1383-
1384 d->proxyIsGivingFocus = false;-
1385}-
1386-
1387/*!-
1388 \reimp-
1389*/-
1390void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event)-
1391{-
1392#ifdef GRAPHICSPROXYWIDGET_DEBUG-
1393 qDebug("QGraphicsProxyWidget::focusOutEvent");-
1394#endif-
1395 Q_D(QGraphicsProxyWidget);-
1396 if (d->widget) {-
1397 // We need to explicitly remove subfocus from the embedded widget's-
1398 // focus widget.-
1399 if (QWidget *focusWidget = d->widget->focusWidget())-
1400 d->removeSubFocusHelper(focusWidget, event->reason());-
1401 }-
1402}-
1403-
1404/*!-
1405 \reimp-
1406*/-
1407bool QGraphicsProxyWidget::focusNextPrevChild(bool next)-
1408{-
1409 Q_D(QGraphicsProxyWidget);-
1410 if (!d->widget || !d->scene)-
1411 return QGraphicsWidget::focusNextPrevChild(next);-
1412-
1413 Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;-
1414 QWidget *lastFocusChild = d->widget->focusWidget();-
1415 if (QWidget *newFocusChild = d->findFocusChild(lastFocusChild, next)) {-
1416 newFocusChild->setFocus(reason);-
1417 return true;-
1418 }-
1419-
1420 return QGraphicsWidget::focusNextPrevChild(next);-
1421}-
1422-
1423/*!-
1424 \reimp-
1425*/-
1426QVariant QGraphicsProxyWidget::inputMethodQuery(Qt::InputMethodQuery query) const-
1427{-
1428 Q_D(const QGraphicsProxyWidget);-
1429-
1430 if (!d->widget || !hasFocus())-
1431 return QVariant();-
1432-
1433 QWidget *focusWidget = widget()->focusWidget();-
1434 if (!focusWidget)-
1435 focusWidget = d->widget;-
1436 QVariant v = focusWidget->inputMethodQuery(query);-
1437 QPointF focusWidgetPos = subWidgetRect(focusWidget).topLeft();-
1438 switch (v.type()) {-
1439 case QVariant::RectF:-
1440 v = v.toRectF().translated(focusWidgetPos);-
1441 break;-
1442 case QVariant::PointF:-
1443 v = v.toPointF() + focusWidgetPos;-
1444 break;-
1445 case QVariant::Rect:-
1446 v = v.toRect().translated(focusWidgetPos.toPoint());-
1447 break;-
1448 case QVariant::Point:-
1449 v = v.toPoint() + focusWidgetPos.toPoint();-
1450 break;-
1451 default:-
1452 break;-
1453 }-
1454 return v;-
1455}-
1456-
1457/*!-
1458 \reimp-
1459*/-
1460void QGraphicsProxyWidget::inputMethodEvent(QInputMethodEvent *event)-
1461{-
1462 // Forward input method events if the focus widget enables input methods.-
1463 Q_D(const QGraphicsProxyWidget);-
1464 QWidget *focusWidget = d->widget->focusWidget();-
1465 if (focusWidget && focusWidget->testAttribute(Qt::WA_InputMethodEnabled))-
1466 QApplication::sendEvent(focusWidget, event);-
1467}-
1468-
1469/*!-
1470 \reimp-
1471*/-
1472QSizeF QGraphicsProxyWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const-
1473{-
1474 Q_D(const QGraphicsProxyWidget);-
1475 if (!d->widget)-
1476 return QGraphicsWidget::sizeHint(which, constraint);-
1477-
1478 QSizeF sh;-
1479 switch (which) {-
1480 case Qt::PreferredSize:-
1481 if (QLayout *l = d->widget->layout())-
1482 sh = l->sizeHint();-
1483 else-
1484 sh = d->widget->sizeHint();-
1485 break;-
1486 case Qt::MinimumSize:-
1487 if (QLayout *l = d->widget->layout())-
1488 sh = l->minimumSize();-
1489 else-
1490 sh = d->widget->minimumSizeHint();-
1491 break;-
1492 case Qt::MaximumSize:-
1493 if (QLayout *l = d->widget->layout())-
1494 sh = l->maximumSize();-
1495 else-
1496 sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);-
1497 break;-
1498 case Qt::MinimumDescent:-
1499 sh = constraint;-
1500 break;-
1501 default:-
1502 break;-
1503 }-
1504 return sh;-
1505}-
1506-
1507/*!-
1508 \reimp-
1509*/-
1510void QGraphicsProxyWidget::resizeEvent(QGraphicsSceneResizeEvent *event)-
1511{-
1512 Q_D(QGraphicsProxyWidget);-
1513 if (d->widget) {-
1514 if (d->sizeChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)-
1515 d->widget->resize(event->newSize().toSize());-
1516 }-
1517 QGraphicsWidget::resizeEvent(event);-
1518}-
1519-
1520/*!-
1521 \reimp-
1522*/-
1523void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)-
1524{-
1525 Q_D(QGraphicsProxyWidget);-
1526 Q_UNUSED(widget);-
1527 if (!d->widget || !d->widget->isVisible())-
1528 return;-
1529-
1530 // Filter out repaints on the window frame.-
1531 const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect();-
1532 if (exposedWidgetRect.isEmpty())-
1533 return;-
1534-
1535 d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);-
1536}-
1537-
1538/*!-
1539 \reimp-
1540*/-
1541int QGraphicsProxyWidget::type() const-
1542{-
1543 return Type;-
1544}-
1545-
1546/*!-
1547 \since 4.5-
1548-
1549 Creates a proxy widget for the given \a child of the widget-
1550 contained in this proxy.-
1551-
1552 This function makes it possible to acquire proxies for-
1553 non top-level widgets. For instance, you can embed a dialog,-
1554 and then transform only one of its widgets.-
1555-
1556 If the widget is already embedded, return the existing proxy widget.-
1557-
1558 \sa newProxyWidget(), QGraphicsScene::addWidget()-
1559*/-
1560QGraphicsProxyWidget *QGraphicsProxyWidget::createProxyForChildWidget(QWidget *child)-
1561{-
1562 QGraphicsProxyWidget *proxy = child->graphicsProxyWidget();-
1563 if (proxy)-
1564 return proxy;-
1565 if (!child->parentWidget()) {-
1566 qWarning("QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene");-
1567 return 0;-
1568 }-
1569-
1570 QGraphicsProxyWidget *parentProxy = createProxyForChildWidget(child->parentWidget());-
1571 if (!parentProxy)-
1572 return 0;-
1573-
1574 if (!QMetaObject::invokeMethod(parentProxy, "newProxyWidget", Qt::DirectConnection,-
1575 Q_RETURN_ARG(QGraphicsProxyWidget*, proxy), Q_ARG(const QWidget*, child)))-
1576 return 0;-
1577 proxy->setParent(parentProxy);-
1578 proxy->setWidget(child);-
1579 return proxy;-
1580}-
1581-
1582/*!-
1583 \fn QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *child)-
1584 \since 4.5-
1585-
1586 Creates a proxy widget for the given \a child of the widget contained in this-
1587 proxy.-
1588-
1589 You should not call this function directly; use-
1590 QGraphicsProxyWidget::createProxyForChildWidget() instead.-
1591-
1592 This function is a fake virtual slot that you can reimplement in-
1593 your subclass in order to control how new proxy widgets are-
1594 created. The default implementation returns a proxy created with-
1595 the QGraphicsProxyWidget() constructor with this proxy widget as-
1596 the parent.-
1597-
1598 \sa createProxyForChildWidget()-
1599*/-
1600QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *)-
1601{-
1602 return new QGraphicsProxyWidget(this);-
1603}-
1604-
1605-
1606-
1607QT_END_NAMESPACE-
1608-
1609#include "moc_qgraphicsproxywidget.cpp"-
1610-
1611#endif //QT_NO_GRAPHICSVIEW-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9