aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/designercore/model/model_p.h
blob: a3e972f329fa30c805eb3d8d23b7a502bdde50c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#pragma once

#include "qmldesignercorelib_global.h"

#include <tracing/qmldesignertracing.h>

#include "abstractview.h"
#ifndef QDS_USE_PROJECTSTORAGE
#  include "metainfo.h"
#endif
#include "modelnode.h"
#include "skipiterator.h"

#include <nodemetainfo.h>

#include <QList>
#include <QPointer>
#include <QSet>
#include <QUrl>
#include <QVector3D>

#include <algorithm>
#include <functional>

QT_BEGIN_NAMESPACE
class QPlainTextEdit;
class QPixmap;
QT_END_NAMESPACE

namespace QmlDesigner {

class AbstractProperty;
class RewriterView;
class NodeInstanceView;
class NodeMetaInfoPrivate;

namespace Internal {

using namespace NanotraceHR::Literals;

class InternalNode;
class InternalProperty;
class InternalBindingProperty;
class InternalSignalHandlerProperty;
class InternalSignalDeclarationProperty;
class InternalVariantProperty;
class InternalNodeAbstractProperty;
class InternalNodeListProperty;

using PropertyPair = QPair<InternalNodePointer, PropertyName>;

class ModelPrivate;

class WriteLocker
{
public:
    WriteLocker(Model *model);
    WriteLocker(ModelPrivate *model);
    ~WriteLocker();

    static void unlock(Model *model);
    static void lock(Model *model);

private:
    QPointer<ModelPrivate> m_model;
};

struct Increment
{
    using iterator = QList<QPointer<AbstractView>>::const_iterator;
    auto operator()(iterator current) {
        return std::find_if(std::next(current),
                            end,
                            [] (iterator::reference &view) { return view && view->isEnabled(); });
    }

   iterator end;
};

class EnabledViewRange : public SkipRange<QList<QPointer<AbstractView>>, Increment>
{
public:
    EnabledViewRange(const container &views)
        : base{views, Increment{views.end()}}
    {}
};

class ModelPrivate : public QObject,
                     protected ProjectStorageObserver
{
    Q_OBJECT

    friend Model;
    friend Internal::WriteLocker;

public:
    ModelPrivate(Model *model,
                 ProjectStorageDependencies m_projectStorageDependencies,
                 const TypeName &type,
                 int major,
                 int minor,
                 Model *metaInfoProxyModel,
                 std::unique_ptr<ModelResourceManagementInterface> resourceManagement);
    ModelPrivate(Model *model,
                 ProjectStorageDependencies m_projectStorageDependencies,
                 Utils::SmallStringView typeName,
                 Imports imports,
                 const QUrl &filePath,
                 std::unique_ptr<ModelResourceManagementInterface> resourceManagement);
    ModelPrivate(Model *model,
                 const TypeName &type,
                 int major,
                 int minor,
                 Model *metaInfoProxyModel,
                 std::unique_ptr<ModelResourceManagementInterface> resourceManagement);

    ~ModelPrivate() override;

    ModelPrivate(const ModelPrivate &) = delete;
    ModelPrivate &operator=(const ModelPrivate &) = delete;

    QUrl fileUrl() const;
    void setFileUrl(const QUrl &url);

    InternalNodePointer createNode(const TypeName &typeName,
                                   int majorVersion,
                                   int minorVersion,
                                   const QList<QPair<PropertyName, QVariant>> &propertyList,
                                   const AuxiliaryDatas &auxPropertyList,
                                   const QString &nodeSource,
                                   ModelNode::NodeSourceType nodeSourceType,
                                   const QString &behaviorPropertyName,
                                   bool isRootNode = false);

    /*factory methods for internal use in model and rewriter*/
    void removeNodeAndRelatedResources(const InternalNodePointer &node);
    void changeNodeId(const InternalNodePointer &node, const QString &id);
    void changeNodeType(const InternalNodePointer &node, const TypeName &typeName, int majorVersion, int minorVersion);

    InternalNodePointer rootNode() const;
    InternalNodePointer findNode(const QString &id) const;

#ifndef QDS_USE_PROJECTSTORAGE
    MetaInfo metaInfo() const;
    void setMetaInfo(const MetaInfo &metaInfo);
#endif

    void attachView(AbstractView *view);
    void detachView(AbstractView *view, bool notifyView);
    void detachAllViews();

    template<typename Callable>
    void notifyNodeInstanceViewLast(Callable call);
    template<typename Callable>
    void notifyNormalViewsLast(Callable call);
    template<typename Callable>
    void notifyInstanceChanges(Callable call);

    void notifyNodeCreated(const InternalNodePointer &newNode);
    void notifyNodeAboutToBeReparent(const InternalNodePointer &node,
                                     const InternalNodePointer &newParent,
                                     const PropertyName &newPropertyName,
                                     const InternalNodePointer &oldParent,
                                     const PropertyName &oldPropertyName,
                                     AbstractView::PropertyChangeFlags propertyChange);
    void notifyNodeReparent(const InternalNodePointer &node,
                            const InternalNodeAbstractProperty *newPropertyParent,
                            const InternalNodePointer &oldParent,
                            const PropertyName &oldPropertyName,
                            AbstractView::PropertyChangeFlags propertyChange);
    void notifyNodeAboutToBeRemoved(const InternalNodePointer &node);
    void notifyNodeRemoved(const InternalNodePointer &removedNode,
                           const InternalNodePointer &parentNode,
                           const PropertyName &parentPropertyName,
                           AbstractView::PropertyChangeFlags propertyChange);
    void notifyNodeIdChanged(const InternalNodePointer &node, const QString &newId, const QString &oldId);
    void notifyNodeTypeChanged(const InternalNodePointer &node, const TypeName &type, int majorVersion, int minorVersion);

    void notifyPropertiesRemoved(const QList<PropertyPair> &propertyList);
    void notifyPropertiesAboutToBeRemoved(const QList<InternalProperty *> &internalPropertyList);
    void notifyBindingPropertiesAboutToBeChanged(
        const QList<QmlDesigner::Internal::InternalBindingProperty *> &internalPropertyList);
    void notifyBindingPropertiesChanged(
        const QList<QmlDesigner::Internal::InternalBindingProperty *> &internalPropertyList,
        AbstractView::PropertyChangeFlags propertyChange);
    void notifySignalHandlerPropertiesChanged(
        const QVector<QmlDesigner::Internal::InternalSignalHandlerProperty *> &propertyList,
        AbstractView::PropertyChangeFlags propertyChange);
    void notifySignalDeclarationPropertiesChanged(
        const QVector<QmlDesigner::Internal::InternalSignalDeclarationProperty *> &propertyList,
        AbstractView::PropertyChangeFlags propertyChange);
    void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange);
    void notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList);

