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
widgetbox_dnditem.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
6#include <widgetfactory_p.h>
7#include <spacer_widget_p.h>
8#include <qdesigner_formbuilder_p.h>
9#include <qtresourcemodel_p.h>
10#include <formwindowbase_p.h>
11#include <qdesigner_utils_p.h>
12#include <qdesigner_dockwidget_p.h>
13#include <qsimpleresource_p.h>
14
15#include <QtDesigner/abstractformeditor.h>
16#include <QtDesigner/abstractformwindowmanager.h>
17
18#include <QtDesigner/private/ui4_p.h>
19
20#include <QtWidgets/qstyle.h>
21#include <QtWidgets/qapplication.h>
22
24
25using namespace Qt::StringLiterals;
26
27namespace qdesigner_internal {
28/*******************************************************************************
29** WidgetBoxResource
30*/
31
32static inline DeviceProfile currentDeviceProfile(const QDesignerFormEditorInterface *core)
33{
34 if (QDesignerFormWindowInterface *cfw = core->formWindowManager()->activeFormWindow())
35 if (const FormWindowBase *fwb = qobject_cast<const FormWindowBase *>(cfw))
36 return fwb->deviceProfile();
37 return DeviceProfile();
38}
39
41{
42public:
43 WidgetBoxResource(QDesignerFormEditorInterface *core);
44
45 // protected->public
46 QWidget *createUI(DomUI *ui, QWidget *parents) { return QDesignerFormBuilder::create(ui, parents); }
47
48protected:
49
50 QWidget *create(DomWidget *ui_widget, QWidget *parents) override;
51 QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name) override;
52 void createCustomWidgets(DomCustomWidgets *) override;
53};
54
55WidgetBoxResource::WidgetBoxResource(QDesignerFormEditorInterface *core) :
57{
58}
59
60
61QWidget *WidgetBoxResource::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name)
62{
63 if (widgetName == "Spacer"_L1) {
64 Spacer *spacer = new Spacer(parentWidget);
65 spacer->setObjectName(name);
66 return spacer;
67 }
68
69 return QDesignerFormBuilder::createWidget(widgetName, parentWidget, name);
70}
71
72QWidget *WidgetBoxResource::create(DomWidget *ui_widget, QWidget *parent)
73{
74 QWidget *result = QDesignerFormBuilder::create(ui_widget, parent);
75 // It is possible to have a syntax error or something in custom
76 // widget XML, so, try to recover here by creating an artificial
77 // top level + widget.
78 if (!result) {
79 const QString msg = QApplication::translate("qdesigner_internal::WidgetBox", "Warning: Widget creation failed in the widget box. This could be caused by invalid custom widget XML.");
80 qdesigner_internal::designerWarning(msg);
81 result = new QWidget(parent);
82 new QWidget(result);
83 }
84 result->setFocusPolicy(Qt::NoFocus);
85 result->setObjectName(ui_widget->attributeName());
86 return result;
87}
88
89void WidgetBoxResource::createCustomWidgets(DomCustomWidgets *dc)
90{
91 // Make a promotion entry in case someone has a promoted widget
92 // in the scratchpad.
93 QSimpleResource::handleDomCustomWidgets(core(), dc);
94
95}
96
97/*******************************************************************************
98** WidgetBoxResource
99*/
100
101static QSize geometryProp(const DomWidget *dw)
102{
103 const auto &prop_list = dw->elementProperty();
104 for (DomProperty *prop : prop_list) {
105 if (prop->attributeName() != "geometry"_L1)
106 continue;
107 DomRect *dr = prop->elementRect();
108 if (dr == nullptr)
109 continue;
110 return QSize(dr->elementWidth(), dr->elementHeight());
111 }
112 return QSize();
113}
114
115static QSize domWidgetSize(const DomWidget *dw)
116{
117 QSize size = geometryProp(dw);
118 if (size.isValid())
119 return size;
120
121 const auto &elementWidgets = dw->elementWidget();
122 for (const DomWidget *child : elementWidgets) {
123 size = geometryProp(child);
124 if (size.isValid())
125 return size;
126 }
127
128 const auto &elementLayouts = dw->elementLayout();
129 for (const DomLayout *dl : elementLayouts) {
130 const auto &elementItems = dl->elementItem();
131 for (DomLayoutItem *item : elementItems) {
132 const DomWidget *child = item->elementWidget();
133 if (child == nullptr)
134 continue;
135 size = geometryProp(child);
136 if (size.isValid())
137 return size;
138 }
139 }
140
141 return QSize();
142}
143
144static QWidget *decorationFromDomWidget(DomUI *dom_ui, QDesignerFormEditorInterface *core)
145{
146 WidgetBoxResource builder(core);
147 // We have the builder create the articial QWidget fake top level as a tooltip
148 // because the size algorithm works better at weird DPI settings
149 // if the actual widget is created as a child of a container
150 QWidget *fakeTopLevel = builder.createUI(dom_ui, nullptr);
151 fakeTopLevel->setParent(nullptr, Qt::ToolTip); // Container
152 // Actual widget
153 const DomWidget *domW = dom_ui->elementWidget()->elementWidget().constFirst();
154 QWidget *w = fakeTopLevel->findChildren<QWidget*>().constFirst();
155 Q_ASSERT(w);
156 // hack begin;
157 // We set _q_dockDrag dynamic property which will be detected in drag enter event of form window.
158 // Dock drop is handled in special way (highlight goes to central widget of main window)
159 if (qobject_cast<QDesignerDockWidget *>(w))
160 fakeTopLevel->setProperty("_q_dockDrag", QVariant(true));
161 // hack end;
162 w->setAutoFillBackground(true); // Different style for embedded
163 QSize size = domWidgetSize(domW);
164 const QSize minimumSize = w->minimumSizeHint();
165 if (!size.isValid())
166 size = w->sizeHint();
167 if (size.width() < minimumSize.width())
168 size.setWidth(minimumSize.width());
169 if (size.height() < minimumSize.height())
170 size.setHeight(minimumSize.height());
171 // A QWidget might have size -1,-1 if no geometry property is specified in the widget box.
172 if (size.isEmpty())
173 size = size.expandedTo(QSize(16, 16));
174 w->setGeometry(QRect(QPoint(0, 0), size));
175 fakeTopLevel->resize(size);
176 return fakeTopLevel;
177}
178
179WidgetBoxDnDItem::WidgetBoxDnDItem(QDesignerFormEditorInterface *core,
180 DomUI *dom_ui,
181 const QPoint &global_mouse_pos) :
183{
184 QWidget *decoration = decorationFromDomWidget(dom_ui, core);
185 decoration->move(global_mouse_pos - QPoint(5, 5));
186
187 init(dom_ui, nullptr, decoration, global_mouse_pos);
188}
189}
190
191QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:421
WidgetBoxDnDItem(QDesignerFormEditorInterface *core, DomUI *dom_ui, const QPoint &global_mouse_pos)
QWidget * createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name) override
void createCustomWidgets(DomCustomWidgets *) override
QWidget * create(DomWidget *ui_widget, QWidget *parents) override
QWidget * createUI(DomUI *ui, QWidget *parents)
WidgetBoxResource(QDesignerFormEditorInterface *core)
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static DeviceProfile currentDeviceProfile(const QDesignerFormEditorInterface *core)
static QSize geometryProp(const DomWidget *dw)
static QWidget * decorationFromDomWidget(DomUI *dom_ui, QDesignerFormEditorInterface *core)
static QSize domWidgetSize(const DomWidget *dw)