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()
{
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");

View File

@ -206,41 +206,50 @@ const std::unordered_map<LanguageId, LanguageCodes::Bundle>
#undef I
#undef S
std::optional<LanguageCodes::Bundle> LanguageCodes::findById(
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
LanguageId LanguageCodes::idForName(const QString &name)
{
auto it = std::find_if(codes_.cbegin(), codes_.cend(),
[name](const std::pair<LanguageId, Bundle> &i) {
return name == QObject::tr(i.second.name);
});
if (it != codes_.cend())
return it->second;
return {};
return it->first;
return name;
}
std::optional<LanguageCodes::Bundle> 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<LanguageId, Bundle> &i) {
return name == i.second.tesseract;
[tesseract](const std::pair<LanguageId, Bundle> &i) {
return tesseract == i.second.tesseract;
});
if (it != codes_.cend())
return it->second;
return {};
return it->first;
return tesseract;
}
const std::unordered_map<LanguageId, LanguageCodes::Bundle>
&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<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
{
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 {
LanguageId id;
QString iso639_1;
@ -17,11 +25,9 @@ public:
const char* name;
};
std::optional<Bundle> findById(const LanguageId& id) const;
std::optional<Bundle> findByName(const QString& name) const;
std::optional<Bundle> findByTesseract(const QString& name) const;
const std::unordered_map<LanguageId, Bundle>& all() const;
LanguageCodes() = delete;
LanguageCodes(const LanguageCodes&) = delete;
LanguageCodes& operator=(const LanguageCodes&) = delete;
private:
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 );
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>();
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())

View File

@ -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);

View File

@ -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<LanguageId, Substitution> SubstitutionsTable::at(int row) const
auto combo = static_cast<QComboBox *>(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<LanguageId, Substitution> 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)

View File

@ -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;

View File

@ -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()