    void notifyNodeOrderChanged(const QmlDesigner::Internal::InternalNodeListProperty *internalListProperty,
                                const InternalNodePointer &node,
                                int oldIndex);
    void notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty);
    void notifyAuxiliaryDataChanged(const InternalNodePointer &node,
                                    AuxiliaryDataKeyView key,
                                    const QVariant &data);
    void notifyNodeSourceChanged(const InternalNodePointer &node, const QString &newNodeSource);

    void notifyRootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);

    void notifyCustomNotification(const AbstractView *senderView, const QString &identifier, const QList<ModelNode> &modelNodeList, const QList<QVariant> &data);
    void notifyInstancePropertyChange(const QList<QPair<ModelNode, PropertyName> > &propertyList);
    void notifyInstanceErrorChange(const QVector<qint32> &instanceIds);
    void notifyInstancesCompleted(const QVector<ModelNode> &modelNodeVector);
    void notifyInstancesInformationsChange(const QMultiHash<ModelNode, InformationName> &informationChangeHash);
    void notifyInstancesRenderImageChanged(const QVector<ModelNode> &modelNodeVector);
    void notifyInstancesPreviewImageChanged(const QVector<ModelNode> &modelNodeVector);
    void notifyInstancesChildrenChanged(const QVector<ModelNode> &modelNodeVector);
    void notifyInstanceToken(const QString &token, int number, const QVector<ModelNode> &modelNodeVector);

    void notifyCurrentStateChanged(const ModelNode &node);
    void notifyCurrentTimelineChanged(const ModelNode &node);

    void notifyRenderImage3DChanged(const QImage &image);
    void notifyUpdateActiveScene3D(const QVariantMap &sceneState);
    void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
    void notifyImport3DSupportChanged(const QVariantMap &supportMap);
    void notifyNodeAtPosResult(const ModelNode &modelNode, const QVector3D &pos3d);
    void notifyView3DAction(View3DActionType type, const QVariant &value);

    void notifyActive3DSceneIdChanged(qint32 sceneId);

    void notifyDragStarted(QMimeData *mimeData);
    void notifyDragEnded();

    void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);

    void notifyRewriterBeginTransaction();
    void notifyRewriterEndTransaction();

    void setSelectedNodes(const QList<InternalNodePointer> &selectedNodeList);
    void clearSelectedNodes();
    QList<InternalNodePointer> selectedNodes() const;
    void selectNode(const InternalNodePointer &node);
    void deselectNode(const InternalNodePointer &node);
    void changeSelectedNodes(const QList<InternalNodePointer> &newSelectedNodeList,
                             const QList<InternalNodePointer> &oldSelectedNodeList);

    void setAuxiliaryData(const InternalNodePointer &node,
                          const AuxiliaryDataKeyView &key,
                          const QVariant &data);
    void removeAuxiliaryData(const InternalNodePointer &node, const AuxiliaryDataKeyView &key);
    void resetModelByRewriter(const QString &description);

    // Imports:
    const Imports &imports() const { return m_imports; }
    void changeImports(Imports importsToBeAdded, Imports importToBeRemoved);
    void notifyImportsChanged(const Imports &addedImports, const Imports &removedImports);
    void notifyPossibleImportsChanged(const Imports &possibleImports);
    void notifyUsedImportsChanged(const Imports &usedImportsChanged);

    //node state property manipulation
    void addProperty(const InternalNodePointer &node, const PropertyName &name);
    void setPropertyValue(const InternalNodePointer &node,const PropertyName &name, const QVariant &value);
    void removePropertyAndRelatedResources(InternalProperty *property);
    void removeProperty(InternalProperty *property);
    void removeProperties(const QList<InternalProperty *> &properties);

    void setBindingProperty(const InternalNodePointer &node,
                            const PropertyName &name,
                            const QString &expression);
    void setBindingProperties(const ModelResourceSet::SetExpressions &setExpressions);
    void setSignalHandlerProperty(const InternalNodePointer &node, const PropertyName &name, const QString &source);
    void setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature);
    void setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value);
    void setDynamicVariantProperty(const InternalNodePointer &node, const PropertyName &name, const TypeName &propertyType, const QVariant &value);
    void setDynamicBindingProperty(const InternalNodePointer &node, const PropertyName &name, const TypeName &dynamicPropertyType, const QString &expression);
    void reparentNode(const InternalNodePointer &parentNode, const PropertyName &name, const InternalNodePointer &childNode,
                      bool list = true, const TypeName &dynamicTypeName = TypeName());
    void changeNodeOrder(const InternalNodePointer &parentNode, const PropertyName &listPropertyName, int from, int to);
    static bool propertyNameIsValid(PropertyNameView propertyName);
    void clearParent(const InternalNodePointer &node);
    void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
    void setScriptFunctions(const InternalNodePointer &node, const QStringList &scriptFunctionList);
    void setNodeSource(const InternalNodePointer &node, const QString &nodeSource);

    InternalNodePointer nodeForId(const QString &id) const;
    bool hasId(const QString &id) const;

    InternalNodePointer nodeForInternalId(qint32 internalId) const;
    bool hasNodeForInternalId(qint32 internalId) const;

    QList<InternalNodePointer> allNodesUnordered() const;
    QList<InternalNodePointer> allNodesOrdered() const;

    bool isWriteLocked() const;

    WriteLocker createWriteLocker() const;

    void setRewriterView(RewriterView *rewriterView);
    RewriterView *rewriterView() const;

    void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
    NodeInstanceView *nodeInstanceView() const;

    InternalNodePointer currentStateNode() const;
    InternalNodePointer currentTimelineNode() const;

    void handleResourceSet(const ModelResourceSet &resourceSet);

    QHash<TypeName, std::shared_ptr<NodeMetaInfoPrivate>> &nodeMetaInfoCache()
    {
        return m_nodeMetaInfoCache;
    }

