Show settings page info and error

This commit is contained in:
Gres 2021-04-15 21:08:16 +03:00
parent 3f2dcbbeb0
commit 718bb7314b
9 changed files with 1150 additions and 859 deletions

View File

@ -59,6 +59,7 @@ HEADERS += \
src/service/widgetstate.h \
src/settings.h \
src/settingseditor.h \
src/settingsvalidator.h \
src/stfwd.h \
src/substitutionstable.h \
src/task.h \
@ -95,6 +96,7 @@ SOURCES += \
src/service/widgetstate.cpp \
src/settings.cpp \
src/settingseditor.cpp \
src/settingsvalidator.cpp \
src/substitutionstable.cpp \
src/translate/translator.cpp \
src/translate/webpage.cpp \

View File

@ -616,69 +616,54 @@ Ctrl - продолжить выделять</translation>
<translation>Любой язык</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="41"/>
<location filename="../../src/manager.cpp" line="42"/>
<source>app</source>
<translation>приложение</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="42"/>
<location filename="../../src/manager.cpp" line="43"/>
<source>recognizers</source>
<translation>распознавание</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="43"/>
<location filename="../../src/manager.cpp" line="44"/>
<source>correction</source>
<translation>коррекция</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="44"/>
<location filename="../../src/manager.cpp" line="45"/>
<source>translators</source>
<translation>перевод</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="59"/>
<location filename="../../src/manager.cpp" line="60"/>
<source>Screen translator started</source>
<translation>Экранный переводчик запущен</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="67"/>
<location filename="../../src/manager.cpp" line="68"/>
<source>Updates available</source>
<translation>Доступны обновления</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="95"/>
<location filename="../../src/manager.cpp" line="96"/>
<source>Current version might be outdated.
Check for updates to silence this warning</source>
<translation>Текущая версия может быть устаревшей.
Проверьте обновления, чтобы отключить это сообщение</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="124"/>
<source>No recognition languages available. Install some via Settings-&gt;Updates</source>
<translation>Нет доступных языков распознавания. Установите нужные через Настройки-&gt;Обновление</translation>
<location filename="../../src/manager.cpp" line="127"/>
<source>Incorrect settings found. Go to Settings</source>
<translation>Обнвружены некорректные настройки. Перейдите в Настройки</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="129"/>
<source>Recognition language not set. Go to Settings-&gt;Recognition and set it</source>
<translation>Язык распознавания не задан. Задайте его в Настройки-&gt;Распознавание</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="133"/>
<source>No translators enabled. Go to Settings-&gt;Translation and select some</source>
<translation>Не выбран ни один переводчик. Активируйте хотя бы один в Настройки-&gt;Перевод</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="138"/>
<source>Translation language not set. Go to Settings-&gt;Translation and set it</source>
<translation>Язык перевода не задан. Задайте его в Настройки-&gt;Перевод</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="205"/>
<location filename="../../src/manager.cpp" line="192"/>
<source>Failed to set log file: %1</source>
<translation>Ошибка установки лог-файла: %1</translation>
</message>
<message>
<location filename="../../src/manager.cpp" line="211"/>
<location filename="../../src/manager.cpp" line="198"/>
<source>Started logging to file: %1</source>
<translation>Начата запись в лог-файл: %1</translation>
</message>
@ -727,35 +712,60 @@ in %1</source>
<translation>Не восстанавливать интерфейс пользователя (размер и положения окна и т.д.)</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="116"/>
<location filename="../../src/settingseditor.cpp" line="183"/>
<source>&lt;p&gt;Optical character recognition (OCR) and translation tool&lt;/p&gt;</source>
<translation>&lt;p&gt;Инструмент оптического распознавания текста (OCR) и перевода&lt;/p&gt;</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="118"/>
<location filename="../../src/settingseditor.cpp" line="185"/>
<source>&lt;p&gt;Version: %1&lt;/p&gt;</source>
<translation>&lt;p&gt;Версия: %1&lt;/p&gt;</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="120"/>
<location filename="../../src/settingseditor.cpp" line="187"/>
<source>&lt;p&gt;Changelog: &lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;Список изменений: &lt;a href=&quot;%1&quot;&gt;%2&lt;/a&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="122"/>
<location filename="../../src/settingseditor.cpp" line="189"/>
<source>&lt;p&gt;License: &lt;a href=&quot;%3&quot;&gt;MIT&lt;/a&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;Лицензия: &lt;a href=&quot;%3&quot;&gt;MIT&lt;/a&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="123"/>
<location filename="../../src/settingseditor.cpp" line="190"/>
<source>&lt;p&gt;Author: Gres (&lt;a href=&quot;mailto:%1&quot;&gt;%1&lt;/a&gt;)&lt;/p&gt;</source>
<translation>&lt;p&gt;Автор: Gres (&lt;a href=&quot;mailto:%1&quot;&gt;%1&lt;/a&gt;)&lt;/p&gt;</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="125"/>
<location filename="../../src/settingseditor.cpp" line="192"/>
<source>&lt;p&gt;Issues: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;Поддержка: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../../src/settingsvalidator.cpp" line="33"/>
<source>No recognizers installed</source>
<translation>Нет установленных языков распознавания</translation>
</message>
<message>
<location filename="../../src/settingsvalidator.cpp" line="35"/>
<source>Recognition language not set</source>
<translation>Не задан язык распознавания по умолчанию</translation>
</message>
<message>
<location filename="../../src/settingsvalidator.cpp" line="38"/>
<source>No translators installed</source>
<translation>Нет установленных переводчиков</translation>
</message>
<message>
<location filename="../../src/settingsvalidator.cpp" line="41"/>
<source>No translators enabled (selected)</source>
<translation>Нет активированных (выделенных) переводчиков</translation>
</message>
<message>
<location filename="../../src/settingsvalidator.cpp" line="43"/>
<source>Translation language not set</source>
<translation>Не задан язык перевода</translation>
</message>
</context>
<context>
<name>RecognizeWorker</name>
@ -839,112 +849,112 @@ in %1</source>
<context>
<name>SettingsEditor</name>
<message>
<location filename="../../src/settingseditor.ui" line="56"/>
<location filename="../../src/settingseditor.ui" line="220"/>
<source>Shortcuts</source>
<translation>Горячие клавиши</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="95"/>
<location filename="../../src/settingseditor.ui" line="259"/>
<source>Capture</source>
<translation>Захват</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="65"/>
<location filename="../../src/settingseditor.ui" line="229"/>
<source>Repeat capture</source>
<translation>Повторить захват</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="75"/>
<location filename="../../src/settingseditor.ui" line="239"/>
<source>Show last result</source>
<translation>Показать последний результат</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="85"/>
<location filename="../../src/settingseditor.ui" line="249"/>
<source>Copy result to clipboard</source>
<translation>Скопировать в буфер обмена</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="102"/>
<location filename="../../src/settingseditor.ui" line="266"/>
<source>Capture saved areas</source>
<translation>Захват сохраненных зон</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="115"/>
<location filename="../../src/settingseditor.ui" line="120"/>
<source>Proxy</source>
<translation>Прокси</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="121"/>
<location filename="../../src/settingseditor.ui" line="126"/>
<source>Type:</source>
<translation>Тип:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="131"/>
<location filename="../../src/settingseditor.ui" line="136"/>
<source>User:</source>
<translation>Пользователь:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="141"/>
<location filename="../../src/settingseditor.ui" line="146"/>
<source>Address:</source>
<translation>Адрес:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="151"/>
<location filename="../../src/settingseditor.ui" line="156"/>
<source>Password:</source>
<translation>Пароль:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="161"/>
<location filename="../../src/settingseditor.ui" line="166"/>
<source>Port:</source>
<translation>Порт:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="178"/>
<location filename="../../src/settingseditor.ui" line="183"/>
<source>save password (unsafe)</source>
<translation>сохранять пароль (небезопасно)</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="291"/>
<location filename="../../src/settingseditor.ui" line="355"/>
<source>Library version</source>
<translation>Версия</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="305"/>
<location filename="../../src/settingseditor.ui" line="369"/>
<source>User substitutions</source>
<translation>Пользовательская коррекция</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="328"/>
<location filename="../../src/settingseditor.ui" line="392"/>
<source>Use auto corrections (hunspell)</source>
<translation>Использовать автокоррекцию (hunspell)</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="335"/>
<location filename="../../src/settingseditor.ui" line="399"/>
<source>Use user substitutions</source>
<translation>Использовать пользовательскую коррекцию</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="342"/>
<location filename="../../src/settingseditor.ui" line="406"/>
<source>Hunspell dictionaries path:</source>
<translation>Путь к словарям Hunspell:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="404"/>
<location filename="../../src/settingseditor.ui" line="468"/>
<source>Language:</source>
<translation>Язык:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="440"/>
<location filename="../../src/settingseditor.ui" line="504"/>
<source> secs</source>
<translation> сек</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="380"/>
<location filename="../../src/settingseditor.ui" line="444"/>
<source>Ignore SSL errors</source>
<translation>Игнорировать ошибки SSL</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="188"/>
<location filename="../../src/settingseditor.ui" line="279"/>
<source>Show message on program start</source>
<translation>Показать сообщения при старте</translation>
</message>
@ -954,202 +964,238 @@ in %1</source>
<translation>Настройки</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="195"/>
<location filename="../../src/settingseditor.ui" line="213"/>
<source>Run at system start</source>
<translation>Добавить в автозапуск</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="202"/>
<location filename="../../src/settingseditor.ui" line="286"/>
<source>Portable (store data in same folder)</source>
<translation>Portable (хранить данные в папке с программой)</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="222"/>
<location filename="../../src/settingseditor.ui" line="206"/>
<source>Write trace file</source>
<translation>Писать логи в файл (отладка)</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="278"/>
<location filename="../../src/settingseditor.ui" line="342"/>
<source>Default language:</source>
<translation>Язык по умолчанию:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="265"/>
<location filename="../../src/settingseditor.ui" line="329"/>
<source>Tessdata path:</source>
<translation>Путь к языкам (tessdata):</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="315"/>
<location filename="../../src/settingseditor.ui" line="379"/>
<source>\\ for \ symbol, \n for newline</source>
<translation>\\ для символа \ , \n для символа новой строки</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="363"/>
<location filename="../../src/settingseditor.ui" line="427"/>
<source>Translators path:</source>
<translation>Путь к переводчикам:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="370"/>
<location filename="../../src/settingseditor.ui" line="434"/>
<source>Translators</source>
<translation>Переводчики</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="505"/>
<location filename="../../src/settingseditor.ui" line="569"/>
<source>Result window</source>
<translation>Окно результата</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="511"/>
<location filename="../../src/settingseditor.ui" line="575"/>
<source>Font:</source>
<translation>Шрифт:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="521"/>
<location filename="../../src/settingseditor.ui" line="585"/>
<source>Font size:</source>
<translation>Размер шрифта:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="538"/>
<location filename="../../src/settingseditor.ui" line="602"/>
<source>Font color:</source>
<translation>Цвет шрифта:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="555"/>
<location filename="../../src/settingseditor.ui" line="619"/>
<source>Background:</source>
<translation>Фон:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="572"/>
<location filename="../../src/settingseditor.ui" line="636"/>
<source>Show image</source>
<translation>Показывать изображение</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="579"/>
<location filename="../../src/settingseditor.ui" line="643"/>
<source>Show recognized</source>
<translation>Показывать распознанное</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="629"/>
<location filename="../../src/settingseditor.ui" line="693"/>
<source>Update check interval (days):</source>
<translation>Интервал проверки обновления (дней):</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="636"/>
<location filename="../../src/settingseditor.ui" line="700"/>
<source>0 - disabled</source>
<translation>- отключено</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="390"/>
<location filename="../../src/settingseditor.ui" line="454"/>
<source>Translate text</source>
<translation>Переводить текст</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="397"/>
<location filename="../../src/settingseditor.ui" line="461"/>
<source>Single translator timeout:</source>
<translation>Переходить к следующему переводчику после:</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="467"/>
<location filename="../../src/settingseditor.ui" line="531"/>
<source>Result type</source>
<translation>Тип результата</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="479"/>
<location filename="../../src/settingseditor.ui" line="543"/>
<source>Tray</source>
<translation>Трей</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="492"/>
<location filename="../../src/settingseditor.ui" line="556"/>
<source>Window</source>
<translation>Окно</translation>
</message>
<message>
<location filename="../../src/settingseditor.ui" line="652"/>
<location filename="../../src/settingseditor.ui" line="716"/>
<source>Check now</source>
<translation>Проверить сейчас</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="29"/>
<location filename="../../src/settingseditor.cpp" line="54"/>
<source>General</source>
<translation>Основное</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="29"/>
<location filename="../../src/settingseditor.cpp" line="54"/>
<source>This page contains general program settings</source>
<translation>Эта страница содержит общие настройки программы</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="57"/>
<source>Recognition</source>
<translation>Распознавание</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="29"/>
<location filename="../../src/settingseditor.cpp" line="58"/>
<source>This page contains text recognition settings. It shows the available languages that program can convert from image to text</source>
<translation>Эта страница содержит настройки распознавания текста. На ней представлены языки, которые программа может преобразовать из изображения в текст</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="63"/>
<source>Correction</source>
<translation>Коррекция</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="30"/>
<location filename="../../src/settingseditor.cpp" line="64"/>
<source>This page contains recognized text correction settings. It allows to fix some errors after recognition.
Hunspell searches for words that are similar to recognized ones in its dictionary.
User correction allows to manually fix some frequently happening mistakes.
User correction occurs before hunspell correction if both are enabled</source>
<translation>Эта страница содаржит настройки исправления распознанного текста. Это позволяет исправить некоторые ошибки в результатах распознавания.
Hunspell ищет в своем словаре слова, похожие на распознанные.
Пользовательская коррекция позволяет вручную изменить частые ошибки.
Пользовательская коррекция выполняется до коррекции hunspell, если они обе активированы</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="74"/>
<source>Translation</source>
<translation>Перевод</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="30"/>
<location filename="../../src/settingseditor.cpp" line="75"/>
<source>This page contains settings, related to translation of the recognized text. Translation is done via enabled (checked) translation services. If one fails, then second one will be used and so on. If translator hangs it will be treated as failed after given timeout</source>
<translation>Эта страница содержит настройки перевода распознанного текста. Перевод выполняется через активированные (выделенные) сервисы перевода. Если один переводчик не может перевести тест, то используется следующие и т.д. Если переводчик не отвечает в течение заданного времени, то также выполняется переход к следующему</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="83"/>
<source>Representation</source>
<translation>Отображение</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="30"/>
<location filename="../../src/settingseditor.cpp" line="84"/>
<source>This page contains result representation settings</source>
<translation>Эта страница содержит настройки отображения результатов</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="87"/>
<source>Update</source>
<translation>Обновление</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="31"/>
<location filename="../../src/settingseditor.cpp" line="88"/>
<source>This page allow to install/update/remove program resources</source>
<translation>Эта страница позволяет устанавливать,обновлять и удалять ресурсы, используемые программой</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="90"/>
<source>Help</source>
<translation>Помощь</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="40"/>
<location filename="../../src/settingseditor.cpp" line="110"/>
<source>Disabled</source>
<translation>Отключен</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="41"/>
<location filename="../../src/settingseditor.cpp" line="111"/>
<source>System</source>
<translation>Системный</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="42"/>
<location filename="../../src/settingseditor.cpp" line="112"/>
<source>SOCKS 5</source>
<translation>SOCKS 5</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="43"/>
<location filename="../../src/settingseditor.cpp" line="113"/>
<source>HTTP</source>
<translation>HTTP</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="57"/>
<location filename="../../src/settingseditor.cpp" line="127"/>
<source>Optimized</source>
<translation>Оптимизированная</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="58"/>
<location filename="../../src/settingseditor.cpp" line="128"/>
<source>Compatible</source>
<translation>Совместимая</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="62"/>
<location filename="../../src/settingseditor.cpp" line="132"/>
<source>Use compatible version if you are experiencing crashes during recognition</source>
<translation>Используйте совместимую версию если программа неожиданно завершается во время распознавания</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="74"/>
<location filename="../../src/settingseditor.cpp" line="144"/>
<source>&lt;b&gt;NOTE! Some translators might require the translation window to be visible. You can make it using the &quot;Show translator&quot; entry in the tray icon&apos;s context menu&lt;/b&gt;</source>
<translation>&lt;b&gt;ПРИМЕЧАНИЕ! Для работы некоторых переводчиков может потребоваться активное окно перевода. Его можно отобразить при помощи пункта &quot;Показать окно перевода&quot; контекстного меню иконки в трее&lt;/b&gt;</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="82"/>
<location filename="../../src/settingseditor.cpp" line="152"/>
<source>Sample text</source>
<translation>Текст для проверки</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="133"/>
<location filename="../../src/settingseditor.cpp" line="200"/>
<source>The program workflow consists of the following steps:
1. Selection on the screen area
2. Recognition of the selected area
@ -1172,9 +1218,9 @@ Then set default recognition and translation languages, enable some (or all) tra
Далее установите языки распознавания и перевода по умолчанию, активируйте некоторые (или все) переводчики и настройку &quot;переводить текст&quot;, если нужно.</translation>
</message>
<message>
<location filename="../../src/settingseditor.cpp" line="363"/>
<location filename="../../src/settingseditor.cpp" line="365"/>
<source>Portable changed. Apply settings first</source>
<translation>Portable режиме изменени. Сначала применить настройки</translation>
<translation>Portable режим изменен. Сначала примените настройки</translation>
</message>
</context>
<context>

