diff --git a/src/plugins/qmldesigner/core/model/bindingproperty.cpp b/src/plugins/qmldesigner/core/model/bindingproperty.cpp index b258bb2cdd93d25f3530cb5391ae9331788b04ac..7a73eba08c553bf6d9f23c43c4dd49749f0d7a9e 100644 --- a/src/plugins/qmldesigner/core/model/bindingproperty.cpp +++ b/src/plugins/qmldesigner/core/model/bindingproperty.cpp @@ -58,6 +58,7 @@ BindingProperty::BindingProperty(const QString &propertyName, const Internal::In void BindingProperty::setExpression(const QString &expression) { + //Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); @@ -161,6 +162,7 @@ AbstractProperty BindingProperty::resolveToProperty() const void BindingProperty::setDynamicTypeNameAndExpression(const QString &typeName, const QString &expression) { + //Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); diff --git a/src/plugins/qmldesigner/core/model/model.cpp b/src/plugins/qmldesigner/core/model/model.cpp index 0e8ddb21eaa35de20d141d90908247f70c7dddc4..8c8234403dcd3baa38377a17867750c32d852816 100644 --- a/src/plugins/qmldesigner/core/model/model.cpp +++ b/src/plugins/qmldesigner/core/model/model.cpp @@ -87,7 +87,8 @@ namespace Internal { ModelPrivate::ModelPrivate(Model *model) : m_q(model), - m_rootInternalNode(createNode("Qt/Rectangle", 4, 6, PropertyListType())) + m_rootInternalNode(createNode("Qt/Rectangle", 4, 6, PropertyListType())), + m_writeLock(false) { } @@ -884,6 +885,34 @@ QList<InternalNodePointer> ModelPrivate::allNodes() const return m_nodeSet.toList(); } +bool ModelPrivate::isWriteLocked() const +{ + return m_writeLock; +} + + +WriteLocker::WriteLocker(ModelPrivate *model) + : m_model(model) +{ + Q_ASSERT(model); + Q_ASSERT(!m_model->m_writeLock); + model->m_writeLock = true; +} + +WriteLocker::WriteLocker(Model *model) + : m_model(model->m_d) +{ + Q_ASSERT(model->m_d); + Q_ASSERT(!m_model->m_writeLock); + m_model->m_writeLock = true; +} + +WriteLocker::~WriteLocker() +{ + Q_ASSERT(m_model->m_writeLock); + m_model->m_writeLock = false; +} + //static QString anchorLinePropertyValue(const InternalNode::Pointer &sourceNode, const InternalNode::Pointer &targetNode, const AnchorLine::Type &targetType) //{ // if (targetNode.isNull() || !targetNode->isValid()) @@ -1029,6 +1058,7 @@ QUrl Model::fileUrl() const */ void Model::setFileUrl(const QUrl &url) { + Internal::WriteLocker locker(m_d); m_d->setFileUrl(url); } @@ -1045,6 +1075,7 @@ const MetaInfo Model::metaInfo() const */ void Model::setMetaInfo(const MetaInfo &metaInfo) { + Internal::WriteLocker locker(m_d); m_d->setMetaInfo(metaInfo); } @@ -1077,6 +1108,7 @@ The view is informed that it has been registered within the model by a call to A */ void Model::attachView(AbstractView *view) { + Internal::WriteLocker locker(m_d); m_d->attachView(view); } @@ -1090,6 +1122,7 @@ void Model::attachView(AbstractView *view) */ void Model::detachView(AbstractView *view, ViewNotification emitDetachNotify) { + Internal::WriteLocker locker(m_d); bool emitNotify = (emitDetachNotify == NotifyView); m_d->detachView(view, emitNotify); } diff --git a/src/plugins/qmldesigner/core/model/model_p.h b/src/plugins/qmldesigner/core/model/model_p.h index 76b56615e31e5698a91182dc7559459aaca06803..4f3dd49addab4b800807df99957bdd5275508f39 100644 --- a/src/plugins/qmldesigner/core/model/model_p.h +++ b/src/plugins/qmldesigner/core/model/model_p.h @@ -67,12 +67,26 @@ typedef QSharedPointer<InternalNodeAbstractProperty> InternalNodeAbstractPropert typedef QSharedPointer<InternalNodeListProperty> InternalNodeListPropertyPointer; typedef QPair<InternalNodePointer, QString> PropertyPair; -class ModelPrivate : QObject { + +class ModelPrivate; + +class WriteLocker +{ +public: + ~WriteLocker(); + WriteLocker(ModelPrivate *model); + WriteLocker(Model *model); +private: // variables + QWeakPointer<ModelPrivate> m_model; +}; + +class ModelPrivate : public QObject { Q_OBJECT Q_DISABLE_COPY(ModelPrivate) friend class QmlDesigner::Model; + friend class QmlDesigner::Internal::WriteLocker; public: ModelPrivate(Model *model); @@ -168,6 +182,10 @@ public: QList<InternalNodePointer> allNodes() const; + bool isWriteLocked() const; + + WriteLocker createWriteLocker() const; + private: //functions void removePropertyWithoutNotification(const InternalPropertyPointer &property); void removeAllSubNodes(const InternalNodePointer &node); @@ -190,6 +208,8 @@ private: QUrl m_fileUrl; QWeakPointer<Model> m_masterModel; + + bool m_writeLock; }; } diff --git a/src/plugins/qmldesigner/core/model/modelnode.cpp b/src/plugins/qmldesigner/core/model/modelnode.cpp index 6fb91ea9b9bf239008f2cb203b99eeabad90b7a9..30b290a4adb497185b83fb4dfb3d15867478c43c 100644 --- a/src/plugins/qmldesigner/core/model/modelnode.cpp +++ b/src/plugins/qmldesigner/core/model/modelnode.cpp @@ -174,6 +174,7 @@ bool ModelNode::isValidId(const QString &id) void ModelNode::setId(const QString& id) { + //Internal::WriteLocker locker(m_model.data()); if (!isValid()) { Q_ASSERT_X(isValid(), Q_FUNC_INFO, "model node is invalid"); throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); @@ -207,6 +208,7 @@ QString ModelNode::type() const */ void ModelNode::changeType(const QString &type, int majorVersion, int minorVersion) { + //Internal::WriteLocker locker(m_model.data()); if (!isValid()) { Q_ASSERT_X(isValid(), Q_FUNC_INFO, "model node is invalid"); throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); @@ -581,6 +583,7 @@ void ModelNode::removeProperty(const QString &name) */ ModelNode ModelNode::addChildNode(const QString &nodeTypeString, int majorVersion, int minorVersion, const QString &propertyName, const PropertyListType &propertyList) { + Internal::WriteLocker locker(m_model.data()); if (!isValid()) { Q_ASSERT_X(isValid(), Q_FUNC_INFO, "model node is invalid"); throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); @@ -928,6 +931,7 @@ QVariant ModelNode::auxiliaryData(const QString &name) const void ModelNode::setAuxiliaryData(const QString &name, const QVariant &data) { + Internal::WriteLocker locker(m_model.data()); m_model.data()->m_d->setAuxiliaryData(internalNode(), name, data); } diff --git a/src/plugins/qmldesigner/core/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/core/model/nodeabstractproperty.cpp index 69c9fd642924f0666a20acf32c61ea53fc73bd1f..4f2408bf6c8d379f489d93c1485996b3ee9a8129 100644 --- a/src/plugins/qmldesigner/core/model/nodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/core/model/nodeabstractproperty.cpp @@ -68,6 +68,7 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode) void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList) { + //Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); diff --git a/src/plugins/qmldesigner/core/model/nodelistproperty.cpp b/src/plugins/qmldesigner/core/model/nodelistproperty.cpp index 53bc1dc2f3d3fc684248dbb492aa44fc21df21a1..a8dca7ee164488a7979c9eb668e6b92174da26af 100644 --- a/src/plugins/qmldesigner/core/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/core/model/nodelistproperty.cpp @@ -101,6 +101,7 @@ const QList<QmlObjectNode> NodeListProperty::toQmlObjectNodeList() const void NodeListProperty::slide(int from, int to) const { + //Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, "<invalid node list property>"); if (to > toModelNodeList().count() - 1) diff --git a/src/plugins/qmldesigner/core/model/variantproperty.cpp b/src/plugins/qmldesigner/core/model/variantproperty.cpp index 051b6fddf732dba98fdc74ba819112a059fff63f..e91a1f40253fb06e525109cc96031ff16a1042fa 100644 --- a/src/plugins/qmldesigner/core/model/variantproperty.cpp +++ b/src/plugins/qmldesigner/core/model/variantproperty.cpp @@ -57,6 +57,7 @@ VariantProperty::VariantProperty(const QString &propertyName, const Internal::In void VariantProperty::setValue(const QVariant &value) { + //Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); @@ -96,6 +97,7 @@ VariantProperty& VariantProperty::operator= (const QVariant &value) void VariantProperty::setDynamicTypeNameAndValue(const QString &type, const QVariant &value) { + //Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);