Keep only available languages in correction selector

This commit is contained in:
Gres 2020-03-18 21:21:17 +03:00
parent 8b84fef929
commit 124d32857f
5 changed files with 74 additions and 38 deletions

View File

@ -7,8 +7,7 @@
#include <tesseract/baseapi.h> #include <tesseract/baseapi.h>
#include <QBuffer> #include <QBuffer>
#include <QDir>
#include <limits>
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
#include <fstream> #include <fstream>
@ -159,6 +158,33 @@ const QString &Tesseract::error() const
return error_; return error_;
} }
QStringList Tesseract::availableLanguageNames(const QString &path)
{
if (path.isEmpty())
return {};
QDir dir(path);
if (!dir.exists())
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);
}
if (names.isEmpty())
return {};
return names;
}
QString Tesseract::recognize(const QPixmap &source) QString Tesseract::recognize(const QPixmap &source)
{ {
SOFT_ASSERT(engine_, return {}); SOFT_ASSERT(engine_, return {});

View File

@ -23,6 +23,8 @@ public:
bool isValid() const; bool isValid() const;
const QString& error() const; const QString& error() const;
static QStringList availableLanguageNames(const QString& path);
private: private:
void init(const LanguageId& language, const QString& tessdataPath); void init(const LanguageId& language, const QString& tessdataPath);

View File

@ -1,12 +1,12 @@
#include "settingseditor.h" #include "settingseditor.h"
#include "languagecodes.h" #include "languagecodes.h"
#include "manager.h" #include "manager.h"
#include "tesseract.h"
#include "ui_settingseditor.h" #include "ui_settingseditor.h"
#include "updates.h" #include "updates.h"
#include "widgetstate.h" #include "widgetstate.h"
#include <QFileDialog> #include <QFileDialog>
#include <QNetworkProxy>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QStringListModel> #include <QStringListModel>
@ -161,6 +161,7 @@ void SettingsEditor::setSettings(const Settings &settings)
ui->tesseractLangCombo->setCurrentText(QObject::tr(lang->name)); ui->tesseractLangCombo->setCurrentText(QObject::tr(lang->name));
ui->useUserSubstitutions->setChecked(settings.useUserSubstitutions); ui->useUserSubstitutions->setChecked(settings.useUserSubstitutions);
ui->userSubstitutionsTable->setTessdataPath(settings.tessdataPath);
ui->userSubstitutionsTable->setSubstitutions(settings.userSubstitutions); ui->userSubstitutionsTable->setSubstitutions(settings.userSubstitutions);
ui->doTranslationCheck->setChecked(settings.doTranslation); ui->doTranslationCheck->setChecked(settings.doTranslation);
@ -188,24 +189,7 @@ void SettingsEditor::updateTesseractLanguages()
{ {
ui->tesseractLangCombo->clear(); ui->tesseractLangCombo->clear();
const auto path = ui->tessdataPath->text(); auto names = Tesseract::availableLanguageNames(ui->tessdataPath->text());
if (path.isEmpty())
return;
QDir dir(path);
if (!dir.exists())
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));
}
if (names.isEmpty()) if (names.isEmpty())
return; return;
@ -289,6 +273,7 @@ void SettingsEditor::handlePortableChanged()
settings.setPortable(ui->portable->isChecked()); settings.setPortable(ui->portable->isChecked());
ui->tessdataPath->setText(settings.tessdataPath); ui->tessdataPath->setText(settings.tessdataPath);
ui->translatorsPath->setText(settings.translatorsDir); ui->translatorsPath->setText(settings.translatorsDir);
ui->userSubstitutionsTable->setTessdataPath(settings.tessdataPath);
updateTesseractLanguages(); updateTesseractLanguages();
updateTranslators(); updateTranslators();

View File

@ -1,6 +1,7 @@
#include "substitutionstable.h" #include "substitutionstable.h"
#include "debug.h" #include "debug.h"
#include "languagecodes.h" #include "languagecodes.h"
#include "tesseract.h"
#include <QComboBox> #include <QComboBox>
#include <QPainter> #include <QPainter>
@ -9,22 +10,6 @@
namespace namespace
{ {
QStringList allSourceLanguages()
{
LanguageCodes langs;
const auto &allLangs = langs.all();
QStringList result;
result.reserve(allLangs.size());
for (const auto &i : allLangs) {
if (i.second.tesseract.isEmpty())
continue;
result.append(QObject::tr(i.second.name));
}
std::sort(result.begin(), result.end());
return result;
}
class SubstitutionDelegate : public QStyledItemDelegate class SubstitutionDelegate : public QStyledItemDelegate
{ {
public: public:
@ -44,7 +29,7 @@ public:
SubstitutionsTable::SubstitutionsTable(QWidget *parent) SubstitutionsTable::SubstitutionsTable(QWidget *parent)
: QTableWidget(parent) : QTableWidget(parent)
, languagesModel_(new QStringListModel(allSourceLanguages(), this)) , languagesModel_(new QStringListModel(this))
{ {
setItemDelegate(new SubstitutionDelegate(this)); setItemDelegate(new SubstitutionDelegate(this));
setColumnCount(int(Column::Count)); setColumnCount(int(Column::Count));
@ -55,11 +40,44 @@ SubstitutionsTable::SubstitutionsTable(QWidget *parent)
void SubstitutionsTable::setSubstitutions(const Substitutions &substitutions) void SubstitutionsTable::setSubstitutions(const Substitutions &substitutions)
{ {
setRowCount(0);
updateModel(substitutions);
for (const auto &i : substitutions) addRow(i.first, i.second); for (const auto &i : substitutions) addRow(i.first, i.second);
addRow(); // for editing addRow(); // for editing
resizeColumnsToContents(); resizeColumnsToContents();
} }
void SubstitutionsTable::setTessdataPath(const QString &tessdataPath)
{
tessdataPath_ = tessdataPath;
if (rowCount() == 0) // must be at least 1 if inited
return;
setSubstitutions(substitutions());
}
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);
if (!strings.contains(name))
strings.append(name);
}
}
std::sort(strings.begin(), strings.end());
languagesModel_->setStringList(strings);
}
Substitutions SubstitutionsTable::substitutions() const Substitutions SubstitutionsTable::substitutions() const
{ {
Substitutions result; Substitutions result;
@ -88,6 +106,8 @@ void SubstitutionsTable::addRow(const LanguageId &language,
LanguageCodes langs; LanguageCodes langs;
if (auto lang = langs.findById(language)) if (auto lang = langs.findById(language))
combo->setCurrentText(QObject::tr(lang->name)); 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 =

View File

@ -15,6 +15,7 @@ public:
explicit SubstitutionsTable(QWidget* parent = nullptr); explicit SubstitutionsTable(QWidget* parent = nullptr);
void setSubstitutions(const Substitutions& substitutions); void setSubstitutions(const Substitutions& substitutions);
void setTessdataPath(const QString& tessdataPath);
Substitutions substitutions() const; Substitutions substitutions() const;
private: private:
@ -22,6 +23,8 @@ private:
void addRow(const LanguageId& language = {}, void addRow(const LanguageId& language = {},
const Substitution& substutution = {}); const Substitution& substutution = {});
std::pair<LanguageId, Substitution> at(int row) const; std::pair<LanguageId, Substitution> at(int row) const;
void updateModel(const Substitutions& substitutions);
QStringListModel* languagesModel_; QStringListModel* languagesModel_;
QString tessdataPath_;
}; };