aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
blob: 86d2ab46e21f89eea9008e3c4d60f37aa9740543 (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
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0

#pragma once

#include "qmldesignercorelib_global.h"
#include "abstractview.h"
#include "modelcache.h"

#include <modelnode.h>
#include <nodeinstance.h>
#include <nodeinstanceclientinterface.h>
#include <nodeinstanceserverinterface.h>

#include <utils/filepath.h>

#include <QElapsedTimer>
#include <QHash>
#include <QImage>
#include <QPointer>
#include <QRectF>
#include <QTime>
#include <QTimer>
#include <QtGui/qevent.h>

#include <memory>

QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher)

namespace ProjectExplorer {
class Target;
}

namespace Utils {
class QtcProcess;
}

namespace QmlDesigner {

class NodeInstanceServerProxy;
class CreateSceneCommand;
class CreateInstancesCommand;
class ClearSceneCommand;
class ReparentInstancesCommand;
class ChangeFileUrlCommand;
class ChangeValuesCommand;
class ChangeBindingsCommand;
class ChangeIdsCommand;
class RemoveInstancesCommand;
class ChangeSelectionCommand;
class RemovePropertiesCommand;
class CompleteComponentCommand;
class InformationContainer;
class TokenCommand;
class ConnectionManagerInterface;

class QMLDESIGNERCORE_EXPORT NodeInstanceView : public AbstractView, public NodeInstanceClientInterface
{
    Q_OBJECT

    friend NodeInstance;

public:
    using Pointer = QWeakPointer<NodeInstanceView>;

    explicit NodeInstanceView(ConnectionManagerInterface &connectionManager);
    ~NodeInstanceView() override;

    void modelAttached(Model *model) override;
    void modelAboutToBeDetached(Model *model) override;
    void nodeCreated(const ModelNode &createdNode) override;
    void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
    void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList) override;
    void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange) override;
    void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange) override;
    void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
                        const NodeAbstractProperty &oldPropertyParent,
                        AbstractView::PropertyChangeFlags propertyChange) override;
    void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override;
    void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override;
    void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override;
    void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
    void nodeOrderChanged(const NodeListProperty &listProperty) override;
    void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
    void auxiliaryDataChanged(const ModelNode &node,
                              AuxiliaryDataKeyView key,
                              const QVariant &data) override;
    void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
    void nodeSourceChanged(const ModelNode &modelNode, const QString &newNodeSource) override;
    void capturedData(const CapturedDataCommand &capturedData) override;
    void currentStateChanged(const ModelNode &node) override;
    void sceneCreated(const SceneCreatedCommand &command) override;

    QList<NodeInstance> instances() const;
    NodeInstance instanceForModelNode(const ModelNode &node) const ;
    bool hasInstanceForModelNode(const ModelNode &node) const;

    NodeInstance instanceForId(qint32 id);
    bool hasInstanceForId(qint32 id);

    QRectF sceneRect() const;

    NodeInstance activeStateInstance() const;

    void updateChildren(const NodeAbstractProperty &newPropertyParent);
    void updatePosition(const QList<VariantProperty>& propertyList);

    void valuesChanged(const ValuesChangedCommand &command) override;
    void valuesModified(const ValuesModifiedCommand &command) override;
    void pixmapChanged(const PixmapChangedCommand &command) override;
    void informationChanged(const InformationChangedCommand &command) override;
    void childrenChanged(const ChildrenChangedCommand &command) override;
    void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command) override;
    void componentCompleted(const ComponentCompletedCommand &command) override;
    void token(const TokenCommand &command) override;
    void debugOutput(const DebugOutputCommand &command) override;

    QImage statePreviewImage(const ModelNode &stateNode) const;

    void setTarget(ProjectExplorer::Target *newTarget);

    void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);

    void selectionChanged(const ChangeSelectionCommand &command) override;

    void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
                              const QList<ModelNode> &lastSelectedNodeList) override;

    void sendInputEvent(QInputEvent *e) const;
    void view3DAction(const View3DActionCommand &command);
    void requestModelNodePreviewImage(const ModelNode &node, const ModelNode &renderNode);
    void edit3DViewResized(const QSize &size) const;

    void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override;

    QVariant previewImageDataForGenericNode(const ModelNode &modelNode, const ModelNode &renderNode);
    QVariant previewImageDataForImageNode(const ModelNode &modelNode);

    void setCrashCallback(std::function<void()> crashCallback)
    {
        m_crashCallback = std::move(crashCallback);
    }

    void setCaptureImageMinimumAndMaximumSize(QSize captureImageMinimumSize,
                                              QSize captureImageMaximumSize)
    {
        m_captureImageMinimumSize = captureImageMinimumSize;
        m_captureImageMaximumSize = captureImageMaximumSize;
    }

    void startNanotrace();
    void endNanotrace();

protected:
    void timerEvent(QTimerEvent *event) override;

