9#include "private/qgraphicsproxywidget_p.h"
10#include "private/qwidget_p.h"
11#include "private/qapplication_p.h"
13#include <QtCore/qdebug.h>
14#include <QtGui/qevent.h>
15#include <QtWidgets/qgraphicsscene.h>
16#include <QtWidgets/qgraphicssceneevent.h>
17#include <QtWidgets/qlayout.h>
18#include <QtGui/qpainter.h>
19#include <QtWidgets/qstyleoption.h>
20#include <QtWidgets/qgraphicsview.h>
21#if QT_CONFIG(lineedit)
22#include <QtWidgets/qlineedit.h>
24#if QT_CONFIG(textedit)
25#include <QtWidgets/qtextedit.h>
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
163
164
165QGraphicsProxyWidgetPrivate::QGraphicsProxyWidgetPrivate()
166 : QGraphicsWidgetPrivate(),
167 dragDropWidget(
nullptr),
168 posChangeMode(NoMode),
169 sizeChangeMode(NoMode),
170 visibleChangeMode(NoMode),
171 enabledChangeMode(NoMode),
172 styleChangeMode(NoMode),
173 paletteChangeMode(NoMode),
174 tooltipChangeMode(NoMode),
175 focusFromWidgetToProxy(
false),
176 proxyIsGivingFocus(
false)
181
182
183QGraphicsProxyWidgetPrivate::~QGraphicsProxyWidgetPrivate()
188
189
190void QGraphicsProxyWidgetPrivate::init()
192 Q_Q(QGraphicsProxyWidget);
193 q->setFocusPolicy(Qt::WheelFocus);
194 q->setAcceptDrops(
true);
198
199
200void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)
202 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
203 mouseEvent.setPos(event->pos());
204 mouseEvent.setScreenPos(event->screenPos());
205 mouseEvent.setButton(Qt::NoButton);
206 mouseEvent.setButtons({ });
207 mouseEvent.setModifiers(event->modifiers());
208 mouseEvent.setTimestamp(event->timestamp());
209 sendWidgetMouseEvent(&mouseEvent);
210 event->setAccepted(mouseEvent.isAccepted());
214
215
216void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent *event)
218 if (!event || !widget || !widget->isVisible())
220 Q_Q(QGraphicsProxyWidget);
223 QPointF pos = event->pos();
224 QPointer<QWidget> alienWidget = widget->childAt(pos.toPoint());
225 QPointer<QWidget> receiver = alienWidget ? alienWidget : widget;
227 if (QWidgetPrivate::nearestGraphicsProxyWidget(receiver) != q)
231 QEvent::Type type = QEvent::None;
232 switch (event->type()) {
233 case QEvent::GraphicsSceneMousePress:
234 type = QEvent::MouseButtonPress;
235 if (!embeddedMouseGrabber)
236 embeddedMouseGrabber = receiver;
238 receiver = embeddedMouseGrabber;
240 case QEvent::GraphicsSceneMouseRelease:
241 type = QEvent::MouseButtonRelease;
242 if (embeddedMouseGrabber)
243 receiver = embeddedMouseGrabber;
245 case QEvent::GraphicsSceneMouseDoubleClick:
246 type = QEvent::MouseButtonDblClick;
247 if (!embeddedMouseGrabber)
248 embeddedMouseGrabber = receiver;
250 receiver = embeddedMouseGrabber;
252 case QEvent::GraphicsSceneMouseMove:
253 type = QEvent::MouseMove;
254 if (embeddedMouseGrabber)
255 receiver = embeddedMouseGrabber;
258 Q_ASSERT_X(
false,
"QGraphicsProxyWidget",
"internal error");
262 if (!lastWidgetUnderMouse) {
263 QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver,
nullptr, event->screenPos());
264 lastWidgetUnderMouse = receiver;
268 pos = mapToReceiver(pos, receiver);
271 QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()),
272 receiver->mapToGlobal(pos.toPoint()),
273 event->button(), event->buttons(), event->modifiers(), event->source());
274 mouseEvent.setTimestamp(event->timestamp());
276 QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber;
277 QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget,
278 &embeddedMouseGrabberPtr, lastWidgetUnderMouse, event->spontaneous());
279 embeddedMouseGrabber = embeddedMouseGrabberPtr;
283 if (embeddedMouseGrabber && type == QEvent::MouseButtonRelease && !event->buttons()) {
284 Q_Q(QGraphicsProxyWidget);
285 if (q->rect().contains(event->pos()) && q->acceptHoverEvents())
286 lastWidgetUnderMouse = alienWidget ? alienWidget : widget;
288 lastWidgetUnderMouse =
nullptr;
290 QApplicationPrivate::dispatchEnterLeave(lastWidgetUnderMouse, embeddedMouseGrabber, event->screenPos());
291 embeddedMouseGrabber =
nullptr;
295 if (!lastWidgetUnderMouse)
302 if (lastWidgetUnderMouse) {
303 QCursor widgetsCursor = lastWidgetUnderMouse->cursor();
304 if (q->cursor() != widgetsCursor)
305 q->setCursor(widgetsCursor);
309 event->setAccepted(mouseEvent.isAccepted());
312void QGraphicsProxyWidgetPrivate::sendWidgetKeyEvent(QKeyEvent *event)
314 Q_Q(QGraphicsProxyWidget);
315 if (!event || !widget || !widget->isVisible())
318 QPointer<QWidget> receiver = widget->focusWidget();
324 bool res = QCoreApplication::sendEvent(receiver, event);
325 if ((res && event->isAccepted()) || (q->isWindow() && receiver == widget))
327 receiver = receiver->parentWidget();
332
333
334void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::FocusReason reason)
336 QFocusEvent event(QEvent::FocusOut, reason);
337 QPointer<QWidget> widgetGuard = widget;
338 QCoreApplication::sendEvent(widget, &event);
339 if (widgetGuard && event.isAccepted())
340 QCoreApplication::sendEvent(widget->style(), &event);
344
345
346
347QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child,
bool next)
const
354 child = next ? widget.data() : widget->previousInFocusChain();
356 child = next ? child->nextInFocusChain() : child->previousInFocusChain();
357 if ((next && child == widget) || (!next && child == widget->previousInFocusChain())) {
365 QWidget *oldChild = child;
366 uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
368 if (child->isEnabled()
369 && child->isVisibleTo(widget)
370 && ((child->focusPolicy() & focus_flag) == focus_flag)
371 && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {
374 child = next ? child->nextInFocusChain() : child->previousInFocusChain();
375 }
while (child != oldChild && !(next && child == widget) && !(!next && child == widget->previousInFocusChain()));
380
381
382void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
384 Q_Q(QGraphicsProxyWidget);
385 if (!widget.isNull()) {
386 if (
const auto &extra = widget->d_func()->extra)
387 extra->proxyWidget =
nullptr;
394
395
396void QGraphicsProxyWidgetPrivate::updateWidgetGeometryFromProxy()
401
402
403void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget()
405 Q_Q(QGraphicsProxyWidget);
409 QRectF widgetGeometry = widget->geometry();
410 QWidget *parentWidget = widget->parentWidget();
411 if (widget->isWindow()) {
412 QGraphicsProxyWidget *proxyParent =
nullptr;
413 if (parentWidget && (proxyParent = qobject_cast<QGraphicsProxyWidget *>(q->parentWidget()))) {
417 widgetGeometry.moveTo(proxyParent->subWidgetRect(parentWidget).topLeft()
418 + parentWidget->mapFromGlobal(widget->pos()));
423 if (!widget->size().isValid())
424 widgetGeometry.setSize(widget->sizeHint());
427 posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
428 sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
429 q->setGeometry(widgetGeometry);
430 posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
431 sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
435
436
437void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()
439 Q_Q(QGraphicsProxyWidget);
443 QWidget *focusWidget = widget->focusWidget();
445 focusWidget = widget;
446 q->setFlag(QGraphicsItem::ItemAcceptsInputMethod,
447 focusWidget->testAttribute(Qt::WA_InputMethodEnabled));
451
452
453
454
455
456
457void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
459 const auto &extra = subWin->d_func()->extra;
460 if (!extra || !extra->proxyWidget) {
461 QGraphicsProxyWidget *subProxy =
new QGraphicsProxyWidget(q_func(), subWin->windowFlags());
462 subProxy->d_func()->setWidget_helper(subWin,
false);
467
468
469
470
471
472
473void QGraphicsProxyWidgetPrivate::unembedSubWindow(QWidget *subWin)
475 for (QGraphicsItem *child : std::as_const(children)) {
476 if (child->isWidget()) {
477 if (QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(
static_cast<QGraphicsWidget *>(child))) {
478 if (proxy->widget() == subWin) {
479 proxy->setWidget(
nullptr);
480 scene->removeItem(proxy);
489bool QGraphicsProxyWidgetPrivate::isProxyWidget()
const
495
496
497QPointF QGraphicsProxyWidgetPrivate::mapToReceiver(
const QPointF &pos,
const QWidget *receiver)
const
502 while (receiver && receiver != widget) {
503 p -= QPointF(receiver->pos());
504 receiver = receiver->parentWidget();
510
511
512
513QGraphicsProxyWidget::QGraphicsProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
514 : QGraphicsWidget(*
new QGraphicsProxyWidgetPrivate, parent, wFlags)
516 Q_D(QGraphicsProxyWidget);
521
522
523QGraphicsProxyWidget::~QGraphicsProxyWidget()
525 Q_D(QGraphicsProxyWidget);
527 d->widget->removeEventFilter(
this);
528 QObject::disconnect(d->widget, SIGNAL(destroyed()),
this, SLOT(_q_removeWidgetSlot()));
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565void QGraphicsProxyWidget::setWidget(QWidget *widget)
567 Q_D(QGraphicsProxyWidget);
568 d->setWidget_helper(widget,
true);
571void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget,
bool autoShow)
573 Q_Q(QGraphicsProxyWidget);
574 if (newWidget == widget)
577 QObject::disconnect(widget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
578 widget->removeEventFilter(q);
579 widget->setAttribute(Qt::WA_DontShowOnScreen,
false);
580 widget->d_func()->extra->proxyWidget =
nullptr;
581 resolveFont(inheritedFontResolveMask);
582 resolvePalette(inheritedPaletteResolveMask);
585 const auto childItems = q->childItems();
586 for (QGraphicsItem *child : childItems) {
587 if (child->d_ptr->isProxyWidget()) {
588 QGraphicsProxyWidget *childProxy =
static_cast<QGraphicsProxyWidget *>(child);
589 QWidget *parent = childProxy->widget();
590 while (parent && parent->parentWidget()) {
591 if (parent == widget)
593 parent = parent->parentWidget();
595 if (!childProxy->widget() || parent != widget)
597 childProxy->setWidget(
nullptr);
606 q->setAcceptHoverEvents(
false);
612 if (!newWidget->isWindow()) {
613 const auto &extra = newWidget->parentWidget()->d_func()->extra;
614 if (!extra || !extra->proxyWidget) {
615 qWarning(
"QGraphicsProxyWidget::setWidget: cannot embed widget %p "
616 "which is not a toplevel widget, and is not a child of an embedded widget", newWidget);
623 QWExtra *extra = newWidget->d_func()->extra.get();
625 newWidget->d_func()->createExtra();
626 extra = newWidget->d_func()->extra.get();
628 QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
630 if (*proxyWidget != q) {
631 qWarning(
"QGraphicsProxyWidget::setWidget: cannot embed widget %p"
632 "; already embedded", newWidget);
638 newWidget->setAttribute(Qt::WA_DontShowOnScreen);
639 newWidget->ensurePolished();
642 newWidget->setAttribute(Qt::WA_QuitOnClose,
false);
643 q->setAcceptHoverEvents(
true);
645 if (newWidget->testAttribute(Qt::WA_NoSystemBackground))
646 q->setAttribute(Qt::WA_NoSystemBackground);
647 if (newWidget->testAttribute(Qt::WA_OpaquePaintEvent))
648 q->setAttribute(Qt::WA_OpaquePaintEvent);
653 enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
654 visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
655 posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
656 sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
658 if ((autoShow && !newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide)) || !newWidget->testAttribute(Qt::WA_WState_Hidden)) {
664 if (newWidget->testAttribute(Qt::WA_SetCursor))
665 q->setCursor(widget->cursor());
667 q->setEnabled(newWidget->isEnabled());
668 q->setVisible(newWidget->isVisible());
669 q->setLayoutDirection(newWidget->layoutDirection());
670 if (newWidget->testAttribute(Qt::WA_SetStyle))
671 q->setStyle(widget->style());
673 resolveFont(inheritedFontResolveMask);
674 resolvePalette(inheritedPaletteResolveMask);
676 if (!newWidget->testAttribute(Qt::WA_Resized))
677 newWidget->adjustSize();
679 q->setContentsMargins(newWidget->contentsMargins());
680 q->setWindowTitle(newWidget->windowTitle());
683 q->setSizePolicy(newWidget->sizePolicy());
684 QSize sz = newWidget->minimumSize();
685 q->setMinimumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
686 sz = newWidget->maximumSize();
687 q->setMaximumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
689 updateProxyGeometryFromWidget();
691 updateProxyInputMethodAcceptanceFromWidget();
694 newWidget->installEventFilter(q);
695 QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
698 enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
699 visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
700 posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
701 sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
705
706
707
708
709QWidget *QGraphicsProxyWidget::widget()
const
711 Q_D(
const QGraphicsProxyWidget);
716
717
718
719
720
721
722
723
724QRectF QGraphicsProxyWidget::subWidgetRect(
const QWidget *widget)
const
726 Q_D(
const QGraphicsProxyWidget);
727 if (!widget || !d->widget)
729 if (d->widget == widget || d->widget->isAncestorOf(widget))
730 return QRectF(widget->mapTo(d->widget, QPoint(0, 0)), widget->size());
735
736
737void QGraphicsProxyWidget::setGeometry(
const QRectF &rect)
739 Q_D(QGraphicsProxyWidget);
740 bool proxyResizesWidget = !d->posChangeMode && !d->sizeChangeMode;
741 if (proxyResizesWidget) {
742 d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
743 d->sizeChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
745 QGraphicsWidget::setGeometry(rect);
746 if (proxyResizesWidget) {
747 d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
748 d->sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
753
754
755QVariant QGraphicsProxyWidget::itemChange(GraphicsItemChange change,
756 const QVariant &value)
758 Q_D(QGraphicsProxyWidget);
761 case ItemPositionChange:
765 if (!d->posChangeMode)
766 d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
768 case ItemPositionHasChanged:
771 if (d->widget && d->posChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
772 d->widget->move(value.toPoint());
773 if (d->posChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
774 d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
776 case ItemVisibleChange:
777 if (!d->visibleChangeMode)
778 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
780 case ItemVisibleHasChanged:
781 if (d->widget && d->visibleChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
782 d->widget->setVisible(isVisible());
783 if (d->visibleChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
784 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
786 case ItemEnabledChange:
787 if (!d->enabledChangeMode)
788 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
790 case ItemEnabledHasChanged:
791 if (d->widget && d->enabledChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
792 d->widget->setEnabled(isEnabled());
793 if (d->enabledChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
794 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
799 return QGraphicsWidget::itemChange(change, value);
803
804
805bool QGraphicsProxyWidget::event(QEvent *event)
807 Q_D(QGraphicsProxyWidget);
809 return QGraphicsWidget::event(event);
811 switch (event->type()) {
812 case QEvent::WindowActivate:
813 case QEvent::WindowDeactivate:
814 QCoreApplication::sendEvent(d->widget, event);
816 case QEvent::StyleChange:
818 if (!d->styleChangeMode) {
819 d->styleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
820 d->widget->setStyle(style());
821 d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
824 case QEvent::FontChange: {
826 QWidgetPrivate *wd = d->widget->d_func();
827 int mask = d->font.resolveMask() | d->inheritedFontResolveMask;
828 wd->inheritedFontResolveMask = mask;
832 case QEvent::PaletteChange: {
834 QWidgetPrivate *wd = d->widget->d_func();
835 int mask = d->palette.resolveMask() | d->inheritedPaletteResolveMask;
836 wd->inheritedPaletteResolveMask = mask;
837 wd->resolvePalette();
840 case QEvent::InputMethod: {
841 inputMethodEvent(
static_cast<QInputMethodEvent *>(event));
842 if (event->isAccepted())
846 case QEvent::ShortcutOverride: {
847 QWidget *focusWidget = d->widget->focusWidget();
848 while (focusWidget) {
849 QCoreApplication::sendEvent(focusWidget, event);
850 if (event->isAccepted())
852 focusWidget = focusWidget->parentWidget();
856 case QEvent::KeyPress: {
857 QKeyEvent *k =
static_cast<QKeyEvent *>(event);
858 if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
859 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {
860 QWidget *focusWidget = d->widget->focusWidget();
861 while (focusWidget) {
862 const bool res = QCoreApplication::sendEvent(focusWidget, event);
863 if ((res && event->isAccepted()) || (isWindow() && focusWidget == d->widget)) {
867 focusWidget = focusWidget->parentWidget();
874#if QT_CONFIG(tooltip)
875 case QEvent::GraphicsSceneHelp: {
877 if (d->lastWidgetUnderMouse) {
878 QGraphicsSceneHelpEvent *he =
static_cast<QGraphicsSceneHelpEvent *>(event);
879 QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();
880 QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());
881 QCoreApplication::sendEvent(d->lastWidgetUnderMouse, &e);
882 event->setAccepted(e.isAccepted());
883 return e.isAccepted();
887 case QEvent::ToolTipChange: {
889 if (!d->tooltipChangeMode) {
890 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
891 d->widget->setToolTip(toolTip());
892 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
897 case QEvent::TouchBegin:
898 case QEvent::TouchUpdate:
899 case QEvent::TouchEnd: {
900 QTouchEvent *touchEvent =
static_cast<QTouchEvent *>(event);
901 bool res = QApplicationPrivate::translateRawTouchEvent(d->widget, touchEvent);
902 if (res & touchEvent->isAccepted())
910 return QGraphicsWidget::event(event);
914
915
916bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
918 Q_D(QGraphicsProxyWidget);
920 if (object == d->widget) {
921 switch (event->type()) {
922 case QEvent::LayoutRequest:
928 if (!d->sizeChangeMode)
929 d->updateProxyGeometryFromWidget();
934 if (!d->posChangeMode)
935 d->updateProxyGeometryFromWidget();
940 if (!d->visibleChangeMode) {
941 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
942 setVisible(event->type() == QEvent::Show);
943 d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
946 case QEvent::EnabledChange:
948 if (!d->enabledChangeMode) {
949 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
950 setEnabled(d->widget->isEnabled());
951 d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
954 case QEvent::StyleChange:
956 if (!d->styleChangeMode) {
957 d->styleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
958 setStyle(d->widget->style());
959 d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
962#if QT_CONFIG(tooltip)
963 case QEvent::ToolTipChange:
965 if (!d->tooltipChangeMode) {
966 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
967 setToolTip(d->widget->toolTip());
968 d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
976 return QGraphicsWidget::eventFilter(object, event);
980
981
982void QGraphicsProxyWidget::showEvent(QShowEvent *event)
988
989
990void QGraphicsProxyWidget::hideEvent(QHideEvent *event)
995#ifndef QT_NO_CONTEXTMENU
997
998
999void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
1001 Q_D(QGraphicsProxyWidget);
1002 if (!event || !d->widget || !d->widget->isVisible() || !hasFocus())
1006 QPointF pos = event->pos();
1007 QPointer<QWidget> alienWidget = d->widget->childAt(pos.toPoint());
1008 QPointer<QWidget> receiver = alienWidget ? alienWidget : d->widget;
1011 pos = d->mapToReceiver(pos, receiver);
1013 QPoint globalPos = receiver->mapToGlobal(pos.toPoint());
1019 if (bypassGraphicsProxyWidget(receiver))
1020 globalPos = event->screenPos();
1023 QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
1024 pos.toPoint(), globalPos, event->modifiers());
1025 contextMenuEvent.setTimestamp(event->timestamp());
1026 QCoreApplication::sendEvent(receiver, &contextMenuEvent);
1028 event->setAccepted(contextMenuEvent.isAccepted());
1032#if QT_CONFIG(draganddrop)
1034
1035
1036void QGraphicsProxyWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
1038#if !QT_CONFIG(draganddrop)
1041 Q_D(QGraphicsProxyWidget);
1045 QDragEnterEvent proxyDragEnter(event->pos().toPoint(), event->dropAction(), event->mimeData(), event->buttons(), event->modifiers());
1046 proxyDragEnter.setAccepted(event->isAccepted());
1047 QCoreApplication::sendEvent(d->widget, &proxyDragEnter);
1048 event->setAccepted(proxyDragEnter.isAccepted());
1049 if (proxyDragEnter.isAccepted())
1050 event->setDropAction(proxyDragEnter.dropAction());
1054
1055
1056void QGraphicsProxyWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
1059#if QT_CONFIG(draganddrop)
1060 Q_D(QGraphicsProxyWidget);
1061 if (!d->widget || !d->dragDropWidget)
1063 QDragLeaveEvent proxyDragLeave;
1064 QCoreApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);
1065 d->dragDropWidget =
nullptr;
1070
1071
1072void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
1074#if !QT_CONFIG(draganddrop)
1077 Q_D(QGraphicsProxyWidget);
1080 QPointF p = event->pos();
1082 QPointer<QWidget> subWidget = d->widget->childAt(p.toPoint());
1083 QPointer<QWidget> receiver = subWidget ? subWidget : d->widget;
1084 bool eventDelivered =
false;
1085 for (; receiver; receiver = receiver->parentWidget()) {
1086 if (!receiver->isEnabled() || !receiver->acceptDrops())
1089 QPoint receiverPos = d->mapToReceiver(p, receiver).toPoint();
1090 if (receiver != d->dragDropWidget) {
1092 QDragEnterEvent dragEnter(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
1093 dragEnter.setDropAction(event->proposedAction());
1094 QCoreApplication::sendEvent(receiver, &dragEnter);
1095 event->setAccepted(dragEnter.isAccepted());
1096 event->setDropAction(dragEnter.dropAction());
1097 if (!event->isAccepted()) {
1102 d->lastDropAction = event->dropAction();
1104 if (d->dragDropWidget) {
1105 QDragLeaveEvent dragLeave;
1106 QCoreApplication::sendEvent(d->dragDropWidget, &dragLeave);
1108 d->dragDropWidget = receiver;
1111 QDragMoveEvent dragMove(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
1112 event->setDropAction(d->lastDropAction);
1113 QCoreApplication::sendEvent(receiver, &dragMove);
1114 event->setAccepted(dragMove.isAccepted());
1115 event->setDropAction(dragMove.dropAction());
1116 if (event->isAccepted())
1117 d->lastDropAction = event->dropAction();
1118 eventDelivered =
true;
1122 if (!eventDelivered) {
1123 if (d->dragDropWidget) {
1125 QDragLeaveEvent dragLeave;
1126 QCoreApplication::sendEvent(d->dragDropWidget, &dragLeave);
1127 d->dragDropWidget =
nullptr;
1130 event->setDropAction(Qt::IgnoreAction);
1136
1137
1138void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
1140#if !QT_CONFIG(draganddrop)
1143 Q_D(QGraphicsProxyWidget);
1144 if (d->widget && d->dragDropWidget) {
1145 QPoint widgetPos = d->mapToReceiver(event->pos(), d->dragDropWidget).toPoint();
1146 QDropEvent dropEvent(widgetPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
1147 QCoreApplication::sendEvent(d->dragDropWidget, &dropEvent);
1148 event->setAccepted(dropEvent.isAccepted());
1149 d->dragDropWidget =
nullptr;
1156
1157
1158void QGraphicsProxyWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
1164
1165
1166void QGraphicsProxyWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
1169 Q_D(QGraphicsProxyWidget);
1171 if (d->lastWidgetUnderMouse) {
1172 QApplicationPrivate::dispatchEnterLeave(
nullptr, d->lastWidgetUnderMouse, event->screenPos());
1173 d->lastWidgetUnderMouse =
nullptr;
1178
1179
1180void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
1182 Q_D(QGraphicsProxyWidget);
1183#ifdef GRAPHICSPROXYWIDGET_DEBUG
1184 qDebug(
"QGraphicsProxyWidget::hoverMoveEvent");
1187 if (!d->widget || !rect().contains(event->pos())) {
1188 if (d->lastWidgetUnderMouse) {
1189 QApplicationPrivate::dispatchEnterLeave(
nullptr, d->lastWidgetUnderMouse, event->screenPos());
1190 d->lastWidgetUnderMouse =
nullptr;
1195 d->embeddedMouseGrabber =
nullptr;
1196 d->sendWidgetMouseEvent(event);
1200
1201
1202void QGraphicsProxyWidget::grabMouseEvent(QEvent *event)
1208
1209
1210void QGraphicsProxyWidget::ungrabMouseEvent(QEvent *event)
1212 Q_D(QGraphicsProxyWidget);
1214 d->embeddedMouseGrabber =
nullptr;
1218
1219
1220void QGraphicsProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
1222 Q_D(QGraphicsProxyWidget);
1223#ifdef GRAPHICSPROXYWIDGET_DEBUG
1224 qDebug(
"QGraphicsProxyWidget::mouseMoveEvent");
1226 d->sendWidgetMouseEvent(event);
1230
1231
1232void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
1234 Q_D(QGraphicsProxyWidget);
1235#ifdef GRAPHICSPROXYWIDGET_DEBUG
1236 qDebug(
"QGraphicsProxyWidget::mousePressEvent");
1238 d->sendWidgetMouseEvent(event);
1242
1243
1244void QGraphicsProxyWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
1246 Q_D(QGraphicsProxyWidget);
1247#ifdef GRAPHICSPROXYWIDGET_DEBUG
1248 qDebug(
"QGraphicsProxyWidget::mouseDoubleClickEvent");
1250 d->sendWidgetMouseEvent(event);
1254
1255
1256#if QT_CONFIG(wheelevent)
1257void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
1259 Q_D(QGraphicsProxyWidget);
1260#ifdef GRAPHICSPROXYWIDGET_DEBUG
1261 qDebug(
"QGraphicsProxyWidget::wheelEvent");
1266 QPointF pos = event->pos();
1267 QPointer<QWidget> receiver = d->widget->childAt(pos.toPoint());
1269 receiver = d->widget;
1275 QPointer<QWidget> prev_grabber = QApplicationPrivate::wheel_widget;
1276 if (event->phase() == Qt::ScrollBegin) {
1277 QApplicationPrivate::wheel_widget = receiver;
1278 }
else if (event->phase() != Qt::NoScrollPhase && QApplicationPrivate::wheel_widget != receiver) {
1285 pos = d->mapToReceiver(pos, receiver);
1289 if (event->orientation() == Qt::Horizontal)
1290 angleDelta.setX(event->delta());
1292 angleDelta.setY(event->delta());
1295 QWheelEvent wheelEvent(pos, event->screenPos(), event->pixelDelta(), angleDelta,
1296 event->buttons(), event->modifiers(), event->phase(),
1297 event->isInverted(), Qt::MouseEventSynthesizedByQt,
1298 QPointingDevice::primaryPointingDevice());
1299 QPointer<QWidget> focusWidget = d->widget->focusWidget();
1300 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
1301 qt_sendSpontaneousEvent(receiver, &wheelEvent);
1302 event->setAccepted(wheelEvent.isAccepted());
1304 if (event->phase() == Qt::ScrollBegin) {
1306 if (!wheelEvent.isAccepted())
1307 QApplicationPrivate::wheel_widget = prev_grabber;
1311 if (focusWidget && !focusWidget->hasFocus()) {
1312 focusWidget->update();
1313 focusWidget = d->widget->focusWidget();
1314 if (focusWidget && focusWidget->hasFocus())
1315 focusWidget->update();
1321
1322
1323void QGraphicsProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
1325 Q_D(QGraphicsProxyWidget);
1326#ifdef GRAPHICSPROXYWIDGET_DEBUG
1327 qDebug(
"QGraphicsProxyWidget::mouseReleaseEvent");
1329 d->sendWidgetMouseEvent(event);
1333
1334
1335void QGraphicsProxyWidget::keyPressEvent(QKeyEvent *event)
1337 Q_D(QGraphicsProxyWidget);
1338#ifdef GRAPHICSPROXYWIDGET_DEBUG
1339 qDebug(
"QGraphicsProxyWidget::keyPressEvent");
1341 d->sendWidgetKeyEvent(event);
1345
1346
1347void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event)
1349 Q_D(QGraphicsProxyWidget);
1350#ifdef GRAPHICSPROXYWIDGET_DEBUG
1351 qDebug(
"QGraphicsProxyWidget::keyReleaseEvent");
1353 d->sendWidgetKeyEvent(event);
1357
1358
1359void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
1361#ifdef GRAPHICSPROXYWIDGET_DEBUG
1362 qDebug(
"QGraphicsProxyWidget::focusInEvent");
1364 Q_D(QGraphicsProxyWidget);
1366 if (d->focusFromWidgetToProxy) {
1373 d->proxyIsGivingFocus =
true;
1375 switch (event->reason()) {
1376 case Qt::TabFocusReason: {
1377 if (QWidget *focusChild = d->findFocusChild(
nullptr,
true))
1378 focusChild->setFocus(event->reason());
1381 case Qt::BacktabFocusReason:
1382 if (QWidget *focusChild = d->findFocusChild(
nullptr,
false))
1383 focusChild->setFocus(event->reason());
1386 if (d->widget && d->widget->focusWidget()) {
1387 d->widget->focusWidget()->setFocus(event->reason());
1393 if (d->widget && d->widget->focusWidget()
1394 && d->widget->focusWidget()->testAttribute(Qt::WA_InputMethodEnabled))
1395 QApplication::inputMethod()->reset();
1397 d->proxyIsGivingFocus =
false;
1401
1402
1403void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event)
1405#ifdef GRAPHICSPROXYWIDGET_DEBUG
1406 qDebug(
"QGraphicsProxyWidget::focusOutEvent");
1408 Q_D(QGraphicsProxyWidget);
1412 if (QWidget *focusWidget = d->widget->focusWidget()) {
1415 if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
1416 QApplication::inputMethod()->reset();
1418 d->removeSubFocusHelper(focusWidget, event->reason());
1424
1425
1426bool QGraphicsProxyWidget::focusNextPrevChild(
bool next)
1428 Q_D(QGraphicsProxyWidget);
1429 if (!d->widget || !d->scene)
1430 return QGraphicsWidget::focusNextPrevChild(next);
1432 Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
1433 QWidget *lastFocusChild = d->widget->focusWidget();
1434 if (QWidget *newFocusChild = d->findFocusChild(lastFocusChild, next)) {
1435 newFocusChild->setFocus(reason);
1439 return QGraphicsWidget::focusNextPrevChild(next);
1443
1444
1445QVariant QGraphicsProxyWidget::inputMethodQuery(Qt::InputMethodQuery query)
const
1447 Q_D(
const QGraphicsProxyWidget);
1449 if (!d->widget || !hasFocus())
1452 QWidget *focusWidget = widget()->focusWidget();
1454 focusWidget = d->widget;
1455 QVariant v = focusWidget->inputMethodQuery(query);
1456 QPointF focusWidgetPos = subWidgetRect(focusWidget).topLeft();
1457 switch (v.userType()) {
1458 case QMetaType::QRectF:
1459 v = v.toRectF().translated(focusWidgetPos);
1461 case QMetaType::QPointF:
1462 v = v.toPointF() + focusWidgetPos;
1464 case QMetaType::QRect:
1465 v = v.toRect().translated(focusWidgetPos.toPoint());
1467 case QMetaType::QPoint:
1468 v = v.toPoint() + focusWidgetPos.toPoint();
1477
1478
1479void QGraphicsProxyWidget::inputMethodEvent(QInputMethodEvent *event)
1482 Q_D(
const QGraphicsProxyWidget);
1483 QWidget *focusWidget = d->widget->focusWidget();
1484 if (focusWidget && focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
1485 QCoreApplication::sendEvent(focusWidget, event);
1489
1490
1491QSizeF QGraphicsProxyWidget::sizeHint(Qt::SizeHint which,
const QSizeF &constraint)
const
1493 Q_D(
const QGraphicsProxyWidget);
1495 return QGraphicsWidget::sizeHint(which, constraint);
1499 case Qt::PreferredSize:
1500 if (QLayout *l = d->widget->layout())
1503 sh = d->widget->sizeHint();
1505 case Qt::MinimumSize:
1506 if (QLayout *l = d->widget->layout())
1507 sh = l->minimumSize();
1509 sh = d->widget->minimumSizeHint();
1511 case Qt::MaximumSize:
1512 if (QLayout *l = d->widget->layout())
1513 sh = l->maximumSize();
1515 sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
1517 case Qt::MinimumDescent:
1527
1528
1529void QGraphicsProxyWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
1531 Q_D(QGraphicsProxyWidget);
1533 if (d->sizeChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
1534 d->widget->resize(event->newSize().toSize());
1536 QGraphicsWidget::resizeEvent(event);
1540
1541
1542void QGraphicsProxyWidget::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget)
1544 Q_D(QGraphicsProxyWidget);
1546 if (!d->widget || !d->widget->isVisible())
1550 const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect();
1551 if (exposedWidgetRect.isEmpty())
1555 if (painter->device()->devType() != QInternal::Widget && (flags() & ItemClipsChildrenToShape))
1556 painter->setClipRect(d->widget->geometry(), Qt::IntersectClip);
1558 d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);
1562
1563
1564
1565
1566
1567
1570
1571
1572int QGraphicsProxyWidget::type()
const
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591QGraphicsProxyWidget *QGraphicsProxyWidget::createProxyForChildWidget(QWidget *child)
1593 QGraphicsProxyWidget *proxy = child->graphicsProxyWidget();
1596 if (!child->parentWidget()) {
1597 qWarning(
"QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene");
1601 QGraphicsProxyWidget *parentProxy = createProxyForChildWidget(child->parentWidget());
1605 if (!QMetaObject::invokeMethod(parentProxy,
"newProxyWidget", Qt::DirectConnection,
1606 Q_RETURN_ARG(QGraphicsProxyWidget*, proxy), Q_ARG(
const QWidget*, child)))
1608 proxy->setParent(parentProxy);
1609 proxy->setWidget(child);
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(
const QWidget *)
1633 return new QGraphicsProxyWidget(
this);
1640#include "moc_qgraphicsproxywidget.cpp"