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