Commit 66ed5367 authored by Marco Bubke's avatar Marco Bubke

QmlDesigner.NodeInstances: Add ChildrenChangedCommand

Because the order of the commands can be changed the reparenting was
changed. Now there is a command with the exact order of child items so
it should be much more correct.
parent da077c36
......@@ -339,9 +339,8 @@ void FormEditorScene::reparentItem(const QmlItemNode &node, const QmlItemNode &n
if (newParent.isValid() && hasItemForQmlItemNode(newParent))
parentItem = itemForQmlItemNode(newParent);
if (item->parentItem() != parentItem) {
item->setParentItem(parentItem);
}
item->setParentItem(0);
item->setParentItem(parentItem);
}
FormEditorItem* FormEditorScene::rootFormEditorItem() const
......
......@@ -456,9 +456,8 @@ void FormEditorView::customNotification(const AbstractView *view, const QString
foreach (const ModelNode &node, nodeList) {
QmlItemNode qmlItemNode(node);
if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) {
scene()->synchronizeParent(qmlItemNode);
scene()->synchronizeTransformation(qmlItemNode);
itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode));
itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode));
}
}
......@@ -477,6 +476,20 @@ void FormEditorView::customNotification(const AbstractView *view, const QString
}
}
if (identifier == "__instance children changed__") {
QList<FormEditorItem*> itemNodeList;
foreach (const ModelNode &node, nodeList) {
QmlItemNode qmlItemNode(node);
if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) {
scene()->synchronizeParent(qmlItemNode);
itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode));
}
}
m_currentTool->formEditorItemsChanged(itemNodeList);
}
QmlModelView::customNotification(view, identifier, nodeList, data);
}
......
......@@ -118,7 +118,8 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/instances/changestatecommand.cpp \
$$PWD/instances/nodeinstanceserverproxy.cpp \
$$PWD/instances/nodeinstanceclientproxy.cpp \
$$PWD/instances/addimportcommand.cpp
$$PWD/instances/addimportcommand.cpp \
$$PWD/instances/childrenchangedcommand.cpp
HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/abstractview.h \
$$PWD/include/nodeinstanceview.h \
......@@ -235,7 +236,8 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/instances/changestatecommand.h \
$$PWD/instances/nodeinstanceserverproxy.h \
$$PWD/instances/nodeinstanceclientproxy.h \
$$PWD/instances/addimportcommand.h
$$PWD/instances/addimportcommand.h \
$$PWD/instances/childrenchangedcommand.h
contains(CONFIG, plugin) {
# If core.pri has been included in the qmldesigner plugin
......
......@@ -23,8 +23,7 @@ enum InformationName
IsAnchoredByChildren,
IsAnchoredBySibling,
HasContent,
HasBindingForProperty,
Parent
HasBindingForProperty
};
}
......
......@@ -56,6 +56,8 @@ protected:
const QVariant &information,
const QVariant &secondInformation,
const QVariant &thirdInformation);
void setParentId(qint32 instanceId);
void setRenderImage(const QImage &image);
NodeInstance(ProxyNodeInstanceData *d);
qint32 instanceId() const;
......
......@@ -8,6 +8,7 @@ namespace QmlDesigner {
class ValuesChangedCommand;
class PixmapChangedCommand;
class InformationChangedCommand;
class ChildrenChangedCommand;
class NodeInstanceClientInterface
{
......@@ -15,6 +16,8 @@ public:
virtual void informationChanged(const InformationChangedCommand &command) = 0;
virtual void valuesChanged(const ValuesChangedCommand &command) = 0;
virtual void pixmapChanged(const PixmapChangedCommand &command) = 0;
virtual void childrenChanged(const ChildrenChangedCommand &command) = 0;
virtual void flush() {};
virtual qint64 bytesToWrite() const {return 0;}
......
......@@ -115,6 +115,7 @@ public:
void valuesChanged(const ValuesChangedCommand &command);
void pixmapChanged(const PixmapChangedCommand &command);
void informationChanged(const InformationChangedCommand &command);
void childrenChanged(const ChildrenChangedCommand &command);
private: // functions
NodeInstance rootNodeInstance() const;
......@@ -166,11 +167,6 @@ private: //variables
QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
QHash<qint32, NodeInstance> m_idInstanceHash; // This is purely internal. Might contain dangling pointers!
QList<QPair<ModelNode, QString> > m_valuePropertyChangeList;
QSet<ModelNode> m_renderImageChangeSet;
QSet<ModelNode> m_informationChangeSet;
uint m_blockUpdates;
QWeakPointer<NodeInstanceServerInterface> m_nodeInstanceServer;
qint32 m_instanceIdCounter;
......
#include "childrenchangedcommand.h"
namespace QmlDesigner {
ChildrenChangedCommand::ChildrenChangedCommand()
: m_parentInstanceId(-1)
{
}
ChildrenChangedCommand::ChildrenChangedCommand(qint32 parentInstanceId, const QVector<qint32> &children)
: m_parentInstanceId(parentInstanceId),
m_childrenVector(children)
{
}
QVector<qint32> ChildrenChangedCommand::childrenInstances() const
{
return m_childrenVector;
}
qint32 ChildrenChangedCommand::parentInstanceId() const
{
return m_parentInstanceId;
}
QDataStream &operator<<(QDataStream &out, const ChildrenChangedCommand &command)
{
out << command.parentInstanceId();
out << command.childrenInstances();
return out;
}
QDataStream &operator>>(QDataStream &in, ChildrenChangedCommand &command)
{
in >> command.m_parentInstanceId;
in >> command.m_childrenVector;
return in;
}
} // namespace QmlDesigner
#ifndef CHILDRENCHANGEDCOMMAND_H
#define CHILDRENCHANGEDCOMMAND_H
#include <QMetaType>
#include <QVector>
namespace QmlDesigner {
class ChildrenChangedCommand
{
friend QDataStream &operator>>(QDataStream &in, ChildrenChangedCommand &command);
public:
ChildrenChangedCommand();
ChildrenChangedCommand(qint32 parentInstanceId, const QVector<qint32> &childrenInstances);
QVector<qint32> childrenInstances() const;
qint32 parentInstanceId() const;
private:
qint32 m_parentInstanceId;
QVector<qint32> m_childrenVector;
};
QDataStream &operator<<(QDataStream &out, const ChildrenChangedCommand &command);
QDataStream &operator>>(QDataStream &in, ChildrenChangedCommand &command);
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::ChildrenChangedCommand);
#endif // CHILDRENCHANGEDCOMMAND_H
......@@ -60,6 +60,20 @@ bool GraphicsObjectNodeInstance::hasContent() const
return m_hasContent;
}
QList<ServerNodeInstance> GraphicsObjectNodeInstance::childItems() const
{
QList<ServerNodeInstance> instanceList;
foreach(QGraphicsItem *item, graphicsObject()->childItems())
{
QGraphicsObject *childObject = item->toGraphicsObject();
if (childObject && nodeInstanceServer()->hasInstanceForObject(childObject)) {
instanceList.append(nodeInstanceServer()->instanceForObject(childObject));
}
}
return instanceList;
}
void GraphicsObjectNodeInstance::setHasContent(bool hasContent)
{
m_hasContent = hasContent;
......
......@@ -71,6 +71,7 @@ public:
bool hasContent() const;
QList<ServerNodeInstance> childItems() const;
void paintUpdate();
......
......@@ -3,6 +3,7 @@ INCLUDEPATH += $$PWD/../include
HEADERS += $$PWD/behaviornodeinstance.h
HEADERS += $$PWD/childrenchangedcommand.h
HEADERS += $$PWD/addimportcommand.h
HEADERS += $$PWD/changebindingscommand.h
HEADERS += $$PWD/changefileurlcommand.h
......@@ -42,6 +43,7 @@ HEADERS += $$PWD/../include/nodeinstanceserverinterface.h
SOURCES += $$PWD/behaviornodeinstance.cpp
SOURCES += $$PWD/childrenchangedcommand.cpp
SOURCES += $$PWD/addimportcommand.cpp
SOURCES += $$PWD/changebindingscommand.cpp
SOURCES += $$PWD/changefileurlcommand.cpp
......
......@@ -283,6 +283,11 @@ void NodeInstance::setRenderImage(const QImage &image)
d->renderImage = image;
}
void NodeInstance::setParentId(qint32 instanceId)
{
d->parentInstanceId = instanceId;
}
void NodeInstance::setInformation(InformationName name, const QVariant &information, const QVariant &secondInformation, const QVariant &thirdInformation)
{
switch (name) {
......@@ -302,7 +307,6 @@ void NodeInstance::setInformation(InformationName name, const QVariant &informat
case Anchor: d->anchors.insert(information.toString(), qMakePair(secondInformation.toString(), thirdInformation.value<qint32>())); break;
case InstanceTypeForProperty: d->instanceTypes.insert(information.toString(), secondInformation.toString()); break;
case HasBindingForProperty: d->hasBindingForProperty.insert(information.toString(), secondInformation.toBool()); break;
case Parent: d->parentInstanceId = information.toInt();
case NoName:
default: break;
}
......
......@@ -27,6 +27,7 @@
#include "informationchangedcommand.h"
#include "pixmapchangedcommand.h"
#include "valueschangedcommand.h"
#include "childrenchangedcommand.h"
namespace QmlDesigner {
......@@ -70,6 +71,11 @@ void NodeInstanceClientProxy::pixmapChanged(const PixmapChangedCommand &command)
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::childrenChanged(const ChildrenChangedCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::flush()
{
}
......
......@@ -23,6 +23,7 @@ public:
void informationChanged(const InformationChangedCommand &command);
void valuesChanged(const ValuesChangedCommand &command);
void pixmapChanged(const PixmapChangedCommand &command);
void childrenChanged(const ChildrenChangedCommand &command);
void flush();
qint64 bytesToWrite() const;
......
......@@ -35,6 +35,7 @@
#include "childrenchangeeventfilter.h"
#include "changestatecommand.h"
#include "addimportcommand.h"
#include "childrenchangedcommand.h"
#include <iostream>
#include <stdio.h>
......@@ -244,7 +245,9 @@ void NodeInstanceServer::addImport(const AddImportCommand &command)
engine()->addPluginPath(importPath);
}
importComponent.setData(componentString.toLatin1(), QUrl());
qDebug() << __FUNCTION__ << fileUrl().resolved(QUrl("content/samegame.js")) << componentString;
importComponent.setData(componentString.toUtf8(), QUrl());
if (!importComponent.errorString().isEmpty())
qDebug() << "QmlDesigner.NodeInstances: import wrong: " << importComponent.errorString();
......@@ -509,6 +512,36 @@ NodeInstanceClientInterface *NodeInstanceServer::nodeInstanceClient() const
return m_nodeInstanceClient;
}
void NodeInstanceServer::sendChildrenChangedCommand(const QList<ServerNodeInstance> childList)
{
QSet<ServerNodeInstance> parentSet;
QList<ServerNodeInstance> noParentList;
foreach (const ServerNodeInstance &child, childList) {
if (!child.hasParent())
noParentList.append(child);
parentSet.insert(child.parent());
}
foreach (const ServerNodeInstance &parent, parentSet)
nodeInstanceClient()->childrenChanged(createChildrenChangedCommand(parent, parent.childItems()));
if (!noParentList.isEmpty())
nodeInstanceClient()->childrenChanged(createChildrenChangedCommand(ServerNodeInstance(), noParentList));
}
ChildrenChangedCommand NodeInstanceServer::createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const
{
QVector<qint32> instanceVector;
foreach(const ServerNodeInstance &instance, instanceList)
instanceVector.append(instance.instanceId());
return ChildrenChangedCommand(parentInstance.instanceId(), instanceVector);
}
InformationChangedCommand NodeInstanceServer::createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial) const
{
QVector<InformationContainer> informationVector;
......@@ -525,7 +558,6 @@ InformationChangedCommand NodeInstanceServer::createAllInformationChangedCommand
informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable()));
informationVector.append(InformationContainer(instance.instanceId(), IsInPositioner, instance.isInPositioner()));
informationVector.append(InformationContainer(instance.instanceId(), PenWidth, instance.penWidth()));
informationVector.append(InformationContainer(instance.instanceId(), Parent, instance.parent().instanceId()));
informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredByChildren, instance.isAnchoredByChildren()));
informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredBySibling, instance.isAnchoredBySibling()));
......@@ -666,7 +698,7 @@ bool NodeInstanceServer::nonInstanceChildIsDirty(QGraphicsObject *graphicsObject
continue;
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child);
if (childPrivate->dirty || childPrivate->dirtyChildren || nonInstanceChildIsDirty(childGraphicsObject))
if (childPrivate->dirty || nonInstanceChildIsDirty(childGraphicsObject))
return true;
}
}
......@@ -693,6 +725,7 @@ void NodeInstanceServer::findItemChangesAndSendChangeCommands()
QSet<ServerNodeInstance> dirtyInstanceSet;
QSet<ServerNodeInstance> informationChangedInstanceSet;
QVector<InstancePropertyPair> propertyChangedList;
QSet<ServerNodeInstance> parentChangedSet;
bool adjustSceneRect = false;
if (m_declarativeView) {
......@@ -731,6 +764,7 @@ void NodeInstanceServer::findItemChangesAndSendChangeCommands()
if (propertyName == "parent") {
informationChangedInstanceSet.insert(instance);
parentChangedSet.insert(instance);
} else {
propertyChangedList.append(property);
}
......@@ -739,9 +773,13 @@ void NodeInstanceServer::findItemChangesAndSendChangeCommands()
m_changedPropertyList.clear();
resetAllItems();
if (!parentChangedSet.isEmpty())
sendChildrenChangedCommand(parentChangedSet.toList());
if (!informationChangedInstanceSet.isEmpty())
nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(informationChangedInstanceSet.toList()));
if (!propertyChangedList.isEmpty())
nodeInstanceClient()->valuesChanged(createValuesChangedCommand(propertyChangedList));
......
......@@ -21,6 +21,7 @@ class NodeInstanceClientInterface;
class ValuesChangedCommand;
class PixmapChangedCommand;
class InformationChangedCommand;
class ChildrenChangedCommand;
namespace Internal {
class ChildrenChangeEventFilter;
......@@ -102,6 +103,9 @@ protected:
ValuesChangedCommand createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const;
PixmapChangedCommand createPixmapChangedCommand(const ServerNodeInstance &instance) const;
InformationChangedCommand createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial = false) const;
ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const;
void sendChildrenChangedCommand(const QList<ServerNodeInstance> childList);
void addChangedProperty(const InstancePropertyPair &property);
......
......@@ -21,6 +21,7 @@
#include "pixmapchangedcommand.h"
#include "valueschangedcommand.h"
#include "addimportcommand.h"
#include "childrenchangedcommand.h"
namespace QmlDesigner {
......@@ -104,6 +105,9 @@ void NodeInstanceServerInterface::registerCommands()
qRegisterMetaType<AddImportCommand>("AddImportCommand");
qRegisterMetaTypeStreamOperators<AddImportCommand>("AddImportCommand");
qRegisterMetaType<ChildrenChangedCommand>("ChildrenChangedCommand");
qRegisterMetaTypeStreamOperators<ChildrenChangedCommand>("ChildrenChangedCommand");
}
}
......@@ -26,6 +26,7 @@
#include "informationchangedcommand.h"
#include "pixmapchangedcommand.h"
#include "valueschangedcommand.h"
#include "childrenchangedcommand.h"
#include "nodeinstanceview.h"
#include "nodeinstanceclientproxy.h"
......@@ -73,6 +74,7 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command)
static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand");
static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand");
static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand");
static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
if (command.userType() == informationChangedCommandType)
nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>());
......@@ -80,6 +82,8 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command)
nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>());
else if (command.userType() == pixmapChangedCommandType)
nodeInstanceClient()->pixmapChanged(command.value<PixmapChangedCommand>());
else if (command.userType() == childrenChangedCommandType)
nodeInstanceClient()->childrenChanged(command.value<ChildrenChangedCommand>());
else
Q_ASSERT(false);
}
......
......@@ -71,6 +71,7 @@
#include "informationchangedcommand.h"
#include "changestatecommand.h"
#include "addimportcommand.h"
#include "childrenchangedcommand.h"
#include "nodeinstanceserverproxy.h"
......@@ -105,8 +106,7 @@ d too.
\see ~NodeInstanceView setRenderOffScreen
*/
NodeInstanceView::NodeInstanceView(QObject *parent)
: AbstractView(parent),
m_blockUpdates(false)
: AbstractView(parent)
{
}
......@@ -162,9 +162,6 @@ void NodeInstanceView::restartProcess()
Model *oldModel = model();
if (oldModel) {
oldModel->detachView(this);
m_valuePropertyChangeList.clear();
m_renderImageChangeSet.clear();
m_informationChangeSet.clear();
oldModel->attachView(this);
}
setBlockUpdates(false);
......@@ -610,24 +607,6 @@ void NodeInstanceView::setBlockUpdates(bool block)
} else if (m_blockUpdates > 0) {
m_blockUpdates--;
}
if (m_blockUpdates == 0) {
m_nodeInstanceServer->setBlockUpdates(false);
if (!m_informationChangeSet.isEmpty()) {
emitCustomNotification("__instance information changed__", m_informationChangeSet.toList());
m_informationChangeSet.clear();
}
if (!m_valuePropertyChangeList.isEmpty()) {
emitInstancePropertyChange(m_valuePropertyChangeList);
m_valuePropertyChangeList.clear();
}
if (!m_renderImageChangeSet.isEmpty()) {
emitCustomNotification("__instance render pixmap changed__", m_renderImageChangeSet.toList());
m_renderImageChangeSet.clear();
}
}
}
void NodeInstanceView::setStateInstance(const NodeInstance &stateInstance)
......@@ -865,57 +844,71 @@ AddImportCommand NodeInstanceView::createImportCommand(const Import &import)
void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
{
QList<QPair<ModelNode, QString> > valuePropertyChangeList;
foreach(const PropertyValueContainer &container, command.valueChanges()) {
if (hasInstanceForId(container.instanceId())) {
NodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) {
instance.setProperty(container.name(), container.value());
m_valuePropertyChangeList.append(qMakePair(instance.modelNode(), container.name()));
valuePropertyChangeList.append(qMakePair(instance.modelNode(), container.name()));
}
}
}
if (!m_blockUpdates && !m_valuePropertyChangeList.isEmpty()) {
emitInstancePropertyChange(m_valuePropertyChangeList);
m_valuePropertyChangeList.clear();
}
if (!valuePropertyChangeList.isEmpty())
emitInstancePropertyChange(valuePropertyChangeList);
}
void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
{
QSet<ModelNode> renderImageChangeSet;
if (hasInstanceForId(command.instanceId())) {
NodeInstance instance = instanceForId(command.instanceId());
if (instance.isValid()) {
instance.setRenderImage(command.renderImage());
m_renderImageChangeSet.insert(instance.modelNode());
renderImageChangeSet.insert(instance.modelNode());
}
}
if (!m_blockUpdates && !m_renderImageChangeSet.isEmpty()) {
emitCustomNotification("__instance render pixmap changed__", m_renderImageChangeSet.toList());
m_renderImageChangeSet.clear();
}
if (!renderImageChangeSet.isEmpty())
emitCustomNotification("__instance render pixmap changed__", renderImageChangeSet.toList());
}
void NodeInstanceView::informationChanged(const InformationChangedCommand &command)
{
QList<ModelNode> informationChangedList;
foreach(const InformationContainer &container, command.informations()) {
if (hasInstanceForId(container.instanceId())) {
NodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) {
instance.setInformation(container.name(), container.information(), container.secondInformation(), container.thirdInformation());
m_informationChangeSet.insert(instance.modelNode());
informationChangedList.append(instance.modelNode());
}
}
}
if (!m_blockUpdates && !m_informationChangeSet.isEmpty()) {
emitCustomNotification("__instance information changed__", m_informationChangeSet.toList());
m_informationChangeSet.clear();
}
if (!informationChangedList.isEmpty())
emitCustomNotification("__instance information changed__", informationChangedList);
}
void NodeInstanceView::childrenChanged(const ChildrenChangedCommand &command)
{
QList<ModelNode> childNodeList;
foreach(qint32 instanceId, command.childrenInstances()) {
if (hasInstanceForId(instanceId)) {
NodeInstance instance = instanceForId(instanceId);
instance.setParentId(command.parentInstanceId());
childNodeList.append(instance.modelNode());
}
}
if (!childNodeList.isEmpty())
emitCustomNotification("__instance children changed__", childNodeList);
}
qint32 NodeInstanceView::generateInstanceId()
{
......
......@@ -604,6 +604,10 @@ QString ObjectNodeInstance::instanceType(const QString &name) const
return property.propertyTypeName();
}
QList<ServerNodeInstance> ObjectNodeInstance::childItems() const
{
return QList<ServerNodeInstance>();
}
void ObjectNodeInstance::setDeleteHeldInstance(bool deleteInstance)
{
......