QmlDesigner: reactivating subcomponent editing

This includes refactoring the DesignDocumentController.
In the ComponentTextMoifier I use replaced because it is not blocked by
beginEditBlock() of the text cursor.

I use the same pattern now for ComponentView like for all the other
views.
The view is created and controlled by DesignModeWidget because we
have only a single instance.

Change-Id: I7809b96f52f4d275f0231f3961c3c4bc2618ce89
Reviewed-on: http://codereview.qt.nokia.com/96
Reviewed-by: Marco Bubke <marco.bubke@nokia.com>
This commit is contained in:
Thomas Hartmann
2011-05-24 18:47:33 +02:00
committed by Marco Bubke
parent e3842f9973
commit f950b8d7c7
9 changed files with 109 additions and 64 deletions

View File

@@ -39,30 +39,17 @@
namespace QmlDesigner { namespace QmlDesigner {
ComponentAction::ComponentAction(QObject *parent) ComponentAction::ComponentAction(ComponentView *componentView)
: QWidgetAction(parent), : QWidgetAction(componentView),
m_componentView(new ComponentView(this)) m_componentView(componentView)
{ {
} }
void ComponentAction::setModel(Model* model)
{
if (model == m_componentView->model())
return;
blockSignals(true);
if (model)
model->attachView(m_componentView.data());
else if (m_componentView->model())
m_componentView->model()->detachView(m_componentView.data());
blockSignals(false);
}
QWidget *ComponentAction::createWidget(QWidget *parent) QWidget *ComponentAction::createWidget(QWidget *parent)
{ {
QComboBox *comboBox = new QComboBox(parent); QComboBox *comboBox = new QComboBox(parent);
comboBox->setMinimumWidth(120);
comboBox->setToolTip(tr("Edit sub components defined in this file"));
comboBox->setModel(m_componentView->standardItemModel()); comboBox->setModel(m_componentView->standardItemModel());
connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(emitCurrentComponentChanged(int))); connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(emitCurrentComponentChanged(int)));

View File

@@ -50,8 +50,7 @@ class ComponentAction : public QWidgetAction
{ {
Q_OBJECT Q_OBJECT
public: public:
ComponentAction(QObject *parent); ComponentAction(ComponentView *componentView);
void setModel(Model* model);
protected: protected:
QWidget *createWidget(QWidget *parent); QWidget *createWidget(QWidget *parent);

View File

@@ -31,9 +31,11 @@
**************************************************************************/ **************************************************************************/
#include "componentview.h" #include "componentview.h"
#include "componentaction.h"
#include <QtDebug> #include <QtDebug>
#include <nodemetainfo.h> #include <nodemetainfo.h>
#include <nodeabstractproperty.h>
#include <QStandardItemModel> #include <QStandardItemModel>
// silence gcc warnings about unused parameters // silence gcc warnings about unused parameters
@@ -43,7 +45,8 @@ namespace QmlDesigner {
ComponentView::ComponentView(QObject *parent) ComponentView::ComponentView(QObject *parent)
: AbstractView(parent), : AbstractView(parent),
m_standardItemModel(new QStandardItemModel(this)), m_standardItemModel(new QStandardItemModel(this)),
m_listChanged(false) m_listChanged(false),
m_componentAction(new ComponentAction(this))
{ {
} }
@@ -56,6 +59,7 @@ void ComponentView::nodeAboutToBeRemoved(const ModelNode &removedNode)
if (item->data(ModelNodeRole).value<ModelNode>() == removedNode) if (item->data(ModelNodeRole).value<ModelNode>() == removedNode)
m_standardItemModel->removeRow(index); m_standardItemModel->removeRow(index);
} }
searchForComponentAndRemoveFromList(removedNode);
} }
QStandardItemModel *ComponentView::standardItemModel() const QStandardItemModel *ComponentView::standardItemModel() const
@@ -86,17 +90,29 @@ void ComponentView::modelAttached(Model *model)
if (AbstractView::model() == model) if (AbstractView::model() == model)
return; return;
bool block = m_componentAction->blockSignals(true);
m_standardItemModel->clear();
AbstractView::modelAttached(model); AbstractView::modelAttached(model);
Q_ASSERT(model->masterModel()); Q_ASSERT(model->masterModel());
appendWholeDocumentAsComponent(); appendWholeDocumentAsComponent();
searchForComponentAndAddToList(rootModelNode()); searchForComponentAndAddToList(rootModelNode());
m_componentAction->blockSignals(block);
} }
void ComponentView::modelAboutToBeDetached(Model *model) void ComponentView::modelAboutToBeDetached(Model *model)
{ {
bool block = m_componentAction->blockSignals(true);
m_standardItemModel->clear(); m_standardItemModel->clear();
AbstractView::modelAboutToBeDetached(model); AbstractView::modelAboutToBeDetached(model);
m_componentAction->blockSignals(block);
}
ComponentAction *ComponentView::action()
{
return m_componentAction;
} }
void ComponentView::nodeCreated(const ModelNode &createdNode) void ComponentView::nodeCreated(const ModelNode &createdNode)
@@ -112,12 +128,23 @@ void ComponentView::searchForComponentAndAddToList(const ModelNode &node)
foreach (const ModelNode &childNode, nodeList) { foreach (const ModelNode &childNode, nodeList) {
if (childNode.type() == "Qt/Component") { if (childNode.type() == "QtQuick.Component") {
if (!childNode.id().isEmpty()) { if (!childNode.id().isEmpty()) {
QStandardItem *item = new QStandardItem(childNode.id()); QStandardItem *item = new QStandardItem(childNode.id());
item->setData(QVariant::fromValue(childNode), ModelNodeRole); item->setData(QVariant::fromValue(childNode), ModelNodeRole);
item->setEditable(false); item->setEditable(false);
m_standardItemModel->appendRow(item); m_standardItemModel->appendRow(item);
} else {
QString description;
if (!childNode.parentProperty().parentModelNode().id().isEmpty())
description = childNode.parentProperty().parentModelNode().id() + QLatin1Char(' ');
else
description = childNode.parentProperty().parentModelNode().simplifiedTypeName() + QLatin1Char(' ');
description += childNode.parentProperty().name();
QStandardItem *item = new QStandardItem(description);
item->setData(QVariant::fromValue(childNode), ModelNodeRole);
item->setEditable(false);
m_standardItemModel->appendRow(item);
} }
} else if (node.metaInfo().isValid() && node.metaInfo().isComponent() && !m_componentList.contains(node.type())) { } else if (node.metaInfo().isValid() && node.metaInfo().isComponent() && !m_componentList.contains(node.type())) {
m_componentList.append(node.type()); m_componentList.append(node.type());
@@ -129,31 +156,31 @@ void ComponentView::searchForComponentAndAddToList(const ModelNode &node)
void ComponentView::nodeRemoved(const ModelNode & /* removedNode */, const NodeAbstractProperty & /*parentProperty*/, PropertyChangeFlags /*propertyChange*/) void ComponentView::nodeRemoved(const ModelNode & /* removedNode */, const NodeAbstractProperty & /*parentProperty*/, PropertyChangeFlags /*propertyChange*/)
{ {
} }
//void ComponentView::searchForComponentAndRemoveFromList(const ModelNode &node) void ComponentView::searchForComponentAndRemoveFromList(const ModelNode &node)
//{ {
// QList<ModelNode> nodeList; QList<ModelNode> nodeList;
// nodeList.append(node); nodeList.append(node);
// nodeList.append(node.allSubModelNodes()); nodeList.append(node.allSubModelNodes());
//
//
// foreach (const ModelNode &childNode, nodeList) { foreach (const ModelNode &childNode, nodeList) {
// if (node.type() == "Qt/Component") { if (childNode.type() == "QtQuick.Component") {
// if (!node.id().isEmpty()) { if (!childNode.id().isEmpty()) {
// for(int row = 0; row < m_standardItemModel->rowCount(); row++) { for (int row = 0; row < m_standardItemModel->rowCount(); row++) {
// if (m_standardItemModel->item(row)->text() == node.id()) if (m_standardItemModel->item(row)->text() == childNode.id())
// m_standardItemModel->removeRow(row); m_standardItemModel->removeRow(row);
// } }
// } }
// } else if (node.metaInfo().isComponent() && !m_componentList.contains(node.type())) { } else if (node.metaInfo().isComponent() && !m_componentList.contains(childNode.type())) {
// m_componentList.append(node.type()); m_componentList.append(childNode.type());
// m_componentList.sort(); m_componentList.sort();
// m_listChanged = true; m_listChanged = true;
// } }
// } }
//} }
void ComponentView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {} void ComponentView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void ComponentView::nodeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {} void ComponentView::nodeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void ComponentView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {} void ComponentView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {}

View File

@@ -44,6 +44,8 @@ QT_END_NAMESPACE
namespace QmlDesigner { namespace QmlDesigner {
class ComponentAction;
class ComponentView : public AbstractView class ComponentView : public AbstractView
{ {
Q_OBJECT Q_OBJECT
@@ -59,6 +61,8 @@ public:
void modelAttached(Model *model); void modelAttached(Model *model);
void modelAboutToBeDetached(Model *model); void modelAboutToBeDetached(Model *model);
ComponentAction *action();
void nodeCreated(const ModelNode &createdNode); void nodeCreated(const ModelNode &createdNode);
void nodeAboutToBeRemoved(const ModelNode &removedNode); void nodeAboutToBeRemoved(const ModelNode &removedNode);
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange); void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
@@ -107,13 +111,14 @@ signals:
private: //functions private: //functions
void updateModel(); void updateModel();
void searchForComponentAndAddToList(const ModelNode &node); void searchForComponentAndAddToList(const ModelNode &node);
// void searchForComponentAndRemoveFromList(const ModelNode &node); void searchForComponentAndRemoveFromList(const ModelNode &node);
void appendWholeDocumentAsComponent(); void appendWholeDocumentAsComponent();
private: private:
QStringList m_componentList; QStringList m_componentList;
QStandardItemModel *m_standardItemModel; QStandardItemModel *m_standardItemModel;
bool m_listChanged; bool m_listChanged;
ComponentAction *m_componentAction;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -48,12 +48,12 @@
#include <componenttextmodifier.h> #include <componenttextmodifier.h>
#include <metainfo.h> #include <metainfo.h>
#include <invalidargumentexception.h> #include <invalidargumentexception.h>
#include <componentview.h>
#include <componentaction.h> #include <componentaction.h>
#include <qmlobjectnode.h> #include <qmlobjectnode.h>
#include <rewriterview.h> #include <rewriterview.h>
#include <rewritingexception.h> #include <rewritingexception.h>
#include <nodelistproperty.h> #include <nodelistproperty.h>
#include <toolbox.h>
#include <variantproperty.h> #include <variantproperty.h>
#include <rewritingexception.h> #include <rewritingexception.h>
@@ -97,6 +97,7 @@ public:
QWeakPointer<StatesEditorView> statesEditorView; QWeakPointer<StatesEditorView> statesEditorView;
QWeakPointer<QStackedWidget> stackedWidget; QWeakPointer<QStackedWidget> stackedWidget;
QWeakPointer<NodeInstanceView> nodeInstanceView; QWeakPointer<NodeInstanceView> nodeInstanceView;
QWeakPointer<ComponentView> componentView;
QWeakPointer<QmlDesigner::Model> model; QWeakPointer<QmlDesigner::Model> model;
QWeakPointer<QmlDesigner::Model> subComponentModel; QWeakPointer<QmlDesigner::Model> subComponentModel;
@@ -112,7 +113,6 @@ public:
QUrl searchPath; QUrl searchPath;
bool documentLoaded; bool documentLoaded;
bool syncBlocked; bool syncBlocked;
QWeakPointer<ComponentAction> componentAction;
}; };
@@ -256,6 +256,12 @@ void DesignDocumentController::setNodeInstanceView(NodeInstanceView *nodeInstanc
m_d->nodeInstanceView = nodeInstanceView; m_d->nodeInstanceView = nodeInstanceView;
} }
void DesignDocumentController::setComponentView(ComponentView *componentView)
{
m_d->componentView = componentView;
connect(m_d->componentView->action(), SIGNAL(currentComponentChanged(ModelNode)), SLOT(changeCurrentModelTo(ModelNode)));
}
QString DesignDocumentController::displayName() const QString DesignDocumentController::displayName() const
{ {
if (fileName().isEmpty()) if (fileName().isEmpty())
@@ -331,6 +337,8 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit *
loadCurrentModel(); loadCurrentModel();
m_d->masterModel->attachView(m_d->componentView.data());
return m_d->rewriterView->errors(); return m_d->rewriterView->errors();
} }
@@ -340,6 +348,17 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo
QWeakPointer<Model> oldModel = m_d->model; QWeakPointer<Model> oldModel = m_d->model;
Q_ASSERT(oldModel.data()); Q_ASSERT(oldModel.data());
QString componentText = m_d->rewriterView->extractText(QList<ModelNode>() << componentNode).value(componentNode);
if (componentText.isEmpty())
return;
bool explicitComponent = false;
if (componentText.contains("Component")) { //explicit component
explicitComponent = true;
}
if (m_d->model == m_d->subComponentModel) { if (m_d->model == m_d->subComponentModel) {
//change back to master model //change back to master model
m_d->model->detachView(m_d->rewriterView.data()); m_d->model->detachView(m_d->rewriterView.data());
@@ -356,10 +375,20 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo
if (m_d->componentTextModifier) if (m_d->componentTextModifier)
delete m_d->componentTextModifier; delete m_d->componentTextModifier;
int componentStartOffset = m_d->rewriterView->firstDefinitionInsideOffset(componentNode);
int componentEndOffset = componentStartOffset + m_d->rewriterView->firstDefinitionInsideLength(componentNode); int componentStartOffset;
int componentEndOffset;
int rootStartOffset = m_d->rewriterView->nodeOffset(rootModelNode); int rootStartOffset = m_d->rewriterView->nodeOffset(rootModelNode);
if (explicitComponent) { //the component is explciit we have to find the first definition inside
componentStartOffset = m_d->rewriterView->firstDefinitionInsideOffset(componentNode);
componentEndOffset = componentStartOffset + m_d->rewriterView->firstDefinitionInsideLength(componentNode);
} else { //the component is implicit
componentStartOffset = m_d->rewriterView->nodeOffset(componentNode);
componentEndOffset = componentStartOffset + m_d->rewriterView->nodeLength(componentNode);
}
m_d->componentTextModifier = new ComponentTextModifier (m_d->textModifier, componentStartOffset, componentEndOffset, rootStartOffset); m_d->componentTextModifier = new ComponentTextModifier (m_d->textModifier, componentStartOffset, componentEndOffset, rootStartOffset);
@@ -392,21 +421,11 @@ void DesignDocumentController::loadCurrentModel()
m_d->model->attachView(m_d->navigator.data()); m_d->model->attachView(m_d->navigator.data());
m_d->itemLibraryView->widget()->setResourcePath(QFileInfo(m_d->fileName).absolutePath()); m_d->itemLibraryView->widget()->setResourcePath(QFileInfo(m_d->fileName).absolutePath());
if (!m_d->componentAction) {
m_d->componentAction = new ComponentAction(m_d->formEditorView->widget());
m_d->componentAction->setModel(m_d->model.data());
connect(m_d->componentAction.data(), SIGNAL(currentComponentChanged(ModelNode)), SLOT(changeCurrentModelTo(ModelNode)));
m_d->formEditorView->widget()->toolBox()->addAction(m_d->componentAction.data());
}
// Disable switching between in file components for the time being
m_d->componentAction->setVisible(false);
connect(m_d->itemLibraryView->widget(), SIGNAL(itemActivated(const QString&)), m_d->formEditorView.data(), SLOT(activateItemCreator(const QString&))); connect(m_d->itemLibraryView->widget(), SIGNAL(itemActivated(const QString&)), m_d->formEditorView.data(), SLOT(activateItemCreator(const QString&)));
m_d->model->attachView(m_d->formEditorView.data()); m_d->model->attachView(m_d->formEditorView.data());
m_d->model->attachView(m_d->itemLibraryView.data()); m_d->model->attachView(m_d->itemLibraryView.data());
if (!m_d->textEdit->parent()) // hack to prevent changing owner of external text edit if (!m_d->textEdit->parent()) // hack to prevent changing owner of external text edit
m_d->stackedWidget->addWidget(m_d->textEdit.data()); m_d->stackedWidget->addWidget(m_d->textEdit.data());

View File

@@ -56,6 +56,7 @@ class QmlObjectNode;
class RewriterView; class RewriterView;
class ItemLibraryView; class ItemLibraryView;
class NavigatorView; class NavigatorView;
class ComponentView;
class PropertyEditor; class PropertyEditor;
class StatesEditorView; class StatesEditorView;
class FormEditorView; class FormEditorView;
@@ -98,6 +99,7 @@ public:
void setStatesEditorView(StatesEditorView* statesEditorView); void setStatesEditorView(StatesEditorView* statesEditorView);
void setFormEditorView(FormEditorView *formEditorView); void setFormEditorView(FormEditorView *formEditorView);
void setNodeInstanceView(NodeInstanceView *nodeInstanceView); void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
void setComponentView(ComponentView *componentView);
signals: signals:
void displayNameChanged(const QString &newFileName); void displayNameChanged(const QString &newFileName);

View File

@@ -39,7 +39,7 @@ ComponentTextModifier::ComponentTextModifier(TextModifier *originalModifier, int
m_componentEndOffset(componentEndOffset), m_componentEndOffset(componentEndOffset),
m_rootStartOffset(rootStartOffset) m_rootStartOffset(rootStartOffset)
{ {
connect(m_originalModifier->textDocument(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChange(int,int,int))); connect(m_originalModifier, SIGNAL(replaced(int, int, int)), this, SLOT(contentsChange(int,int,int)));
connect(m_originalModifier, SIGNAL(textChanged()), this, SIGNAL(textChanged())); connect(m_originalModifier, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
connect(m_originalModifier, SIGNAL(replaced(int, int, int)), this, SIGNAL(replaced(int, int, int))); connect(m_originalModifier, SIGNAL(replaced(int, int, int)), this, SIGNAL(replaced(int, int, int)));

View File

@@ -40,7 +40,8 @@
#include <formeditorwidget.h> #include <formeditorwidget.h>
#include <stateseditorwidget.h> #include <stateseditorwidget.h>
#include <itemlibrarywidget.h> #include <itemlibrarywidget.h>
#include <componentaction.h>
#include <toolbox.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/modemanager.h> #include <coreplugin/modemanager.h>
@@ -312,6 +313,7 @@ void DesignModeWidget::showEditor(Core::IEditor *editor)
newDocument->setStatesEditorView(m_statesEditorView.data()); newDocument->setStatesEditorView(m_statesEditorView.data());
newDocument->setItemLibraryView(m_itemLibraryView.data()); newDocument->setItemLibraryView(m_itemLibraryView.data());
newDocument->setFormEditorView(m_formEditorView.data()); newDocument->setFormEditorView(m_formEditorView.data());
newDocument->setComponentView(m_componentView.data());
newDocument->setFileName(fileName); newDocument->setFileName(fileName);
@@ -674,6 +676,8 @@ void DesignModeWidget::setup()
m_formEditorView = new FormEditorView(this); m_formEditorView = new FormEditorView(this);
m_componentView = new ComponentView(this);
m_formEditorView->widget()->toolBox()->addLeftSideAction(m_componentView->action());
m_fakeToolBar = Core::EditorManager::createToolBar(this); m_fakeToolBar = Core::EditorManager::createToolBar(this);
m_mainSplitter = new MiniSplitter(this); m_mainSplitter = new MiniSplitter(this);

View File

@@ -45,6 +45,7 @@
#include <navigatorwidget.h> #include <navigatorwidget.h>
#include <navigatorview.h> #include <navigatorview.h>
#include <stateseditorview.h> #include <stateseditorview.h>
#include <componentview.h>
#include <modelnode.h> #include <modelnode.h>
#include <formeditorview.h> #include <formeditorview.h>
#include <propertyeditor.h> #include <propertyeditor.h>
@@ -185,6 +186,7 @@ private:
QWeakPointer<PropertyEditor> m_propertyEditorView; QWeakPointer<PropertyEditor> m_propertyEditorView;
QWeakPointer<StatesEditorView> m_statesEditorView; QWeakPointer<StatesEditorView> m_statesEditorView;
QWeakPointer<FormEditorView> m_formEditorView; QWeakPointer<FormEditorView> m_formEditorView;
QWeakPointer<ComponentView> m_componentView;
QWeakPointer<NodeInstanceView> m_nodeInstanceView; QWeakPointer<NodeInstanceView> m_nodeInstanceView;
bool m_syncWithTextEdit; bool m_syncWithTextEdit;