fix bug's (translation color in stardict and kept settings after leave)
[mdictionary] / src / mdictionary / gui / TranslationWidget.cpp
1 /*******************************************************************************
2
3     This file is part of mDictionary.
4
5     mDictionary is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     mDictionary is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with mDictionary.  If not, see <http://www.gnu.org/licenses/>.
17
18     Copyright 2010 Comarch S.A.
19
20 *******************************************************************************/
21
22 //! \file TranslationWidget.cpp
23 //! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
24
25 #include "TranslationWidget.h"
26 #include <QDebug>
27 #ifdef Q_WS_MAEMO_5
28     #include <QtGui/QX11Info>
29     #include <X11/Xlib.h>
30     #include <X11/Xatom.h>
31 #endif
32 #include <QWebFrame>
33
34 TranslationWidget::TranslationWidget(QWidget *parent):
35         QScrollArea(parent){
36
37     guiinterface = qobject_cast<GUIInterface*>(parent);
38
39     #ifdef Q_WS_MAEMO_5
40         setAttribute(Qt::WA_Maemo5StackedWindow);
41         setWindowFlags(windowFlags() | Qt::Window);
42     #endif
43
44
45     initializeUI();
46
47     setWindowTitle("mDictionary");
48
49     connect(webkit, SIGNAL(search()),
50            this, SLOT(searchSelected()));
51
52     QFile file(":/xsl/xsl.xsl");
53     if(!file.open(QFile::ReadOnly))
54         qDebug()<<"error can't open a xslt file";
55     else
56         xslt=file.readAll();
57 }
58
59
60 void TranslationWidget::show() {
61     QScrollArea::show();
62 }
63
64
65 void TranslationWidget::show(QStringList translations) {
66     showMaximized();
67
68     #ifdef Q_WS_MAEMO_5
69         if(!buttonsInitialized)
70             initButtons();
71     #endif
72
73    // webkit->repaint(this->rect());
74    // update(this->rect());
75
76     QString trans;
77     QString t;
78
79     foreach(t, translations) {
80         trans += t + "\n";
81     }
82
83
84     trans=QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") + QString("\n <ar>")
85            + trans + QString("\n </ar>");
86
87     trans=checkTranslation(trans);
88     qDebug()<<"\n\n trans"<<trans;
89     trans=XslConversion(trans);
90
91     QString head = "<html><head>";
92     head += "<link rel=\"stylesheet\" type=\"text/css\" " ;
93     head += "href=\"/usr/share/mdictionary/css/" "style.css";
94     head += "\" /></head><body ondragstart=\"return false\">";
95     trans = head + trans;
96
97     trans+= "</body></html>";
98     trans.replace("$STAR$", "/usr/share/mdictionary/staron.png");
99
100  //   qDebug()<<"\n\n trans"<<trans;
101     webkit->setHtml(trans, QUrl().fromLocalFile("/"));
102     //webkit->repaint(this->rect());
103     //update(this->rect());
104
105   //  Q_EMIT updateSize();
106 }
107
108 QString TranslationWidget::XslConversion(QString translation)
109 {
110     QXmlQuery myQuery(QXmlQuery::XSLT20);
111     myQuery.setFocus(translation);
112     myQuery.setQuery(xslt);
113     QString result("");
114     myQuery.evaluateTo(&result);
115     return result;
116 }
117
118 QString TranslationWidget::checkTranslation(QString trans){
119     /*check all "&"*/
120     int pos=0;
121     int pos2;
122     int count=0;
123
124     while(pos!=-1){
125         pos=trans.indexOf("&",pos+1);
126         pos2=trans.indexOf("amp;",pos);
127         if(pos!=-1 && pos2!=-1 && pos+1==pos2)
128             continue;
129         pos2=trans.indexOf("gt;",pos);
130         if(pos!=-1 && pos2!=-1 && pos+1==pos2)
131             continue;
132         pos2=trans.indexOf("lt;",pos);
133         if(pos!=-1 && pos2!=-1 && pos+1==pos2)
134             continue;
135         pos2=trans.indexOf("apos;",pos);
136         if(pos!=-1 && pos2!=-1 && pos+1==pos2)
137             continue;
138         pos2=trans.indexOf("quot;",pos);
139         if(pos!=-1 && pos2!=-1 && pos+1==pos2)
140             continue;
141         if(pos!=-1)
142             trans.insert(pos+1,"amp;");
143     }
144
145
146     /*check all "<" and ">" in key */
147     pos=0;
148     count=0;
149     while(pos<trans.size()){
150         if(pos==trans.indexOf("<key>",pos)){
151             qDebug()<<"key";
152             count++;
153             pos+=4;
154         }
155         else if(pos==trans.indexOf("</key>",pos))
156             count--;
157         else if(count==1 && (trans.at(pos)=='<' ||  trans.at(pos)=='>' ))
158             trans.remove(pos,1);
159         pos++;
160     }
161
162
163     /*check all """ and "'" */
164     pos=0;
165     count=0;
166     while(pos<trans.size()){
167         if(trans.at(pos)=='<')
168             count++;
169         else if(trans.at(pos)=='>')
170             count--;
171         else if(trans.at(pos)=='\"' && count==0)
172             trans.replace(pos,1,"&quot;");
173         else if(trans.at(pos)=='\'' && count==0)
174             trans.replace(pos,1,"&apos;");
175         pos++;
176     }
177     return trans;
178 }
179
180 #ifdef Q_WS_MAEMO_5
181 void TranslationWidget::initButtons() {
182
183         int x = width() - showButtonsButton->sizeHint().width();
184         int y = height() - showButtonsButton->sizeHint().height();
185
186         showButtonsButton->move(QPoint(x,y));
187         showButtonsButton->show();
188
189
190
191         x = width() - zoomOutButton->sizeHint().width();
192         y = height() - 2*zoomOutButton->sizeHint().height();
193         zoomOutButton->move(QPoint(x, height()));
194
195         zoomOutButtonAnimation =
196                 new QPropertyAnimation(zoomOutButton, "pos", this);
197
198         zoomOutButtonAnimation->setStartValue(QPoint(x, height()));
199         zoomOutButtonAnimation->setEndValue(QPoint(x,y));
200         zoomOutButtonAnimation->setDuration(200);
201         zoomOutButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
202
203
204
205         x = width() - zoomInButton->sizeHint().width();
206         y = height() - 3*zoomInButton->sizeHint().height();
207         zoomInButton->move(QPoint(x, height()));
208
209         zoomInButtonAnimation =
210                 new QPropertyAnimation(zoomInButton, "pos", this);
211
212         zoomInButtonAnimation->setStartValue(QPoint(x, height()));
213         zoomInButtonAnimation->setEndValue(QPoint(x,y));
214         zoomInButtonAnimation->setDuration(400);
215         zoomInButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
216
217
218
219         x = 0;
220         y = height() - copyButton->sizeHint().height();
221
222         copyButton->move(QPoint(x, height()));
223
224         copyButtonAnimation =
225                 new QPropertyAnimation(copyButton, "pos", this);
226
227         copyButtonAnimation->setStartValue(QPoint(x, height()));
228         copyButtonAnimation->setEndValue(QPoint(x,y));
229         copyButtonAnimation->setDuration(200);
230         copyButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
231
232
233
234         x = 0;
235         y = height() - 2*copyButton->sizeHint().height();
236
237         selectAllButton->move(QPoint(x, height()));
238
239         selectAllButtonAnimation =
240                 new QPropertyAnimation(selectAllButton, "pos", this);
241
242         selectAllButtonAnimation->setStartValue(QPoint(x, height()));
243         selectAllButtonAnimation->setEndValue(QPoint(x,y));
244         selectAllButtonAnimation->setDuration(400);
245         selectAllButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
246
247
248
249         x = 0;
250         y = height() - 3*copyButton->sizeHint().height();
251
252         searchButton->move(QPoint(x, height()));
253
254         searchButtonAnimation =
255                 new QPropertyAnimation(searchButton, "pos", this);
256
257         searchButtonAnimation->setStartValue(QPoint(x, height()));
258         searchButtonAnimation->setEndValue(QPoint(x,y));
259         searchButtonAnimation->setDuration(600);
260         searchButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
261
262
263
264
265         buttonsAnimation = new QParallelAnimationGroup(this);
266         buttonsAnimation->addAnimation(zoomInButtonAnimation);
267         buttonsAnimation->addAnimation(zoomOutButtonAnimation);
268         buttonsAnimation->addAnimation(selectAllButtonAnimation);
269         buttonsAnimation->addAnimation(copyButtonAnimation);
270         buttonsAnimation->addAnimation(searchButtonAnimation);
271         buttonsInitialized = true;
272         buttonsVisible = false;
273
274         connect(showButtonsButton, SIGNAL(clicked()),
275                 this, SLOT(showButtons()));
276 }
277 #endif
278
279 void TranslationWidget::initializeUI() {
280
281     webkit = new TranslationView(this);
282     Settings* set = guiinterface->settings();
283     qreal fac = set->value("zoom").toFloat();
284     if(!fac)
285         fac++;
286     webkit->setZoomFactor(fac);
287     delete set;
288
289     QWidget*w = new QWidget(this);
290     verticalLayout = new QVBoxLayout(w);
291     verticalLayout->addWidget(webkit);
292
293     this->setWidget(w);
294     this->setWidgetResizable(true);
295
296     #ifdef Q_WS_MAEMO_5
297         zoomInButton = new QToolButton(this);
298         zoomInButton->setIcon(QIcon::fromTheme("pdf_zoomin"));
299         zoomInButton->setMinimumSize(zoomInButton->sizeHint());
300
301         zoomOutButton = new QToolButton(this);
302         zoomOutButton->setIcon(QIcon::fromTheme("pdf_zoomout"));
303         zoomOutButton->setMinimumSize(zoomOutButton->sizeHint());
304
305         selectAllButton = new QToolButton(this);
306         selectAllButton->setIcon(QIcon(":/icons/48x48/edit-select-all.png"));
307         selectAllButton->setMinimumSize(selectAllButton->sizeHint());
308
309         copyButton = new QToolButton(this);
310         copyButton->setIcon(QIcon::fromTheme("general_notes"));
311         copyButton->setMinimumSize(copyButton->sizeHint());
312
313         searchButton = new QToolButton(this);
314         searchButton->setIcon(QIcon::fromTheme("general_search"));
315         searchButton->setMinimumSize(searchButton->sizeHint());
316
317         showButtonsButton = new QToolButton(this);
318         showButtonsButton->setIcon(QIcon::fromTheme("general_sent"));
319         showButtonsButton->setMinimumSize(searchButton->sizeHint());
320
321         connect(zoomInButton, SIGNAL(clicked()),
322                 webkit, SLOT(zoomIn()));
323
324         connect(zoomOutButton, SIGNAL(clicked()),
325                 webkit, SLOT(zoomOut()));
326
327
328         connect(searchButton, SIGNAL(clicked()),
329                 this, SLOT(searchSelected()));
330
331         connect(copyButton, SIGNAL(clicked()),
332                 this, SLOT(copySelected()));
333
334         connect(selectAllButton, SIGNAL(clicked()),
335                 webkit, SLOT(selectAll()));
336
337         buttonsInitialized = false;
338
339
340
341         grabZoomKeys(true);
342     #endif
343 }
344
345 void TranslationWidget::searchSelected() {
346     if(webkit->selectedText().isEmpty()) {
347         Q_EMIT notify(Notify::Warning, tr("No text is selected"));
348     }
349     else {
350         #ifdef Q_WS_MAEMO_5
351             hide();
352         #endif
353         Q_EMIT search(webkit->selectedText().toLower());
354     }
355 }
356
357 void TranslationWidget::copySelected() {
358     if(webkit->selectedText().isEmpty()) {
359         Q_EMIT notify(Notify::Warning, tr("No text is selected"));
360     }
361     else {
362         Q_EMIT notify(Notify::Info, tr("Copyied selected text"));
363     }
364 }
365
366 #ifdef Q_WS_MAEMO_5
367 void TranslationWidget::showButtons() {
368     if(!buttonsVisible) {
369         buttonsAnimation->setDirection(QAbstractAnimation::Forward);
370         buttonsAnimation->start();
371         buttonsVisible = true;
372
373         showButtonsButton->setIcon(QIcon::fromTheme("general_received"));
374     }
375     else if(buttonsVisible) {
376         buttonsAnimation->setDirection(QAbstractAnimation::Backward);
377         buttonsAnimation->start();
378         buttonsVisible = false;
379         showButtonsButton->setIcon(QIcon::fromTheme("general_sent"));
380     }
381 }
382
383 void TranslationWidget::grabZoomKeys(bool grab) {
384      if (!winId()) {
385          return;
386      }
387
388     unsigned long val = (grab) ? 1 : 0;
389     Atom atom = XInternAtom(QX11Info::display(),
390                             "_HILDON_ZOOM_KEY_ATOM", False);
391     if (!atom) {
392         return;
393     }
394
395     XChangeProperty (QX11Info::display(),
396          winId(),
397          atom,
398          XA_INTEGER,
399          32,
400          PropModeReplace,
401          reinterpret_cast<unsigned char *>(&val),
402          1);
403 }
404
405 void TranslationWidget::hideEvent(QHideEvent* e) {
406     if(buttonsVisible)
407         showButtons();
408
409     QScrollArea::hideEvent(e);
410 }
411
412 void TranslationWidget::keyPressEvent(QKeyEvent* event) {
413     switch (event->key()) {
414         case Qt::Key_F7:
415         webkit->zoomIn();
416         event->accept();
417         break;
418
419         case Qt::Key_F8:
420         webkit->zoomOut();
421         event->accept();
422         break;
423     }
424     QWidget::keyPressEvent(event);
425 }
426 #endif
427
428
429 void TranslationWidget::updateZoom(qreal factor) {
430     Settings* set = guiinterface->settings();
431     set->setValue("zoom", QString("%1").arg(factor));
432     guiinterface->setSettings(set);
433 }
434
435
436