View File

@ -5,6 +5,7 @@
#include "recognizer.h"
#include "representer.h"
#include "settingseditor.h"
#include "settingsvalidator.h"
#include "task.h"
#include "translator.h"
#include "trayicon.h"
@ -119,25 +120,11 @@ void Manager::updateSettings()
tray_->setCaptureLockedEnabled(capturer_->canCaptureLocked());
if (models_->sourceLanguageModel()->rowCount() == 0) {
fatalError(
QObject::tr("No recognition languages available. Install some via "
"Settings->Updates"));
}
if (settings_->sourceLanguage.isEmpty()) {
fatalError(
QObject::tr("Recognition language not set. Go to Settings->Recognition "
"and set it"));
}
if (settings_->doTranslation && settings_->translators.isEmpty()) {
fatalError(QObject::tr(
"No translators enabled. Go to Settings->Translation and select some"));
}
if (settings_->doTranslation && settings_->targetLanguage.isEmpty()) {
fatalError(
QObject::tr("Translation language not set. Go to Settings->Translation "
"and set it"));
}
const auto errors = SettingsValidator().check(*settings_, *models_);
if (errors.isEmpty())
return;
fatalError(QObject::tr("Incorrect settings found. Go to Settings"));
}
void Manager::setupProxy(const Settings &settings)

