diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro
index 1227a908..3ff5f1a8 100644
--- a/YACReader/YACReader.pro
+++ b/YACReader/YACReader.pro
@@ -29,7 +29,7 @@ INCLUDEPATH += /usr/local/include/poppler/qt4
LIBS += -L/usr/local/lib -lpoppler-qt4
}
-QT += network webkit phonon opengl
+QT += network phonon opengl
CONFIG += release
CONFIG -= flat
diff --git a/YACReader/files.qrc b/YACReader/files.qrc
index 6bce09ab..453372fa 100644
--- a/YACReader/files.qrc
+++ b/YACReader/files.qrc
@@ -3,7 +3,6 @@
../files/about.html
../files/helpYACReader.html
../files/shortcuts.html
- ../files/translator.html
diff --git a/YACReader/images.qrc b/YACReader/images.qrc
index 535f84f2..c0c13672 100644
--- a/YACReader/images.qrc
+++ b/YACReader/images.qrc
@@ -69,5 +69,9 @@
../images/useNewFlowButton.png
../images/useOldFlowButton.png
../images/notificationsLabel.png
+ ../images/fromTo.png
+ ../images/dropDownArrow.png
+ ../images/translatorSearch.png
+ ../images/speaker.png
diff --git a/YACReader/translator.cpp b/YACReader/translator.cpp
index ced688a2..85029c67 100644
--- a/YACReader/translator.cpp
+++ b/YACReader/translator.cpp
@@ -6,63 +6,285 @@
#include
#include
#include
+#include "translator.h"
+
+#include "yacreader_busy_widget.h"
+
#include
#include
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
-#include "translator.h"
+#include
+
+#define APPID "417CEAD93449502CC3C9B69FED26C54118E62BCC"
YACReaderTranslator::YACReaderTranslator(QWidget * parent)
-:QWidget(parent)
+:QWidget(parent),drag(false)
{
+ QString scrollBarStyle = "QScrollBar:vertical { border: none; background: #404040; width: 7px; margin: 0 3px 0 0; }"
+ "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }"
+ "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}"
+
+ "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}"
+ "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}"
+ "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}"
+
+ "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }";
+
this->setCursor(QCursor(Qt::ArrowCursor));
this->setAutoFillBackground(true);
this->setBackgroundRole(QPalette::Window);
QPalette p(this->palette());
- p.setColor(QPalette::Window, QColor(96,96,96));
+ p.setColor(QPalette::Window, QColor("#404040"));
this->setPalette(p);
QVBoxLayout *layout = new QVBoxLayout(this);
- QWebView * view = new QWebView();
- QFile f(":/files/translator.html");
- f.open(QIODevice::ReadOnly);
- QTextStream txtS(&f);
- txtS.setCodec(QTextCodec::codecForName("UTF-8"));
- QString contentHTML = txtS.readAll();
- view->setHtml(contentHTML);
- view->page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
- connect(view->page(),SIGNAL(linkClicked(QUrl)),this,SLOT(play(QUrl)));
- QHBoxLayout * buttonBar = new QHBoxLayout();
+ //TITLE BAR
+ QHBoxLayout * titleBar = new QHBoxLayout();
QPushButton * close = new QPushButton(QIcon(QPixmap(":/images/close.png")),"");
close->setFlat(true);
- buttonBar->addStretch();
- close->resize(18,18);
- buttonBar->addWidget(close);
- buttonBar->setMargin(0);
+ QLabel * title = new QLabel(tr("YACReader translator"));
+ title->setStyleSheet("QLabel {font-size:18px; font-family:Arial; color:white;}");
+ titleBar->addWidget(title);
+ titleBar->addStretch();
+ close->resize(14,14);
+ close->setStyleSheet("QPushButton {margin:0;padding:0;border:none;}");
+ titleBar->addWidget(close);
+ titleBar->setContentsMargins(0,0,0,0);
+ titleBar->setSpacing(0);
connect(close,SIGNAL(clicked()),this->parent(),SLOT(animateHideTranslator()));
- layout->setMargin(0);
- layout->setSpacing(0);
+ layout->addLayout(titleBar);
- layout->addLayout(buttonBar);
- layout->addWidget(view);
+ //INPUT TEXT
+ text = new QTextEdit(this);
+ text->setMinimumHeight(110);
+ text->setMaximumHeight(110);
+ layout->addSpacing(12);
+ layout->addWidget(text);
+ text->setStyleSheet("QTextEdit{border:none;background:#2a2a2a;color:white; font-size:12px; padding:6px;}"+scrollBarStyle);
- resize(view->size().width()/1.60,view->size().height());
+ //COMBOBOXES
+ QHBoxLayout * combos = new QHBoxLayout();
+ from = new QComboBox(this);
+ to = new QComboBox(this);
+ QString comboBoxStyle = "QComboBox {border:none;background:#2a2a2a;color:white;font-size:12px;font-family:Arial;padding-left:8px;}"
+ "QComboBox::down-arrow {image: url(:/images/dropDownArrow.png);}"
+ "QComboBox::drop-down {border:none; padding-right:10px;}"
+ "QComboBox QAbstractItemView {border: none; background:#272727; color:white; selection-background-color: #202020; outline:none;}"
+ "QComboBox QAbstractItemView::item {padding-left:8px;}" + scrollBarStyle
+ ;
+ from->setStyleSheet(comboBoxStyle);
+ to->setStyleSheet(comboBoxStyle);
+ from->setFixedHeight(22);
+ to->setFixedHeight(22);
+ QLabel * arrow = new QLabel(this);
+ QPixmap arrowPixmap(":/images/fromTo.png");
+ arrow->setPixmap(arrowPixmap);
+ QPushButton * searchButton = new QPushButton(this);
+ searchButton->setIcon(QIcon(":/images/translatorSearch.png"));
+ searchButton->setStyleSheet("QPushButton {border:none; background:#2a2a2a;}");
+ searchButton->setFixedSize(22,22);
+ combos->addWidget(from,1);
+ combos->addSpacing(9);
+ combos->addWidget(arrow,0);
+ combos->addSpacing(9);
+ combos->addWidget(to,1);
+ combos->addSpacing(9);
+ combos->addWidget(searchButton,0);
+ layout->addSpacing(12);
+ layout->addLayout(combos);
+
+
+ //RESULTS
+ QHBoxLayout * resultsTitleLayout = new QHBoxLayout();
+ resultsTitle = new QLabel(tr("Translation"));
+ resultsTitle->setStyleSheet("QLabel {font-family:Arial;font-size:14px;color:#e3e3e3;}");
+ speakButton = new QPushButton(this);
+ speakButton->setStyleSheet("QPushButton {border:none;}");
+ speakButton->setIcon(QIcon(":/images/speaker.png"));
+ resultsTitleLayout->addWidget(resultsTitle,0,Qt::AlignVCenter);
+ resultsTitleLayout->addSpacing(10);
+ resultsTitleLayout->addWidget(speakButton,0,Qt::AlignVCenter);
+ resultsTitleLayout->addStretch();
+
+ layout->addSpacing(15);
+ layout->addLayout(resultsTitleLayout);
+ layout->addSpacing(12);
+
+ resultText = new QLabel();
+ resultText->setWordWrap(true);
+ resultText->setStyleSheet("QLabel {color:white;font-size:12px;}");
+ resultText->setText("ñlkas lakj dflkaj lasd jflie lkajd fie kljads ijef lasei afsliej ljse f");
+ layout->addWidget(resultText);
+
+ layout->addStretch();
+
+ //CLEAR BUTTON
+ clearButton = new QPushButton(tr("clear"));
+ layout->addWidget(clearButton,0,Qt::AlignRight);
+ clearButton->setMinimumWidth(95);
+ clearButton->setStyleSheet("QPushButton {border:1px solid #212121; background:#2a2a2a; color:white; font-family:Arial; font-size:12px; padding-top:5px; padding-bottom:5px;}");
+
+ resize(400,479);
music = createPlayer(MusicCategory);
+ layout->setMargin(0);
+ layout->setContentsMargins(18,12,18,12);
+ setContentsMargins(0,0,0,0);
+ layout->setSpacing(0);
+
+ hideResults();
+ populateCombos();
+
+ busyIndicator = new YACReaderBusyWidget(this);
+ busyIndicator->move((this->width()-busyIndicator->width())/2,(this->height()-busyIndicator->height())*2/3);
+ busyIndicator->hide();
+
show();
+
+ connect(searchButton,SIGNAL(pressed()),this,SLOT(translate()));
+ connect(speakButton,SIGNAL(pressed()),this,SLOT(play()));
+ connect(clearButton,SIGNAL(pressed()),this,SLOT(clear()));
}
-void YACReaderTranslator::play(const QUrl & url)
+void YACReaderTranslator::hideResults()
{
- MediaSource src(url);
+ resultsTitle->setHidden(true);
+ speakButton->setHidden(true);
+ resultText->setHidden(true);
+}
+
+void YACReaderTranslator::clear()
+{
+ hideResults();
+ text->clear();
+}
+
+void YACReaderTranslator::translate()
+{
+ QString text = this->text->toPlainText();
+ if(text.isEmpty())
+ return;
+ QString from = this->from->itemData(this->from->currentIndex()).toString();
+ QString to = this->to->itemData(this->to->currentIndex()).toString();
+
+ TranslationLoader * translationLoader = new TranslationLoader(text,from,to);
+ connect(translationLoader,SIGNAL(requestFinished(QString)),this,SLOT(setTranslation(QString)));
+ connect(translationLoader,SIGNAL(error()),this,SLOT(error()));
+ connect(translationLoader,SIGNAL(timeOut()),this,SLOT(error()));
+ connect(translationLoader,SIGNAL(finished()),translationLoader,SLOT(deleteLater()));
+
+ TextToSpeachLoader * tts = new TextToSpeachLoader(text,from);
+ connect(tts,SIGNAL(requestFinished(QUrl)),this,SLOT(setSpeak(QUrl)));
+ connect(tts,SIGNAL(error()),this,SLOT(error()));
+ connect(tts,SIGNAL(timeOut()),this,SLOT(error()));
+ connect(tts,SIGNAL(finished()),tts,SLOT(deleteLater()));
+
+ translationLoader->start();
+ tts->start();
+
+ resultsTitle->setText(tr("Translation"));
+
+ hideResults();
+
+ busyIndicator->show();
+}
+
+void YACReaderTranslator::error()
+{
+ resultsTitle->setText(tr("Service not available"));
+ resultsTitle->setHidden(false);
+ busyIndicator->hide();
+}
+
+void YACReaderTranslator::setSpeak(const QUrl & url)
+{
+ resultsTitle->setHidden(false);
+ speakButton->setHidden(false);
+
+ ttsSource = url;
+}
+
+void YACReaderTranslator::setTranslation(const QString & string)
+{
+ resultText->setText(string);
+
+ resultsTitle->setHidden(false);
+ resultText->setHidden(false);
+ busyIndicator->hide();
+}
+
+void YACReaderTranslator::populateCombos()
+{
+ QList combos;
+ combos.append(from);
+ combos.append(to);
+
+ for(int i=0;iaddItem("Arabic","ar");
+ combo->addItem("Bulgarian","bg");
+ combo->addItem("Catalan","ca");
+ combo->addItem("Chinese Simplified","zh-CHS");
+ combo->addItem("Chinese Traditional","zh-CHT");
+ combo->addItem("Czech","cs");
+ combo->addItem("Danish","da");
+ combo->addItem("Dutch","nl");
+ combo->addItem("English","en");
+ combo->addItem("Estonian","et");
+ combo->addItem("Finnish","fi");
+ combo->addItem("French","fr");
+ combo->addItem("German","de");
+ combo->addItem("Greek","el");
+ combo->addItem("Haitian Creole","ht");
+ combo->addItem("Hebrew","he");
+ combo->addItem("Hindi","hi");
+ combo->addItem("Hungarian","hu");
+ combo->addItem("Indonesian","id");
+ combo->addItem("Italian","it");
+ combo->addItem("Japanese","ja");
+ combo->addItem("Korean","ko");
+ combo->addItem("Latvian","lv");
+ combo->addItem("Lithuanian","lt");
+ combo->addItem("Norwegian","no");
+ combo->addItem("Polish","pl");
+ combo->addItem("Portuguese","pt");
+ combo->addItem("Romanian","ro");
+ combo->addItem("Russian","ru");
+ combo->addItem("Slovak","sk");
+ combo->addItem("Slovenian","sl");
+ combo->addItem("Spanish","es");
+ combo->addItem("Swedish","sv");
+ combo->addItem("Thai","th");
+ combo->addItem("Turkish","tr");
+ combo->addItem("Ukrainian","uk");
+ combo->addItem("Vietnamese","vi");
+ }
+ from->setCurrentIndex(from->findText("English"));
+ to->setCurrentIndex(from->findText("Spanish"));
+}
+
+void YACReaderTranslator::play()
+{
+ //QMessageBox::question(this,"xxx",ttsSource.toString());
+ MediaSource src(ttsSource);
src.setAutoDelete(true);
- music->setCurrentSource(src);
- music->play();
+ music->setCurrentSource(src);
+ music->play();
}
YACReaderTranslator::~YACReaderTranslator()
@@ -72,8 +294,12 @@ YACReaderTranslator::~YACReaderTranslator()
void YACReaderTranslator::mousePressEvent(QMouseEvent *event)
{
- drag = true;
- click = event->pos();
+ QPoint p = mapTo(this,event->pos());
+ if(p.y() < 40)
+ {
+ drag = true;
+ click = event->pos();
+ }
}
void YACReaderTranslator::mouseReleaseEvent(QMouseEvent *event)
@@ -88,3 +314,94 @@ void YACReaderTranslator::mouseMoveEvent(QMouseEvent * event)
}
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+
+TranslationLoader::TranslationLoader(QString text, QString from, QString to)
+ :QThread(),text(text),from(from),to(to)
+{
+}
+
+void TranslationLoader::run()
+{
+ QNetworkAccessManager manager;
+ QEventLoop q;
+ QTimer tT;
+
+ tT.setSingleShot(true);
+ connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
+ connect(&manager, SIGNAL(finished(QNetworkReply*)),&q, SLOT(quit()));
+
+ QString url = "http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appid=%1&from=%2&to=%3&text=%4&contentType=text/plain";
+ url = url.arg(APPID).arg(from).arg(to).arg(text);
+
+ QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));
+
+ tT.start(5000); // 5s timeout
+ q.exec();
+
+ if(tT.isActive()){
+ // download complete
+ if(reply->error() == QNetworkReply::NoError)
+ {
+ QString utf8 = QString::fromUtf8(reply->readAll());
+ utf8 = utf8.remove(0,1);
+ utf8 = utf8.remove(utf8.count()-1,1);
+
+ QString translated(utf8);
+ emit(requestFinished(translated));
+ }
+ else
+ emit(error());
+ } else {
+ emit(timeOut());
+ }
+}
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+
+
+TextToSpeachLoader::TextToSpeachLoader(QString text, QString language)
+ :QThread(),text(text),language(language)
+{
+}
+
+
+void TextToSpeachLoader::run()
+{
+ QNetworkAccessManager manager;
+ QEventLoop q;
+ QTimer tT;
+
+ tT.setSingleShot(true);
+ connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
+ connect(&manager, SIGNAL(finished(QNetworkReply*)),&q, SLOT(quit()));
+
+ QString url = "http://api.microsofttranslator.com/V2/Ajax.svc/Speak?appid=%1&language=%2&text=%3&contentType=text/plain";
+ url = url.arg(APPID).arg(language).arg(text);
+
+ QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));
+
+ tT.start(5000); // 5s timeout
+ q.exec();
+
+ if(tT.isActive()){
+ // download complete
+ if(reply->error() == QNetworkReply::NoError)
+ {
+ QString utf8 = QString::fromUtf8(reply->readAll());
+ utf8 = utf8.remove(0,1);
+ utf8 = utf8.remove(utf8.count()-1,1);
+ utf8 = utf8.replace("\\","");
+
+ emit(requestFinished(QUrl(utf8)));
+ }
+ else
+ emit(error());
+ } else {
+ emit(timeOut());
+ }
+}
diff --git a/YACReader/translator.h b/YACReader/translator.h
index 759ce22c..71fb49e9 100644
--- a/YACReader/translator.h
+++ b/YACReader/translator.h
@@ -4,7 +4,16 @@
class QUrl;
class QMouseEvent;
class QPoint;
-#include
+class QTextEdit;
+class QComboBox;
+class QLabel;
+class QPushButton;
+class YACReaderBusyWidget;
+
+#include
+#include
+#include
+
#include
using namespace Phonon;
@@ -17,16 +26,66 @@ class YACReaderTranslator : public QWidget
~YACReaderTranslator();
public slots:
- void play(const QUrl & url);
+ void play();
+
+ protected slots:
+ void translate();
+ void setSpeak(const QUrl & url);
+ void setTranslation(const QString & string);
+ void error();
+ void clear();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent ( QMouseEvent * event );
+ void hideResults();
+
+ void populateCombos();
bool drag;
QPoint click;
private:
MediaObject * music;
+ QTextEdit * text;
+ QComboBox * from;
+ QComboBox * to;
+ QLabel * resultsTitle;
+ QPushButton * speakButton;
+ QLabel * resultText;
+ YACReaderBusyWidget * busyIndicator;
+ QUrl ttsSource;
+ QPushButton * clearButton;
+
};
+class TranslationLoader : public QThread
+{
+ Q_OBJECT
+public:
+ TranslationLoader(QString text, QString from, QString to);
+signals:
+ void requestFinished(QString);
+ void timeOut();
+ void error();
+private:
+ QString text;
+ QString from;
+ QString to;
+ void run();
+};
+
+class TextToSpeachLoader : public QThread
+{
+ Q_OBJECT
+public:
+ TextToSpeachLoader(QString text, QString language);
+signals:
+ void requestFinished(QUrl);
+ void timeOut();
+ void error();
+private:
+ QString text;
+ QString language;
+ void run();
+};
#endif
\ No newline at end of file
diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp
index 58305bd3..81ed5730 100644
--- a/YACReader/viewer.cpp
+++ b/YACReader/viewer.cpp
@@ -12,7 +12,6 @@
#include "page_label_widget.h"
#include "notifications_label_widget.h"
-#include
#include
#define STEPS 22
diff --git a/images/close.png b/images/close.png
index 964f2065..54d51b35 100644
Binary files a/images/close.png and b/images/close.png differ
diff --git a/images/dropDownArrow.png b/images/dropDownArrow.png
new file mode 100644
index 00000000..db5ea8d8
Binary files /dev/null and b/images/dropDownArrow.png differ
diff --git a/images/fromTo.png b/images/fromTo.png
new file mode 100644
index 00000000..87ec680d
Binary files /dev/null and b/images/fromTo.png differ
diff --git a/images/speaker.png b/images/speaker.png
new file mode 100644
index 00000000..e75be689
Binary files /dev/null and b/images/speaker.png differ
diff --git a/images/translatorSearch.png b/images/translatorSearch.png
new file mode 100644
index 00000000..066f21e9
Binary files /dev/null and b/images/translatorSearch.png differ