ScreenTranslator/src/correct/corrector.cpp

121 lines
2.8 KiB
C++
Raw Normal View History

2020-02-21 00:45:53 +07:00
#include "corrector.h"
2020-04-09 03:17:23 +07:00
#include "correctorworker.h"
2020-02-21 00:45:53 +07:00
#include "debug.h"
#include "languagecodes.h"
2020-02-21 00:45:53 +07:00
#include "manager.h"
2020-03-21 17:03:58 +07:00
#include "settings.h"
2020-02-21 00:45:53 +07:00
#include "task.h"
2020-04-09 03:17:23 +07:00
#include <QThread>
2020-03-21 17:03:58 +07:00
Corrector::Corrector(Manager &manager, const Settings &settings)
2020-02-21 00:45:53 +07:00
: manager_(manager)
2020-03-21 17:03:58 +07:00
, settings_(settings)
2020-04-09 03:17:23 +07:00
, workerThread_(new QThread(this))
{
auto worker = new CorrectorWorker;
connect(this, &Corrector::resetAuto, //
worker, &CorrectorWorker::reset);
connect(this, &Corrector::correctAuto, //
worker, &CorrectorWorker::handle);
connect(worker, &CorrectorWorker::finished, //
this, &Corrector::finishCorrection);
connect(workerThread_, &QThread::finished, //
worker, &QObject::deleteLater);
workerThread_->start();
worker->moveToThread(workerThread_);
}
Corrector::~Corrector()
2020-02-21 00:45:53 +07:00
{
2020-04-09 03:17:23 +07:00
workerThread_->quit();
const auto timeoutMs = 2000;
if (!workerThread_->wait(timeoutMs))
workerThread_->terminate();
2020-02-21 00:45:53 +07:00
}
void Corrector::correct(const TaskPtr &task)
{
SOFT_ASSERT(task, return );
SOFT_ASSERT(task->isValid(), return );
2020-03-09 15:47:40 +07:00
if (task->recognized.isEmpty()) {
manager_.corrected(task);
return;
}
2020-04-09 03:17:23 +07:00
task->corrected = task->recognized;
2020-04-24 02:06:08 +07:00
if (!settings_.userSubstitutions.empty()) {
task->corrected = substituteUser(task->recognized, task->sourceLanguage);
2020-04-24 02:06:08 +07:00
LTRACE() << "Corrected with user data";
}
2020-02-21 00:45:53 +07:00
2020-04-09 03:17:23 +07:00
if (task->useHunspell) {
emit correctAuto(task);
return;
}
finishCorrection(task);
}
void Corrector::updateSettings()
{
emit resetAuto(settings_.hunspellDir);
}
void Corrector::finishCorrection(const TaskPtr &task)
{
2020-02-21 00:45:53 +07:00
manager_.corrected(task);
}
QString Corrector::substituteUser(const QString &source,
const LanguageId &language) const
{
auto result = source;
using It = Substitutions::const_iterator;
std::vector<std::pair<It, It>> ranges;
{
const auto range = settings_.userSubstitutions.equal_range(language);
if (range.first != settings_.userSubstitutions.cend())
ranges.push_back(range);
}
{
const auto anyId = LanguageCodes::anyLanguageId();
const auto range = settings_.userSubstitutions.equal_range(anyId);
if (range.first != settings_.userSubstitutions.cend())
ranges.push_back(range);
}
if (ranges.empty())
2020-02-21 00:45:53 +07:00
return result;
while (true) {
auto bestMatch = ranges.front().first;
2020-02-21 00:45:53 +07:00
auto bestMatchLen = 0;
for (const auto &range : ranges) {
for (auto it = range.first; it != range.second; ++it) {
const auto &sub = it->second;
if (!result.contains(sub.source))
continue;
const auto len = sub.source.length();
if (len > bestMatchLen) {
bestMatchLen = len;
bestMatch = it;
}
2020-02-21 00:45:53 +07:00
}
}
if (bestMatchLen < 1)
break;
result.replace(bestMatch->second.source, bestMatch->second.target);
}
return result;
}