ScreenTranslator/WebTranslator.cpp

157 lines
4.9 KiB
C++
Raw Normal View History

2015-10-08 22:36:02 +07:00
#include <QWebView>
#include <QWebFrame>
#include <QSettings>
#include <QNetworkReply>
#include <QFile>
#include "WebTranslator.h"
#include "ProcessingItem.h"
#include "Settings.h"
#include "StAssert.h"
#include "WebTranslatorProxy.h"
2015-10-10 03:33:35 +07:00
#include "TranslatorHelper.h"
2015-10-08 22:36:02 +07:00
WebTranslator::WebTranslator ()
: QObject (),
2015-10-10 03:33:35 +07:00
proxy_ (new WebTranslatorProxy (this)), view_ (new QWebView),
2017-05-27 17:03:17 +07:00
translatorHelper_ (new TranslatorHelper), isReady_ (true),
2018-02-23 01:31:24 +07:00
ignoreSslErrors_ (settings_values::ignoreSslErrors),
forceRotateTranslators_ (settings_values::forceRotateTranslators) {
2015-10-08 22:36:02 +07:00
view_->settings ()->setAttribute (QWebSettings::AutoLoadImages, false);
view_->settings ()->setAttribute (QWebSettings::DeveloperExtrasEnabled, true);
view_->settings ()->setAttribute (QWebSettings::LocalStorageEnabled, true);
2015-10-08 22:36:02 +07:00
connect (view_, SIGNAL (loadFinished (bool)), SLOT (loadFinished (bool)));
connect (view_->page ()->mainFrame (), SIGNAL (javaScriptWindowObjectCleared ()),
this, SLOT (addProxyToView ()));
connect (view_->page ()->networkAccessManager (), SIGNAL (finished (QNetworkReply *)),
this, SLOT (replyFinished (QNetworkReply *)));
2017-05-27 17:03:17 +07:00
connect (view_->page ()->networkAccessManager (),
SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)),
this, SLOT (handleSslErrors (QNetworkReply *, QList<QSslError>)));
2015-10-08 22:36:02 +07:00
translationTimeout_.setSingleShot (true);
connect (&translationTimeout_, SIGNAL (timeout ()), SLOT (abortTranslation ()));
connect (proxy_, SIGNAL (translated (QString)), SLOT (proxyTranslated (QString)));
2015-10-10 03:33:35 +07:00
// Delay because it can emit signal that is not connected yet.
QTimer::singleShot (500, this, SLOT (applySettings ()));
2015-10-08 22:36:02 +07:00
}
WebTranslator::~WebTranslator () {
2015-10-10 03:33:35 +07:00
delete translatorHelper_;
2015-10-08 22:36:02 +07:00
delete view_;
}
void WebTranslator::addProxyToView () {
view_->page ()->mainFrame ()->addToJavaScriptWindowObject ("st_wtp", proxy_);
2015-10-10 03:33:35 +07:00
view_->page ()->mainFrame ()->evaluateJavaScript (translatorHelper_->currentScript ());
2015-10-08 22:36:02 +07:00
}
void WebTranslator::translate (ProcessingItem item) {
if (!item.isValid () || item.translateLanguage.isEmpty ()) {
emit translated (item);
return;
}
2015-10-08 22:36:02 +07:00
queue_.push_back (item);
translateQueued ();
}
void WebTranslator::translateQueued () {
2015-10-10 03:33:35 +07:00
if (isReady_ && !queue_.isEmpty ()) {
2018-02-23 01:31:24 +07:00
translatorHelper_->newItem (forceRotateTranslators_);
2015-10-10 03:33:35 +07:00
proxy_->setItem (queue_.first ());
if (!tryNextTranslator (true)) {
return;
}
2015-10-08 22:36:02 +07:00
}
}
void WebTranslator::proxyTranslated (const QString &text) {
if (!queue_.isEmpty () && queue_.first ().recognized == proxy_->sourceText ()) {
2015-10-10 03:33:35 +07:00
if (text.isEmpty () && tryNextTranslator ()) {
return;
}
2015-10-08 22:36:02 +07:00
ProcessingItem &item = queue_.first ();
item.translated = text;
emit translated (item);
}
finishTranslation (false);
2015-10-08 22:36:02 +07:00
}
2017-05-27 17:03:17 +07:00
void WebTranslator::handleSslErrors (QNetworkReply *reply, const QList<QSslError> &) {
if (ignoreSslErrors_) {
reply->ignoreSslErrors ();
}
}
2015-10-08 22:36:02 +07:00
void WebTranslator::abortTranslation () {
2015-10-10 03:33:35 +07:00
if (!tryNextTranslator ()) {
emit error (tr ("Перевод отменен по таймауту."));
finishTranslation ();
}
2015-10-08 22:36:02 +07:00
}
void WebTranslator::loadFinished (bool ok) {
2015-10-10 03:33:35 +07:00
if (!ok && !tryNextTranslator ()) {
2015-10-08 22:36:02 +07:00
QString url = view_->url ().toString ();
emit error (tr ("Ошибка загрузки страницы (%1) для перевода.").arg (url));
finishTranslation ();
}
}
void WebTranslator::finishTranslation (bool markAsTranslated) {
2015-10-08 22:36:02 +07:00
translationTimeout_.stop ();
view_->stop ();
2015-10-08 22:36:02 +07:00
if (!queue_.isEmpty ()) {
if (markAsTranslated) {
emit translated (queue_.first ());
}
2015-10-08 22:36:02 +07:00
queue_.pop_front ();
}
isReady_ = true;
translateQueued ();
}
2015-10-10 03:33:35 +07:00
bool WebTranslator::tryNextTranslator (bool firstTime) {
QString script = firstTime ? translatorHelper_->currentScript ()
: translatorHelper_->nextScript ();
if (script.isEmpty ()) {
return false;
}
translationTimeout_.stop ();
view_->stop ();
addProxyToView ();
view_->page ()->mainFrame ()->evaluateJavaScript ("translate();");
isReady_ = false;
translationTimeout_.start ();
return true;
}
2015-10-08 22:36:02 +07:00
void WebTranslator::replyFinished (QNetworkReply *reply) {
emit proxy_->resourceLoaded (reply->url ().toString ());
}
void WebTranslator::applySettings () {
QSettings settings;
settings.beginGroup (settings_names::translationGroup);
#define GET(NAME) settings.value (settings_names::NAME, settings_values::NAME)
translationTimeout_.setInterval (GET (translationTimeout).toInt () * 1000);
2015-10-10 03:33:35 +07:00
translatorHelper_->loadScripts ();
if (!translatorHelper_->gotScripts ()) {
emit error (tr ("Нет сценариев для перевода. Измените настройки."));
2015-10-08 22:36:02 +07:00
}
2015-10-10 03:34:03 +07:00
bool debugMode = GET (translationDebugMode).toBool ();
setDebugMode (debugMode);
2017-05-27 17:03:17 +07:00
2018-02-23 01:31:24 +07:00
ignoreSslErrors_ = GET (ignoreSslErrors).toBool ();
forceRotateTranslators_ = GET (forceRotateTranslators).toBool ();
2015-10-10 03:33:35 +07:00
#undef GET
2015-10-08 22:36:02 +07:00
}
void WebTranslator::setDebugMode (bool isOn) {
view_->setVisible (isOn);
}