forked from qt-creator/qt-creator
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:
committed by
Marco Bubke
parent
e3842f9973
commit
f950b8d7c7
@@ -39,30 +39,17 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ComponentAction::ComponentAction(QObject *parent)
|
||||
: QWidgetAction(parent),
|
||||
m_componentView(new ComponentView(this))
|
||||
ComponentAction::ComponentAction(ComponentView *componentView)
|
||||
: QWidgetAction(componentView),
|
||||
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)
|
||||
{
|
||||
QComboBox *comboBox = new QComboBox(parent);
|
||||
comboBox->setMinimumWidth(120);
|
||||
comboBox->setToolTip(tr("Edit sub components defined in this file"));
|
||||
comboBox->setModel(m_componentView->standardItemModel());
|
||||
connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(emitCurrentComponentChanged(int)));
|
||||
|
||||
|
||||
@@ -50,8 +50,7 @@ class ComponentAction : public QWidgetAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ComponentAction(QObject *parent);
|
||||
void setModel(Model* model);
|
||||
ComponentAction(ComponentView *componentView);
|
||||
|
||||
protected:
|
||||
QWidget *createWidget(QWidget *parent);
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "componentview.h"
|
||||
#include "componentaction.h"
|
||||
#include <QtDebug>
|
||||
|
||||
#include <nodemetainfo.h>
|
||||
#include <nodeabstractproperty.h>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
// silence gcc warnings about unused parameters
|
||||
@@ -43,7 +45,8 @@ namespace QmlDesigner {
|
||||
ComponentView::ComponentView(QObject *parent)
|
||||
: AbstractView(parent),
|
||||
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)
|
||||
m_standardItemModel->removeRow(index);
|
||||
}
|
||||
searchForComponentAndRemoveFromList(removedNode);
|
||||
}
|
||||
|
||||
QStandardItemModel *ComponentView::standardItemModel() const
|
||||
@@ -86,17 +90,29 @@ void ComponentView::modelAttached(Model *model)
|
||||
if (AbstractView::model() == model)
|
||||
return;
|
||||
|
||||
bool block = m_componentAction->blockSignals(true);
|
||||
m_standardItemModel->clear();
|
||||
|
||||
AbstractView::modelAttached(model);
|
||||
|
||||
Q_ASSERT(model->masterModel());
|
||||
appendWholeDocumentAsComponent();
|
||||
searchForComponentAndAddToList(rootModelNode());
|
||||
|
||||
m_componentAction->blockSignals(block);
|
||||
}
|
||||
|
||||
void ComponentView::modelAboutToBeDetached(Model *model)
|
||||
{
|
||||
bool block = m_componentAction->blockSignals(true);
|
||||
m_standardItemModel->clear();
|
||||
AbstractView::modelAboutToBeDetached(model);
|
||||
m_componentAction->blockSignals(block);
|
||||
}
|
||||
|
||||
ComponentAction *ComponentView::action()
|
||||
{
|
||||
return m_componentAction;
|
||||
}
|
||||
|
||||
void ComponentView::nodeCreated(const ModelNode &createdNode)
|
||||
@@ -112,12 +128,23 @@ void ComponentView::searchForComponentAndAddToList(const ModelNode &node)
|
||||
|
||||
|
||||
foreach (const ModelNode &childNode, nodeList) {
|
||||
if (childNode.type() == "Qt/Component") {
|
||||
if (childNode.type() == "QtQuick.Component") {
|
||||
if (!childNode.id().isEmpty()) {
|
||||
QStandardItem *item = new QStandardItem(childNode.id());
|
||||
item->setData(QVariant::fromValue(childNode), ModelNodeRole);
|
||||
item->setEditable(false);
|
||||
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())) {
|
||||
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::searchForComponentAndRemoveFromList(const ModelNode &node)
|
||||
//{
|
||||
// QList<ModelNode> nodeList;
|
||||
// nodeList.append(node);
|
||||
// nodeList.append(node.allSubModelNodes());
|
||||
//
|
||||
//
|
||||
// foreach (const ModelNode &childNode, nodeList) {
|
||||
// if (node.type() == "Qt/Component") {
|
||||
// if (!node.id().isEmpty()) {
|
||||
// for(int row = 0; row < m_standardItemModel->rowCount(); row++) {
|
||||
// if (m_standardItemModel->item(row)->text() == node.id())
|
||||
// m_standardItemModel->removeRow(row);
|
||||
// }
|
||||
// }
|
||||
// } else if (node.metaInfo().isComponent() && !m_componentList.contains(node.type())) {
|
||||
// m_componentList.append(node.type());
|
||||
// m_componentList.sort();
|
||||
// m_listChanged = true;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
void ComponentView::searchForComponentAndRemoveFromList(const ModelNode &node)
|
||||
{
|
||||
QList<ModelNode> nodeList;
|
||||
nodeList.append(node);
|
||||
nodeList.append(node.allSubModelNodes());
|
||||
|
||||
|
||||
foreach (const ModelNode &childNode, nodeList) {
|
||||
if (childNode.type() == "QtQuick.Component") {
|
||||
if (!childNode.id().isEmpty()) {
|
||||
for (int row = 0; row < m_standardItemModel->rowCount(); row++) {
|
||||
if (m_standardItemModel->item(row)->text() == childNode.id())
|
||||
m_standardItemModel->removeRow(row);
|
||||
}
|
||||
}
|
||||
} else if (node.metaInfo().isComponent() && !m_componentList.contains(childNode.type())) {
|
||||
m_componentList.append(childNode.type());
|
||||
m_componentList.sort();
|
||||
m_listChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {}
|
||||
|
||||
@@ -44,6 +44,8 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ComponentAction;
|
||||
|
||||
class ComponentView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -59,6 +61,8 @@ public:
|
||||
void modelAttached(Model *model);
|
||||
void modelAboutToBeDetached(Model *model);
|
||||
|
||||
ComponentAction *action();
|
||||
|
||||
void nodeCreated(const ModelNode &createdNode);
|
||||
void nodeAboutToBeRemoved(const ModelNode &removedNode);
|
||||
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
|
||||
@@ -107,13 +111,14 @@ signals:
|
||||
private: //functions
|
||||
void updateModel();
|
||||
void searchForComponentAndAddToList(const ModelNode &node);
|
||||
// void searchForComponentAndRemoveFromList(const ModelNode &node);
|
||||
void searchForComponentAndRemoveFromList(const ModelNode &node);
|
||||
void appendWholeDocumentAsComponent();
|
||||
|
||||
private:
|
||||
QStringList m_componentList;
|
||||
QStandardItemModel *m_standardItemModel;
|
||||
bool m_listChanged;
|
||||
ComponentAction *m_componentAction;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -48,12 +48,12 @@
|
||||
#include <componenttextmodifier.h>
|
||||
#include <metainfo.h>
|
||||
#include <invalidargumentexception.h>
|
||||
#include <componentview.h>
|
||||
#include <componentaction.h>
|
||||
#include <qmlobjectnode.h>
|
||||
#include <rewriterview.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <toolbox.h>
|
||||
#include <variantproperty.h>
|
||||
#include <rewritingexception.h>
|
||||
|
||||
@@ -97,6 +97,7 @@ public:
|
||||
QWeakPointer<StatesEditorView> statesEditorView;
|
||||
QWeakPointer<QStackedWidget> stackedWidget;
|
||||
QWeakPointer<NodeInstanceView> nodeInstanceView;
|
||||
QWeakPointer<ComponentView> componentView;
|
||||
|
||||
QWeakPointer<QmlDesigner::Model> model;
|
||||
QWeakPointer<QmlDesigner::Model> subComponentModel;
|
||||
@@ -112,7 +113,6 @@ public:
|
||||
QUrl searchPath;
|
||||
bool documentLoaded;
|
||||
bool syncBlocked;
|
||||
QWeakPointer<ComponentAction> componentAction;
|
||||
|
||||
};
|
||||
|
||||
@@ -256,6 +256,12 @@ void DesignDocumentController::setNodeInstanceView(NodeInstanceView *nodeInstanc
|
||||
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
|
||||
{
|
||||
if (fileName().isEmpty())
|
||||
@@ -331,6 +337,8 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit *
|
||||
|
||||
loadCurrentModel();
|
||||
|
||||
m_d->masterModel->attachView(m_d->componentView.data());
|
||||
|
||||
return m_d->rewriterView->errors();
|
||||
}
|
||||
|
||||
@@ -340,6 +348,17 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo
|
||||
QWeakPointer<Model> oldModel = m_d->model;
|
||||
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) {
|
||||
//change back to master model
|
||||
m_d->model->detachView(m_d->rewriterView.data());
|
||||
@@ -356,10 +375,20 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo
|
||||
if (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);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -392,21 +421,11 @@ void DesignDocumentController::loadCurrentModel()
|
||||
m_d->model->attachView(m_d->navigator.data());
|
||||
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&)));
|
||||
|
||||
m_d->model->attachView(m_d->formEditorView.data());
|
||||
m_d->model->attachView(m_d->itemLibraryView.data());
|
||||
|
||||
|
||||
if (!m_d->textEdit->parent()) // hack to prevent changing owner of external text edit
|
||||
m_d->stackedWidget->addWidget(m_d->textEdit.data());
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ class QmlObjectNode;
|
||||
class RewriterView;
|
||||
class ItemLibraryView;
|
||||
class NavigatorView;
|
||||
class ComponentView;
|
||||
class PropertyEditor;
|
||||
class StatesEditorView;
|
||||
class FormEditorView;
|
||||
@@ -98,6 +99,7 @@ public:
|
||||
void setStatesEditorView(StatesEditorView* statesEditorView);
|
||||
void setFormEditorView(FormEditorView *formEditorView);
|
||||
void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
|
||||
void setComponentView(ComponentView *componentView);
|
||||
|
||||
signals:
|
||||
void displayNameChanged(const QString &newFileName);
|
||||
|
||||
@@ -39,7 +39,7 @@ ComponentTextModifier::ComponentTextModifier(TextModifier *originalModifier, int
|
||||
m_componentEndOffset(componentEndOffset),
|
||||
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(replaced(int, int, int)), this, SIGNAL(replaced(int, int, int)));
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
#include <formeditorwidget.h>
|
||||
#include <stateseditorwidget.h>
|
||||
#include <itemlibrarywidget.h>
|
||||
|
||||
#include <componentaction.h>
|
||||
#include <toolbox.h>
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
@@ -312,6 +313,7 @@ void DesignModeWidget::showEditor(Core::IEditor *editor)
|
||||
newDocument->setStatesEditorView(m_statesEditorView.data());
|
||||
newDocument->setItemLibraryView(m_itemLibraryView.data());
|
||||
newDocument->setFormEditorView(m_formEditorView.data());
|
||||
newDocument->setComponentView(m_componentView.data());
|
||||
|
||||
|
||||
newDocument->setFileName(fileName);
|
||||
@@ -674,6 +676,8 @@ void DesignModeWidget::setup()
|
||||
|
||||
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_mainSplitter = new MiniSplitter(this);
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <navigatorwidget.h>
|
||||
#include <navigatorview.h>
|
||||
#include <stateseditorview.h>
|
||||
#include <componentview.h>
|
||||
#include <modelnode.h>
|
||||
#include <formeditorview.h>
|
||||
#include <propertyeditor.h>
|
||||
@@ -185,6 +186,7 @@ private:
|
||||
QWeakPointer<PropertyEditor> m_propertyEditorView;
|
||||
QWeakPointer<StatesEditorView> m_statesEditorView;
|
||||
QWeakPointer<FormEditorView> m_formEditorView;
|
||||
QWeakPointer<ComponentView> m_componentView;
|
||||
QWeakPointer<NodeInstanceView> m_nodeInstanceView;
|
||||
|
||||
bool m_syncWithTextEdit;
|
||||
|
||||
Reference in New Issue
Block a user