diff --git a/src/capture/captureareaselector.cpp b/src/capture/captureareaselector.cpp index b9f03b2..2daef86 100644 --- a/src/capture/captureareaselector.cpp +++ b/src/capture/captureareaselector.cpp @@ -45,13 +45,8 @@ void CaptureAreaSelector::setScreenRects(const std::vector &screens) void CaptureAreaSelector::updateSettings() { - LanguageCodes languages; - const auto source = languages.findById(settings_.sourceLanguage); - const auto sourceName = - source ? QObject::tr(source->name) : settings_.sourceLanguage; - const auto target = languages.findById(settings_.targetLanguage); - const auto targetName = - target ? QObject::tr(target->name) : settings_.targetLanguage; + const auto sourceName = LanguageCodes::name(settings_.sourceLanguage); + const auto targetName = LanguageCodes::name(settings_.targetLanguage); const auto translationState = settings_.doTranslation ? tr("on") : tr("off"); diff --git a/src/languagecodes.cpp b/src/languagecodes.cpp index ccf0917..cd6a0d9 100644 --- a/src/languagecodes.cpp +++ b/src/languagecodes.cpp @@ -206,41 +206,50 @@ const std::unordered_map #undef I #undef S -std::optional LanguageCodes::findById( - const LanguageId &id) const -{ - auto it = codes_.find(id); - if (it != codes_.cend()) - return it->second; - return {}; -} - -std::optional LanguageCodes::findByName( - const QString &name) const +LanguageId LanguageCodes::idForName(const QString &name) { auto it = std::find_if(codes_.cbegin(), codes_.cend(), [name](const std::pair &i) { return name == QObject::tr(i.second.name); }); if (it != codes_.cend()) - return it->second; - return {}; + return it->first; + return name; } -std::optional LanguageCodes::findByTesseract( - const QString &name) const +LanguageId LanguageCodes::idForTesseract(const QString &tesseract) { auto it = std::find_if(codes_.cbegin(), codes_.cend(), - [name](const std::pair &i) { - return name == i.second.tesseract; + [tesseract](const std::pair &i) { + return tesseract == i.second.tesseract; }); if (it != codes_.cend()) - return it->second; - return {}; + return it->first; + return tesseract; } -const std::unordered_map - &LanguageCodes::all() const +QString LanguageCodes::iso639_1(const LanguageId &id) { - return codes_; + auto it = codes_.find(id); + return it != codes_.cend() ? it->second.iso639_1 : id; +} + +QString LanguageCodes::tesseract(const LanguageId &id) +{ + auto it = codes_.find(id); + return it != codes_.cend() ? it->second.tesseract : id; +} + +QString LanguageCodes::name(const LanguageId &id) +{ + auto it = codes_.find(id); + return it != codes_.cend() ? QObject::tr(it->second.name) : id; +} + +std::vector LanguageCodes::allIds() +{ + std::vector result; + result.reserve(codes_.size()); + for (const auto &code : codes_) result.push_back(code.first); + return result; } diff --git a/src/languagecodes.h b/src/languagecodes.h index c41c96f..f1b5e46 100644 --- a/src/languagecodes.h +++ b/src/languagecodes.h @@ -10,6 +10,14 @@ using LanguageId = QString; class LanguageCodes { public: + static LanguageId idForTesseract(const QString& tesseract); + static LanguageId idForName(const QString& name); + static QString iso639_1(const LanguageId& id); + static QString tesseract(const LanguageId& id); + static QString name(const LanguageId& id); + static std::vector allIds(); + +private: struct Bundle { LanguageId id; QString iso639_1; @@ -17,11 +25,9 @@ public: const char* name; }; - std::optional findById(const LanguageId& id) const; - std::optional findByName(const QString& name) const; - std::optional findByTesseract(const QString& name) const; - const std::unordered_map& all() const; + LanguageCodes() = delete; + LanguageCodes(const LanguageCodes&) = delete; + LanguageCodes& operator=(const LanguageCodes&) = delete; -private: const static std::unordered_map codes_; }; diff --git a/src/ocr/tesseract.cpp b/src/ocr/tesseract.cpp index 504f9bb..096ced2 100644 --- a/src/ocr/tesseract.cpp +++ b/src/ocr/tesseract.cpp @@ -133,17 +133,11 @@ void Tesseract::init(const LanguageId &language, const QString &tessdataPath) { SOFT_ASSERT(!engine_, return ); - LanguageCodes languages; - auto langCodes = languages.findById(language); - if (!langCodes) { - error_ = QObject::tr("unknown recognition language: %1").arg(language); - return; - } - engine_ = std::make_unique(); + const auto tesseractName = LanguageCodes::tesseract(language); auto result = - engine_->Init(qPrintable(tessdataPath), qPrintable(langCodes->tesseract), + engine_->Init(qPrintable(tessdataPath), qPrintable(tesseractName), tesseract::OEM_DEFAULT); if (result == 0) return; @@ -167,15 +161,12 @@ QStringList Tesseract::availableLanguageNames(const QString &path) return {}; LanguageIds names; - LanguageCodes languages; const auto files = dir.entryList({"*.traineddata"}, QDir::Files); for (const auto &file : files) { const auto lang = file.left(file.indexOf(".")); - if (const auto bundle = languages.findByTesseract(lang)) - names.append(QObject::tr(bundle->name)); - else - names.append(lang); + const auto name = LanguageCodes::name(LanguageCodes::idForTesseract(lang)); + names.append(name); } if (names.isEmpty()) diff --git a/src/settingseditor.cpp b/src/settingseditor.cpp index 59e2204..68fbe9c 100644 --- a/src/settingseditor.cpp +++ b/src/settingseditor.cpp @@ -119,9 +119,8 @@ Settings SettingsEditor::settings() const settings.proxyPassword = ui->proxyPassEdit->text(); settings.proxySavePassword = ui->proxySaveCheck->isChecked(); - LanguageCodes langs; - if (auto lang = langs.findByName(ui->tesseractLangCombo->currentText())) - settings.sourceLanguage = lang->id; + settings.sourceLanguage = + LanguageCodes::idForName(ui->tesseractLangCombo->currentText()); settings.useUserSubstitutions = ui->useUserSubstitutions->isChecked(); settings.userSubstitutions = ui->userSubstitutionsTable->substitutions(); @@ -131,8 +130,8 @@ Settings SettingsEditor::settings() const settings.debugMode = ui->translatorDebugCheck->isChecked(); settings.translationTimeout = std::chrono::seconds(ui->translateTimeoutSpin->value()); - if (auto lang = langs.findByName(ui->translateLangCombo->currentText())) - settings.targetLanguage = lang->id; + settings.targetLanguage = + LanguageCodes::idForName(ui->translateLangCombo->currentText()); settings.translators.clear(); for (auto i = 0, end = ui->translatorList->count(); i < end; ++i) { @@ -174,11 +173,10 @@ void SettingsEditor::setSettings(const Settings &settings) ui->proxyPassEdit->setText(settings.proxyPassword); ui->proxySaveCheck->setChecked(settings.proxySavePassword); - LanguageCodes langs; ui->tessdataPath->setText(settings.tessdataPath); updateTesseractLanguages(); - if (auto lang = langs.findById(settings.sourceLanguage)) - ui->tesseractLangCombo->setCurrentText(QObject::tr(lang->name)); + ui->tesseractLangCombo->setCurrentText( + LanguageCodes::name(settings.sourceLanguage)); ui->useUserSubstitutions->setChecked(settings.useUserSubstitutions); ui->userSubstitutionsTable->setTessdataPath(settings.tessdataPath); @@ -191,8 +189,8 @@ void SettingsEditor::setSettings(const Settings &settings) ui->translatorsPath->setText(settings.translatorsDir); enabledTranslators_ = settings.translators; updateTranslators(); - if (auto lang = langs.findById(settings.targetLanguage)) - ui->translateLangCombo->setCurrentText(QObject::tr(lang->name)); + ui->translateLangCombo->setCurrentText( + LanguageCodes::name(settings.targetLanguage)); ui->trayRadio->setChecked(settings.resultShowType == ResultMode::Tooltip); ui->dialogRadio->setChecked(settings.resultShowType == ResultMode::Widget); diff --git a/src/substitutionstable.cpp b/src/substitutionstable.cpp index 0993578..b57160f 100644 --- a/src/substitutionstable.cpp +++ b/src/substitutionstable.cpp @@ -63,11 +63,9 @@ void SubstitutionsTable::updateModel(const Substitutions &substitutions) auto strings = Tesseract::availableLanguageNames(tessdataPath_); if (!substitutions.empty()) { - LanguageCodes languages; for (const auto &i : substitutions) { - auto name = i.first; - if (const auto bundle = languages.findByTesseract(name)) - name = QObject::tr(bundle->name); + const auto name = + LanguageCodes::name(LanguageCodes::idForTesseract(i.first)); if (!strings.contains(name)) strings.append(name); @@ -103,11 +101,7 @@ void SubstitutionsTable::addRow(const LanguageId &language, using E = Column; if (!language.isEmpty()) { - LanguageCodes langs; - if (auto lang = langs.findById(language)) - combo->setCurrentText(QObject::tr(lang->name)); - else - combo->setCurrentText(language); + combo->setCurrentText(LanguageCodes::name(language)); } else if (rowCount() > 1) { const auto previousRow = rowCount() - 2; auto previousCombo = @@ -129,9 +123,8 @@ std::pair SubstitutionsTable::at(int row) const auto combo = static_cast(cellWidget(row, int(E::Language))); SOFT_ASSERT(combo, return {}); - LanguageCodes langs; - auto lang = langs.findByName(combo->currentText()); - SOFT_ASSERT(lang, return {}); + const auto langId = LanguageCodes::idForName(combo->currentText()); + SOFT_ASSERT(!langId.isEmpty(), return {}); Substitution sub; auto sourceItem = item(row, int(E::Source)); @@ -142,7 +135,7 @@ std::pair SubstitutionsTable::at(int row) const SOFT_ASSERT(targetItem, return {}); sub.target = targetItem->text(); - return std::make_pair(lang->id, sub); + return std::make_pair(langId, sub); } void SubstitutionsTable::handleItemChange(QTableWidgetItem *item) diff --git a/src/translate/translator.cpp b/src/translate/translator.cpp index 2c7f28a..7b987db 100644 --- a/src/translate/translator.cpp +++ b/src/translate/translator.cpp @@ -292,11 +292,11 @@ QStringList Translator::availableTranslators(const QString &path) QStringList Translator::availableLanguageNames() { QStringList names; - LanguageCodes languages; - for (const auto &bundle : languages.all()) { - if (!bundle.second.iso639_1.isEmpty()) - names.append(QObject::tr(bundle.second.name)); + for (const auto &id : LanguageCodes::allIds()) { + const auto iso = LanguageCodes::iso639_1(id); + if (!iso.isEmpty()) + names.append(LanguageCodes::name(id)); } return names; diff --git a/src/translate/webpage.cpp b/src/translate/webpage.cpp index 6356d46..ed63601 100644 --- a/src/translate/webpage.cpp +++ b/src/translate/webpage.cpp @@ -96,10 +96,9 @@ void WebPage::setTimeout(std::chrono::seconds timeout) void WebPage::start(const TaskPtr &task) { - LanguageCodes languages; - auto sourceLanguage = languages.findById(task->sourceLanguage); - auto targetLanguage = languages.findById(task->targetLanguage); - if (!sourceLanguage || !targetLanguage) { + const auto sourceLanguage = LanguageCodes::iso639_1(task->sourceLanguage); + const auto targetLanguage = LanguageCodes::iso639_1(task->targetLanguage); + if (sourceLanguage.isEmpty() || targetLanguage.isEmpty()) { task->error = QObject::tr("unknown translation languages: %1 or %2") .arg(task->sourceLanguage) .arg(task->targetLanguage); @@ -111,8 +110,7 @@ void WebPage::start(const TaskPtr &task) isBusy_ = true; nextIdleTime_ = QDateTime::currentDateTime().addSecs(timeout_.count()); - proxy_->translate(task->corrected, sourceLanguage->iso639_1, - targetLanguage->iso639_1); + proxy_->translate(task->corrected, sourceLanguage, targetLanguage); } bool WebPage::checkBusy()