View File

@ -100,8 +100,7 @@ Substitutions loadLegacySubstitutions()
const auto data = f.readAll();
const auto lines =
QString::fromUtf8(data).split('\n', QString::SkipEmptyParts);
const auto lines = QString::fromUtf8(data).split('\n', Qt::SkipEmptyParts);
for (const auto& line : lines) {
const auto parts = line.mid(1, line.size() - 2).split("\",\""); // remove "
if (parts.size() < 3)

View File

@ -1,18 +1,37 @@
#include "settingseditor.h"
#include "debug.h"
#include "languagecodes.h"
#include "manager.h"
#include "runatsystemstart.h"
#include "settingsvalidator.h"
#include "translator.h"
#include "ui_settingseditor.h"
#include "updates.h"
#include "widgetstate.h"
#include <QColorDialog>
#include <QStandardItemModel>
namespace
{
enum class Page { // order must match ui->pagesView
General,
Recognition,
Correction,
Translation,
Representation,
Update,
Help,
Count
};
enum class PageColumn { Name, Description, Error, Count };
} // namespace
SettingsEditor::SettingsEditor(Manager &manager, update::Updater &updater)
: ui(new Ui::SettingsEditor)
, manager_(manager)
, updater_(updater)
, pageModel_(new QStandardItemModel(this))
{
ui->setupUi(this);
@ -20,19 +39,70 @@ SettingsEditor::SettingsEditor(Manager &manager, update::Updater &updater)
this, &SettingsEditor::handleButtonBoxClicked);
connect(ui->portable, &QCheckBox::toggled, //
this, &SettingsEditor::handlePortableChanged);
this, &SettingsEditor::updateState);
ui->runAtSystemStart->setEnabled(service::RunAtSystemStart::isAvailable());
{
auto model = new QStringListModel(this);
model->setStringList({tr("General"), tr("Recognition"), tr("Correction"),
tr("Translation"), tr("Representation"), tr("Update"),
tr("Help")});
ui->pagesList->setModel(model);
struct Info {
QString title;
QString description;
};
QMap<Page, Info> names{
{Page::General,
{tr("General"), tr("This page contains general program settings")}},
{Page::Recognition,
{tr("Recognition"),
tr("This page contains text recognition settings. "
"It shows the available languages that program can convert from "
"image to text")}},
{Page::Correction,
{tr("Correction"),
tr("This page contains recognized text correction settings. "
"It allows to fix some errors after recognition.\n"
"Hunspell searches for words that are similar to recognized ones "
"in its dictionary.\n"
"User correction allows to manually fix some frequently "
"happening mistakes.\n"
"User correction occurs before hunspell correction if both "
"are enabled")}},
{Page::Translation,
{tr("Translation"),
tr("This page contains settings, related to translation of the "
"recognized text. "
"Translation is done via enabled (checked) translation services. "
"If one fails, then second one will be used and so on. "
"If translator hangs it will be treated as failed after "
"given timeout")}},
{Page::Representation,
{tr("Representation"),
tr("This page contains result representation settings")}},
{Page::Update,
{tr("Update"),
tr("This page allow to install/update/remove program resources")}},
{Page::Help, {tr("Help"), tr("")}},
};
for (const auto &i : names) {
const auto error = QString();
pageModel_->appendRow({new QStandardItem(i.title),
new QStandardItem(i.description),
new QStandardItem(error)});
}
ui->pagesList->setModel(pageModel_);
ui->pagesList->setModelColumn(int(PageColumn::Name));
auto selection = ui->pagesList->selectionModel();
connect(selection, &QItemSelectionModel::currentRowChanged, //
this, &SettingsEditor::updateCurrentPage);
selection->select(pageModel_->index(0, 0),
QItemSelectionModel::SelectCurrent);
}
{
@ -89,16 +159,13 @@ SettingsEditor::SettingsEditor(Manager &manager, update::Updater &updater)
connect(ui->fontColor, &QPushButton::clicked, //
this, [this] { pickColor(ColorContext::Font); });
connect(ui->backgroundColor, &QPushButton::clicked, //
this, [this] { pickColor(ColorContext::Bagkround); });
this, [this] { pickColor(ColorContext::Background); });
// updates
ui->updatesView->header()->setObjectName("updatesHeader");
updater_.initView(ui->updatesView);
adjustUpdatesView();
connect(&updater_, &update::Updater::checkedForUpdates, //
this, &SettingsEditor::adjustUpdatesView);
connect(&updater_, &update::Updater::updated, //
this, &SettingsEditor::adjustUpdatesView);
this, &SettingsEditor::updateState);
connect(ui->checkUpdates, &QPushButton::clicked, //
&updater_, &update::Updater::checkForUpdates);
@ -198,13 +265,7 @@ Settings SettingsEditor::settings() const
std::chrono::seconds(ui->translateTimeoutSpin->value());
settings.targetLanguage =
LanguageCodes::idForName(ui->translateLangCombo->currentText());
settings.translators.clear();
for (auto i = 0, end = ui->translatorList->count(); i < end; ++i) {
auto item = ui->translatorList->item(i);
if (item->checkState() == Qt::Checked)
settings.translators.append(item->text());
}
settings.translators = enabledTranslators();
settings.resultShowType =
ui->trayRadio->isChecked() ? ResultMode::Tooltip : ResultMode::Widget;
@ -223,11 +284,10 @@ Settings SettingsEditor::settings() const
void SettingsEditor::setSettings(const Settings &settings)
{
if (settings.isPortable() == ui->portable->isChecked())
updateModels(settings.tessdataPath);
wasPortable_ = settings.isPortable();
ui->portable->blockSignals(true);
ui->portable->setChecked(settings.isPortable());
ui->portable->blockSignals(false);
ui->runAtSystemStart->setChecked(settings.runAtSystemStart);
@ -248,6 +308,7 @@ void SettingsEditor::setSettings(const Settings &settings)
ui->proxySaveCheck->setChecked(settings.proxySavePassword);
ui->tessdataPath->setText(settings.tessdataPath);
updateModels();
ui->tesseractLangCombo->setCurrentText(
LanguageCodes::name(settings.sourceLanguage));
ui->tesseractVersion->setCurrentIndex(int(settings.tesseractVersion));
@ -261,10 +322,9 @@ void SettingsEditor::setSettings(const Settings &settings)
ui->ignoreSslCheck->setChecked(settings.ignoreSslErrors);
ui->translateTimeoutSpin->setValue(settings.translationTimeout.count());
ui->translatorsPath->setText(settings.translatorsDir);
enabledTranslators_ = settings.translators;
updateTranslators();
ui->translateLangCombo->setCurrentText(
LanguageCodes::name(settings.targetLanguage));
updateTranslators(settings.translators);
ui->trayRadio->setChecked(settings.resultShowType == ResultMode::Tooltip);
ui->dialogRadio->setChecked(settings.resultShowType == ResultMode::Widget);
@ -282,19 +342,52 @@ void SettingsEditor::setSettings(const Settings &settings)
ui->showCaptured->setChecked(settings.showCaptured);
ui->autoUpdateInterval->setValue(settings.autoUpdateIntervalDays);
updateState();
}
void SettingsEditor::updateState()
{
Settings settings;
settings.setPortable(ui->portable->isChecked());
ui->tessdataPath->setText(settings.tessdataPath);
ui->translatorsPath->setText(settings.translatorsDir);
ui->hunspellDir->setText(settings.hunspellDir);
updateModels();
updateTranslators(enabledTranslators());
validateSettings();
updateCurrentPage();
const auto portableChanged = wasPortable_ != settings.isPortable();
ui->pageUpdate->setEnabled(!portableChanged);
ui->pageUpdate->setToolTip(portableChanged
? tr("Portable changed. Apply settings first")
: QString());
}
void SettingsEditor::updateCurrentPage()
{
ui->pagesView->setCurrentIndex(ui->pagesList->currentIndex().row());
const auto row = ui->pagesList->currentIndex().row();
const auto description = pageModel_->index(row, int(PageColumn::Description));
ui->pageInfoLabel->setText(description.data().toString());
ui->pageInfoLabel->setVisible(!ui->pageInfoLabel->text().isEmpty());
const auto error = pageModel_->index(row, int(PageColumn::Error));
ui->pageErrorLabel->setText(error.data().toString());
ui->pageErrorLabel->setVisible(!ui->pageErrorLabel->text().isEmpty());
ui->pagesView->setCurrentIndex(row);
if (ui->pagesView->currentWidget() != ui->pageUpdate)
return;
if (ui->updatesView->model()->rowCount() == 0)
updater_.checkForUpdates();
}
void SettingsEditor::updateTranslators()
void SettingsEditor::updateTranslators(const QStringList &translators)
{
ui->translatorList->clear();
@ -304,30 +397,15 @@ void SettingsEditor::updateTranslators()
std::sort(names.begin(), names.end());
if (!enabledTranslators_.isEmpty()) {
for (const auto &name : enabledTranslators_) names.removeOne(name);
names = enabledTranslators_ + names;
}
ui->translatorList->addItems(names);
for (auto i = 0, end = ui->translatorList->count(); i < end; ++i) {
auto item = ui->translatorList->item(i);
item->setCheckState(enabledTranslators_.contains(item->text())
? Qt::Checked
: Qt::Unchecked);
item->setCheckState(translators.contains(item->text()) ? Qt::Checked
: Qt::Unchecked);
}
}
void SettingsEditor::adjustUpdatesView()
{
if (ui->tessdataPath->text().isEmpty()) // not inited yet
return;
updateModels(ui->tessdataPath->text());
updateTranslators();
}
void SettingsEditor::handleButtonBoxClicked(QAbstractButton *button)
{
if (!button)
@ -344,31 +422,12 @@ void SettingsEditor::handleButtonBoxClicked(QAbstractButton *button)
if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
const auto settings = this->settings();
manager_.applySettings(settings);
if (settings.isPortable() != wasPortable_) {
wasPortable_ = settings.isPortable();
handlePortableChanged();
}
wasPortable_ = ui->portable->isChecked();
updateState();
return;
}
}
void SettingsEditor::handlePortableChanged()
{
Settings settings;
settings.setPortable(ui->portable->isChecked());
ui->tessdataPath->setText(settings.tessdataPath);
ui->translatorsPath->setText(settings.translatorsDir);
ui->hunspellDir->setText(settings.hunspellDir);
updateModels(settings.tessdataPath);
updateTranslators();
const auto portableChanged = wasPortable_ != settings.isPortable();
ui->pageUpdate->setEnabled(!portableChanged);
ui->pageUpdate->setToolTip(portableChanged
? tr("Portable changed. Apply settings first")
: QString());
}
void SettingsEditor::updateResultFont()
{
auto font = ui->resultFont->currentFont();
@ -376,10 +435,21 @@ void SettingsEditor::updateResultFont()
ui->resultFont->setFont(font);
}
void SettingsEditor::updateModels(const QString &tessdataPath)
QStringList SettingsEditor::enabledTranslators() const
{
QStringList result;
for (auto i = 0, end = ui->translatorList->count(); i < end; ++i) {
auto item = ui->translatorList->item(i);
if (item->checkState() == Qt::Checked)
result.append(item->text());
}
return result;
}
void SettingsEditor::updateModels()
{
const auto source = ui->tesseractLangCombo->currentText();
models_.update(tessdataPath);
models_.update(ui->tessdataPath->text());
if (!source.isEmpty()) {
ui->tesseractLangCombo->setCurrentText(source);
} else if (ui->tesseractLangCombo->count() > 0) {
@ -401,7 +471,7 @@ void SettingsEditor::pickColor(ColorContext context)
palette.setColor(QPalette::Button, color);
widget->setPalette(palette);
if (context == ColorContext::Bagkround)
if (context == ColorContext::Background)
return;
palette = ui->backgroundColor->palette();
@ -409,3 +479,44 @@ void SettingsEditor::pickColor(ColorContext context)
ui->backgroundColor->setPalette(palette);
ui->backgroundColor->update();
}
void SettingsEditor::validateSettings()
{
for (auto i = 0, end = pageModel_->rowCount(); i < end; ++i) {
const auto name = pageModel_->index(i, int(PageColumn::Name));
pageModel_->setData(name, QBrush(Qt::black), Qt::ForegroundRole);
const auto error = pageModel_->index(i, int(PageColumn::Error));
pageModel_->setData(error, {});
}
SettingsValidator validator;
const auto errors = validator.check(settings(), models_);
if (errors.isEmpty())
return;
using E = SettingsValidator::Error;
QMap<E, Page> errorToPage{
{E::NoSourceInstalled, Page::Update},
{E::NoSourceSet, Page::Recognition},
{E::NoTranslatorInstalled, Page::Update},
{E::NoTranslatorSet, Page::Translation},
{E::NoTargetSet, Page::Translation},
};
QMap<Page, QStringList> summary;
for (const auto err : errors) {
SOFT_ASSERT(errorToPage.contains(err), continue);
auto page = errorToPage[err];
summary[page].push_back(validator.toString(err));
}
for (auto it = summary.cbegin(), end = summary.cend(); it != end; ++it) {
const auto row = int(it.key());
const auto index = pageModel_->index(row, int(PageColumn::Name));
pageModel_->setData(index, QBrush(Qt::red), Qt::ForegroundRole);
const auto error = pageModel_->index(row, int(PageColumn::Error));
pageModel_->setData(error, it.value().join('\n'));
}
}

View File

@ -10,6 +10,7 @@ namespace Ui
class SettingsEditor;
}
class QAbstractButton;
class QStandardItemModel;
class SettingsEditor : public QDialog
{
@ -23,20 +24,22 @@ public:
void setSettings(const Settings &settings);
private:
enum ColorContext { Font, Bagkround };
void updateCurrentPage();
void updateTranslators();
void adjustUpdatesView();
enum ColorContext { Font, Background };
void handleButtonBoxClicked(QAbstractButton *button);
void handlePortableChanged();
void updateResultFont();
void updateModels(const QString &tessdataPath);
void pickColor(ColorContext context);
void updateResultFont();
QStringList enabledTranslators() const;
void updateState();
void updateCurrentPage();
void updateTranslators(const QStringList &translators);
void updateModels();
void validateSettings();
Ui::SettingsEditor *ui;
Manager &manager_;
update::Updater &updater_;
CommonModels models_;
QStringList enabledTranslators_;
bool wasPortable_{false};
QStandardItemModel *pageModel_;
};

