#include #include #include #include #include #include "WebTranslator.h" #include "ProcessingItem.h" #include "Settings.h" #include "StAssert.h" #include "WebTranslatorProxy.h" #include "TranslatorHelper.h" WebTranslator::WebTranslator () : QObject (), proxy_ (new WebTranslatorProxy (this)), view_ (new QWebView), translatorHelper_ (new TranslatorHelper), isReady_ (true) { view_->settings ()->setAttribute (QWebSettings::AutoLoadImages, false); view_->settings ()->setAttribute (QWebSettings::DeveloperExtrasEnabled, true); view_->settings ()->setAttribute (QWebSettings::LocalStorageEnabled, true); 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 *))); translationTimeout_.setSingleShot (true); connect (&translationTimeout_, SIGNAL (timeout ()), SLOT (abortTranslation ())); connect (proxy_, SIGNAL (translated (QString)), SLOT (proxyTranslated (QString))); // Delay because it can emit signal that is not connected yet. QTimer::singleShot (500, this, SLOT (applySettings ())); } WebTranslator::~WebTranslator () { delete translatorHelper_; delete view_; } void WebTranslator::addProxyToView () { view_->page ()->mainFrame ()->addToJavaScriptWindowObject ("st_wtp", proxy_); view_->page ()->mainFrame ()->evaluateJavaScript (translatorHelper_->currentScript ()); } void WebTranslator::translate (ProcessingItem item) { if (item.translateLanguage.isEmpty ()) { emit translated (item); return; } queue_.push_back (item); translateQueued (); } void WebTranslator::translateQueued () { if (isReady_ && !queue_.isEmpty ()) { translatorHelper_->newItem (); proxy_->setItem (queue_.first ()); if (!tryNextTranslator (true)) { return; } } } void WebTranslator::proxyTranslated (const QString &text) { if (!queue_.isEmpty () && queue_.first ().recognized == proxy_->sourceText ()) { if (text.isEmpty () && tryNextTranslator ()) { return; } ProcessingItem &item = queue_.first (); item.translated = text; emit translated (item); } finishTranslation (false); } void WebTranslator::abortTranslation () { if (!tryNextTranslator ()) { emit error (tr ("Перевод отменен по таймауту.")); finishTranslation (); } } void WebTranslator::loadFinished (bool ok) { if (!ok && !tryNextTranslator ()) { QString url = view_->url ().toString (); emit error (tr ("Ошибка загрузки страницы (%1) для перевода.").arg (url)); finishTranslation (); } } void WebTranslator::finishTranslation (bool markAsTranslated) { translationTimeout_.stop (); view_->stop (); if (!queue_.isEmpty ()) { if (markAsTranslated) { emit translated (queue_.first ()); } queue_.pop_front (); } isReady_ = true; translateQueued (); } 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; } 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); translatorHelper_->loadScripts (); if (!translatorHelper_->gotScripts ()) { emit error (tr ("Нет сценариев для перевода. Измените настройки.")); } bool debugMode = GET (translationDebugMode).toBool (); setDebugMode (debugMode); #undef GET } void WebTranslator::setDebugMode (bool isOn) { view_->setVisible (isOn); }