Changed language codes to singleton
This commit is contained in:
		
							parent
							
								
									aee380fcd5
								
							
						
					
					
						commit
						cc815f4245
					
				@ -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");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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())
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user