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