private: // functions
    std::unique_ptr<NodeInstanceServerProxy> createNodeInstanceServerProxy();
    void activateState(const NodeInstance &instance);
    void activateBaseState();

    NodeInstance rootNodeInstance() const;

    NodeInstance loadNode(const ModelNode &node);

    void clearErrors();

    void removeAllInstanceNodeRelationships();

    void removeRecursiveChildRelationship(const ModelNode &removedNode);

    void insertInstanceRelationships(const NodeInstance &instance);
    void removeInstanceNodeRelationship(const ModelNode &node);

    void removeInstanceAndSubInstances(const ModelNode &node);

    void setStateInstance(const NodeInstance &stateInstance);
    void clearStateInstance();

    QMultiHash<ModelNode, InformationName> informationChanged(
        const QVector<InformationContainer> &containerVector);

    CreateSceneCommand createCreateSceneCommand();
    ClearSceneCommand createClearSceneCommand() const;
    CreateInstancesCommand createCreateInstancesCommand(const QList<NodeInstance> &instanceList) const;
    CompleteComponentCommand createComponentCompleteCommand(const QList<NodeInstance> &instanceList) const;
    ComponentCompletedCommand createComponentCompletedCommand(const QList<NodeInstance> &instanceList) const;
    ReparentInstancesCommand createReparentInstancesCommand(const QList<NodeInstance> &instanceList) const;
    ReparentInstancesCommand createReparentInstancesCommand(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent) const;
    ChangeFileUrlCommand createChangeFileUrlCommand(const QUrl &fileUrl) const;
    ChangeValuesCommand createChangeValueCommand(const QList<VariantProperty> &propertyList) const;
    ChangeBindingsCommand createChangeBindingCommand(const QList<BindingProperty> &propertyList) const;
    ChangeIdsCommand createChangeIdsCommand(const QList<NodeInstance> &instanceList) const;
    RemoveInstancesCommand createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const;
    ChangeSelectionCommand createChangeSelectionCommand(const QList<ModelNode> &nodeList) const;
    RemoveInstancesCommand createRemoveInstancesCommand(const ModelNode &node) const;
    RemovePropertiesCommand createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const;
    RemoveSharedMemoryCommand createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, quint32 keyNumber);
    RemoveSharedMemoryCommand createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, const QList<ModelNode> &nodeList);

    void resetHorizontalAnchors(const ModelNode &node);
    void resetVerticalAnchors(const ModelNode &node);

    void restartProcess();
    void delayedRestartProcess();

    void handleCrash();
    void startPuppetTransaction();
    void endPuppetTransaction();

    // puppet to creator command handlers
    void handlePuppetKeyPress(int key, Qt::KeyboardModifiers modifiers);

    struct ModelNodePreviewImageData {
        QDateTime time;
        QPixmap pixmap;
        QString type;
        QString id;
        QString info;
    };
    QVariant modelNodePreviewImageDataToVariant(const ModelNodePreviewImageData &imageData);
    void updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image);

    void updateWatcher(const QString &path);
    void handleShaderChanges();
    void handleQsbProcessExit(Utils::QtcProcess *qsbProcess, const QString &shader);
    void updateQsbPathToFilterMap();
    void updateRotationBlocks();
    void maybeResetOnPropertyChange(const PropertyName &name, const ModelNode &node,
                                    PropertyChangeFlags flags);

private:
    struct NodeInstanceCacheData
    {
        NodeInstanceCacheData(const QHash<ModelNode, NodeInstance> &i,
                              const QHash<ModelNode, QImage> &p)
            : instances(i)
            , previewImages(p)
        {}

        NodeInstanceCacheData() = default;

        QHash<ModelNode, NodeInstance> instances;
        QHash<ModelNode, QImage> previewImages;
    };

    QList<NodeInstance> loadInstancesFromCache(const QList<ModelNode> &nodeList,
                                               const NodeInstanceCacheData &cache);

    QHash<QString, ModelNodePreviewImageData> m_imageDataMap;

    NodeInstance m_rootNodeInstance;
    NodeInstance m_activeStateInstance;
    QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
    ModelCache<NodeInstanceCacheData> m_nodeInstanceCache;
    QHash<ModelNode, QImage> m_statePreviewImage;
    ConnectionManagerInterface &m_connectionManager;
    std::unique_ptr<NodeInstanceServerProxy> m_nodeInstanceServer;
    QImage m_baseStatePreviewImage;
    QElapsedTimer m_lastCrashTime;
    QPointer<ProjectExplorer::Target> m_currentTarget;
    int m_restartProcessTimerId;
    RewriterTransaction m_puppetTransaction;

    // key: fileUrl value: (key: instance qml id, value: related tool states)
    QHash<QUrl, QHash<QString, QVariantMap>> m_edit3DToolStates;

    std::function<void()> m_crashCallback{[this] { handleCrash(); }};

    // We use QFileSystemWatcher directly instead of Utils::FileSystemWatcher as we want
    // shader changes to be applied immediately rather than requiring reactivation of
    // the creator application.
    QFileSystemWatcher *m_fileSystemWatcher;
    QTimer m_resetTimer;
    QTimer m_updateWatcherTimer;
    QTimer m_generateQsbFilesTimer;
    Utils::FilePath m_qsbPath;
    QSet<QString> m_pendingUpdateDirs;
    QHash<QString, bool> m_qsbTargets; // Value indicates if target is pending qsb generation
    QHash<QString, QStringList> m_qsbPathToFilterMap;
    int m_remainingQsbTargets = 0;
    QTimer m_rotBlockTimer;
    QSize m_captureImageMinimumSize{150, 150};
    QSize m_captureImageMaximumSize{1000, 1000};
};

} // namespace ProxyNodeInstanceView