Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
tool_widgeteditor.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant reason:default
4
6#include "formwindow.h"
7
8// sdk
9#include <QtDesigner/abstractformeditor.h>
10#include <QtDesigner/abstractwidgetfactory.h>
11#include <QtDesigner/abstractwidgetbox.h>
12
13#include <layoutinfo_p.h>
14#include <qdesigner_dnditem_p.h>
15#include <qdesigner_resource.h>
16
17#include <QtWidgets/qmainwindow.h>
18
19#include <QtGui/qaction.h>
20#include <QtGui/qcursor.h>
21#include <QtGui/qevent.h>
22
23#include <QtCore/qdebug.h>
24
26
27namespace qdesigner_internal {
28
29WidgetEditorTool::WidgetEditorTool(FormWindow *formWindow)
30 : QDesignerFormWindowToolInterface(formWindow),
31 m_formWindow(formWindow),
32 m_action(new QAction(tr("Edit Widgets"), this)),
33 m_specialDockDrag(false)
34{
35}
36
37QAction *WidgetEditorTool::action() const
38{
39 return m_action;
40}
41
43
44QDesignerFormEditorInterface *WidgetEditorTool::core() const
45{
46 return m_formWindow->core();
47}
48
50{
51 return m_formWindow;
52}
53
54// separators in QMainWindow are no longer widgets
55bool WidgetEditorTool::mainWindowSeparatorEvent(QWidget *widget, QEvent *event)
56{
57 QMainWindow *mw = qobject_cast<QMainWindow*>(widget);
58 if (mw == nullptr)
59 return false;
60
61 if (event->type() != QEvent::MouseButtonPress
62 && event->type() != QEvent::MouseMove
63 && event->type() != QEvent::MouseButtonRelease)
64 return false;
65
66 QMouseEvent *e = static_cast<QMouseEvent*>(event);
67
68 if (event->type() == QEvent::MouseButtonPress) {
69 if (mw->isSeparator(e->position().toPoint())) {
70 m_separator_drag_mw = mw;
71 return true;
72 }
73 return false;
74 }
75
76 if (event->type() == QEvent::MouseMove)
77 return m_separator_drag_mw == mw;
78
79 if (event->type() == QEvent::MouseButtonRelease) {
80 if (m_separator_drag_mw != mw)
81 return false;
82 m_separator_drag_mw = nullptr;
83 return true;
84 }
85
86 return false;
87}
88
89bool WidgetEditorTool::isPassiveInteractor(QWidget *widget, QEvent *event)
90{
91 auto *widgetFactory = core()->widgetFactory();
92 return widgetFactory->isPassiveInteractor(widget) || mainWindowSeparatorEvent(widget, event);
93}
94
95bool WidgetEditorTool::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
96{
97 switch (event->type()) {
98 case QEvent::Resize:
99 case QEvent::Move:
100 m_formWindow->updateSelection(widget);
101 break;
102
103 case QEvent::FocusOut:
104 case QEvent::FocusIn: // Popup cancelled over a form widget: Reset its focus frame
105 return widget != m_formWindow && widget != m_formWindow->mainContainer()
106 && !isPassiveInteractor(widget, event);
107
108 case QEvent::Wheel: // Prevent spinboxes and combos from reacting
109 if (widget == m_formWindow->formContainer() || widget == m_formWindow
110 || widget == m_formWindow->mainContainer()) { // Allow scrolling the form with wheel.
111 return false;
112 }
113 return !isPassiveInteractor(widget, event);
114
115 case QEvent::KeyPress:
116 return !isPassiveInteractor(widget, event)
117 && handleKeyPressEvent(widget, managedWidget, static_cast<QKeyEvent*>(event));
118
119 case QEvent::KeyRelease:
120 return !isPassiveInteractor(widget, event)
121 && handleKeyReleaseEvent(widget, managedWidget, static_cast<QKeyEvent*>(event));
122
123 case QEvent::MouseMove:
124 return !isPassiveInteractor(widget, event)
125 && handleMouseMoveEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
126
127 case QEvent::MouseButtonPress:
128 return !isPassiveInteractor(widget, event)
129 && handleMousePressEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
130
131 case QEvent::MouseButtonRelease:
132 return !isPassiveInteractor(widget, event)
133 && handleMouseReleaseEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
134
135 case QEvent::MouseButtonDblClick:
136 return !isPassiveInteractor(widget, event)
137 && handleMouseButtonDblClickEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
138
139 case QEvent::ContextMenu:
140 return !isPassiveInteractor(widget, event)
141 && handleContextMenu(widget, managedWidget, static_cast<QContextMenuEvent*>(event));
142
143 case QEvent::DragEnter:
144 return handleDragEnterMoveEvent(widget, managedWidget, static_cast<QDragEnterEvent *>(event), true);
145 case QEvent::DragMove:
146 return handleDragEnterMoveEvent(widget, managedWidget, static_cast<QDragMoveEvent *>(event), false);
147 case QEvent::DragLeave:
148 return handleDragLeaveEvent(widget, managedWidget, static_cast<QDragLeaveEvent *>(event));
149 case QEvent::Drop:
150 return handleDropEvent(widget, managedWidget, static_cast<QDropEvent *>(event));
151 default:
152 break;
153
154 } // end switch
155
156 return false;
157}
158
159// ### remove me
160
161bool WidgetEditorTool::handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e)
162{
163 return m_formWindow->handleContextMenu(widget, managedWidget, e);
164}
165
166bool WidgetEditorTool::handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
167{
168 return m_formWindow->handleMouseButtonDblClickEvent(widget, managedWidget, e);
169}
170
171bool WidgetEditorTool::handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
172{
173 return m_formWindow->handleMousePressEvent(widget, managedWidget, e);
174}
175
176bool WidgetEditorTool::handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
177{
178 return m_formWindow->handleMouseMoveEvent(widget, managedWidget, e);
179}
180
181bool WidgetEditorTool::handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
182{
183 return m_formWindow->handleMouseReleaseEvent(widget, managedWidget, e);
184}
185
186bool WidgetEditorTool::handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
187{
188 return m_formWindow->handleKeyPressEvent(widget, managedWidget, e);
189}
190
191bool WidgetEditorTool::handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
192{
193 return m_formWindow->handleKeyReleaseEvent(widget, managedWidget, e);
194}
195
196bool WidgetEditorTool::handlePaintEvent(QWidget *widget, QWidget *managedWidget, QPaintEvent *e)
197{
198 Q_UNUSED(widget);
199 Q_UNUSED(managedWidget);
200 Q_UNUSED(e);
201
202 return false;
203}
204
205void WidgetEditorTool::detectDockDrag(const QDesignerMimeData *mimeData)
206{
207 m_specialDockDrag = false;
208 if (!mimeData)
209 return;
210
211 QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
212 if (!mw)
213 return;
214
215 const auto item_list = mimeData->items();
216
217 for (QDesignerDnDItemInterface *item : item_list) {
218 if (item->decoration() && item->decoration()->property("_q_dockDrag").toBool())
219 m_specialDockDrag = true;
220
221 }
222}
223
224bool WidgetEditorTool::handleDragEnterMoveEvent(QWidget *widget, QWidget * /*managedWidget*/, QDragMoveEvent *e, bool isEnter)
225{
226 const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(e->mimeData());
227 if (!mimeData)
228 return false;
229
230 if (!m_formWindow->hasFeature(QDesignerFormWindowInterface::EditFeature)) {
231 e->ignore();
232 return true;
233 }
234
235 if (isEnter)
236 detectDockDrag(mimeData);
237
238
239 QPoint globalPos = QPoint(0, 0);
240 if (m_specialDockDrag) {
241 m_lastDropTarget = nullptr;
242 QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
243 if (mw)
244 m_lastDropTarget = mw->centralWidget();
245 } else {
246 // If custom widgets have acceptDrops=true, the event occurs for them
247 const QPoint formPos = widget != m_formWindow ? widget->mapTo(m_formWindow, e->position().toPoint()) : e->position().toPoint();
248 globalPos = m_formWindow->mapToGlobal(formPos);
249 const FormWindowBase::WidgetUnderMouseMode wum = mimeData->items().size() == 1 ? FormWindowBase::FindSingleSelectionDropTarget : FormWindowBase::FindMultiSelectionDropTarget;
250 QWidget *dropTarget = m_formWindow->widgetUnderMouse(formPos, wum);
251 if (m_lastDropTarget && dropTarget != m_lastDropTarget)
252 m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(globalPos), FormWindow::Restore);
253 m_lastDropTarget = dropTarget;
254 }
255
256 if (m_lastDropTarget)
257 m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(globalPos), FormWindow::Highlight);
258
259 if (isEnter || m_lastDropTarget)
260 mimeData->acceptEvent(e);
261 else
262 e->ignore();
263 return true;
264}
265
266bool WidgetEditorTool::handleDropEvent(QWidget *widget, QWidget *, QDropEvent *e)
267{
268 const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(e->mimeData());
269 if (!mimeData)
270 return false;
271
272 if (!m_lastDropTarget ||
273 !m_formWindow->hasFeature(QDesignerFormWindowInterface::EditFeature)) {
274 e->ignore();
275 return true;
276 }
277 // FormWindow determines the position from the decoration.
278 const QPoint globalPos = widget->mapToGlobal(e->position().toPoint());
279 mimeData->moveDecoration(globalPos);
280 if (m_specialDockDrag) {
281 if (!m_formWindow->dropDockWidget(mimeData->items().at(0), globalPos)) {
282 e->ignore();
283 return true;
284 }
285 } else if (!m_formWindow->dropWidgets(mimeData->items(), m_lastDropTarget, globalPos)) {
286 e->ignore();
287 return true;
288 }
289 mimeData->acceptEvent(e);
290 return true;
291}
292
293bool WidgetEditorTool::restoreDropHighlighting()
294{
295 if (!m_lastDropTarget)
296 return false;
297
298 m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(QCursor::pos()), FormWindow::Restore);
299 m_lastDropTarget = nullptr;
300 return true;
301}
302
303bool WidgetEditorTool::handleDragLeaveEvent(QWidget *, QWidget *, QDragLeaveEvent *event)
304{
305 if (restoreDropHighlighting()) {
306 event->accept();
307 return true;
308 }
309 return false;
310}
311
313{
314 Q_ASSERT(formWindow() != nullptr);
315 return formWindow()->mainContainer();
316}
317
319{
320 if (core()->widgetBox())
321 core()->widgetBox()->setEnabled(true);
322
323 if (m_formWindow == nullptr)
324 return;
325
326 const QWidgetList &sel = m_formWindow->selectedWidgets();
327 for (QWidget *w : sel)
328 m_formWindow->raiseSelection(w);
329}
330
332{
333 if (core()->widgetBox())
334 core()->widgetBox()->setEnabled(false);
335
336 if (m_formWindow == nullptr)
337 return;
338
339 m_formWindow->clearSelection();
340}
341
342} // namespace qdesigner_internal
343
344QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:432
QWidget * mainContainer() const override
Returns the main container widget for the form window.
void clearSelection(bool changePropertyDisplay=true) override
Clears the current selection in the form window.
QWidget * formContainer() const override
Returns the form the widget containing the main container widget.
bool handlePaintEvent(QWidget *widget, QWidget *managedWidget, QPaintEvent *e)
bool handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
bool handleDragLeaveEvent(QWidget *widget, QWidget *managedWidget, QDragLeaveEvent *e)
QDesignerFormWindowInterface * formWindow() const override
bool handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
bool handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e)
bool handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
bool handleDropEvent(QWidget *widget, QWidget *managedWidget, QDropEvent *e)
bool handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
QDesignerFormEditorInterface * core() const override
bool handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event) override
bool handleDragEnterMoveEvent(QWidget *widget, QWidget *managedWidget, QDragMoveEvent *e, bool isEnter)
bool handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.