forked from qt-creator/qt-creator
QmlDesigner: Fix copy / paste bug
Fix a bug in calculating the scatter value when pasting an object. Also some tweaks and clean ups in the same file. Fixes: QDS-2982 Change-Id: Ic2847d03ccf03d188c5fbca2cd14bc74b9d20223 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -217,6 +217,7 @@ Utils::FilePath DesignDocument::fileName() const
|
|||||||
{
|
{
|
||||||
if (editor())
|
if (editor())
|
||||||
return editor()->document()->filePath();
|
return editor()->document()->filePath();
|
||||||
|
|
||||||
return Utils::FilePath();
|
return Utils::FilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,14 +240,11 @@ void DesignDocument::loadDocument(QPlainTextEdit *edit)
|
|||||||
{
|
{
|
||||||
Q_CHECK_PTR(edit);
|
Q_CHECK_PTR(edit);
|
||||||
|
|
||||||
connect(edit, &QPlainTextEdit::undoAvailable,
|
connect(edit, &QPlainTextEdit::undoAvailable, this, &DesignDocument::undoAvailable);
|
||||||
this, &DesignDocument::undoAvailable);
|
connect(edit, &QPlainTextEdit::redoAvailable, this, &DesignDocument::redoAvailable);
|
||||||
connect(edit, &QPlainTextEdit::redoAvailable,
|
connect(edit, &QPlainTextEdit::modificationChanged, this, &DesignDocument::dirtyStateChanged);
|
||||||
this, &DesignDocument::redoAvailable);
|
|
||||||
connect(edit, &QPlainTextEdit::modificationChanged,
|
|
||||||
this, &DesignDocument::dirtyStateChanged);
|
|
||||||
|
|
||||||
m_documentTextModifier.reset(new BaseTextEditModifier(dynamic_cast<TextEditor::TextEditorWidget*>(plainTextEdit())));
|
m_documentTextModifier.reset(new BaseTextEditModifier(qobject_cast<TextEditor::TextEditorWidget *>(plainTextEdit())));
|
||||||
|
|
||||||
connect(m_documentTextModifier.data(), &TextModifier::textChanged, this, &DesignDocument::updateQrcFiles);
|
connect(m_documentTextModifier.data(), &TextModifier::textChanged, this, &DesignDocument::updateQrcFiles);
|
||||||
|
|
||||||
@@ -266,7 +264,6 @@ void DesignDocument::changeToDocumentModel()
|
|||||||
viewManager().detachRewriterView();
|
viewManager().detachRewriterView();
|
||||||
viewManager().detachViewsExceptRewriterAndComponetView();
|
viewManager().detachViewsExceptRewriterAndComponetView();
|
||||||
|
|
||||||
|
|
||||||
m_inFileComponentModel.reset();
|
m_inFileComponentModel.reset();
|
||||||
|
|
||||||
viewManager().attachRewriterView();
|
viewManager().attachRewriterView();
|
||||||
@@ -299,7 +296,8 @@ void DesignDocument::updateQrcFiles()
|
|||||||
ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName());
|
ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName());
|
||||||
|
|
||||||
if (currentProject) {
|
if (currentProject) {
|
||||||
for (const Utils::FilePath &fileName : currentProject->files(ProjectExplorer::Project::SourceFiles)) {
|
const auto srcFiles = currentProject->files(ProjectExplorer::Project::SourceFiles);
|
||||||
|
for (const Utils::FilePath &fileName : srcFiles) {
|
||||||
if (fileName.endsWith(".qrc"))
|
if (fileName.endsWith(".qrc"))
|
||||||
QmlJS::ModelManagerInterface::instance()->updateQrcFile(fileName.toString());
|
QmlJS::ModelManagerInterface::instance()->updateQrcFile(fileName.toString());
|
||||||
}
|
}
|
||||||
@@ -350,6 +348,7 @@ bool DesignDocument::isUndoAvailable() const
|
|||||||
{
|
{
|
||||||
if (plainTextEdit())
|
if (plainTextEdit())
|
||||||
return plainTextEdit()->document()->isUndoAvailable();
|
return plainTextEdit()->document()->isUndoAvailable();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,6 +356,7 @@ bool DesignDocument::isRedoAvailable() const
|
|||||||
{
|
{
|
||||||
if (plainTextEdit())
|
if (plainTextEdit())
|
||||||
return plainTextEdit()->document()->isRedoAvailable();
|
return plainTextEdit()->document()->isRedoAvailable();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,8 +409,7 @@ void DesignDocument::deleteSelected()
|
|||||||
}
|
}
|
||||||
|
|
||||||
rewriterView()->executeInTransaction("DesignDocument::deleteSelected", [this]() {
|
rewriterView()->executeInTransaction("DesignDocument::deleteSelected", [this]() {
|
||||||
QList<ModelNode> toDelete = view()->selectedModelNodes();
|
const QList<ModelNode> toDelete = view()->selectedModelNodes();
|
||||||
|
|
||||||
for (ModelNode node : toDelete) {
|
for (ModelNode node : toDelete) {
|
||||||
if (node.isValid() && !node.isRootNode() && QmlObjectNode::isValidQmlObjectNode(node))
|
if (node.isValid() && !node.isRootNode() && QmlObjectNode::isValidQmlObjectNode(node))
|
||||||
QmlObjectNode(node).destroy();
|
QmlObjectNode(node).destroy();
|
||||||
@@ -442,32 +441,33 @@ static void scatterItem(const ModelNode &pastedNode, const ModelNode &targetNode
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
bool scatter = false;
|
bool scatter = false;
|
||||||
foreach (const ModelNode &childNode, targetNode.directSubModelNodes()) {
|
for (const ModelNode &childNode : targetNode.directSubModelNodes()) {
|
||||||
if ((childNode.variantProperty("x").value() == pastedNode.variantProperty("x").value()) &&
|
if (childNode.variantProperty("x").value() == pastedNode.variantProperty("x").value() &&
|
||||||
(childNode.variantProperty("y").value() == pastedNode.variantProperty("y").value()))
|
childNode.variantProperty("y").value() == pastedNode.variantProperty("y").value()) {
|
||||||
scatter = true;
|
scatter = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!scatter)
|
if (!scatter)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (offset == -2000) {
|
if (offset == -2000) { // scatter in range
|
||||||
double x = pastedNode.variantProperty("x").value().toDouble();
|
double x = pastedNode.variantProperty("x").value().toDouble();
|
||||||
double y = pastedNode.variantProperty("y").value().toDouble();
|
double y = pastedNode.variantProperty("y").value().toDouble();
|
||||||
double targetWidth = 20;
|
|
||||||
double targetHeight = 20;
|
const double scatterRange = 20.;
|
||||||
x = x + double(QRandomGenerator::global()->generate()) / RAND_MAX * targetWidth
|
x += QRandomGenerator::global()->generateDouble() * scatterRange - scatterRange / 2;
|
||||||
- targetWidth / 2;
|
y += QRandomGenerator::global()->generateDouble() * scatterRange - scatterRange / 2;
|
||||||
y = y + double(QRandomGenerator::global()->generate()) / RAND_MAX * targetHeight
|
|
||||||
- targetHeight / 2;
|
|
||||||
pastedNode.variantProperty("x").setValue(int(x));
|
|
||||||
pastedNode.variantProperty("y").setValue(int(y));
|
|
||||||
} else {
|
|
||||||
double x = pastedNode.variantProperty("x").value().toDouble();
|
|
||||||
double y = pastedNode.variantProperty("y").value().toDouble();
|
|
||||||
x = x + offset;
|
|
||||||
y = y + offset;
|
|
||||||
pastedNode.variantProperty("x").setValue(int(x));
|
pastedNode.variantProperty("x").setValue(int(x));
|
||||||
pastedNode.variantProperty("y").setValue(int(y));
|
pastedNode.variantProperty("y").setValue(int(y));
|
||||||
|
} else { // offset
|
||||||
|
int x = pastedNode.variantProperty("x").value().toInt();
|
||||||
|
int y = pastedNode.variantProperty("y").value().toInt();
|
||||||
|
x += offset;
|
||||||
|
y += offset;
|
||||||
|
pastedNode.variantProperty("x").setValue(x);
|
||||||
|
pastedNode.variantProperty("y").setValue(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +495,7 @@ void DesignDocument::paste()
|
|||||||
if (!view.selectedModelNodes().isEmpty())
|
if (!view.selectedModelNodes().isEmpty())
|
||||||
targetNode = view.selectedModelNodes().constFirst();
|
targetNode = view.selectedModelNodes().constFirst();
|
||||||
|
|
||||||
//In case we copy and paste a selection we paste in the parent item
|
// in case we copy and paste a selection we paste in the parent item
|
||||||
if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) {
|
if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) {
|
||||||
targetNode = targetNode.parentProperty().parentModelNode();
|
targetNode = targetNode.parentProperty().parentModelNode();
|
||||||
} else {
|
} else {
|
||||||
@@ -516,8 +516,8 @@ void DesignDocument::paste()
|
|||||||
if (!targetNode.isValid())
|
if (!targetNode.isValid())
|
||||||
targetNode = view.rootModelNode();
|
targetNode = view.rootModelNode();
|
||||||
|
|
||||||
foreach (const ModelNode &node, selectedNodes) {
|
for (const ModelNode &node : qAsConst(selectedNodes)) {
|
||||||
foreach (const ModelNode &node2, selectedNodes) {
|
for (const ModelNode &node2 : qAsConst(selectedNodes)) {
|
||||||
if (node.isAncestorOf(node2))
|
if (node.isAncestorOf(node2))
|
||||||
selectedNodes.removeAll(node2);
|
selectedNodes.removeAll(node2);
|
||||||
}
|
}
|
||||||
@@ -526,9 +526,10 @@ void DesignDocument::paste()
|
|||||||
rewriterView()->executeInTransaction("DesignDocument::paste1", [&view, selectedNodes, targetNode]() {
|
rewriterView()->executeInTransaction("DesignDocument::paste1", [&view, selectedNodes, targetNode]() {
|
||||||
QList<ModelNode> pastedNodeList;
|
QList<ModelNode> pastedNodeList;
|
||||||
|
|
||||||
int offset = double(QRandomGenerator::global()->generate()) / RAND_MAX * 20 - 10;
|
const double scatterRange = 20.;
|
||||||
|
int offset = QRandomGenerator::global()->generateDouble() * scatterRange - scatterRange / 2;
|
||||||
|
|
||||||
foreach (const ModelNode &node, selectedNodes) {
|
for (const ModelNode &node : qAsConst(selectedNodes)) {
|
||||||
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
|
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
|
||||||
ModelNode pastedNode(view.insertModel(node));
|
ModelNode pastedNode(view.insertModel(node));
|
||||||
pastedNodeList.append(pastedNode);
|
pastedNodeList.append(pastedNode);
|
||||||
@@ -572,11 +573,11 @@ void DesignDocument::paste()
|
|||||||
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
|
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
|
||||||
|
|
||||||
scatterItem(pastedNode, targetNode);
|
scatterItem(pastedNode, targetNode);
|
||||||
if (targetNode.metaInfo().propertyIsListProperty(defaultProperty)) {
|
if (targetNode.metaInfo().propertyIsListProperty(defaultProperty))
|
||||||
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
|
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
|
||||||
} else {
|
else
|
||||||
qWarning() << "Cannot reparent to" << targetNode;
|
qWarning() << "Cannot reparent to" << targetNode;
|
||||||
}
|
|
||||||
view.setSelectedModelNodes({pastedNode});
|
view.setSelectedModelNodes({pastedNode});
|
||||||
});
|
});
|
||||||
view.model()->clearMetaInfoCache();
|
view.model()->clearMetaInfoCache();
|
||||||
@@ -591,7 +592,6 @@ void DesignDocument::selectAll()
|
|||||||
DesignDocumentView view;
|
DesignDocumentView view;
|
||||||
currentModel()->attachView(&view);
|
currentModel()->attachView(&view);
|
||||||
|
|
||||||
|
|
||||||
QList<ModelNode> allNodesExceptRootNode(view.allModelNodes());
|
QList<ModelNode> allNodesExceptRootNode(view.allModelNodes());
|
||||||
allNodesExceptRootNode.removeOne(view.rootModelNode());
|
allNodesExceptRootNode.removeOne(view.rootModelNode());
|
||||||
view.setSelectedModelNodes(allNodesExceptRootNode);
|
view.setSelectedModelNodes(allNodesExceptRootNode);
|
||||||
@@ -607,7 +607,6 @@ void DesignDocument::setEditor(Core::IEditor *editor)
|
|||||||
m_textEditor = editor;
|
m_textEditor = editor;
|
||||||
// if the user closed the file explicit we do not want to do anything with it anymore
|
// if the user closed the file explicit we do not want to do anything with it anymore
|
||||||
|
|
||||||
|
|
||||||
connect(Core::EditorManager::instance(), &Core::EditorManager::aboutToSave,
|
connect(Core::EditorManager::instance(), &Core::EditorManager::aboutToSave,
|
||||||
this, [this](Core::IDocument *document) {
|
this, [this](Core::IDocument *document) {
|
||||||
if (m_textEditor && m_textEditor->document() == document) {
|
if (m_textEditor && m_textEditor->document() == document) {
|
||||||
@@ -622,8 +621,7 @@ void DesignDocument::setEditor(Core::IEditor *editor)
|
|||||||
m_textEditor.clear();
|
m_textEditor.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(editor->document(), &Core::IDocument::filePathChanged,
|
connect(editor->document(), &Core::IDocument::filePathChanged, this, &DesignDocument::updateFileName);
|
||||||
this, &DesignDocument::updateFileName);
|
|
||||||
|
|
||||||
updateActiveTarget();
|
updateActiveTarget();
|
||||||
updateActiveTarget();
|
updateActiveTarget();
|
||||||
@@ -678,7 +676,6 @@ static Target *getActiveTarget(DesignDocument *designDocument)
|
|||||||
if (!currentProject)
|
if (!currentProject)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
||||||
QObject::connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
|
QObject::connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
|
||||||
designDocument, &DesignDocument::updateActiveTarget, Qt::UniqueConnection);
|
designDocument, &DesignDocument::updateActiveTarget, Qt::UniqueConnection);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user