Changed language codes to singleton

This commit is contained in:
Gres 2020-03-24 21:38:05 +03:00
parent aee380fcd5
commit cc815f4245
8 changed files with 70 additions and 80 deletions

View File

@ -45,13 +45,8 @@ void CaptureAreaSelector::setScreenRects(const std::vector<QRect> &screens)
void CaptureAreaSelector::updateSettings() void CaptureAreaSelector::updateSettings()
{ {
LanguageCodes languages; const auto sourceName = LanguageCodes::name(settings_.sourceLanguage);
const auto source = languages.findById(settings_.sourceLanguage); const auto targetName = LanguageCodes::name(settings_.targetLanguage);
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 translationState = settings_.doTranslation ? tr("on") : tr("off"); const auto translationState = settings_.doTranslation ? tr("on") : tr("off");

View File

@ -206,41 +206,50 @@ const std::unordered_map<LanguageId, LanguageCodes::Bundle>
#undef I #undef I
#undef S #undef S
std::optional<LanguageCodes::Bundle> LanguageCodes::findById( LanguageId LanguageCodes::idForName(const QString &name)
const LanguageId &id) const
{
auto it = codes_.find(id);
if (it != codes_.cend())
return it->second;
return {};
}
std::optional<LanguageCodes::Bundle> LanguageCodes::findByName(
const QString &name) const
{ {
auto it = std::find_if(codes_.cbegin(), codes_.cend(), auto it = std::find_if(codes_.cbegin(), codes_.cend(),
[name](const std::pair<LanguageId, Bundle> &i) { [name](const std::pair<LanguageId, Bundle> &i) {
return name == QObject::tr(i.second.name); return name == QObject::tr(i.second.name);
}); });
if (it != codes_.cend()) if (it != codes_.cend())
return it->second; return it->first;
return {}; return name;
} }
std::optional<LanguageCodes::Bundle> LanguageCodes::findByTesseract( LanguageId LanguageCodes::idForTesseract(const QString &tesseract)
const QString &name) const
{ {
auto it = std::find_if(codes_.cbegin(), codes_.cend(), auto it = std::find_if(codes_.cbegin(), codes_.cend(),
[name](const std::pair<LanguageId, Bundle> &i) { [tesseract](const std::pair<LanguageId, Bundle> &i) {
return name == i.second.tesseract; return tesseract == i.second.tesseract;
}); });
if (it != codes_.cend()) if (it != codes_.cend())
return it->second; return it->first;
return {}; return tesseract;
} }
const std::unordered_map<LanguageId, LanguageCodes::Bundle> QString LanguageCodes::iso639_1(const LanguageId &id)
&LanguageCodes::all() const
{ {
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<LanguageId> LanguageCodes::allIds()
{
std::vector<LanguageId> result;
result.reserve(codes_.size());
for (const auto &code : codes_) result.push_back(code.first);
return result;
} }

View File

@ -10,6 +10,14 @@ using LanguageId = QString;
class LanguageCodes class LanguageCodes
{ {
public: 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<LanguageId> allIds();
private:
struct Bundle { struct Bundle {
LanguageId id; LanguageId id;
QString iso639_1; QString iso639_1;
@ -17,11 +25,9 @@ public:
const char* name; const char* name;
}; };
std::optional<Bundle> findById(const LanguageId& id) const; LanguageCodes() = delete;
std::optional<Bundle> findByName(const QString& name) const; LanguageCodes(const LanguageCodes&) = delete;
std::optional<Bundle> findByTesseract(const QString& name) const; LanguageCodes& operator=(const LanguageCodes&) = delete;
const std::unordered_map<LanguageId, Bundle>& all() const;
private:
const static std::unordered_map<LanguageId, Bundle> codes_; const static std::unordered_map<LanguageId, Bundle> codes_;
}; };

View File

@ -133,17 +133,11 @@ void Tesseract::init(const LanguageId &language, const QString &tessdataPath)
{ {
SOFT_ASSERT(!engine_, return ); 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<tesseract::TessBaseAPI>(); engine_ = std::make_unique<tesseract::TessBaseAPI>();
const auto tesseractName = LanguageCodes::tesseract(language);
auto result = auto result =
engine_->Init(qPrintable(tessdataPath), qPrintable(langCodes->tesseract), engine_->Init(qPrintable(tessdataPath), qPrintable(tesseractName),
tesseract::OEM_DEFAULT); tesseract::OEM_DEFAULT);
if (result == 0) if (result == 0)
return; return;
@ -167,15 +161,12 @@ QStringList Tesseract::availableLanguageNames(const QString &path)
return {}; return {};
LanguageIds names; LanguageIds names;
LanguageCodes languages;
const auto files = dir.entryList({"*.traineddata"}, QDir::Files); const auto files = dir.entryList({"*.traineddata"}, QDir::Files);
for (const auto &file : files) { for (const auto &file : files) {
const auto lang = file.left(file.indexOf(".")); const auto lang = file.left(file.indexOf("."));
if (const auto bundle = languages.findByTesseract(lang)) const auto name = LanguageCodes::name(LanguageCodes::idForTesseract(lang));
names.append(QObject::tr(bundle->name)); names.append(name);
else
names.append(lang);
} }
if (names.isEmpty()) if (names.isEmpty())

View File

@ -119,9 +119,8 @@ Settings SettingsEditor::settings() const
settings.proxyPassword = ui->proxyPassEdit->text(); settings.proxyPassword = ui->proxyPassEdit->text();
settings.proxySavePassword = ui->proxySaveCheck->isChecked(); settings.proxySavePassword = ui->proxySaveCheck->isChecked();
LanguageCodes langs; settings.sourceLanguage =
if (auto lang = langs.findByName(ui->tesseractLangCombo->currentText())) LanguageCodes::idForName(ui->tesseractLangCombo->currentText());
settings.sourceLanguage = lang->id;
settings.useUserSubstitutions = ui->useUserSubstitutions->isChecked(); settings.useUserSubstitutions = ui->useUserSubstitutions->isChecked();
settings.userSubstitutions = ui->userSubstitutionsTable->substitutions(); settings.userSubstitutions = ui->userSubstitutionsTable->substitutions();
@ -131,8 +130,8 @@ Settings SettingsEditor::settings() const
settings.debugMode = ui->translatorDebugCheck->isChecked(); settings.debugMode = ui->translatorDebugCheck->isChecked();
settings.translationTimeout = settings.translationTimeout =
std::chrono::seconds(ui->translateTimeoutSpin->value()); std::chrono::seconds(ui->translateTimeoutSpin->value());
if (auto lang = langs.findByName(ui->translateLangCombo->currentText())) settings.targetLanguage =
settings.targetLanguage = lang->id; LanguageCodes::idForName(ui->translateLangCombo->currentText());
settings.translators.clear(); settings.translators.clear();
for (auto i = 0, end = ui->translatorList->count(); i < end; ++i) { 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->proxyPassEdit->setText(settings.proxyPassword);
ui->proxySaveCheck->setChecked(settings.proxySavePassword); ui->proxySaveCheck->setChecked(settings.proxySavePassword);
LanguageCodes langs;
ui->tessdataPath->setText(settings.tessdataPath); ui->tessdataPath->setText(settings.tessdataPath);
updateTesseractLanguages(); updateTesseractLanguages();
if (auto lang = langs.findById(settings.sourceLanguage)) ui->tesseractLangCombo->setCurrentText(
ui->tesseractLangCombo->setCurrentText(QObject::tr(lang->name)); LanguageCodes::name(settings.sourceLanguage));
ui->useUserSubstitutions->setChecked(settings.useUserSubstitutions); ui->useUserSubstitutions->setChecked(settings.useUserSubstitutions);
ui->userSubstitutionsTable->setTessdataPath(settings.tessdataPath); ui->userSubstitutionsTable->setTessdataPath(settings.tessdataPath);
@ -191,8 +189,8 @@ void SettingsEditor::setSettings(const Settings &settings)
ui->translatorsPath->setText(settings.translatorsDir); ui->translatorsPath->setText(settings.translatorsDir);
enabledTranslators_ = settings.translators; enabledTranslators_ = settings.translators;
updateTranslators(); updateTranslators();
if (auto lang = langs.findById(settings.targetLanguage)) ui->translateLangCombo->setCurrentText(
ui->translateLangCombo->setCurrentText(QObject::tr(lang->name)); LanguageCodes::name(settings.targetLanguage));
ui->trayRadio->setChecked(settings.resultShowType == ResultMode::Tooltip); ui->trayRadio->setChecked(settings.resultShowType == ResultMode::Tooltip);
ui->dialogRadio->setChecked(settings.resultShowType == ResultMode::Widget); ui->dialogRadio->setChecked(settings.resultShowType == ResultMode::Widget);

View File

@ -63,11 +63,9 @@ void SubstitutionsTable::updateModel(const Substitutions &substitutions)
auto strings = Tesseract::availableLanguageNames(tessdataPath_); auto strings = Tesseract::availableLanguageNames(tessdataPath_);
if (!substitutions.empty()) { if (!substitutions.empty()) {
LanguageCodes languages;
for (const auto &i : substitutions) { for (const auto &i : substitutions) {
auto name = i.first; const auto name =
if (const auto bundle = languages.findByTesseract(name)) LanguageCodes::name(LanguageCodes::idForTesseract(i.first));
name = QObject::tr(bundle->name);
if (!strings.contains(name)) if (!strings.contains(name))
strings.append(name); strings.append(name);
@ -103,11 +101,7 @@ void SubstitutionsTable::addRow(const LanguageId &language,
using E = Column; using E = Column;
if (!language.isEmpty()) { if (!language.isEmpty()) {
LanguageCodes langs; combo->setCurrentText(LanguageCodes::name(language));
if (auto lang = langs.findById(language))
combo->setCurrentText(QObject::tr(lang->name));
else
combo->setCurrentText(language);
} else if (rowCount() > 1) { } else if (rowCount() > 1) {
const auto previousRow = rowCount() - 2; const auto previousRow = rowCount() - 2;
auto previousCombo = auto previousCombo =
@ -129,9 +123,8 @@ std::pair<LanguageId, Substitution> SubstitutionsTable::at(int row) const
auto combo = static_cast<QComboBox *>(cellWidget(row, int(E::Language))); auto combo = static_cast<QComboBox *>(cellWidget(row, int(E::Language)));
SOFT_ASSERT(combo, return {}); SOFT_ASSERT(combo, return {});
LanguageCodes langs; const auto langId = LanguageCodes::idForName(combo->currentText());
auto lang = langs.findByName(combo->currentText()); SOFT_ASSERT(!langId.isEmpty(), return {});
SOFT_ASSERT(lang, return {});
Substitution sub; Substitution sub;
auto sourceItem = item(row, int(E::Source)); auto sourceItem = item(row, int(E::Source));
@ -142,7 +135,7 @@ std::pair<LanguageId, Substitution> SubstitutionsTable::at(int row) const
SOFT_ASSERT(targetItem, return {}); SOFT_ASSERT(targetItem, return {});
sub.target = targetItem->text(); sub.target = targetItem->text();
return std::make_pair(lang->id, sub); return std::make_pair(langId, sub);
} }
void SubstitutionsTable::handleItemChange(QTableWidgetItem *item) void SubstitutionsTable::handleItemChange(QTableWidgetItem *item)

View File

@ -292,11 +292,11 @@ QStringList Translator::availableTranslators(const QString &path)
QStringList Translator::availableLanguageNames() QStringList Translator::availableLanguageNames()
{ {
QStringList names; QStringList names;
LanguageCodes languages;
for (const auto &bundle : languages.all()) { for (const auto &id : LanguageCodes::allIds()) {
if (!bundle.second.iso639_1.isEmpty()) const auto iso = LanguageCodes::iso639_1(id);
names.append(QObject::tr(bundle.second.name)); if (!iso.isEmpty())
names.append(LanguageCodes::name(id));
} }
return names; return names;

View File

@ -96,10 +96,9 @@ void WebPage::setTimeout(std::chrono::seconds timeout)
void WebPage::start(const TaskPtr &task) void WebPage::start(const TaskPtr &task)
{ {
LanguageCodes languages; const auto sourceLanguage = LanguageCodes::iso639_1(task->sourceLanguage);
auto sourceLanguage = languages.findById(task->sourceLanguage); const auto targetLanguage = LanguageCodes::iso639_1(task->targetLanguage);
auto targetLanguage = languages.findById(task->targetLanguage); if (sourceLanguage.isEmpty() || targetLanguage.isEmpty()) {
if (!sourceLanguage || !targetLanguage) {
task->error = QObject::tr("unknown translation languages: %1 or %2") task->error = QObject::tr("unknown translation languages: %1 or %2")
.arg(task->sourceLanguage) .arg(task->sourceLanguage)
.arg(task->targetLanguage); .arg(task->targetLanguage);
@ -111,8 +110,7 @@ void WebPage::start(const TaskPtr &task)
isBusy_ = true; isBusy_ = true;
nextIdleTime_ = QDateTime::currentDateTime().addSecs(timeout_.count()); nextIdleTime_ = QDateTime::currentDateTime().addSecs(timeout_.count());
proxy_->translate(task->corrected, sourceLanguage->iso639_1, proxy_->translate(task->corrected, sourceLanguage, targetLanguage);
targetLanguage->iso639_1);
} }
bool WebPage::checkBusy() bool WebPage::checkBusy()