diff --git a/src/plugins/qmldesigner/core/include/nodeinstance.h b/src/plugins/qmldesigner/core/include/nodeinstance.h index ce8d818d7f0..644f503f573 100644 --- a/src/plugins/qmldesigner/core/include/nodeinstance.h +++ b/src/plugins/qmldesigner/core/include/nodeinstance.h @@ -148,6 +148,7 @@ private: // functions void setPropertyDynamicBinding(const QString &name, const QString &typeName, const QString &expression); void resetProperty(const QString &name); + void refreshProperty(const QString &name); void activateState(); void deactivateState(); diff --git a/src/plugins/qmldesigner/core/include/nodeinstanceview.h b/src/plugins/qmldesigner/core/include/nodeinstanceview.h index f22df82ad86..402643d3aa9 100644 --- a/src/plugins/qmldesigner/core/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/core/include/nodeinstanceview.h @@ -41,6 +41,8 @@ class QDeclarativeEngine; class QGraphicsView; +class QFileSystemWatcher; + namespace QmlDesigner { @@ -59,6 +61,7 @@ class CORESHARED_EXPORT NodeInstanceView : public AbstractView public: typedef QWeakPointer Pointer; + typedef QPair, QString> ObjectPropertyPair; NodeInstanceView(QObject *parent = 0); ~NodeInstanceView(); @@ -105,6 +108,7 @@ public: private slots: void emitParentChanged(QObject *child); + void refreshLocalFileProperty(const QString &path); private: // functions NodeInstance rootNodeInstance() const; @@ -131,6 +135,11 @@ private: // functions void setStateInstance(const NodeInstance &stateInstance); void clearStateInstance(); + QFileSystemWatcher *fileSystemWatcher(); + + void addFilePropertyToFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path); + void removeFilePropertyFromFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path); + private: //variables NodeInstance m_rootNodeInstance; NodeInstance m_activeStateInstance; @@ -138,12 +147,17 @@ private: //variables QHash m_nodeInstanceHash; QHash m_objectInstanceHash; // This is purely internal. Might contain dangling pointers! + QMultiHash m_fileSystemWatcherHash; QWeakPointer m_engine; QWeakPointer m_childrenChangeEventFilter; QWeakPointer m_qmlModelView; + QWeakPointer m_fileSystemWatcher; + bool m_blockStatePropertyChanges; + + }; } // namespace NodeInstanceView diff --git a/src/plugins/qmldesigner/core/instances/nodeinstance.cpp b/src/plugins/qmldesigner/core/instances/nodeinstance.cpp index 4080e20008e..f0898677eda 100644 --- a/src/plugins/qmldesigner/core/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/core/instances/nodeinstance.cpp @@ -394,6 +394,11 @@ void NodeInstance::resetProperty(const QString &name) m_nodeInstance->resetProperty(name); } +void NodeInstance::refreshProperty(const QString &name) +{ + m_nodeInstance->refreshProperty(name); +} + void NodeInstance::setId(const QString &id) { m_nodeInstance->setId(id); diff --git a/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp index 8f050a931a4..27972079263 100644 --- a/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -653,6 +654,7 @@ void NodeInstanceView::render(QPainter * painter, const QRectF &target, const QR } } + QRectF NodeInstanceView::sceneRect() const { if (m_graphicsView) @@ -662,3 +664,41 @@ QRectF NodeInstanceView::sceneRect() const } } + +QFileSystemWatcher *NodeInstanceView::fileSystemWatcher() +{ + if (m_fileSystemWatcher.isNull()) { + m_fileSystemWatcher = new QFileSystemWatcher(this); + connect(m_fileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshLocalFileProperty(QString))); + } + + return m_fileSystemWatcher.data(); +} + +void NodeInstanceView::addFilePropertyToFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path) +{ + m_fileSystemWatcherHash.insert(path, ObjectPropertyPair(object, propertyName)); + fileSystemWatcher()->addPath(path); + +} + +void NodeInstanceView::removeFilePropertyFromFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path) +{ + fileSystemWatcher()->removePath(path); + m_fileSystemWatcherHash.remove(path, ObjectPropertyPair(object, propertyName)); +} + +void NodeInstanceView::refreshLocalFileProperty(const QString &path) +{ + if (m_fileSystemWatcherHash.contains(path)) { + QList objectPropertyPairList = m_fileSystemWatcherHash.values(); + foreach(const ObjectPropertyPair &objectPropertyPair, objectPropertyPairList) { + QObject *object = objectPropertyPair.first.data(); + QString propertyName = objectPropertyPair.second; + + if (hasInstanceForObject(object)) { + instanceForObject(object).refreshProperty(propertyName); + } + } + } +} diff --git a/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp b/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp index eae8123cb80..1b4937a0a9a 100644 --- a/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp +++ b/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp @@ -55,6 +55,9 @@ #include #include #include +#include +#include +#include #include #include @@ -404,7 +407,27 @@ void ObjectNodeInstance::reparent(const NodeInstance &oldParentInstance, const Q void ObjectNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) { QDeclarativeProperty property(object(), name, context()); + + QVariant oldValue = property.read(); + if (oldValue.type() == QVariant::Url) { + QUrl url = oldValue.toUrl(); + QString path = url.toLocalFile(); + if (QFileInfo(path).exists() && nodeInstanceView() && !path.isEmpty()) + nodeInstanceView()->removeFilePropertyFromFileSystemWatcher(object(), name, path); + } + + property.write(value); + + QVariant newValue = property.read(); + if (newValue.type() == QVariant::Url) { + QUrl url = newValue.toUrl(); + QString path = url.toLocalFile(); + if (QFileInfo(path).exists() && nodeInstanceView() && !path.isEmpty()) + nodeInstanceView()->addFilePropertyToFileSystemWatcher(object(), name, path); + } + + } void ObjectNodeInstance::setPropertyBinding(const QString &name, const QString &expression) @@ -460,27 +483,55 @@ NodeInstance ObjectNodeInstance::instanceForNode(const ModelNode &node, const QS } } +void ObjectNodeInstance::refreshProperty(const QString &name) +{ + QDeclarativeProperty property(object(), name, context()); + + QVariant oldValue(property.read()); + + if (property.isResettable()) + property.reset(); + else + property.write(resetValue(name)); + + if (oldValue.type() == QVariant::Url) { + QByteArray key = oldValue.toUrl().toEncoded(QUrl::FormattingOption(0x100)); + QString pixmapKey = QString::fromLatin1(key.constData(), key.count()); + QPixmapCache::remove(pixmapKey); + } + + property.write(oldValue); +} + void ObjectNodeInstance::resetProperty(QObject *object, const QString &propertyName) { m_modelAbstractPropertyHash.remove(propertyName); - QDeclarativeProperty qmlProperty(object, propertyName, context()); - QMetaProperty metaProperty = qmlProperty.property(); + QDeclarativeProperty property(object, propertyName, context()); - QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::binding(qmlProperty); + QVariant oldValue = property.read(); + if (oldValue.type() == QVariant::Url) { + QUrl url = oldValue.toUrl(); + QString path = url.toLocalFile(); + if (QFileInfo(path).exists() && nodeInstanceView()) + nodeInstanceView()->removeFilePropertyFromFileSystemWatcher(object, propertyName, path); + } + + + QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::binding(property); if (binding) { binding->setEnabled(false, 0); binding->destroy(); } - if (metaProperty.isResettable()) { - metaProperty.reset(object); - } else if (qmlProperty.isWritable()) { - if (qmlProperty.read() == resetValue(propertyName)) + if (property.isResettable()) { + property.reset(); + } else if (property.isWritable()) { + if (property.read() == resetValue(propertyName)) return; - qmlProperty.write(resetValue(propertyName)); - } else if (qmlProperty.propertyTypeCategory() == QDeclarativeProperty::List) { - qvariant_cast(qmlProperty.read()).clear(); + property.write(resetValue(propertyName)); + } else if (property.propertyTypeCategory() == QDeclarativeProperty::List) { + qvariant_cast(property.read()).clear(); } } diff --git a/src/plugins/qmldesigner/core/instances/objectnodeinstance.h b/src/plugins/qmldesigner/core/instances/objectnodeinstance.h index 0db7b3dac6d..9376aa78788 100644 --- a/src/plugins/qmldesigner/core/instances/objectnodeinstance.h +++ b/src/plugins/qmldesigner/core/instances/objectnodeinstance.h @@ -143,6 +143,7 @@ public: virtual void setPropertyBinding(const QString &name, const QString &expression); virtual QVariant property(const QString &name) const; virtual void resetProperty(const QString &name); + virtual void refreshProperty(const QString &name); virtual bool isVisible() const; virtual void setVisible(bool isVisible);