From ff43ab624bb4816c592c0d8a2dca081a13dec0d3 Mon Sep 17 00:00:00 2001 From: msn Date: Sun, 24 Nov 2013 16:43:37 +0400 Subject: [PATCH] works --- GlobalActionHelper.cpp | 34 ++++++- GlobalActionHelper.h | 1 + Manager.cpp | 50 ++++++++-- Manager.h | 6 ++ Recognizer.cpp | 83 ++++++++++++++++- Recognizer.h | 18 ++++ ScreenTranslator.pro | 8 +- SelectionDialog.cpp | 16 +++- Settings.h | 42 +++++++++ SettingsEditor.cpp | 189 ++++++++++++++++++++++++++++++++++++++ SettingsEditor.h | 17 ++++ SettingsEditor.ui | 203 +++++++++++++++++++++++++---------------- Translator.cpp | 84 ++++++++++++++++- Translator.h | 11 ++- main.cpp | 5 +- 15 files changed, 667 insertions(+), 100 deletions(-) create mode 100644 Settings.h diff --git a/GlobalActionHelper.cpp b/GlobalActionHelper.cpp index d7b206d..349265e 100644 --- a/GlobalActionHelper.cpp +++ b/GlobalActionHelper.cpp @@ -32,6 +32,10 @@ void GlobalActionHelper::init() bool GlobalActionHelper::makeGlobal(QAction* action) { QKeySequence hotKey = action->shortcut (); + if (hotKey.isEmpty ()) + { + return true; + } Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; Qt::Key key = hotKey.isEmpty() ? @@ -50,6 +54,35 @@ bool GlobalActionHelper::makeGlobal(QAction* action) return res; } +bool GlobalActionHelper::removeGlobal(QAction *action) +{ + QKeySequence hotKey = action->shortcut (); + if (hotKey.isEmpty ()) + { + return true; + } + Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | + Qt::AltModifier | Qt::MetaModifier; + Qt::Key key = hotKey.isEmpty() ? + Qt::Key(0) : + Qt::Key((hotKey[0] ^ allMods) & hotKey[0]); + Qt::KeyboardModifiers mods = hotKey.isEmpty() ? + Qt::KeyboardModifiers(0) : + Qt::KeyboardModifiers(hotKey[0] & allMods); + const quint32 nativeKey = nativeKeycode(key); + const quint32 nativeMods = nativeModifiers(mods); + if (!actions_.contains (qMakePair(nativeKey, nativeMods))) + { + return true; + } + const bool res = unregisterHotKey(nativeKey, nativeMods); + if (res) + actions_.remove (qMakePair(nativeKey, nativeMods)); + else + qWarning() << "Failed to unregister global hotkey:" << hotKey.toString(); + return res; +} + quint32 GlobalActionHelper::nativeKeycode(Qt::Key key) { switch (key) @@ -227,7 +260,6 @@ quint32 GlobalActionHelper::nativeModifiers(Qt::KeyboardModifiers modifiers) native |= MOD_ALT; if (modifiers & Qt::MetaModifier) native |= MOD_WIN; - // TODO: resolve these? //if (modifiers & Qt::KeypadModifier) //if (modifiers & Qt::GroupSwitchModifier) return native; diff --git a/GlobalActionHelper.h b/GlobalActionHelper.h index 41ed160..05e2826 100644 --- a/GlobalActionHelper.h +++ b/GlobalActionHelper.h @@ -14,6 +14,7 @@ class GlobalActionHelper : public QAbstractNativeEventFilter static void init (); static bool makeGlobal (QAction* action); + static bool removeGlobal (QAction* action); private: static QHash, QAction*> actions_; diff --git a/Manager.cpp b/Manager.cpp index b8f727b..62dd275 100644 --- a/Manager.cpp +++ b/Manager.cpp @@ -7,7 +7,9 @@ #include #include #include +#include +#include "Settings.h" #include "SettingsEditor.h" #include "SelectionDialog.h" #include "GlobalActionHelper.h" @@ -17,7 +19,8 @@ Manager::Manager(QObject *parent) : QObject(parent), trayIcon_ (new QSystemTrayIcon (QIcon (":/images/icon.png"), this)), - selection_ (new SelectionDialog) + selection_ (new SelectionDialog), + captureAction_ (NULL) { GlobalActionHelper::init (); @@ -28,6 +31,8 @@ Manager::Manager(QObject *parent) : Recognizer* recognizer = new Recognizer; connect (selection_, SIGNAL (selected (QPixmap)), recognizer, SLOT (recognize (QPixmap))); + connect (recognizer, SIGNAL (error (QString)), + SLOT (showError (QString))); QThread* recognizerThread = new QThread (this); recognizer->moveToThread (recognizerThread); recognizerThread->start (); @@ -35,6 +40,8 @@ Manager::Manager(QObject *parent) : Translator* translator = new Translator; connect (recognizer, SIGNAL (recognized (QString)), translator, SLOT (translate (QString))); + connect (translator, SIGNAL (error (QString)), + SLOT (showError (QString))); QThread* translatorThread = new QThread (this); translator->moveToThread (translatorThread); translatorThread->start (); @@ -42,25 +49,43 @@ Manager::Manager(QObject *parent) : connect (translator, SIGNAL (translated (QString, QString)), SLOT (showTranslation (QString, QString))); + + connect (this, SIGNAL (settingsEdited ()), this, SLOT (applySettings ())); + connect (this, SIGNAL (settingsEdited ()), recognizer, SLOT (applySettings ())); + connect (this, SIGNAL (settingsEdited ()), translator, SLOT (applySettings ())); + trayIcon_->setContextMenu (trayContextMenu ()); trayIcon_->show (); -} -Manager::~Manager() -{ + applySettings (); } QMenu*Manager::trayContextMenu() { QMenu* menu = new QMenu (); - QAction* capture = menu->addAction (tr ("Захват"), this, SLOT (capture ()), - tr ("Ctrl+Alt+Z")); - GlobalActionHelper::makeGlobal (capture); + captureAction_ = menu->addAction (tr ("Захват"), this, SLOT (capture ())); menu->addAction (tr ("Настройки"), this, SLOT (settings ())); menu->addAction (tr ("Выход"), this, SLOT (close ())); return menu; } +void Manager::applySettings() +{ + QSettings settings; + settings.beginGroup (settings_names::guiGroup); + QString captureHotkey = settings.value (settings_names::captureHotkey, + settings_values::captureHotkey). + toString (); + Q_CHECK_PTR (captureAction_); + GlobalActionHelper::removeGlobal (captureAction_); + captureAction_->setShortcut (captureHotkey); + GlobalActionHelper::makeGlobal (captureAction_); +} + +Manager::~Manager() +{ +} + void Manager::capture() { QList screens = QApplication::screens (); @@ -77,6 +102,7 @@ void Manager::settings() { SettingsEditor editor; editor.setWindowIcon (trayIcon_->icon ()); + connect (&editor, SIGNAL (settingsEdited ()), SIGNAL (settingsEdited ())); editor.exec (); } @@ -87,5 +113,13 @@ void Manager::close() void Manager::showTranslation(QString sourceText, QString translatedText) { - + QString message = sourceText + " - " + translatedText; + qDebug () << sourceText << translatedText; + trayIcon_->showMessage (tr ("Перевод"), message, QSystemTrayIcon::Information); +} + +void Manager::showError(QString text) +{ + qCritical () << text; + trayIcon_->showMessage (tr ("Ошибка"), text, QSystemTrayIcon::Critical); } diff --git a/Manager.h b/Manager.h index 53c0523..b9d01ae 100644 --- a/Manager.h +++ b/Manager.h @@ -4,6 +4,7 @@ #include #include +class QAction; class QMenu; class QSystemTrayIcon; @@ -19,13 +20,17 @@ class Manager : public QObject signals: void showPixmap (QPixmap pixmap); void recognize (QPixmap pixmap); + void settingsEdited (); private slots: void capture (); void settings (); void close (); + void applySettings (); + void showTranslation (QString sourceText, QString translatedText); + void showError (QString text); private: QMenu* trayContextMenu (); @@ -33,6 +38,7 @@ class Manager : public QObject private: QSystemTrayIcon* trayIcon_; SelectionDialog* selection_; + QAction* captureAction_; }; diff --git a/Recognizer.cpp b/Recognizer.cpp index 4dbddb1..70be52f 100644 --- a/Recognizer.cpp +++ b/Recognizer.cpp @@ -1,11 +1,92 @@ #include "Recognizer.h" +#include + +#include +#include + +#include "Settings.h" + Recognizer::Recognizer(QObject *parent) : - QObject(parent) + QObject(parent), + engine_ (NULL), imageScale_ (0) { + applySettings (); +} + +void Recognizer::applySettings() +{ + QSettings settings; + settings.beginGroup (settings_names::recogntionGroup); + + tessDataDir_ = settings.value (settings_names::tessDataPlace, + settings_values::tessDataPlace).toString (); + ocrLanguage_ = settings.value (settings_names::ocrLanguage, + settings_values::ocrLanguage).toString (); + imageScale_ = settings.value (settings_names::imageScale, + settings_values::imageScale).toInt (); + + initEngine (); +} + +bool Recognizer::initEngine() +{ + if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ()) + { + emit error (tr ("Неверные параметры для OCR")); + return false; + } + if (engine_ != NULL) + { + delete engine_; + } + engine_ = new tesseract::TessBaseAPI(); + int result = engine_->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_), + tesseract::OEM_DEFAULT); + if (result != 0) + { + emit error (tr ("Ошибка инициализации OCR: %1").arg (result)); + delete engine_; + engine_ = NULL; + return false; + } + return true; } void Recognizer::recognize(QPixmap pixmap) { + Q_ASSERT (!pixmap.isNull ()); + if (engine_ == NULL) + { + if (!initEngine ()) + { + return; + } + } + QPixmap scaled = pixmap; + if (imageScale_ > 0) + { + scaled = pixmap.scaledToHeight (pixmap.height () * imageScale_, + Qt::SmoothTransformation); + } + QImage image = scaled.toImage (); + const int bytesPerPixel = image.depth () / 8; + engine_->SetImage (image.bits (), image.width (), image.height (), + bytesPerPixel, image.bytesPerLine ()); + + char* outText = engine_->GetUTF8Text(); + engine_->Clear(); + + QString result (outText); + result = result.trimmed(); + if (!result.isEmpty ()) + { + emit recognized (result); + } + else + { + emit error (tr ("Текст не распознан.")); + } + delete [] outText; } diff --git a/Recognizer.h b/Recognizer.h index 3df9922..5f54a27 100644 --- a/Recognizer.h +++ b/Recognizer.h @@ -4,6 +4,12 @@ #include #include "QPixmap" + +namespace tesseract +{ + class TessBaseAPI; +} + class Recognizer : public QObject { Q_OBJECT @@ -12,9 +18,21 @@ class Recognizer : public QObject signals: void recognized (QString text); + void error (QString text); public slots: void recognize (QPixmap pixmap); + void applySettings (); + + private: + bool initEngine (); + + private: + tesseract::TessBaseAPI* engine_; + + QString tessDataDir_; + QString ocrLanguage_; + int imageScale_; }; diff --git a/ScreenTranslator.pro b/ScreenTranslator.pro index e23d4f8..d850938 100644 --- a/ScreenTranslator.pro +++ b/ScreenTranslator.pro @@ -4,13 +4,16 @@ # #------------------------------------------------- -QT += core gui +QT += core gui network webkitwidgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = ScreenTranslator TEMPLATE = app +INCLUDEPATH += C:/build/include + +LIBS += -LC:/build/bin -ltesseract SOURCES += main.cpp\ Manager.cpp \ @@ -26,7 +29,8 @@ HEADERS += \ SelectionDialog.h \ GlobalActionHelper.h \ Recognizer.h \ - Translator.h + Translator.h \ + Settings.h FORMS += \ SettingsEditor.ui \ diff --git a/SelectionDialog.cpp b/SelectionDialog.cpp index 1eb0039..418917d 100644 --- a/SelectionDialog.cpp +++ b/SelectionDialog.cpp @@ -50,8 +50,11 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event) QRect selection = QRect (startSelectPos_, endPos).normalized (); startSelectPos_ = currentSelectPos_ = QPoint (); QPixmap selectedPixmap = currentPixmap_.copy (selection); - emit selected (selectedPixmap); - accept (); + if (!selectedPixmap.isNull ()) + { + emit selected (selectedPixmap); + accept (); + } } } else if (event->type () == QEvent::MouseMove) @@ -65,10 +68,13 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event) } else if (event->type () == QEvent::Paint) { - QPainter painter (ui->label); - painter.setPen (Qt::red); QRect selection = QRect (startSelectPos_, currentSelectPos_).normalized (); - painter.drawRect (selection); + if (selection.isValid ()) + { + QPainter painter (ui->label); + painter.setPen (Qt::red); + painter.drawRect (selection); + } } return QDialog::eventFilter (object, event); diff --git a/Settings.h b/Settings.h new file mode 100644 index 0000000..27f40c9 --- /dev/null +++ b/Settings.h @@ -0,0 +1,42 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include + +namespace settings_names +{ + //! UI + const QString guiGroup = "GUI"; + const QString geometry = "geometry"; + const QString captureHotkey = "captureHotkey"; + + //! Recognition + const QString recogntionGroup = "Recognition"; + const QString tessDataPlace = "tessdata_dir"; + const QString ocrLanguage = "language"; + const QString imageScale = "image_scale"; + + //! Translation + const QString translationGroup = "Translation"; + const QString translationLanguage = "translation_language"; + +} + +namespace settings_values +{ + const QString appName = "ScreenTranslator"; + const QString companyName = "Gres"; + + //! UI + const QString captureHotkey = "Ctrl+Alt+Z"; + + //! Recognition + const QString tessDataPlace = "./"; + const QString ocrLanguage = "eng"; + const int imageScale = 5; + + //! Translation + const QString translationLanguage = "ru"; +} + +#endif // SETTINGS_H diff --git a/SettingsEditor.cpp b/SettingsEditor.cpp index 078a081..687a8a4 100644 --- a/SettingsEditor.cpp +++ b/SettingsEditor.cpp @@ -1,14 +1,203 @@ #include "SettingsEditor.h" #include "ui_SettingsEditor.h" +#include +#include + +#include "Settings.h" + + + SettingsEditor::SettingsEditor(QWidget *parent) : QDialog(parent), ui(new Ui::SettingsEditor) { ui->setupUi(this); + + connect (ui->tessdataButton, SIGNAL (clicked ()), SLOT (openTessdataDialog ())); + connect (ui->tessdataEdit, SIGNAL (textChanged (const QString&)), + SLOT (initOcrLangCombo ())); + + initTranslateLangCombo (); + loadSettings (); + loadState (); } SettingsEditor::~SettingsEditor() { + saveState (); delete ui; } + +void SettingsEditor::done(int result) +{ + if (result == QDialog::Accepted) + { + saveSettings (); + emit settingsEdited (); + } + QDialog::done (result); +} + +void SettingsEditor::saveSettings() const +{ + QSettings settings; + settings.beginGroup (settings_names::guiGroup); + settings.setValue (settings_names::captureHotkey, ui->captureEdit->text ()); + settings.endGroup (); + + + settings.beginGroup (settings_names::recogntionGroup); + settings.setValue (settings_names::tessDataPlace, ui->tessdataEdit->text ()); + settings.setValue (settings_names::ocrLanguage, ui->ocrLangCombo->currentText ()); + settings.setValue (settings_names::imageScale, ui->imageScaleSpin->value ()); + settings.endGroup (); + + + settings.beginGroup (settings_names::translationGroup); + settings.setValue (settings_names::translationLanguage, + ui->translateLangCombo->currentText ()); + settings.endGroup (); +} + +void SettingsEditor::openTessdataDialog() +{ + QString path = QFileDialog::getExistingDirectory (this, tr ("Путь к tessdata")); + if (path.isEmpty ()) + { + return; + } + QDir dir (path); + if (dir.dirName () == QString ("tessdata")) + { + dir.cdUp (); + } + ui->tessdataEdit->setText (dir.path ()); +} + +void SettingsEditor::loadSettings() +{ + QSettings settings; + settings.beginGroup (settings_names::guiGroup); + QString captureHotkey = settings.value (settings_names::captureHotkey, + settings_values::captureHotkey).toString (); + ui->captureEdit->setText (captureHotkey); + settings.endGroup (); + + + settings.beginGroup (settings_names::recogntionGroup); + QString tessDataPlace = settings.value (settings_names::tessDataPlace, + settings_values::tessDataPlace).toString (); + ui->tessdataEdit->setText (tessDataPlace); + QString ocrLang = settings.value (settings_names::ocrLanguage, + settings_values::ocrLanguage).toString (); + ui->ocrLangCombo->setCurrentText (ocrLang); + int imageScale = settings.value (settings_names::imageScale, + settings_values::imageScale).toInt (); + ui->imageScaleSpin->setValue (imageScale); + settings.endGroup (); + + + settings.beginGroup (settings_names::translationGroup); + QString translationLanguage = settings.value (settings_names::translationLanguage, + settings_values::translationLanguage).toString (); + ui->translateLangCombo->setCurrentText (translationLanguage); + settings.endGroup (); +} + +void SettingsEditor::saveState() const +{ + QSettings settings; + settings.beginGroup (settings_names::guiGroup); + settings.setValue (objectName () + "_" + settings_names::geometry, saveGeometry ()); +} + +void SettingsEditor::loadState() +{ + QSettings settings; + settings.beginGroup (settings_names::guiGroup); + restoreGeometry (settings.value (objectName () + "_" + settings_names::geometry).toByteArray ()); +} + +void SettingsEditor::initOcrLangCombo() +{ + ui->ocrLangCombo->clear (); + QString tessdataDir = ui->tessdataEdit->text (); + QDir dir (tessdataDir + "tessdata/"); + if (!dir.exists ()) + { + return; + } + QStringList files = dir.entryList (QStringList () << "*.traineddata", QDir::Files); + QStringList languages; + foreach (const QString& file, files) + { + QString lang = file.left (file.indexOf (".")); + languages << lang; + } + ui->ocrLangCombo->addItems (languages); +} + +void SettingsEditor::initTranslateLangCombo() +{ + QHash gtLang; + gtLang.insert("Afrikaans","af"); + gtLang.insert("Albanian","sq"); + gtLang.insert("Arabic","ar"); + gtLang.insert("Armenian","hy"); + gtLang.insert("Azerbaijani","az"); + gtLang.insert("Basque","eu"); + gtLang.insert("Belarusian","be"); + gtLang.insert("Bulgarian","bg"); + gtLang.insert("Catalan","ca"); + gtLang.insert("Chinese (Simplified)","zh-CN"); + gtLang.insert("Chinese (Traditional)","zh-TW"); + gtLang.insert("Croatian","hr"); + gtLang.insert("Czech","cs"); + gtLang.insert("Danish","da"); + gtLang.insert("Dutch","nl"); + gtLang.insert("English","en"); + gtLang.insert("Estonian","et"); + gtLang.insert("Filipino","tl"); + gtLang.insert("Finnish","fi"); + gtLang.insert("French","fr"); + gtLang.insert("Galician","gl"); + gtLang.insert("Georgian","ka"); + gtLang.insert("German","de"); + gtLang.insert("Greek","el"); + gtLang.insert("Haitian Creole","ht"); + gtLang.insert("Hebrew","iw"); + gtLang.insert("Hindi","hi"); + gtLang.insert("Hungarian","hu"); + gtLang.insert("Icelandic","is"); + gtLang.insert("Indonesian","id"); + gtLang.insert("Irish","ga"); + gtLang.insert("Italian","it"); + gtLang.insert("Japanese","ja"); + gtLang.insert("Korean","ko"); + gtLang.insert("Latvian","lv"); + gtLang.insert("Lithuanian","lt"); + gtLang.insert("Macedonian","mk"); + gtLang.insert("Malay","ms"); + gtLang.insert("Maltese","mt"); + gtLang.insert("Norwegian","no"); + gtLang.insert("Persian","fa"); + gtLang.insert("Polish","pl"); + gtLang.insert("Portuguese","pt"); + gtLang.insert("Romanian","ro"); + gtLang.insert("Russian","ru"); + gtLang.insert("Serbian","sr"); + gtLang.insert("Slovak","sk"); + gtLang.insert("Slovenian","sl"); + gtLang.insert("Spanish","es"); + gtLang.insert("Swahili","sw"); + gtLang.insert("Swedish","sv"); + gtLang.insert("Thai","th"); + gtLang.insert("Turkish","tr"); + gtLang.insert("Ukrainian","uk"); + gtLang.insert("Urdu","ur"); + gtLang.insert("Vietnamese","vi"); + gtLang.insert("Welsh","cy"); + gtLang.insert("Yiddish","yi"); + ui->translateLangCombo->addItems (gtLang.values ()); +} diff --git a/SettingsEditor.h b/SettingsEditor.h index d398ac2..15bd40d 100644 --- a/SettingsEditor.h +++ b/SettingsEditor.h @@ -15,6 +15,23 @@ class SettingsEditor : public QDialog explicit SettingsEditor(QWidget *parent = 0); ~SettingsEditor(); + signals: + void settingsEdited (); + + public slots: + void done (int result); + + private slots: + void saveSettings () const; + void openTessdataDialog (); + void initOcrLangCombo (); + + private: + void loadSettings (); + void saveState () const; + void loadState (); + void initTranslateLangCombo (); + private: Ui::SettingsEditor *ui; }; diff --git a/SettingsEditor.ui b/SettingsEditor.ui index fc45651..1f3e150 100644 --- a/SettingsEditor.ui +++ b/SettingsEditor.ui @@ -6,88 +6,135 @@ 0 0 - 400 - 300 + 456 + 165 - Dialog + Настройки - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 50 - 40 - 46 - 13 - - - - TextLabel - - - - - - 40 - 80 - 46 - 13 - - - - TextLabel - - - - - - 50 - 120 - 46 - 13 - - - - One time select - - - - - - 160 - 80 - 69 - 22 - - - - - - - 160 - 40 - 69 - 22 - - - + + + + + Горячие клавиши + + + + + + Захват + + + + + + + + + + + + + Распознавание + + + + + + Путь к tessdata + + + + + + + + + + ... + + + + + + + Язык распознавания + + + + + + + Увеличение масштаба + + + + + + + + + + + + + + + + Перевод + + + + + + Язык результата + + + + + + + + + + + + + Qt::Horizontal + + + + 24 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 37 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + diff --git a/Translator.cpp b/Translator.cpp index 2dad4a8..c45ce01 100644 --- a/Translator.cpp +++ b/Translator.cpp @@ -1,11 +1,89 @@ #include "Translator.h" -Translator::Translator(QObject *parent) : - QObject(parent) +#include +#include +#include +#include +#include +#include +#include + +#include "Settings.h" + +namespace { + const QString translateBaseUrl = "http://translate.google.com/translate_a/" + "t?client=t&text=%1&sl=auto&tl=%2"; +} + +Translator::Translator(QObject *parent) : + QObject(parent), + network_ (this) +{ + connect (&network_, SIGNAL (finished (QNetworkReply*)), + SLOT (replyFinished (QNetworkReply*))); + + applySettings (); +} + +void Translator::applySettings() +{ + QSettings settings; + settings.beginGroup (settings_names::translationGroup); + translationLanguage_ = settings.value (settings_names::translationLanguage, + settings_values::translationLanguage). + toString (); } void Translator::translate(QString text) { - + Q_ASSERT (!text.isEmpty ()); + if (translationLanguage_.isEmpty ()) + { + emit error (tr ("Неверные парметры для перевода.")); + return; + } + QUrl url (translateBaseUrl.arg (text, translationLanguage_)); + network_.get (QNetworkRequest (url)); +} + +void Translator::replyFinished(QNetworkReply* reply) +{ + Q_ASSERT (reply->isFinished ()); + if (reply->error () != QNetworkReply::NoError) + { + emit error (tr ("Ошибка перевода: %1").arg (reply->errorString ())); + reply->deleteLater (); + return; + } + QByteArray data = reply->readAll (); + reply->deleteLater (); + + while (data.indexOf (",,") != -1)//make json valid + { + data.replace (",,", ","); + } + QJsonParseError parseError; + QJsonDocument document = QJsonDocument::fromJson (data, &parseError); + if (document.isEmpty ()) + { + emit error (tr ("Ошибка разбора перевода: %1 (%2)"). + arg (parseError.errorString ()).arg (parseError.offset)); + return; + } + QJsonArray answerArray = document.array (); + QJsonArray fullTranslation = answerArray.first ().toArray (); + QString source = ""; + QString translation = ""; + foreach (QJsonValue part, fullTranslation) + { + QJsonArray partTranslation = part.toArray (); + if (partTranslation.isEmpty ()) + { + continue; + } + translation += partTranslation.at (0).toString (); + source += partTranslation.at (1).toString (); + } + emit translated (source, translation); } diff --git a/Translator.h b/Translator.h index 3ddc4ba..2c0c819 100644 --- a/Translator.h +++ b/Translator.h @@ -1,7 +1,7 @@ #ifndef TRANSLATOR_H #define TRANSLATOR_H -#include +#include class Translator : public QObject { @@ -11,9 +11,18 @@ class Translator : public QObject signals: void translated (QString sourceText, QString translatedText); + void error (QString text); public slots: void translate (QString text); + void applySettings (); + + private slots: + void replyFinished (QNetworkReply* reply); + + private: + QNetworkAccessManager network_; + QString translationLanguage_; }; diff --git a/main.cpp b/main.cpp index af44e71..db5dd32 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,14 @@ #include #include +#include int main(int argc, char *argv[]) { QApplication a(argc, argv); -// a.setQuitOnLastWindowClosed (false);//DEBUG + a.setQuitOnLastWindowClosed (false);//DEBUG + a.setApplicationName (settings_values::appName); + a.setOrganizationName (settings_values::companyName); Manager manager;