protected:
    void removedTypeIds(const TypeIds &removedTypeIds) override;
    void removeNode(const InternalNodePointer &node);

private:
    void removePropertyWithoutNotification(InternalProperty *property);
    void removeAllSubNodes(const InternalNodePointer &node);
    void removeNodeFromModel(const InternalNodePointer &node);
    QList<InternalNodePointer> toInternalNodeList(const QList<ModelNode> &modelNodeList) const;
    QList<ModelNode> toModelNodeList(const QList<InternalNodePointer> &nodeList, AbstractView *view) const;
    QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &nodeVector, AbstractView *view) const;
    QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &modelNodeVector) const;
    static QList<InternalProperty *> toInternalProperties(const AbstractProperties &properties);
    static QList<std::tuple<QmlDesigner::Internal::InternalBindingProperty *, QString>>
    toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions);
    EnabledViewRange enabledViews() const;
    ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName);
    void setTypeId(InternalNode *node, Utils::SmallStringView typeName);

public:
    NotNullPointer<ProjectStorageType> projectStorage = nullptr;
    NotNullPointer<PathCacheType> pathCache = nullptr;
    ModelTracing::AsynchronousToken traceToken = ModelTracing::category().beginAsynchronous("Model"_t);

private:
    Model *m_model = nullptr;
#ifndef QDS_USE_PROJECTSTORAGE
    MetaInfo m_metaInfo;
#endif
    Imports m_imports;
    Imports m_possibleImportList;
    Imports m_usedImportList;
    QList<QPointer<AbstractView>> m_viewList;
    QList<InternalNodePointer> m_selectedInternalNodeList;
    QHash<QString,InternalNodePointer> m_idNodeHash;
    QHash<qint32, InternalNodePointer> m_internalIdNodeHash;
    QList<InternalNodePointer> m_nodes;
    InternalNodePointer m_currentStateNode;
    InternalNodePointer m_rootInternalNode;
    InternalNodePointer m_currentTimelineNode;
    std::unique_ptr<ModelResourceManagementInterface> m_resourceManagement;
    QUrl m_fileUrl;
    SourceId m_sourceId;
    QPointer<RewriterView> m_rewriterView;
    QPointer<NodeInstanceView> m_nodeInstanceView;
    QPointer<Model> m_metaInfoProxyModel;
    QHash<TypeName, std::shared_ptr<NodeMetaInfoPrivate>> m_nodeMetaInfoCache;

    bool m_writeLock = false;
    qint32 m_internalIdCounter = 1;
};

} // namespace Internal
} // namespace QmlDesigner