From 5adf7992e8a032ef595d989ee2e9a79e0598e575 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann <Thomas.Hartmann@nokia.com> Date: Thu, 15 Sep 2011 14:31:30 +0200 Subject: [PATCH] QmlDesigner: adding crumblePath Change-Id: Ic0d68b145398a161194d2a469e9a2f15fe0901d5 Reviewed-on: http://codereview.qt-project.org/4996 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com> --- .../integration/designdocumentcontroller.cpp | 95 +++++++++++++++- .../integration/designdocumentcontroller.h | 17 ++- .../model/modelnodecontextmenu.cpp | 105 ++++++++++++++++-- src/plugins/qmldesigner/designmodewidget.cpp | 6 +- src/plugins/qmldesigner/designmodewidget.h | 2 + 5 files changed, 209 insertions(+), 16 deletions(-) diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp index 214273e47c5..ae11f4b2d38 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp @@ -46,6 +46,7 @@ #include <formeditorview.h> #include <propertyeditor.h> #include <formeditorwidget.h> +#include <toolbox.h> #include <basetexteditmodifier.h> #include <componenttextmodifier.h> #include <metainfo.h> @@ -59,8 +60,10 @@ #include <variantproperty.h> #include <rewritingexception.h> #include <model/modelnodecontextmenu.h> +#include <designmodewidget.h> #include <utils/fileutils.h> +#include <utils/crumblepath.h> #include <QtCore/QCoreApplication> #include <QtCore/QDir> @@ -118,15 +121,22 @@ public: QmlDesigner::ComponentTextModifier *componentTextModifier; QWeakPointer<SubComponentManager> subComponentManager; QWeakPointer<Internal::ViewLogger> viewLogger; + ModelNode componentNode; QString fileName; QUrl searchPath; bool documentLoaded; bool syncBlocked; int qt_versionId; + static bool clearCrumblePath; + static bool pushCrumblePath; }; +bool DesignDocumentControllerPrivate::clearCrumblePath = true; +bool DesignDocumentControllerPrivate::pushCrumblePath = true; + + /** \class QmlDesigner::DesignDocumentController @@ -191,6 +201,15 @@ void DesignDocumentController::changeToMasterModel() d->rewriterView->setTextModifier(d->textModifier); d->model = d->masterModel; d->model->attachView(d->rewriterView.data()); + d->componentNode = d->rewriterView->rootModelNode(); +} + +QVariant DesignDocumentController::createCrumbleBarInfo() +{ + CrumbleBarInfo info; + info.fileName = fileName(); + info.modelNode = d->componentNode; + return QVariant::fromValue<CrumbleBarInfo>(info); } QWidget *DesignDocumentController::centralWidget() const @@ -302,7 +321,27 @@ void DesignDocumentController::setComponentView(ComponentView *componentView) connect(d->componentView->action(), SIGNAL(currentComponentChanged(ModelNode)), SLOT(changeCurrentModelTo(ModelNode))); } +static inline bool compareCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo1, const CrumbleBarInfo &crumbleBarInfo2) +{ + return crumbleBarInfo1.fileName == crumbleBarInfo2.fileName && crumbleBarInfo1.modelNode == crumbleBarInfo2.modelNode; +} + +void DesignDocumentController::setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo) { + DesignDocumentControllerPrivate::clearCrumblePath = false; + DesignDocumentControllerPrivate::pushCrumblePath = false; + while (!compareCrumbleBarInfo(d->formEditorView->widget()->toolBox()->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), crumbleBarInfo)) + d->formEditorView->widget()->toolBox()->crumblePath()->popElement(); + Core::EditorManager::instance()->openEditor(crumbleBarInfo.fileName); + DesignDocumentControllerPrivate::pushCrumblePath = true; + Internal::DesignModeWidget::instance()->currentDesignDocumentController()->changeToSubComponent(crumbleBarInfo.modelNode); + DesignDocumentControllerPrivate::clearCrumblePath = true; +} + +void DesignDocumentController::setBlockCrumbleBar(bool b) +{ + DesignDocumentControllerPrivate::clearCrumblePath = !b; + DesignDocumentControllerPrivate::pushCrumblePath = !b; } QString DesignDocumentController::displayName() const @@ -313,6 +352,22 @@ QString DesignDocumentController::displayName() const return fileName(); } +QString DesignDocumentController::simplfiedDisplayName() const +{ + if (!d->componentNode.isRootNode()) { + if (d->componentNode.id().isEmpty()) { + if (d->formEditorView->rootModelNode().id().isEmpty()) { + return d->formEditorView->rootModelNode().simplifiedTypeName(); + } + return d->formEditorView->rootModelNode().id(); + } + return d->componentNode.id(); + } + + QStringList list = displayName().split("/"); + return list.last(); +} + QString DesignDocumentController::fileName() const { return d->fileName; @@ -374,6 +429,7 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit * d->masterModel->attachView(d->rewriterView.data()); d->model = d->masterModel; + d->componentNode = d->rewriterView->rootModelNode(); d->subComponentManager = new SubComponentManager(d->masterModel.data(), this); d->subComponentManager->update(d->searchPath, d->model->imports()); @@ -385,7 +441,22 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit * return d->rewriterView->errors(); } -void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNode) +void DesignDocumentController::changeCurrentModelTo(const ModelNode &node) +{ + if (d->componentNode == node) + return; + if (Internal::DesignModeWidget::instance()->currentDesignDocumentController() != this) + return; + DesignDocumentControllerPrivate::clearCrumblePath = false; + while (!d->formEditorView->widget()->toolBox()->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isRootNode()) + d->formEditorView->widget()->toolBox()->crumblePath()->popElement(); + if (node.isRootNode()) + d->formEditorView->widget()->toolBox()->crumblePath()->popElement(); + changeToSubComponent(node); + DesignDocumentControllerPrivate::clearCrumblePath = true; +} + +void DesignDocumentController::changeToSubComponent(const ModelNode &componentNode) { Q_ASSERT(d->masterModel); QWeakPointer<Model> oldModel = d->model; @@ -405,6 +476,7 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo explicitComponent = true; } + d->componentNode = componentNode; if (!componentNode.isRootNode()) { Q_ASSERT(d->model == d->masterModel); Q_ASSERT(componentNode.isValid()); @@ -449,6 +521,13 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo d->componentView->setComponentNode(componentNode); } +void DesignDocumentController::changeToExternalSubComponent(const QString &fileName) +{ + DesignDocumentControllerPrivate::clearCrumblePath = false; + Core::EditorManager::instance()->openEditor(fileName); + DesignDocumentControllerPrivate::clearCrumblePath = true; +} + void DesignDocumentController::goIntoComponent() { if (!d->model) @@ -469,6 +548,7 @@ void DesignDocumentController::loadCurrentModel() Q_ASSERT(d->masterModel); Q_ASSERT(d->model); d->model->setMasterModel(d->masterModel.data()); + d->masterModel->attachView(d->componentView.data()); d->nodeInstanceView->setPathToQt(pathToQt()); d->model->attachView(d->nodeInstanceView.data()); @@ -486,6 +566,15 @@ void DesignDocumentController::loadCurrentModel() d->model->attachView(d->propertyEditorView.data()); + + if (DesignDocumentControllerPrivate::clearCrumblePath) + d->formEditorView->widget()->toolBox()->crumblePath()->clear(); + + if (DesignDocumentControllerPrivate::pushCrumblePath && + !compareCrumbleBarInfo(d->formEditorView->widget()->toolBox()->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), + createCrumbleBarInfo().value<CrumbleBarInfo>())) + d->formEditorView->widget()->toolBox()->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo()); + d->documentLoaded = true; Q_ASSERT(d->masterModel); QApplication::restoreOverrideCursor(); @@ -738,7 +827,7 @@ void DesignDocumentController::paste() } view.setSelectedModelNodes(pastedNodeList); - } catch (RewritingException &e) { + } catch (RewritingException &e) { qWarning() << e.description(); //silent error } } else { @@ -774,7 +863,7 @@ void DesignDocumentController::paste() NodeMetaInfo::clearCache(); view.setSelectedModelNodes(QList<ModelNode>() << pastedNode); - } catch (RewritingException &e) { + } catch (RewritingException &e) { qWarning() << e.description(); //silent error } } diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h index 9ac261e3510..b0d6f14bca7 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h @@ -60,6 +60,7 @@ class ComponentView; class PropertyEditor; class StatesEditorView; class FormEditorView; +struct CrumbleBarInfo; class DesignDocumentController: public QObject { @@ -70,6 +71,8 @@ public: ~DesignDocumentController(); QString displayName() const; + QString simplfiedDisplayName() const; + QString fileName() const; void setFileName(const QString &fileName); @@ -101,7 +104,8 @@ public: void setNodeInstanceView(NodeInstanceView *nodeInstanceView); void setComponentView(ComponentView *componentView); - static DesignDocumentController *instance(); + void setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo); + static void setBlockCrumbleBar(bool); signals: void displayNameChanged(const QString &newFileName); @@ -126,6 +130,8 @@ public slots: void redo(); void activeQtVersionChanged(); void changeCurrentModelTo(const ModelNode &node); + void changeToSubComponent(const ModelNode &node); + void changeToExternalSubComponent(const QString &fileName); void goIntoComponent(); #ifdef ENABLE_TEXT_VIEW @@ -140,14 +146,23 @@ private: void detachNodeInstanceView(); void attachNodeInstanceView(); void changeToMasterModel(); + QVariant createCrumbleBarInfo(); QWidget *centralWidget() const; QString pathToQt() const; + class DesignDocumentControllerPrivate *d; +}; + +struct CrumbleBarInfo { + ModelNode modelNode; + QString fileName; }; +Q_DECLARE_METATYPE(CrumbleBarInfo) + } // namespace QmlDesigner #endif // DesignDocumentController_h diff --git a/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.cpp b/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.cpp index af7613cf3f4..93f329bad9f 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.cpp @@ -47,12 +47,16 @@ #include <rewritertransaction.h> #include <designmodewidget.h> #include <qmlanchors.h> -#include <designdocumentcontroller.h> const QString auxDataString = QLatin1String("anchors_"); namespace QmlDesigner { +static inline DesignDocumentController* designDocumentController() +{ + return Internal::DesignModeWidget::instance()->currentDesignDocumentController(); +} + static inline QString captionForModelNode(const ModelNode &modelNode) { if (modelNode.id().isEmpty()) @@ -188,15 +192,82 @@ static inline bool isFileComponent(const ModelNode &node) return false; } +static inline void getWidthHeight(const ModelNode &node, int &width, int &height) +{ + QmlItemNode itemNode(node); + if (itemNode.isValid()) { + width = itemNode.instanceValue("width").toInt(); + height = itemNode.instanceValue("height").toInt(); + } +} + +static inline void getProperties(const ModelNode node, QHash<QString, QVariant> &propertyHash) +{ + if (QmlObjectNode(node).isValid()) { + foreach (const QString &propertyName, node.propertyNames()) { + if (node.property(propertyName).isVariantProperty() || + node.property(propertyName).isBindingProperty() && + !propertyName.contains(QLatin1String("anchors."))) { + propertyHash.insert(propertyName, QmlObjectNode(node).instanceValue(propertyName)); + } + } + } + QmlItemNode itemNode(node); + if (itemNode.isValid()) { + propertyHash.insert(QLatin1String("width"), itemNode.instanceValue(QLatin1String("width"))); + propertyHash.insert(QLatin1String("height"), itemNode.instanceValue(QLatin1String("height"))); + propertyHash.remove(QLatin1String("x")); + propertyHash.remove(QLatin1String("y")); + propertyHash.remove(QLatin1String("rotation")); + propertyHash.remove(QLatin1String("opacity")); + } +} + +static inline void applyProperties(ModelNode &node, const QHash<QString, QVariant> &propertyHash) +{ + QHash<QString, QVariant> auxiliaryData = node.auxiliaryData(); + foreach (const QString propertyName, auxiliaryData.keys()) { + node.setAuxiliaryData(propertyName, QVariant()); + } + + QHashIterator<QString, QVariant> i(propertyHash); + while (i.hasNext()) { + i.next(); + if (i.key() == QLatin1String("width") || i.key() == QLatin1String("height")) { + node.setAuxiliaryData(i.key(), i.value()); + } else if (node.property(i.key()).isDynamic() && + node.property(i.key()).dynamicTypeName() == QLatin1String("alias") && + node.property(i.key()).isBindingProperty()) { + AbstractProperty targetProperty = node.bindingProperty(i.key()).resolveToProperty(); + if (targetProperty.isValid()) { + targetProperty.parentModelNode().setAuxiliaryData(targetProperty.name() + QLatin1String("@NodeInstance"), i.value()); + } + } else { + node.setAuxiliaryData(i.key() + QLatin1String("@NodeInstance"), i.value()); + } + } +} + static inline void openFileForComponent(const ModelNode &node) { + //int width = 0; + //int height = 0; + QHash<QString, QVariant> propertyHash; if (node.metaInfo().isComponent()) { - Core::EditorManager::instance()->openEditor(node.metaInfo().componentFileName()); + //getWidthHeight(node, width, height); + getProperties(node, propertyHash); + designDocumentController()->changeToExternalSubComponent(node.metaInfo().componentFileName()); } else if (checkIfNodeIsAView(node) && node.hasNodeProperty("delegate") && node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) { - Core::EditorManager::instance()->openEditor(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName()); + //getWidthHeight(node, width, height); + getProperties(node, propertyHash); + designDocumentController()->changeToExternalSubComponent(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName()); } + ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode(); + applyProperties(rootModelNode, propertyHash); + //rootModelNode.setAuxiliaryData("width", width); + //rootModelNode.setAuxiliaryData("height", height); } static inline void openInlineComponent(const ModelNode &node) @@ -204,16 +275,30 @@ static inline void openInlineComponent(const ModelNode &node) if (!node.isValid() || !node.metaInfo().isValid()) return; - if (!DesignDocumentController::instance()) + if (!designDocumentController()) return; - if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) - DesignDocumentController::instance()->changeCurrentModelTo(node); - if (checkIfNodeIsAView(node) && - node.hasNodeProperty("delegate")) { - if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) - DesignDocumentController::instance()->changeCurrentModelTo(node.nodeProperty("delegate").modelNode()); + //int width = 0; + //int height = 0; + QHash<QString, QVariant> propertyHash; + + if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) { + //getWidthHeight(node, width, height); + getProperties(node, propertyHash); + designDocumentController()->changeToSubComponent(node); + } else if (checkIfNodeIsAView(node) && + node.hasNodeProperty("delegate")) { + if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) { + //getWidthHeight(node, width, height); + getProperties(node, propertyHash); + designDocumentController()->changeToSubComponent(node.nodeProperty("delegate").modelNode()); + } } + + ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode(); + applyProperties(rootModelNode, propertyHash); + //rootModelNode.setAuxiliaryData("width", width); + //rootModelNode.setAuxiliaryData("height", height); } static inline bool modelNodesHaveProperty(const QList<ModelNode> &modelNodeList, const QString &propertyName) diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 63360e3317c..84dd5317768 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -59,6 +59,7 @@ #include <utils/parameteraction.h> #include <utils/fileutils.h> #include <utils/qtcassert.h> +#include <utils/crumblepath.h> #include <QtCore/QSettings> #include <QtCore/QEvent> @@ -333,7 +334,7 @@ void DesignModeWidget::showEditor(Core::IEditor *editor) newDocument->setFileName(fileName); - document = newDocument; + document = newDocument; m_documentHash.insert(textEdit, document); } @@ -702,8 +703,9 @@ void DesignModeWidget::setup() m_itemLibraryView = new ItemLibraryView(this); m_statesEditorView = new StatesEditorView(this); - + m_formEditorView = new FormEditorView(this); + connect(m_formEditorView->widget()->toolBox()->crumblePath(), SIGNAL(elementClicked(QVariant)), this, SLOT(onCrumblePathElementClicked(QVariant))); m_componentView = new ComponentView(this); m_formEditorView->widget()->toolBox()->addLeftSideAction(m_componentView->action()); diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 8c2f80ae3ca..1debe8d32cc 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -165,6 +165,8 @@ private slots: void onGoBackClicked(); void onGoForwardClicked(); + void onCrumblePathElementClicked(const QVariant &data); + protected: void resizeEvent(QResizeEvent *event); -- GitLab