File diff suppressed because it is too large Load Diff

46
src/settingsvalidator.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "settingsvalidator.h"
#include <commonmodels.h>
#include <settings.h>
QVector<SettingsValidator::Error> SettingsValidator::check(
const Settings &settings, const CommonModels &models) const
{
QVector<SettingsValidator::Error> result;
if (models.sourceLanguageModel()->rowCount() == 0)
result.append(Error::NoSourceInstalled);
if (settings.sourceLanguage.isEmpty())
result.append(Error::NoSourceSet);
if (settings.doTranslation && models.targetLanguageModel()->rowCount() == 0)
result.append(Error::NoTranslatorInstalled);
if (settings.doTranslation && settings.translators.isEmpty())
result.append(Error::NoTranslatorSet);
if (settings.doTranslation && settings.targetLanguage.isEmpty())
result.append(Error::NoTargetSet);
return result;
}
QString SettingsValidator::toString(Error error) const
{
switch (error) {
case Error::NoSourceInstalled:
return QObject::tr("No recognizers installed");
case Error::NoSourceSet: return QObject::tr("Recognition language not set");
case Error::NoTranslatorInstalled:
return QObject::tr("No translators installed");
case Error::NoTranslatorSet:
return QObject::tr("No translators enabled (selected)");
case Error::NoTargetSet: return QObject::tr("Translation language not set");
}
return {};
}

21
src/settingsvalidator.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <stfwd.h>
#include <QVector>
class SettingsValidator
{
public:
enum class Error {
NoSourceInstalled,
NoSourceSet,
NoTranslatorSet,
NoTranslatorInstalled,
NoTargetSet
};
QVector<Error> check(const Settings& settings,
const CommonModels& models) const;
QString toString(Error error) const;
};