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