From 973119c4e38b4c9ce1fb589d8fa71adcf9e2f813 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 12 Apr 2023 17:11:06 +0200 Subject: lrelease: Report all occurrences of duplicates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before, lrelease reported only the line number of the first of duplicated messages. To actually resolve the duplicates the user must know the occurrences of all duplicated messages. Now, lrelease reports the line numbers of all duplicated messages. Change-Id: I19836f54dcaa9b1d22a9e3e708f830769c50bff2 Reviewed-by: Kai Köhne --- src/linguist/linguist/messagemodel.cpp | 8 +++--- src/linguist/shared/translator.cpp | 31 +++++++++++++++------- src/linguist/shared/translator.h | 8 +++++- tests/auto/linguist/lrelease/testdata/dupes.errors | 3 ++- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/linguist/linguist/messagemodel.cpp b/src/linguist/linguist/messagemodel.cpp index 4a485a703..0910527af 100644 --- a/src/linguist/linguist/messagemodel.cpp +++ b/src/linguist/linguist/messagemodel.cpp @@ -182,15 +182,15 @@ bool DataModel::load(const QString &fileName, bool *langGuessed, QWidget *parent if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) { QString err = tr("Duplicate messages found in '%1':").arg(fileName.toHtmlEscaped()); int numdups = 0; - for (int i : dupes.byId) { + for (auto it = dupes.byId.begin(); it != dupes.byId.end(); ++it) { if (++numdups >= 5) { err += tr("

[more duplicates omitted]"); goto doWarn; } - err += tr("

* ID: %1").arg(tor.message(i).id().toHtmlEscaped()); + err += tr("

* ID: %1").arg(tor.message(it.key()).id().toHtmlEscaped()); } - for (int j : dupes.byContents) { - const TranslatorMessage &msg = tor.message(j); + for (auto it = dupes.byContents.begin(); it != dupes.byContents.end(); ++it) { + const TranslatorMessage &msg = tor.message(it.key()); if (++numdups >= 5) { err += tr("

[more duplicates omitted]"); break; diff --git a/src/linguist/shared/translator.cpp b/src/linguist/shared/translator.cpp index b52b8a253..156208b3f 100644 --- a/src/linguist/shared/translator.cpp +++ b/src/linguist/shared/translator.cpp @@ -562,7 +562,7 @@ Translator::Duplicates Translator::resolveDuplicates() const TranslatorMessage &msg = m_messages.at(i); TranslatorMessage *omsg; int oi; - QSet *pDup; + DuplicateEntries *pDup; if (!msg.id().isEmpty()) { const auto it = idRefs.constFind(TranslatorMessageIdPtr(this, i)); if (it != idRefs.constEnd()) { @@ -594,7 +594,7 @@ Translator::Duplicates Translator::resolveDuplicates() ++i; continue; gotDupe: - pDup->insert(oi); + (*pDup)[oi].append(msg.tsLineNumber()); if (!omsg->isTranslated() && msg.isTranslated()) omsg->setTranslations(msg.translations()); m_indexOk = false; @@ -612,23 +612,36 @@ void Translator::reportDuplicates(const Duplicates &dupes, std::cerr << "'\n(try -verbose for more info).\n"; } else { std::cerr << "':\n"; - for (int i : dupes.byId) - std::cerr << "\n* ID: " << qPrintable(message(i).id()) << std::endl; - for (int j : dupes.byContents) { - const TranslatorMessage &msg = message(j); + for (auto it = dupes.byId.begin(); it != dupes.byId.end(); ++it) { + const TranslatorMessage &msg = message(it.key()); + std::cerr << "\n* ID: " << qPrintable(msg.id()) << std::endl; + reportDuplicatesLines(msg, it.value()); + } + for (auto it = dupes.byContents.begin(); it != dupes.byContents.end(); ++it) { + const TranslatorMessage &msg = message(it.key()); std::cerr << "\n* Context: " << qPrintable(msg.context()) << "\n* Source: " << qPrintable(msg.sourceText()) << std::endl; if (!msg.comment().isEmpty()) std::cerr << "* Comment: " << qPrintable(msg.comment()) << std::endl; - const int tsLine = msg.tsLineNumber(); - if (tsLine >= 0) - std::cerr << "* Line in .ts File: " << msg.tsLineNumber() << std::endl; + reportDuplicatesLines(msg, it.value()); } std::cerr << std::endl; } } } +void Translator::reportDuplicatesLines(const TranslatorMessage &msg, + const DuplicateEntries::value_type &dups) const +{ + if (msg.tsLineNumber() >= 0) { + std::cerr << "* Line in .ts file: " << msg.tsLineNumber() << std::endl; + for (int tsLineNumber : dups) { + if (tsLineNumber >= 0) + std::cerr << "* Duplicate at line: " << tsLineNumber << std::endl; + } + } +} + // Used by lupdate to be able to search using absolute paths during merging void Translator::makeFileNamesAbsolute(const QDir &originalPath) { diff --git a/src/linguist/shared/translator.h b/src/linguist/shared/translator.h index 4bc88c7df..8a0957fd2 100644 --- a/src/linguist/shared/translator.h +++ b/src/linguist/shared/translator.h @@ -114,9 +114,15 @@ public: void makeFileNamesAbsolute(const QDir &originalPath); bool translationsExist() const; - struct Duplicates { QSet byId, byContents; }; + using DuplicateEntries = QHash>; + struct Duplicates + { + DuplicateEntries byId, byContents; + }; Duplicates resolveDuplicates(); void reportDuplicates(const Duplicates &dupes, const QString &fileName, bool verbose); + void reportDuplicatesLines(const TranslatorMessage &msg, + const DuplicateEntries::value_type &dups) const; QString languageCode() const { return m_language; } QString sourceLanguageCode() const { return m_sourceLanguage; } diff --git a/tests/auto/linguist/lrelease/testdata/dupes.errors b/tests/auto/linguist/lrelease/testdata/dupes.errors index 8d65b84fd..ed4394d7f 100644 --- a/tests/auto/linguist/lrelease/testdata/dupes.errors +++ b/tests/auto/linguist/lrelease/testdata/dupes.errors @@ -2,4 +2,5 @@ Warning: dropping duplicate messages in '.*testdata/dupes\.qm': \* Context: FindDialog \* Source: Text not found -\* Line in .ts File: 11 +\* Line in .ts file: 11 +\* Duplicate at line: 16 -- cgit v1.2.1