From fd9b74dbbbba2e62b7c9358e6d63d1bfe51a1818 Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@nokia.com> Date: Tue, 6 Jul 2010 11:09:16 +0200 Subject: [PATCH] Improve translation quickfix * Use tr if a tr method is available at the object * Use QT_TRANSLATE_NOOP for global string constants * Do not offer to translate stuff inside QLatin1String and QLatin1Literal * Do not offer to wrap strings inside tr, trUtf8 and QT_TRANSLATE_NOOP with QLatin1String --- src/plugins/cppeditor/cppquickfix.cpp | 111 +++++++++++++------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp index 5ad8e5f1faf..29dc9ed1b6e 100644 --- a/src/plugins/cppeditor/cppquickfix.cpp +++ b/src/plugins/cppeditor/cppquickfix.cpp @@ -46,6 +46,7 @@ #include <Symbol.h> #include <Symbols.h> #include <Name.h> +#include <Names.h> #include <Literals.h> #include <cppeditor/cpprefactoringchanges.h> @@ -813,7 +814,8 @@ public: if (SimpleNameAST *functionName = call->base_expression->asSimpleName()) { const QByteArray id(tokenAt(functionName->identifier_token).identifier->chars()); - if ((type == TypeString && (id == "QLatin1String" || id == "QLatin1Literal")) + if (id == "QT_TRANSLATE_NOOP" || id == "tr" || id == "trUtf8" + || (type == TypeString && (id == "QLatin1String" || id == "QLatin1Literal")) || (type == TypeChar && id == "QLatin1Char")) return -1; // skip it } @@ -856,7 +858,8 @@ private: "abcd" With tr("abcd") or - QCoreApplication::translate("CONTEXT", "abcd") + QCoreApplication::translate("CONTEXT", "abcd") or + QT_TRANSLATE_NOOP("GLOBAL", "abcd") */ class TranslateStringLiteral: public CppQuickFixOperation { @@ -865,7 +868,7 @@ public: : CppQuickFixOperation(editor), m_literal(0) { } - enum TranslationOption { unknown, useTr, useQCoreApplicationTranslate }; + enum TranslationOption { unknown, useTr, useQCoreApplicationTranslate, useMacro }; virtual QString description() const { @@ -880,73 +883,69 @@ public: m_context.clear(); if (path.isEmpty()) - return -1; // nothing to do + return -1; m_literal = path.last()->asStringLiteral(); if (!m_literal) - return -1; // nothing to do + return -1; // No string, nothing to do - if (path.size() > 1) { + // Do we already have a translation markup? + if (path.size() >= 2) { if (CallAST *call = path.at(path.size() - 2)->asCall()) { if (call->base_expression) { if (SimpleNameAST *functionName = call->base_expression->asSimpleName()) { const QByteArray id(tokenAt(functionName->identifier_token).identifier->chars()); if (id == "tr" || id == "trUtf8" - || id == "QApplication::translate" - || id == "QCoreApplication::translate") + || id == "translate" + || id == "QT_TRANSLATE_NOOP" + || id == "QLatin1String" || id == "QLatin1Literal") return -1; // skip it } } } - for (int i = path.size() - 1; i >= 0; --i) - { - if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) { - Function *function = definition->symbol; - LookupContext context(document(), snapshot()); - - ClassOrNamespace *b = context.lookupType(function); - if (b) { - QList<ClassOrNamespace *> todo; - todo.append(b); - QSet<ClassOrNamespace *> done; - while(!todo.isEmpty()) { - ClassOrNamespace *current = todo.first(); - todo.removeFirst(); - if (done.contains(current)) - continue; - done.insert(current); - foreach (Symbol *s, current->symbols()) { - if (Class *klass = s->asClass()) { - if (strcmp(klass->name()->identifier()->chars(), - "QObject") == 0) { - m_option = useTr; - return path.size() - 1; - } - } - } - todo.append(current->usings()); - } - } - // We need to do a QCA::translate, so we need a context. - // Use fully qualified class name: - - Overview oo; - foreach (const Name *n, LookupContext::fullyQualifiedName(function)) { - if (! m_context.isEmpty()) - m_context.append(QLatin1String("::")); + } - m_context.append(oo.prettyName(n)); + LookupContext context(document(), snapshot()); + QSharedPointer<Control> control = context.control(); + const Name *trName = control->nameId(control->findOrInsertIdentifier("tr")); + + // Check whether we are in a method: + for (int i = path.size() - 1; i >= 0; --i) + { + if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) { + Function *function = definition->symbol; + ClassOrNamespace *b = context.lookupType(function); + if (b) { + // Do we have a tr method? + foreach(Symbol *s, b->find(trName)) { + if (s->type()->isFunctionType()) { + m_option = useTr; + // no context required for tr + return path.size() - 1; + } } - - if (m_context.isEmpty()) - m_context.append("GLOBAL"); } + // We need to do a QCA::translate, so we need a context. + // Use fully qualified class name: + Overview oo; + foreach (const Name *n, LookupContext::fullyQualifiedName(function)) { + if (!m_context.isEmpty()) + m_context.append(QLatin1String("::")); + m_context.append(oo.prettyName(n)); + } + // ... or global if none available! + if (m_context.isEmpty()) + m_context = QLatin1String("GLOBAL"); + m_option = useQCoreApplicationTranslate; + return path.size() - 1; } } - m_option = useQCoreApplicationTranslate; - return path.size() - 1; // very high priority + // We need to use Q_TRANSLATE_NOOP + m_context = QLatin1String("GLOBAL"); + m_option = useMacro; + return path.size() - 1; } virtual void createChanges() @@ -954,11 +953,13 @@ public: ChangeSet changes; const int startPos = startOf(m_literal); - QString replacement("tr("); + QString replacement(QLatin1String("tr(")); if (m_option == useQCoreApplicationTranslate) { - replacement = QLatin1String("QCoreApplication::translate(\""); - replacement += m_context; - replacement += QLatin1String("\", "); + replacement = QLatin1String("QCoreApplication::translate(\"") + + m_context + QLatin1String("\", "); + } else if (m_option == useMacro) { + replacement = QLatin1String("QT_TRANSLATE_NOOP(\"") + + m_context + QLatin1String("\", "); } changes.insert(startPos, replacement); @@ -970,7 +971,7 @@ public: private: ExpressionAST *m_literal; TranslationOption m_option; - QString m_context; + QString m_context; }; class CStringToNSString: public CppQuickFixOperation -- GitLab