summaryrefslogtreecommitdiff
path: root/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp
diff options
context:
space:
mode:
authorThomas Hartmann <Thomas.Hartmann@theqtcompany.com>2016-04-29 10:31:21 +0200
committerThomas Hartmann <Thomas.Hartmann@theqtcompany.com>2016-04-29 08:43:31 +0000
commit5c45e9ec343d8edaddfd0a1f92ca4bc2a307923c (patch)
tree7f8ab18a730d61f48544655a9eb5e97d36cc527d /src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp
parent1ba0e5cdf954a53b383ae3fdcf47233e93d219e8 (diff)
downloadqt-creator-5c45e9ec343d8edaddfd0a1f92ca4bc2a307923c.tar.gz
QmlJSEditor: Improving ComponentFromObjectDef
Now the use can choose which properties are defined inside the component and which properties are kept in the original file. To make the concept clear the dialog contains a snippet of the generated code. Change-Id: I92f9f241c9780345dd03b991232c4a811356c266 Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
Diffstat (limited to 'src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp')
-rw-r--r--src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp79
1 files changed, 70 insertions, 9 deletions
diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp
index ffb7f17321..eca12dc55f 100644
--- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp
+++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp
@@ -35,6 +35,8 @@
#include <qmljs/parser/qmljsast_p.h>
#include <qmljs/qmljsdocument.h>
#include <qmljs/qmljsutils.h>
+#include <qmljs/qmljspropertyreader.h>
+#include <qmljs/qmljsrewriter.h>
#include <qmljstools/qmljsrefactoringchanges.h>
#include <projectexplorer/session.h>
#include <projectexplorer/projectnodes.h>
@@ -61,6 +63,7 @@ class Operation: public QmlJSQuickFixOperation
QString m_idName, m_componentName;
SourceLocation m_firstSourceLocation;
SourceLocation m_lastSourceLocation;
+ UiObjectInitializer *m_initializer;
public:
void init()
{
@@ -78,7 +81,8 @@ public:
: QmlJSQuickFixOperation(interface, 0),
m_idName(idOfObject(objDef)),
m_firstSourceLocation(objDef->firstSourceLocation()),
- m_lastSourceLocation(objDef->lastSourceLocation())
+ m_lastSourceLocation(objDef->lastSourceLocation()),
+ m_initializer(objDef->initializer)
{
init();
}
@@ -88,7 +92,8 @@ public:
: QmlJSQuickFixOperation(interface, 0),
m_idName(idOfObject(objDef)),
m_firstSourceLocation(objDef->qualifiedTypeNameId->firstSourceLocation()),
- m_lastSourceLocation(objDef->lastSourceLocation())
+ m_lastSourceLocation(objDef->lastSourceLocation()),
+ m_initializer(objDef->initializer)
{
init();
}
@@ -98,8 +103,33 @@ public:
{
QString componentName = m_componentName;
QString path = QFileInfo(fileName()).path();
- bool confirm = ComponentNameDialog::go(&componentName, &path, Core::ICore::dialogParent());
+ QmlJS::PropertyReader propertyReader(currentFile->qmljsDocument(), m_initializer);
+ QStringList result;
+ QStringList sourcePreview;
+
+ if (!m_idName.isEmpty())
+ sourcePreview.append(QLatin1String(" id: ") + m_idName);
+ else
+ sourcePreview.append(QString());
+
+ QStringList sortedPropertiesWithoutId;
+
+ foreach (const QString &property, propertyReader.properties())
+ if (property != QLatin1String("id"))
+ sortedPropertiesWithoutId.append(property);
+
+ sortedPropertiesWithoutId.sort();
+
+ foreach (const QString &property, sortedPropertiesWithoutId)
+ sourcePreview.append(QLatin1String(" ") + property + QLatin1String(": ") + propertyReader.readAstValue(property));
+
+ bool confirm = ComponentNameDialog::go(&componentName, &path,
+ sortedPropertiesWithoutId,
+ sourcePreview,
+ QFileInfo(fileName()).fileName(),
+ &result,
+ Core::ICore::dialogParent());
if (!confirm)
return;
@@ -112,18 +142,44 @@ public:
QString imports;
UiProgram *prog = currentFile->qmljsDocument()->qmlProgram();
if (prog && prog->headers) {
- const int start = currentFile->startOf(prog->headers->firstSourceLocation());
- const int end = currentFile->startOf(prog->members->member->firstSourceLocation());
+ const unsigned int start = currentFile->startOf(prog->headers->firstSourceLocation());
+ const unsigned int end = currentFile->startOf(prog->members->member->firstSourceLocation());
imports = currentFile->textOf(start, end);
}
- const int start = currentFile->startOf(m_firstSourceLocation);
- const int end = currentFile->startOf(m_lastSourceLocation);
- const QString txt = imports + currentFile->textOf(start, end)
+ const unsigned int start = currentFile->startOf(m_firstSourceLocation);
+ const unsigned int end = currentFile->startOf(m_lastSourceLocation);
+ QString newComponentSource = imports + currentFile->textOf(start, end)
+ QLatin1String("}\n");
+ //Remove properties from resulting code...
+
+ Utils::ChangeSet changeSet;
+ QmlJS::Rewriter rewriter(newComponentSource, &changeSet, QStringList());
+
+ QmlJS::Dialect dialect = QmlJS::Dialect::Qml;
+
+ QmlJS::Document::MutablePtr doc = QmlJS::Document::create(newFileName, dialect);
+ doc->setSource(newComponentSource);
+ doc->parseQml();
+
+ if (doc->isParsedCorrectly()) {
+
+ UiObjectMember *astRootNode = 0;
+ if (UiProgram *program = doc->qmlProgram())
+ if (program->members)
+ astRootNode = program->members->member;
+
+ foreach (const QString &property, result)
+ rewriter.removeBindingByName(initializerOfObject(astRootNode), property);
+ } else {
+ qWarning() << Q_FUNC_INFO << "parsing failed:" << newComponentSource;
+ }
+
+ changeSet.apply(&newComponentSource);
+
// stop if we can't create the new file
- if (!refactoring.createFile(newFileName, txt))
+ if (!refactoring.createFile(newFileName, newComponentSource))
return;
if (path == QFileInfo(fileName()).path()) {
@@ -151,10 +207,14 @@ public:
Core::VcsManager::msgToAddToVcsFailed(QStringList(newFileName), versionControl));
}
}
+
QString replacement = componentName + QLatin1String(" {\n");
if (!m_idName.isEmpty())
replacement += QLatin1String("id: ") + m_idName + QLatin1Char('\n');
+ foreach (const QString &property, result)
+ replacement += property + QLatin1String(": ") + propertyReader.readAstValue(property) + QLatin1Char('\n');
+
Utils::ChangeSet changes;
changes.replace(start, end, replacement);
currentFile->setChangeSet(changes);
@@ -174,6 +234,7 @@ void ComponentFromObjectDef::match(const QmlJSQuickFixInterface &interface, Quic
for (int i = path.size() - 1; i >= 0; --i) {
Node *node = path.at(i);
if (UiObjectDefinition *objDef = cast<UiObjectDefinition *>(node)) {
+
if (!interface->currentFile()->isCursorOn(objDef->qualifiedTypeNameId))
return;
// check that the node is not the root node