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
qquickdesignersupportitems.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7
8#include <QtQml/qqmlcomponent.h>
9
10#include <private/qabstractanimation_p.h>
11#include <private/qobject_p.h>
12#include <private/qquickbehavior_p.h>
13#include <private/qquicktext_p.h>
14#include <private/qquicktextinput_p.h>
15#include <private/qquicktextedit_p.h>
16#include <private/qquicktransition_p.h>
17#include <private/qquickloader_p.h>
18
19#include <private/qquickanimation_p.h>
20#include <private/qqmlmetatype_p.h>
21#include <private/qqmltimer_p.h>
22
24
25static void (*fixResourcePathsForObjectCallBack)(QObject*) = nullptr;
26
27static void stopAnimation(QObject *object)
28{
29 if (object == nullptr)
30 return;
31
32 QQuickTransition *transition = qobject_cast<QQuickTransition*>(object);
33 QQuickAbstractAnimation *animation = qobject_cast<QQuickAbstractAnimation*>(object);
34 QQmlTimer *timer = qobject_cast<QQmlTimer*>(object);
35 if (transition) {
36 transition->setFromState(QString());
37 transition->setToState(QString());
38 } else if (animation) {
39// QQuickScriptAction *scriptAimation = qobject_cast<QQuickScriptAction*>(animation);
40// if (scriptAimation) FIXME
41// scriptAimation->setScript(QQmlScriptString());
42 animation->complete();
43 animation->setDisableUserControl();
44 } else if (timer) {
45 timer->blockSignals(true);
46 }
47}
48
49static void makeLoaderSynchronous(QObject *object)
50{
51 if (QQuickLoader *loader = qobject_cast<QQuickLoader*>(object))
52 loader->setAsynchronous(false);
53}
54
55static void allSubObjects(QObject *object, QObjectList &objectList)
56{
57 // don't add null pointer and stop if the object is already in the list
58 if (!object || objectList.contains(object))
59 return;
60
61 objectList.append(object);
62
63 const QMetaObject *mo = object->metaObject();
64
65 QByteArrayList deferredPropertyNames;
66 const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames");
67 if (namesIndex != -1) {
68 QMetaClassInfo classInfo = mo->classInfo(namesIndex);
69 deferredPropertyNames = QByteArray(classInfo.value()).split(',');
70 }
71
72 for (int index = QObject::staticMetaObject.propertyOffset();
73 index < object->metaObject()->propertyCount();
74 index++) {
75
76 QMetaProperty metaProperty = object->metaObject()->property(index);
77
78 if (deferredPropertyNames.contains(metaProperty.name()))
79 continue;
80
81 // search recursive in property objects
82 if (metaProperty.isReadable()
83 && metaProperty.isWritable()
84 && metaProperty.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
85 if (qstrcmp(metaProperty.name(), "parent")) {
86 QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(object));
87 allSubObjects(propertyObject, objectList);
88 }
89
90 }
91
92 // search recursive in property object lists
93 if (metaProperty.isReadable()
94 && QQmlMetaType::isList(metaProperty.metaType())) {
95 QQmlListReference list(object, metaProperty.name());
96 if (list.canCount() && list.canAt()) {
97 for (qsizetype i = 0; i < list.count(); i++) {
98 QObject *propertyObject = list.at(i);
99 allSubObjects(propertyObject, objectList);
100
101 }
102 }
103 }
104 }
105
106 // search recursive in object children list
107 for (QObject *childObject : object->children()) {
108 allSubObjects(childObject, objectList);
109 }
110
111 // search recursive in quick item childItems list
112 QQuickItem *quickItem = qobject_cast<QQuickItem*>(object);
113 if (quickItem) {
114 const auto childItems = quickItem->childItems();
115 for (QQuickItem *childItem : childItems)
116 allSubObjects(childItem, objectList);
117 }
118}
119
120void QQuickDesignerSupportItems::tweakObjects(QObject *object)
121{
122 QObjectList objectList;
123 allSubObjects(object, objectList);
124 for (QObject* childObject : std::as_const(objectList)) {
125 stopAnimation(childObject);
126 makeLoaderSynchronous(childObject);
127 if (fixResourcePathsForObjectCallBack)
128 fixResourcePathsForObjectCallBack(childObject);
129 }
130}
131
132static QObject *createDummyWindow(QQmlEngine *engine)
133{
134 QQmlComponent component(engine, QUrl(QStringLiteral("qrc:/qtquickplugin/mockfiles/Window.qml")));
135 return component.create();
136}
137
138static bool isWindowMetaObject(const QMetaObject *metaObject)
139{
140 if (metaObject) {
141 if (metaObject->className() == QByteArrayLiteral("QWindow"))
142 return true;
143
144 return isWindowMetaObject(metaObject->superClass());
145 }
146
147 return false;
148}
149
150static bool isWindow(QObject *object) {
151 if (object)
152 return isWindowMetaObject(object->metaObject());
153
154 return false;
155}
156
157static bool isCrashingType(const QQmlType &type)
158{
159 QString name = type.qmlTypeName();
160
161 if (name == QLatin1String("QtMultimedia/MediaPlayer"))
162 return true;
163
164 if (name == QLatin1String("QtMultimedia/Audio"))
165 return true;
166
167 if (name == QLatin1String("QtQuick.Controls/MenuItem"))
168 return true;
169
170 if (name == QLatin1String("QtQuick.Controls/Menu"))
171 return true;
172
173 if (name == QLatin1String("QtQuick/Timer"))
174 return true;
175
176 return false;
177}
178
179QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context)
180{
181 ComponentCompleteDisabler disableComponentComplete;
182
183 Q_UNUSED(disableComponentComplete);
184
185 QObject *object = nullptr;
186 QQmlType type = QQmlMetaType::qmlType(typeName, version);
187
188 if (isCrashingType(type)) {
189 object = new QObject;
190 } else if (type.isValid()) {
191 if ( type.isComposite()) {
192 object = createComponent(type.sourceUrl(), context);
193 } else
194 {
195 if (type.typeName() == "QQmlComponent") {
196 object = new QQmlComponent(context->engine(), nullptr);
197 } else {
198 object = type.create();
199 }
200 }
201
202 if (isWindow(object)) {
203 delete object;
204 object = createDummyWindow(context->engine());
205 }
206
207 }
208
209 if (!object) {
210 qWarning() << "QuickDesigner: Cannot create an object of type"
211 << QString::fromLatin1("%1 %2,%3").arg(typeName)
212 .arg(version.majorVersion()).arg(version.minorVersion())
213 << "- type isn't known to declarative meta type system";
214 }
215
216 tweakObjects(object);
217
218 if (object && QQmlEngine::contextForObject(object) == nullptr)
219 QQmlEngine::setContextForObject(object, context);
220
221 QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
222
223 return object;
224}
225
226QObject *QQuickDesignerSupportItems::createComponent(const QUrl &componentUrl, QQmlContext *context)
227{
228 ComponentCompleteDisabler disableComponentComplete;
229 Q_UNUSED(disableComponentComplete);
230
231 QQmlComponent component(context->engine(), componentUrl);
232
233 QObject *object = component.beginCreate(context);
234 tweakObjects(object);
235 component.completeCreate();
236 QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
237
238 if (component.isError()) {
239 qWarning() << "Error in:" << Q_FUNC_INFO << componentUrl;
240 const auto errors = component.errors();
241 for (const QQmlError &error : errors)
242 qWarning() << error;
243 }
244 return object;
245}
246
247bool QQuickDesignerSupportItems::objectWasDeleted(QObject *object)
248{
249 return QObjectPrivate::get(object)->wasDeleted;
250}
251
252void QQuickDesignerSupportItems::disableNativeTextRendering(QQuickItem *item)
253{
254 QQuickText *text = qobject_cast<QQuickText*>(item);
255 if (text)
256 text->setRenderType(QQuickText::QtRendering);
257
258 QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(item);
259 if (textInput)
260 textInput->setRenderType(QQuickTextInput::QtRendering);
261
262 QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(item);
263 if (textEdit)
264 textEdit->setRenderType(QQuickTextEdit::QtRendering);
265}
266
267void QQuickDesignerSupportItems::disableTextCursor(QQuickItem *item)
268{
269 const auto childItems = item->childItems();
270 for (QQuickItem *childItem : childItems)
271 disableTextCursor(childItem);
272
273 QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(item);
274 if (textInput)
275 textInput->setCursorVisible(false);
276
277 QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(item);
278 if (textEdit)
279 textEdit->setCursorVisible(false);
280}
281
282void QQuickDesignerSupportItems::disableTransition(QObject *object)
283{
284 QQuickTransition *transition = qobject_cast<QQuickTransition*>(object);
285 Q_ASSERT(transition);
286 const QString invalidState = QLatin1String("invalidState");
287 transition->setToState(invalidState);
288 transition->setFromState(invalidState);
289}
290
291void QQuickDesignerSupportItems::disableBehaivour(QObject *object)
292{
293 QQuickBehavior* behavior = qobject_cast<QQuickBehavior*>(object);
294 Q_ASSERT(behavior);
295 behavior->setEnabled(false);
296}
297
298void QQuickDesignerSupportItems::stopUnifiedTimer()
299{
300 QUnifiedTimer::instance()->setSpeedModifier(0);
301}
302
303void QQuickDesignerSupportItems::registerFixResourcePathsForObjectCallBack(void (*callback)(QObject *))
304{
305 fixResourcePathsForObjectCallBack = callback;
306}
307
308QT_END_NAMESPACE
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE void(* fixResourcePathsForObjectCallBack)(QObject *)
static bool isCrashingType(const QQmlType &type)
static void makeLoaderSynchronous(QObject *object)
static void stopAnimation(QObject *object)
static void allSubObjects(QObject *object, QObjectList &objectList)
static bool isWindow(QObject *object)
static QObject * createDummyWindow(QQmlEngine *engine)
static bool isWindowMetaObject(const QMetaObject *metaObject)