Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qdesigner_formbuilder.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
5
#
include
"qdesigner_formbuilder_p.h"
6
#
include
"dynamicpropertysheet.h"
7
#
include
"qsimpleresource_p.h"
8
#
include
"widgetfactory_p.h"
9
#
include
"qdesigner_introspection_p.h"
10
11
#
include
<
QtDesigner
/
private
/
ui4_p
.
h
>
12
#
include
<
QtDesigner
/
private
/
formbuilderextra_p
.
h
>
13
// sdk
14
#
include
<
QtDesigner
/
container
.
h
>
15
#
include
<
QtDesigner
/
propertysheet
.
h
>
16
#
include
<
QtDesigner
/
qextensionmanager
.
h
>
17
#
include
<
QtDesigner
/
abstractformeditor
.
h
>
18
#
include
<
QtDesigner
/
abstractformwindow
.
h
>
19
#
include
<
QtDesigner
/
abstractwidgetfactory
.
h
>
20
#
include
<
abstractdialoggui_p
.
h
>
21
22
#
include
<
QtUiPlugin
/
customwidget
.
h
>
23
24
// shared
25
#
include
<
qdesigner_propertysheet_p
.
h
>
26
#
include
<
qdesigner_utils_p
.
h
>
27
#
include
<
formwindowbase_p
.
h
>
28
#
include
<
qtresourcemodel_p
.
h
>
29
30
#
include
<
QtWidgets
/
qwidget
.
h
>
31
#
include
<
QtWidgets
/
qmenu
.
h
>
32
#
include
<
QtWidgets
/
qtoolbar
.
h
>
33
#
include
<
QtWidgets
/
qmenubar
.
h
>
34
#
include
<
QtWidgets
/
qmainwindow
.
h
>
35
#
include
<
QtWidgets
/
qstylefactory
.
h
>
36
#
include
<
QtWidgets
/
qstyle
.
h
>
37
#
include
<
QtWidgets
/
qapplication
.
h
>
38
#
include
<
QtWidgets
/
qabstractscrollarea
.
h
>
39
#
include
<
QtWidgets
/
qmessagebox
.
h
>
40
#
include
<
QtGui
/
qpixmap
.
h
>
41
42
#
include
<
QtCore
/
qbuffer
.
h
>
43
#
include
<
QtCore
/
qdebug
.
h
>
44
#
include
<
QtCore
/
qcoreapplication
.
h
>
45
46
QT_BEGIN_NAMESPACE
47
48
using
namespace
Qt::StringLiterals;
49
50
namespace
qdesigner_internal
{
51
52
QDesignerFormBuilder
::
QDesignerFormBuilder
(
QDesignerFormEditorInterface
*
core
,
53
const
DeviceProfile
&
deviceProfile
) :
54
m_core
(
core
),
55
m_deviceProfile
(
deviceProfile
),
56
m_iconCache
(&
m_pixmapCache
),
57
m_ignoreCreateResources
(
false
),
58
m_tempResourceSet
(
nullptr
),
59
m_mainWidget
(
true
)
60
{
61
Q_ASSERT
(
m_core
);
62
}
63
64
QString
QDesignerFormBuilder
::
systemStyle
()
const
65
{
66
return
m_deviceProfile
.
isEmpty
() ?
67
QString
::
fromUtf8
(
QApplication
::
style
()->
metaObject
()->
className
()) :
68
m_deviceProfile
.
style
();
69
}
70
71
QWidget
*
QDesignerFormBuilder
::
create
(
DomUI
*
ui
,
QWidget
*
parentWidget
)
72
{
73
m_mainWidget
=
true
;
74
QtResourceSet
*
resourceSet
=
core
()->
resourceModel
()->
currentResourceSet
();
75
76
// reload resource properties;
77
createResources
(
ui
->
elementResources
());
78
core
()->
resourceModel
()->
setCurrentResourceSet
(
m_tempResourceSet
);
79
80
m_ignoreCreateResources
=
true
;
81
DesignerPixmapCache
pixmapCache
;
82
DesignerIconCache
iconCache
(&
pixmapCache
);
83
m_pixmapCache
.
clear
();
84
m_iconCache
.
clear
();
85
86
QWidget
*
widget
=
QFormBuilder
::
create
(
ui
,
parentWidget
);
87
88
core
()->
resourceModel
()->
setCurrentResourceSet
(
resourceSet
);
89
core
()->
resourceModel
()->
removeResourceSet
(
m_tempResourceSet
);
90
m_tempResourceSet
=
nullptr
;
91
m_ignoreCreateResources
=
false
;
92
m_pixmapCache
.
clear
();
93
m_iconCache
.
clear
();
94
95
m_customWidgetsWithScript
.
clear
();
96
return
widget
;
97
}
98
99
QWidget
*
QDesignerFormBuilder
::
createWidget
(
const
QString
&
widgetName
,
QWidget
*
parentWidget
,
const
QString
&
name
)
100
{
101
QWidget
*
widget
=
nullptr
;
102
103
if
(
widgetName
==
"QToolBar"_L1
) {
104
widget
=
new
QToolBar
(
parentWidget
);
105
}
else
if
(
widgetName
==
"QMenu"_L1
) {
106
widget
=
new
QMenu
(
parentWidget
);
107
}
else
if
(
widgetName
==
"QMenuBar"_L1
) {
108
widget
=
new
QMenuBar
(
parentWidget
);
109
}
else
{
110
widget
=
core
()->
widgetFactory
()->
createWidget
(
widgetName
,
parentWidget
);
111
}
112
113
if
(
widget
) {
114
widget
->
setObjectName
(
name
);
115
if
(
QSimpleResource
::
hasCustomWidgetScript
(
m_core
,
widget
))
116
m_customWidgetsWithScript
.
insert
(
widget
);
117
}
118
119
if
(
m_mainWidget
) {
// We need to apply the DPI here to take effect on size hints, etc.
120
m_deviceProfile
.
apply
(
m_core
,
widget
,
DeviceProfile
::
ApplyPreview
);
121
m_mainWidget
=
false
;
122
}
123
return
widget
;
124
}
125
126
bool
QDesignerFormBuilder
::
addItem
(
DomWidget
*
ui_widget
,
QWidget
*
widget
,
QWidget
*
parentWidget
)
127
{
128
// Use container extension or rely on scripts unless main window.
129
if
(
QFormBuilder
::
addItem
(
ui_widget
,
widget
,
parentWidget
))
130
return
true
;
131
132
if
(
QDesignerContainerExtension
*
container
=
qt_extension
<
QDesignerContainerExtension
*>(
m_core
->
extensionManager
(),
parentWidget
)) {
133
container
->
addWidget
(
widget
);
134
return
true
;
135
}
136
return
false
;
137
}
138
139
bool
QDesignerFormBuilder
::
addItem
(
DomLayoutItem
*
ui_item
,
QLayoutItem
*
item
,
QLayout
*
layout
)
140
{
141
return
QFormBuilder
::
addItem
(
ui_item
,
item
,
layout
);
142
}
143
144
QIcon
QDesignerFormBuilder
::
nameToIcon
(
const
QString
&
filePath
,
const
QString
&
qrcPath
)
145
{
146
Q_UNUSED
(
filePath
);
147
Q_UNUSED
(
qrcPath
);
148
qWarning
() <<
"QDesignerFormBuilder::nameToIcon() is obsoleted"
;
149
return
QIcon
();
150
}
151
152
QPixmap
QDesignerFormBuilder
::
nameToPixmap
(
const
QString
&
filePath
,
const
QString
&
qrcPath
)
153
{
154
Q_UNUSED
(
filePath
);
155
Q_UNUSED
(
qrcPath
);
156
qWarning
() <<
"QDesignerFormBuilder::nameToPixmap() is obsoleted"
;
157
return
QPixmap
();
158
}
159
160
/* If the property is a enum or flag value, retrieve
161
* the existing enum/flag type via property sheet and use it to convert */
162
163
static
bool
readDomEnumerationValue
(
const
DomProperty *p,
164
const
QDesignerPropertySheetExtension* sheet,
165
QVariant &v)
166
{
167
switch
(p->kind()) {
168
case
DomProperty::Set: {
169
const
int
index = sheet->indexOf(p->attributeName());
170
if
(index == -1)
171
return
false
;
172
const
QVariant sheetValue = sheet->property(index);
173
if
(sheetValue.canConvert<PropertySheetFlagValue>()) {
174
const
PropertySheetFlagValue f = qvariant_cast<
PropertySheetFlagValue
>(sheetValue);
175
const
auto
flags = f.metaFlags.parseFlags(p->elementSet());
176
if
(!flags)
177
designerWarning(f.metaFlags.messageParseFailed(p->elementSet()));
178
v = flags.value_or(0);
179
return
true
;
180
}
181
}
182
break
;
183
case
DomProperty::Enum: {
184
const
int
index = sheet->indexOf(p->attributeName());
185
if
(index == -1)
186
return
false
;
187
const
QVariant sheetValue = sheet->property(index);
188
if
(sheetValue.canConvert<PropertySheetEnumValue>()) {
189
const
PropertySheetEnumValue e = qvariant_cast<
PropertySheetEnumValue
>(sheetValue);
190
const
auto
value = e.metaEnum.parseEnum(p->elementEnum());
191
if
(!value)
192
designerWarning(e.metaEnum.messageParseFailed(p->elementEnum()));
193
v = value.value_or(0);
194
return
true
;
195
}
196
}
197
break
;
198
default
:
199
break
;
200
}
201
return
false
;
202
}
203
204
void
QDesignerFormBuilder
::
applyProperties
(
QObject
*
o
,
const
QList
<
DomProperty
*> &
properties
)
205
{
206
if
(
properties
.
isEmpty
())
207
return
;
208
209
const
QDesignerPropertySheetExtension
*
sheet
=
qt_extension
<
QDesignerPropertySheetExtension
*>(
core
()->
extensionManager
(),
o
);
210
const
QDesignerDynamicPropertySheetExtension
*
dynamicSheet
=
qt_extension
<
QDesignerDynamicPropertySheetExtension
*>(
core
()->
extensionManager
(),
o
);
211
const
bool
changingMetaObject
=
WidgetFactory
::
classNameOf
(
core
(),
o
) ==
"QAxWidget"_L1
;
212
const
QDesignerMetaObjectInterface
*
meta
=
core
()->
introspection
()->
metaObject
(
o
);
213
const
bool
dynamicPropertiesAllowed
=
dynamicSheet
&&
dynamicSheet
->
dynamicPropertiesAllowed
();
214
215
QDesignerPropertySheet
*
designerPropertySheet
=
qobject_cast
<
QDesignerPropertySheet
*>(
216
core
()->
extensionManager
()->
extension
(
o
,
Q_TYPEID
(
QDesignerPropertySheetExtension
)));
217
218
DesignerPixmapCache
*
oldPixmapCache
{};
219
DesignerIconCache
*
oldIconCache
{};
220
if
(
designerPropertySheet
) {
221
oldPixmapCache
=
designerPropertySheet
->
pixmapCache
();
222
designerPropertySheet
->
setPixmapCache
(&
m_pixmapCache
);
223
oldIconCache
=
designerPropertySheet
->
iconCache
();
224
designerPropertySheet
->
setIconCache
(&
m_iconCache
);
225
}
226
227
for
(
DomProperty
*
p
:
properties
) {
228
QVariant
v
;
229
if
(!
readDomEnumerationValue
(
p
,
sheet
,
v
))
230
v
=
toVariant
(
o
->
metaObject
(),
p
);
231
232
if
(
v
.
isNull
())
233
continue
;
234
235
const
QString
attributeName
=
p
->
attributeName
();
236
if
(
d
->
applyPropertyInternally
(
o
,
attributeName
,
v
))
237
continue
;
238
239
// refuse fake properties like current tab name (weak test)
240
if
(!
dynamicPropertiesAllowed
) {
241
if
(
changingMetaObject
)
// Changes after setting control of QAxWidget
242
meta
=
core
()->
introspection
()->
metaObject
(
o
);
243
if
(
meta
->
indexOfProperty
(
attributeName
) == -1)
244
continue
;
245
}
246
247
QObject
*
obj
=
o
;
248
QAbstractScrollArea
*
scroll
=
qobject_cast
<
QAbstractScrollArea
*>(
o
);
249
if
(
scroll
&&
attributeName
==
"cursor"_L1
&&
scroll
->
viewport
())
250
obj
=
scroll
->
viewport
();
251
252
// a real property
253
obj
->
setProperty
(
attributeName
.
toUtf8
().
constData
(),
v
);
254
}
255
256
if
(
designerPropertySheet
) {
257
designerPropertySheet
->
setPixmapCache
(
oldPixmapCache
);
258
designerPropertySheet
->
setIconCache
(
oldIconCache
);
259
}
260
}
261
262
DomWidget
*
QDesignerFormBuilder
::
createDom
(
QWidget
*
widget
,
DomWidget
*
ui_parentWidget
,
bool
recursive
)
263
{
264
DomWidget
*
ui_widget
=
QFormBuilder
::
createDom
(
widget
,
ui_parentWidget
,
recursive
);
265
QSimpleResource
::
addExtensionDataToDOM
(
this
,
m_core
,
ui_widget
,
widget
);
266
return
ui_widget
;
267
}
268
269
QWidget
*
QDesignerFormBuilder
::
create
(
DomWidget
*
ui_widget
,
QWidget
*
parentWidget
)
270
{
271
QWidget
*
widget
=
QFormBuilder
::
create
(
ui_widget
,
parentWidget
);
272
// Do not apply state if scripts are to be run in preview mode
273
QSimpleResource
::
applyExtensionDataFromDOM
(
this
,
m_core
,
ui_widget
,
widget
);
274
return
widget
;
275
}
276
277
void
QDesignerFormBuilder
::
createResources
(
DomResources
*
resources
)
278
{
279
if
(
m_ignoreCreateResources
)
280
return
;
281
QStringList
paths
;
282
if
(
resources
!=
nullptr
) {
283
const
auto
&
dom_include
=
resources
->
elementInclude
();
284
for
(
DomResource
*
res
:
dom_include
) {
285
QString
path
=
QDir
::
cleanPath
(
workingDirectory
().
absoluteFilePath
(
res
->
attributeLocation
()));
286
paths
<<
path
;
287
}
288
}
289
290
m_tempResourceSet
=
core
()->
resourceModel
()->
addResourceSet
(
paths
);
291
}
292
293
QLayout
*
QDesignerFormBuilder
::
create
(
DomLayout
*
ui_layout
,
QLayout
*
layout
,
QWidget
*
parentWidget
)
294
{
295
return
QFormBuilder
::
create
(
ui_layout
,
layout
,
parentWidget
);
296
}
297
298
void
QDesignerFormBuilder
::
loadExtraInfo
(
DomWidget
*
ui_widget
,
QWidget
*
widget
,
QWidget
*
parentWidget
)
299
{
300
QFormBuilder
::
loadExtraInfo
(
ui_widget
,
widget
,
parentWidget
);
301
}
302
303
QWidget
*
QDesignerFormBuilder
::
createPreview
(
const
QDesignerFormWindowInterface
*
fw
,
304
const
QString
&
styleName
,
305
const
QString
&
appStyleSheet
,
306
const
DeviceProfile
&
deviceProfile
,
307
QString
*
errorMessage
)
308
{
309
// load
310
QDesignerFormBuilder
builder
(
fw
->
core
(),
deviceProfile
);
311
builder
.
setWorkingDirectory
(
fw
->
absoluteDir
());
312
313
QByteArray
bytes
=
fw
->
contents
().
toUtf8
();
314
315
QBuffer
buffer
(&
bytes
);
316
buffer
.
open
(
QIODevice
::
ReadOnly
);
317
318
QWidget
*
widget
=
builder
.
load
(&
buffer
,
nullptr
);
319
if
(!
widget
) {
// Shouldn't happen
320
*
errorMessage
=
QCoreApplication
::
translate
(
"QDesignerFormBuilder"
,
"The preview failed to build."
);
321
return
nullptr
;
322
}
323
// Make sure palette is applied
324
const
QString
styleToUse
=
styleName
.
isEmpty
() ?
builder
.
deviceProfile
().
style
() :
styleName
;
325
if
(!
styleToUse
.
isEmpty
()) {
326
if
(
WidgetFactory
*
wf
=
qobject_cast
<
qdesigner_internal
::
WidgetFactory
*>(
fw
->
core
()->
widgetFactory
())) {
327
if
(
styleToUse
!=
wf
->
styleName
())
328
WidgetFactory
::
applyStyleToTopLevel
(
wf
->
getStyle
(
styleToUse
),
widget
);
329
}
330
}
331
// Fake application style sheet by prepending. (If this doesn't work, fake by nesting
332
// into parent widget).
333
if
(!
appStyleSheet
.
isEmpty
())
334
widget
->
setStyleSheet
(
appStyleSheet
+ u'\n' +
widget
->
styleSheet
());
335
return
widget
;
336
}
337
338
QWidget
*
QDesignerFormBuilder
::
createPreview
(
const
QDesignerFormWindowInterface
*
fw
,
const
QString
&
styleName
)
339
{
340
return
createPreview
(
fw
,
styleName
,
QString
());
341
}
342
343
QWidget
*
QDesignerFormBuilder
::
createPreview
(
const
QDesignerFormWindowInterface
*
fw
,
344
const
QString
&
styleName
,
345
const
QString
&
appStyleSheet
,
346
QString
*
errorMessage
)
347
{
348
return
createPreview
(
fw
,
styleName
,
appStyleSheet
,
DeviceProfile
(),
errorMessage
);
349
}
350
351
QWidget
*
QDesignerFormBuilder
::
createPreview
(
const
QDesignerFormWindowInterface
*
fw
,
const
QString
&
styleName
,
const
QString
&
appStyleSheet
)
352
{
353
QString
errorMessage
;
354
QWidget
*
widget
=
createPreview
(
fw
,
styleName
,
appStyleSheet
,
DeviceProfile
(), &
errorMessage
);
355
if
(!
widget
&& !
errorMessage
.
isEmpty
()) {
356
// Display Script errors or message box
357
QWidget
*
dialogParent
=
fw
->
core
()->
topLevel
();
358
fw
->
core
()->
dialogGui
()->
message
(
dialogParent
,
QDesignerDialogGuiInterface
::
PreviewFailureMessage
,
359
QMessageBox
::
Warning
,
QCoreApplication
::
translate
(
"QDesignerFormBuilder"
,
"Designer"
),
360
errorMessage
,
QMessageBox
::
Ok
);
361
return
nullptr
;
362
}
363
return
widget
;
364
}
365
366
QPixmap
QDesignerFormBuilder
::
createPreviewPixmap
(
const
QDesignerFormWindowInterface
*
fw
,
const
QString
&
styleName
,
const
QString
&
appStyleSheet
)
367
{
368
QWidget
*
widget
=
createPreview
(
fw
,
styleName
,
appStyleSheet
);
369
if
(!
widget
)
370
return
QPixmap
();
371
372
const
QPixmap
rc
=
widget
->
grab
(
QRect
(0, 0, -1, -1));
373
widget
->
deleteLater
();
374
return
rc
;
375
}
376
377
// ---------- NewFormWidgetFormBuilder
378
379
NewFormWidgetFormBuilder
::
NewFormWidgetFormBuilder
(
QDesignerFormEditorInterface
*
core
,
380
const
DeviceProfile
&
deviceProfile
) :
381
QDesignerFormBuilder
(
core
,
deviceProfile
)
382
{
383
}
384
385
void
NewFormWidgetFormBuilder
::
createCustomWidgets
(
DomCustomWidgets
*
dc
)
386
{
387
QSimpleResource
::
handleDomCustomWidgets
(
core
(),
dc
);
388
}
389
390
}
// namespace qdesigner_internal
391
392
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qdesigner_internal
Auxiliary methods to store/retrieve settings.
Definition
buddyeditor.cpp:67
qdesigner_internal::readDomEnumerationValue
static bool readDomEnumerationValue(const DomProperty *p, const QDesignerPropertySheetExtension *sheet, QVariant &v)
Definition
qdesigner_formbuilder.cpp:163
qdesigner_internal::PropertySheetEnumValue::PropertySheetEnumValue
PropertySheetEnumValue()
qdesigner_internal::PropertySheetFlagValue::PropertySheetFlagValue
PropertySheetFlagValue()
qttools
src
designer
src
lib
shared
qdesigner_formbuilder.cpp
Generated on
for Qt by
1.18.0