QmlDesigner: Add Move to Component to the designer

This allows the creation of components from existing code in the designer.

Change-Id: I2a0e45fca64c4ddbce6d594d40e683600b7fec32
Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
Thomas Hartmann
2016-05-02 10:57:05 +02:00
parent b98715a0b2
commit d25b88c304
11 changed files with 66 additions and 0 deletions

View File

@@ -72,6 +72,7 @@ const char resetPositionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMen
const char goIntoComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Go into Component");
const char goToImplementationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Go to Implementation");
const char moveToComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Move to Component");
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");

View File

@@ -510,6 +510,8 @@ void DesignerActionManager::createDefaultDesignerActions()
(goIntoComponentDisplayName, rootCategory, priorityGoIntoComponent, &goIntoComponent, &selectionIsComponent));
addDesignerAction(new ModelNodeAction
(goToImplementationDisplayName, rootCategory, 42, &gotoImplementation, &singleSelectedAndUiFile, &singleSelectedAndUiFile));
addDesignerAction(new ModelNodeAction
(moveToComponentDisplayName, rootCategory, 44, &moveToComponent, &singleSelection, &singleSelection));
}

View File

@@ -773,6 +773,16 @@ void removePositioner(const SelectionContext &selectionContext)
removeLayout(selectionContext);
}
void moveToComponent(const SelectionContext &selectionContext)
{
ModelNode modelNode;
if (selectionContext.singleNodeIsSelected())
modelNode = selectionContext.selectedModelNodes().first();
if (modelNode.isValid())
selectionContext.view()->model()->rewriterView()->moveToComponent(modelNode);
}
} // namespace Mode
} //QmlDesigner

View File

@@ -66,6 +66,7 @@ void layoutGridLayout(const SelectionContext &selectionState);
void gotoImplementation(const SelectionContext &selectionState);
void removeLayout(const SelectionContext &selectionContext);
void removePositioner(const SelectionContext &selectionContext);
void moveToComponent(const SelectionContext &selectionContext);
} // namespace ModelNodeOperationso

View File

@@ -46,6 +46,7 @@ public:
virtual int indentDepth() const;
virtual bool renameId(const QString &oldId, const QString &newId);
virtual bool moveToComponent(int nodeOffset);
};
} // namespace QmlDesigner

View File

@@ -54,6 +54,7 @@ public:
virtual void reactivateChangeSignals();
virtual bool renameId(const QString & /* oldId */, const QString & /* newId */) { return false; }
virtual bool moveToComponent(int /* nodeOffset */) { return false; }
public slots:
void contentsChange(int position, int charsRemoved, int charsAdded);

View File

@@ -69,6 +69,7 @@ public:
virtual void reactivateChangeSignals();
virtual bool renameId(const QString & /* oldId */, const QString & /* newId */) { return false; }
virtual bool moveToComponent(int /* nodeOffset */) { return false; }
protected:
QPlainTextEdit *plainTextEdit() const

View File

@@ -176,6 +176,8 @@ public:
QSet<QPair<QString, QString> > qrcMapping() const;
void moveToComponent(const ModelNode &modelNode);
signals:
void errorsChanged(const QList<RewriterError> &errors);

View File

@@ -82,6 +82,8 @@ public:
virtual bool renameId(const QString &oldId, const QString &newId) = 0;
virtual bool moveToComponent(int nodeOffset) = 0;
signals:
void textChanged();

View File

@@ -26,11 +26,15 @@
#include "basetexteditmodifier.h"
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljs/parser/qmljsast_p.h>
#include <qmljstools/qmljsindenter.h>
#include <qmljseditor/qmljseditordocument.h>
#include <qmljseditor/qmljscomponentfromobjectdef.h>
#include <texteditor/tabsettings.h>
#include <utils/changeset.h>
#include <typeinfo>
using namespace QmlDesigner;
BaseTextEditModifier::BaseTextEditModifier(TextEditor::TextEditorWidget *textEdit):
@@ -100,3 +104,37 @@ bool BaseTextEditModifier::renameId(const QString &oldId, const QString &newId)
}
return false;
}
static QmlJS::AST::UiObjectDefinition *getObjectDefinition(QList<QmlJS::AST::Node *> path, QmlJS::AST::UiQualifiedId *qualifiedId)
{
QmlJS::AST::UiObjectDefinition *object = 0;
for (int i = path.size() - 1; i >= 0; --i) {
auto node = path.at(i);
if (auto objDef = QmlJS::AST::cast<QmlJS::AST::UiObjectDefinition *>(node)) {
if (objDef->qualifiedTypeNameId == qualifiedId)
object = objDef;
}
}
return object;
}
bool BaseTextEditModifier::moveToComponent(int nodeOffset)
{
if (TextEditor::TextEditorWidget *bte = qobject_cast<TextEditor::TextEditorWidget*>(plainTextEdit())) {
if (QmlJSEditor::QmlJSEditorDocument *document
= qobject_cast<QmlJSEditor::QmlJSEditorDocument *>(bte->textDocument())) {
auto *qualifiedId = QmlJS::AST::cast<QmlJS::AST::UiQualifiedId *>(document->semanticInfo().astNodeAt(nodeOffset));
QList<QmlJS::AST::Node *> path = document->semanticInfo().rangePath(nodeOffset);
QmlJS::AST::UiObjectDefinition *object = getObjectDefinition(path, qualifiedId);
if (!object)
return false;
QmlJSEditor::ComponentFromObjectDef::perform(document->filePath().toString(), object);
return true;
}
}
return false;
}

View File

@@ -715,6 +715,13 @@ QSet<QPair<QString, QString> > RewriterView::qrcMapping() const
return m_textToModelMerger->qrcMapping();
}
void RewriterView::moveToComponent(const ModelNode &modelNode)
{
int offset = nodeOffset(modelNode);
textModifier()->moveToComponent(offset);
}
void RewriterView::qmlTextChanged()
{
if (inErrorState())