From 3c36e7785853fd11373a2018e514534b72a4826a Mon Sep 17 00:00:00 2001 From: Aleksei German Date: Thu, 11 May 2023 12:00:19 +0200 Subject: [PATCH] QmlDesigner: Fix some escape characters Task-number: QDS-9415 Change-Id: I6459451d0f7699c727b2e0baad726f5c6af2ca74 Reviewed-by: Reviewed-by: Thomas Hartmann --- .../imports/HelperWidgets/LineEdit.qml | 2 +- src/plugins/qmldesigner/CMakeLists.txt | 1 + .../designercore/include/stringutils.h | 42 +++++++++++++++++++ .../designercore/model/qmlobjectnode.cpp | 15 ++++--- .../designercore/model/qmltextgenerator.cpp | 34 ++++----------- .../designercore/model/qmltextgenerator.h | 2 - 6 files changed, 60 insertions(+), 36 deletions(-) create mode 100644 src/plugins/qmldesigner/designercore/include/stringutils.h diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml index b73bde29310..dffe3d779ea 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml @@ -40,7 +40,7 @@ StudioControls.TextField { function escapeString(string) { var str = string str = str.replace(/\\/g, "\\\\") - str.replace(/\"/g, "\\\"") + str = str.replace(/\"/g, "\\\"") str = str.replace(/\t/g, "\\t") str = str.replace(/\r/g, "\\r") str = str.replace(/\n/g, '\\n') diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 4913ac79eed..16668bf3281 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -252,6 +252,7 @@ extend_qtc_library(QmlDesignerCore rewriterview.h rewritingexception.h signalhandlerproperty.h + stringutils.h stylesheetmerger.h subcomponentmanager.h synchronousimagecache.h diff --git a/src/plugins/qmldesigner/designercore/include/stringutils.h b/src/plugins/qmldesigner/designercore/include/stringutils.h new file mode 100644 index 00000000000..38c3c260a97 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/include/stringutils.h @@ -0,0 +1,42 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace QmlDesigner { + +inline QString escape(const QString &value) +{ + QString result = value; + + if (value.length() == 6 && value.startsWith("\\u")) //Do not double escape unicode chars + return value; + + result.replace(QStringLiteral("\\"), QStringLiteral("\\\\")); + result.replace(QStringLiteral("\""), QStringLiteral("\\\"")); + result.replace(QStringLiteral("\t"), QStringLiteral("\\t")); + result.replace(QStringLiteral("\r"), QStringLiteral("\\r")); + result.replace(QStringLiteral("\n"), QStringLiteral("\\n")); + + return result; +} + +inline QString deescape(const QString &value) +{ + QString result = value; + + if (value.length() == 6 && value.startsWith("\\u")) //Ignore unicode chars + return value; + + result.replace(QStringLiteral("\\\\"), QStringLiteral("\\")); + result.replace(QStringLiteral("\\\""), QStringLiteral("\"")); + result.replace(QStringLiteral("\\t"), QStringLiteral("\t")); + result.replace(QStringLiteral("\\r"), QStringLiteral("\r")); + result.replace(QStringLiteral("\\n"), QStringLiteral("\n")); + + return result; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index 118d1c1acc6..b2694b9951d 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -14,6 +14,7 @@ #include "qmlstate.h" #include "qmltimelinekeyframegroup.h" #include "qmlvisualnode.h" +#include "stringutils.h" #include "variantproperty.h" #include @@ -256,7 +257,7 @@ QString QmlObjectNode::stripedTranslatableText(const PropertyName &name) const const QRegularExpressionMatch match = regularExpressionPattern.match( modelNode().bindingProperty(name).expression()); if (match.hasMatch()) - return match.captured(2); + return deescape(match.captured(2)); return instanceValue(name).toString(); } return instanceValue(name).toString(); @@ -536,15 +537,17 @@ QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, const Property QString QmlObjectNode::generateTranslatableText([[maybe_unused]] const QString &text, const DesignerSettings &settings) { + const QString escapedText = escape(text); + if (settings.value(DesignerSettingsKey::TYPE_OF_QSTR_FUNCTION).toInt()) switch (settings.value(DesignerSettingsKey::TYPE_OF_QSTR_FUNCTION).toInt()) { - case 0: return QString(QStringLiteral("qsTr(\"%1\")")).arg(text); - case 1: return QString(QStringLiteral("qsTrId(\"%1\")")).arg(text); - case 2: return QString(QStringLiteral("qsTranslate(\"%1\", \"context\")")).arg(text); + case 0: return QString(QStringLiteral("qsTr(\"%1\")")).arg(escapedText); + case 1: return QString(QStringLiteral("qsTrId(\"%1\")")).arg(escapedText); + case 2: return QString(QStringLiteral("qsTranslate(\"%1\", \"context\")")).arg(escapedText); default: break; } - return QString(QStringLiteral("qsTr(\"%1\")")).arg(text); + return QString(QStringLiteral("qsTr(\"%1\")")).arg(escapedText); } QString QmlObjectNode::stripedTranslatableTextFunction(const QString &text) @@ -553,7 +556,7 @@ QString QmlObjectNode::stripedTranslatableTextFunction(const QString &text) QLatin1String("^qsTr(|Id|anslate)\\(\"(.*)\"\\)$")); const QRegularExpressionMatch match = regularExpressionPattern.match(text); if (match.hasMatch()) - return match.captured(2); + return deescape(match.captured(2)); return text; } diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp index c283bf5b269..bcf22aa3f04 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp @@ -3,19 +3,20 @@ #include "qmltextgenerator.h" -#include #include -#include -#include +#include #include +#include +#include #include "bindingproperty.h" -#include "signalhandlerproperty.h" -#include "nodeproperty.h" +#include "model.h" #include "nodelistproperty.h" +#include "nodeproperty.h" +#include "signalhandlerproperty.h" +#include "stringutils.h" #include "variantproperty.h" #include -#include "model.h" using namespace QmlDesigner; using namespace QmlDesigner::Internal; @@ -114,13 +115,9 @@ QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDept if (property.name() == "id") return stringValue; - - if (false) { - } if (variantProperty.holdsEnumeration()) { return variantProperty.enumeration().toString(); } else { - switch (value.userType()) { case QMetaType::Bool: if (value.toBool()) @@ -284,20 +281,3 @@ QString QmlTextGenerator::propertyToQml(const AbstractProperty &property, int in return result; } - -QString QmlTextGenerator::escape(const QString &value) -{ - QString result = value; - - if (value.count() == 6 && value.startsWith("\\u")) //Do not dobule escape unicode chars - return result; - - result.replace(QStringLiteral("\\"), QStringLiteral("\\\\")); - - result.replace(QStringLiteral("\""), QStringLiteral("\\\"")); - result.replace(QStringLiteral("\t"), QStringLiteral("\\t")); - result.replace(QStringLiteral("\r"), QStringLiteral("\\r")); - result.replace(QStringLiteral("\n"), QStringLiteral("\\n")); - - return result; -} diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.h b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.h index 6b114ebe1bf..971d6a2d1d0 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.h +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.h @@ -32,8 +32,6 @@ private: QString propertiesToQml(const ModelNode &node, int indentDepth) const; QString propertyToQml(const AbstractProperty &property, int indentDepth) const; - static QString escape(const QString &value); - private: PropertyNameList m_propertyOrder; TextEditor::TabSettings m_tabSettings;