1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 10:46:35 +01:00

[spellcheck] Added context menu options to replace misspelled words.

And also to add word into user dictionary.
This commit is contained in:
nowrep 2013-02-05 20:43:53 +01:00
parent 074bd928c7
commit c3a0e1f13a
11 changed files with 262 additions and 58 deletions

View File

@ -53,7 +53,10 @@
#include "checkboxdialog.h" #include "checkboxdialog.h"
#include "registerqappassociation.h" #include "registerqappassociation.h"
#include "html5permissions/html5permissionsmanager.h" #include "html5permissions/html5permissionsmanager.h"
#ifdef USE_HUNSPELL
#include "qtwebkit/spellcheck/speller.h" #include "qtwebkit/spellcheck/speller.h"
#endif
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#include <QFileOpenEvent> #include <QFileOpenEvent>
@ -93,7 +96,9 @@ MainApplication::MainApplication(int &argc, char** argv)
, m_restoreManager(0) , m_restoreManager(0)
, m_proxyStyle(0) , m_proxyStyle(0)
, m_html5permissions(0) , m_html5permissions(0)
#ifdef USE_HUNSPELL
, m_speller(0) , m_speller(0)
#endif
, m_dbWriter(new DatabaseWriter(this)) , m_dbWriter(new DatabaseWriter(this))
, m_uaManager(new UserAgentManager) , m_uaManager(new UserAgentManager)
, m_isPrivateSession(false) , m_isPrivateSession(false)
@ -498,11 +503,47 @@ QList<QupZilla*> MainApplication::mainWindows()
return list; return list;
} }
QString MainApplication::currentLanguage() bool MainApplication::isClosing() const
{
return m_isClosing;
}
bool MainApplication::isPrivateSession() const
{
return m_isPrivateSession;
}
bool MainApplication::isStartingAfterCrash() const
{
return m_startingAfterCrash;
}
int MainApplication::windowCount() const
{
return m_mainWindows.count();
}
QString MainApplication::currentLanguageFile() const
{ {
return m_activeLanguage; return m_activeLanguage;
} }
QString MainApplication::currentLanguage() const
{
QString lang = m_activeLanguage;
if (lang.isEmpty()) {
return "en_US";
}
return lang.left(lang.length() - 3);
}
QString MainApplication::currentProfilePath() const
{
return m_activeProfil;
}
void MainApplication::sendMessages(Qz::AppMessageType mes, bool state) void MainApplication::sendMessages(Qz::AppMessageType mes, bool state)
{ {
emit message(mes, state); emit message(mes, state);
@ -626,7 +667,11 @@ void MainApplication::connectDatabase()
void MainApplication::translateApp() void MainApplication::translateApp()
{ {
Settings settings; Settings settings;
const QString &file = settings.value("Language/language", QLocale::system().name()).toString(); QString file = settings.value("Language/language", QLocale::system().name()).toString();
if (!file.isEmpty() && !file.endsWith(QLatin1String(".qm"))) {
file.append(".qm");
}
QTranslator* app = new QTranslator(this); QTranslator* app = new QTranslator(this);
app->load(file, TRANSLATIONSDIR); app->load(file, TRANSLATIONSDIR);
@ -821,13 +866,15 @@ HTML5PermissionsManager* MainApplication::html5permissions()
return m_html5permissions; return m_html5permissions;
} }
#ifdef USE_HUNSPELL
Speller* MainApplication::speller() Speller* MainApplication::speller()
{ {
if (!m_speller) { if (!m_speller) {
m_speller = new Speller(); m_speller = new Speller(this);
} }
return m_speller; return m_speller;
} }
#endif
void MainApplication::startPrivateBrowsing() void MainApplication::startPrivateBrowsing()
{ {
@ -1104,5 +1151,4 @@ QString MainApplication::tempPath() const
MainApplication::~MainApplication() MainApplication::~MainApplication()
{ {
delete m_uaManager; delete m_uaManager;
delete m_speller;
} }

View File

@ -76,14 +76,15 @@ public:
QList<QupZilla*> mainWindows(); QList<QupZilla*> mainWindows();
inline static MainApplication* getInstance() { return static_cast<MainApplication*>(QCoreApplication::instance()); } static MainApplication* getInstance() { return static_cast<MainApplication*>(QCoreApplication::instance()); }
inline QString currentProfilePath() { return m_activeProfil; }
inline bool isPrivateSession() { return m_isPrivateSession; }
inline bool isClosing() { return m_isClosing; }
inline bool isStartingAfterCrash() { return m_startingAfterCrash; }
inline int windowCount() { return m_mainWindows.count(); }
QString currentLanguage(); bool isClosing() const;
bool isPrivateSession() const;
bool isStartingAfterCrash() const;
int windowCount() const;
QString currentLanguageFile() const;
QString currentLanguage() const;
QString currentProfilePath() const;
bool checkSettingsDir(); bool checkSettingsDir();
void destroyRestoreManager(); void destroyRestoreManager();
@ -109,7 +110,9 @@ public:
QNetworkDiskCache* networkCache(); QNetworkDiskCache* networkCache();
DesktopNotificationsFactory* desktopNotifications(); DesktopNotificationsFactory* desktopNotifications();
HTML5PermissionsManager* html5permissions(); HTML5PermissionsManager* html5permissions();
#ifdef USE_HUNSPELL
Speller* speller(); Speller* speller();
#endif
DatabaseWriter* dbWriter() { return m_dbWriter; } DatabaseWriter* dbWriter() { return m_dbWriter; }
UserAgentManager* uaManager() { return m_uaManager; } UserAgentManager* uaManager() { return m_uaManager; }
@ -170,7 +173,9 @@ private:
RestoreManager* m_restoreManager; RestoreManager* m_restoreManager;
ProxyStyle* m_proxyStyle; ProxyStyle* m_proxyStyle;
HTML5PermissionsManager* m_html5permissions; HTML5PermissionsManager* m_html5permissions;
#ifdef USE_HUNSPELL
Speller* m_speller; Speller* m_speller;
#endif
DatabaseWriter* m_dbWriter; DatabaseWriter* m_dbWriter;
UserAgentManager* m_uaManager; UserAgentManager* m_uaManager;

View File

@ -218,7 +218,7 @@ PluginInterface* Plugins::initPlugin(PluginInterface* interface, QPluginLoader*
return 0; return 0;
} }
qApp->installTranslator(interface->getTranslator(mApp->currentLanguage())); qApp->installTranslator(interface->getTranslator(mApp->currentLanguageFile()));
return interface; return interface;
} }

View File

@ -1,6 +1,6 @@
HEADERS += $$PWD/qtwebkitplugin.h \ HEADERS += $$PWD/qtwebkitplugin.h \
$$PWD/notifications/notificationpresenter.h \ $$PWD/notifications/notificationpresenter.h \
$$[QT_INSTALL_HEADERS]/QtWebKit/qwebkitplatformplugin.h $$[QT_INSTALL_HEADERS]/QtWebKit/qwebkitplatformplugin.h \
SOURCES += $$PWD/qtwebkitplugin.cpp \ SOURCES += $$PWD/qtwebkitplugin.cpp \
@ -11,9 +11,13 @@ DEFINES *= QT_STATICPLUGIN
unix:contains(DEFINES, USE_QTWEBKIT_2_3):system(pkg-config --exists hunspell) { unix:contains(DEFINES, USE_QTWEBKIT_2_3):system(pkg-config --exists hunspell) {
HEADERS += $$PWD/spellcheck/spellcheck.h \ HEADERS += $$PWD/spellcheck/spellcheck.h \
$$PWD/spellcheck/speller.h \ $$PWD/spellcheck/speller.h \
$$PWD/spellcheck/spellcheckdialog.h \
SOURCES += $$PWD/spellcheck/spellcheck.cpp \ SOURCES += $$PWD/spellcheck/spellcheck.cpp \
$$PWD/spellcheck/speller.cpp \ $$PWD/spellcheck/speller.cpp \
$$PWD/spellcheck/spellcheckdialog.cpp \
FORMS += $$PWD/spellcheck/spellcheckdialog.ui
DEFINES *= USE_HUNSPELL DEFINES *= USE_HUNSPELL
LIBS += $$system(pkg-config --libs hunspell) LIBS += $$system(pkg-config --libs hunspell)

View File

@ -30,7 +30,7 @@ SpellCheck::SpellCheck()
bool SpellCheck::isContinousSpellCheckingEnabled() const bool SpellCheck::isContinousSpellCheckingEnabled() const
{ {
return true; return m_speller->isEnabled();
} }
void SpellCheck::toggleContinousSpellChecking() void SpellCheck::toggleContinousSpellChecking()
@ -50,7 +50,7 @@ void SpellCheck::ignoreWordInSpellDocument(const QString &word)
void SpellCheck::checkSpellingOfString(const QString &word, void SpellCheck::checkSpellingOfString(const QString &word,
int* misspellingLocation, int* misspellingLength) int* misspellingLocation, int* misspellingLength)
{ {
if (misspellingLocation == NULL || misspellingLength == NULL || !m_speller) { if (misspellingLocation == NULL || misspellingLength == NULL) {
return; return;
} }
@ -69,7 +69,7 @@ void SpellCheck::checkSpellingOfString(const QString &word,
if (endOfWord(boundary, finder.type()) && inWord) { if (endOfWord(boundary, finder.type()) && inWord) {
end = finder.position(); end = finder.position();
QString str = finder.string().mid(start, end - start); QString str = finder.string().mid(start, end - start);
if (isValidWord(str)) { if (Speller::isValidWord(str)) {
if (m_speller->isMisspelled(str)) { if (m_speller->isMisspelled(str)) {
*misspellingLocation = start; *misspellingLocation = start;
*misspellingLength = end - start; *misspellingLength = end - start;
@ -133,21 +133,6 @@ void SpellCheck::checkGrammarOfString(const QString &, QList<GrammarDetail> &,
Q_UNUSED(badGrammarLength); Q_UNUSED(badGrammarLength);
} }
bool SpellCheck::isValidWord(const QString &str)
{
if (str.isEmpty() || (str.length() == 1 && !str[0].isLetter())) {
return false;
}
const int length = str.length();
for (int i = 0; i < length; ++i) {
if (!str[i].isNumber()) {
return true;
}
}
// 'str' only contains numbers
return false;
}
bool SpellCheck::endOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons, bool SpellCheck::endOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons,
const QTextBoundaryFinder::BoundaryType &type) const QTextBoundaryFinder::BoundaryType &type)
{ {

View File

@ -47,7 +47,6 @@ public:
int* badGrammarLocation, int* badGrammarLength); int* badGrammarLocation, int* badGrammarLength);
private: private:
bool isValidWord(const QString &str);
bool endOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons, bool endOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons,
const QTextBoundaryFinder::BoundaryType &type); const QTextBoundaryFinder::BoundaryType &type);
bool startOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons, bool startOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons,

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */ * ============================================================ */
#include "speller.h" #include "speller.h"
#include "spellcheckdialog.h"
#include "settings.h" #include "settings.h"
#include "mainapplication.h" #include "mainapplication.h"
#include "qztools.h" #include "qztools.h"
@ -27,11 +28,16 @@
#include <QLocale> #include <QLocale>
#include <QDebug> #include <QDebug>
#include <QDirIterator> #include <QDirIterator>
#include <QWebHitTestResult>
#include <QTextBoundaryFinder>
#include <QTextStream>
#include <QMenu>
#include <hunspell/hunspell.hxx> #include <hunspell/hunspell.hxx>
Speller::Speller() Speller::Speller(QObject* parent)
: m_textCodec(0) : QObject(parent)
, m_textCodec(0)
, m_hunspell(0) , m_hunspell(0)
, m_enabled(false) , m_enabled(false)
{ {
@ -45,6 +51,7 @@ bool Speller::isEnabled() const
void Speller::loadSettings() void Speller::loadSettings()
{ {
Settings settings; Settings settings;
settings.beginGroup("SpellCheck"); settings.beginGroup("SpellCheck");
m_enabled = settings.value("enabled", true).toBool(); m_enabled = settings.value("enabled", true).toBool();
@ -83,7 +90,18 @@ void Speller::initialize()
m_textCodec = QTextCodec::codecForName(m_hunspell->get_dic_encoding()); m_textCodec = QTextCodec::codecForName(m_hunspell->get_dic_encoding());
if (m_userDictionary.exists()) { if (m_userDictionary.exists()) {
m_hunspell->add_dic(m_userDictionary.fileName().toLocal8Bit().constData()); if (!m_userDictionary.open(QFile::ReadOnly)) {
qWarning() << "SpellCheck: Cannot open" << m_userDictionary.fileName() << "for reading!";
}
else {
QString word;
QTextStream stream(&m_userDictionary);
while (!stream.atEnd()) {
stream >> word;
putWord(word);
}
}
m_userDictionary.close();
} }
qDebug() << "SpellCheck: Language =" << language().code; qDebug() << "SpellCheck: Language =" << language().code;
@ -98,8 +116,7 @@ QList<Speller::Language> Speller::availableLanguages() const
{ {
QList<Language> languages; QList<Language> languages;
QDirIterator it(m_dictionaryPath, QStringList("*.dic"), QDirIterator it(m_dictionaryPath, QStringList("*.dic"), QDir::Files);
QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
while (it.hasNext()) { while (it.hasNext()) {
const QString affFilePath = it.next().replace(QLatin1String(".dic"), QLatin1String(".aff")); const QString affFilePath = it.next().replace(QLatin1String(".dic"), QLatin1String(".aff"));
@ -112,20 +129,76 @@ QList<Speller::Language> Speller::availableLanguages() const
lang.code = it.fileInfo().baseName(); lang.code = it.fileInfo().baseName();
lang.name = nameForLanguage(lang.code); lang.name = nameForLanguage(lang.code);
if (!languages.contains(lang)) {
languages.append(lang); languages.append(lang);
} }
}
return languages; return languages;
} }
void Speller::learnWord(const QString &word) QString Speller::dictionaryPath() const
{ {
if (!m_hunspell || !m_textCodec) { return m_dictionaryPath;
}
void Speller::showSettings(QWidget* parent)
{
SpellCheckDialog dialog(parent);
if (dialog.exec() == QDialog::Accepted) {
loadSettings();
}
}
void Speller::populateContextMenu(QMenu* menu, const QWebHitTestResult &hitTest)
{
m_element = hitTest.element();
if (m_element.isNull()) {
return; return;
} }
const char* encodedWord = m_textCodec->fromUnicode(word).constData(); const QString text = m_element.evaluateJavaScript("this.value").toString();
m_hunspell->add(encodedWord); const int pos = m_element.evaluateJavaScript("this.selectionStart").toInt() + 1;
QTextBoundaryFinder finder = QTextBoundaryFinder(QTextBoundaryFinder::Word, text);
finder.setPosition(pos);
m_startPos = finder.toPreviousBoundary();
m_endPos = finder.toNextBoundary();
const QString &word = text.mid(m_startPos, m_endPos - m_startPos).trimmed();
if (!isValidWord(word) || !isMisspelled(word)) {
return;
}
const int limit = 6;
QStringList suggests = suggest(word);
int count = suggests.count() > limit ? limit : suggests.count();
QFont boldFont = menu->font();
boldFont.setBold(true);
for (int i = 0; i < count; ++i) {
QAction* act = menu->addAction(suggests.at(i), this, SLOT(replaceWord()));
act->setData(suggests.at(i));
act->setFont(boldFont);
}
if (count == 0) {
menu->addAction(tr("No suggestions"))->setEnabled(false);
}
menu->addAction(tr("Add to dictionary"), this, SLOT(addToDictionary()))->setData(word);
menu->addSeparator();
}
void Speller::addToDictionary()
{
if (QAction* act = qobject_cast<QAction*>(sender())) {
QString word = act->data().toString();
putWord(word);
if (!m_userDictionary.open(QFile::WriteOnly | QFile::Append)) { if (!m_userDictionary.open(QFile::WriteOnly | QFile::Append)) {
qWarning() << "SpellCheck: Cannot open file" << m_userDictionary.fileName() << "for writing!"; qWarning() << "SpellCheck: Cannot open file" << m_userDictionary.fileName() << "for writing!";
@ -136,6 +209,40 @@ void Speller::learnWord(const QString &word)
m_userDictionary.write("\n"); m_userDictionary.write("\n");
m_userDictionary.close(); m_userDictionary.close();
} }
}
void Speller::replaceWord()
{
if (m_element.isNull()) {
return;
}
if (QAction* act = qobject_cast<QAction*>(sender())) {
QString word = act->data().toString();
QString text = m_element.evaluateJavaScript("this.value").toString();
const int cursorPos = m_element.evaluateJavaScript("this.selectionStart").toInt();
text.replace(m_startPos, m_endPos - m_startPos, word);
text.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
text.replace(QLatin1Char('\''), QLatin1String("\\'"));
word.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
word.replace(QLatin1Char('\''), QLatin1String("\\'"));
m_element.evaluateJavaScript(QString("this.value='%1'").arg(text));
m_element.evaluateJavaScript(QString("this.selectionStart=this.selectionEnd=%1").arg(cursorPos));
}
}
void Speller::putWord(const QString &word)
{
if (!m_hunspell || !m_textCodec) {
return;
}
const char* encodedWord = m_textCodec->fromUnicode(word).constData();
m_hunspell->add(encodedWord);
}
bool Speller::isMisspelled(const QString &string) bool Speller::isMisspelled(const QString &string)
{ {
@ -166,6 +273,23 @@ QStringList Speller::suggest(const QString &word)
return suggests; return suggests;
} }
bool Speller::isValidWord(const QString &str)
{
if (str.isEmpty() || (str.length() == 1 && !str[0].isLetter())) {
return false;
}
const int length = str.length();
for (int i = 0; i < length; ++i) {
if (!str[i].isNumber()) {
return true;
}
}
return false;
}
bool Speller::dictionaryExists(const QString &path) const bool Speller::dictionaryExists(const QString &path) const
{ {
return QFile(path + ".dic").exists() && return QFile(path + ".dic").exists() &&

View File

@ -18,21 +18,34 @@
#ifndef SPELLER_H #ifndef SPELLER_H
#define SPELLER_H #define SPELLER_H
#include <QWebElement>
#include <QStringList> #include <QStringList>
#include <QFile> #include <QFile>
class QTextCodec; class QTextCodec;
class Hunspell; class Hunspell;
class Speller class QMenu;
class QWebHitTestResult;
class Speller : public QObject
{ {
Q_OBJECT
public: public:
struct Language { struct Language {
QString code; QString code;
QString name; QString name;
bool operator==(const Language &other) {
return this->name == other.name &&
this->name.left(2) == other.name.left(2);
// Compare only first two chars of name.
// So "cs_CZ - CzechRepublic" == "cs - CzechRepublic"
}
}; };
explicit Speller(); explicit Speller(QObject* parent);
~Speller(); ~Speller();
bool isEnabled() const; bool isEnabled() const;
@ -41,13 +54,22 @@ public:
Language language() const; Language language() const;
QList<Language> availableLanguages() const; QList<Language> availableLanguages() const;
void learnWord(const QString &word); QString dictionaryPath() const;
void showSettings(QWidget* parent);
void populateContextMenu(QMenu* menu, const QWebHitTestResult &hitTest);
bool isMisspelled(const QString &string); bool isMisspelled(const QString &string);
QStringList suggest(const QString &word); QStringList suggest(const QString &word);
static bool isValidWord(const QString &str);
private slots:
void addToDictionary();
void replaceWord();
private: private:
void initialize(); void initialize();
void putWord(const QString &word);
bool dictionaryExists(const QString &path) const; bool dictionaryExists(const QString &path) const;
QString getDictionaryPath() const; QString getDictionaryPath() const;
@ -60,6 +82,11 @@ private:
QFile m_userDictionary; QFile m_userDictionary;
Language m_language; Language m_language;
bool m_enabled; bool m_enabled;
// Replacing word
QWebElement m_element;
int m_startPos;
int m_endPos;
}; };
#endif // SPELLER_H #endif // SPELLER_H

View File

@ -372,8 +372,8 @@ Preferences::Preferences(QupZilla* mainClass, QWidget* parent)
//OTHER //OTHER
//Languages //Languages
QString activeLanguage; QString activeLanguage;
if (!mApp->currentLanguage().isEmpty()) { if (!mApp->currentLanguageFile().isEmpty()) {
activeLanguage = mApp->currentLanguage(); activeLanguage = mApp->currentLanguageFile();
QLocale locale(activeLanguage); QLocale locale(activeLanguage);
QString country = QLocale::countryToString(locale.country()); QString country = QLocale::countryToString(locale.country());
QString language = QLocale::languageToString(locale.language()); QString language = QLocale::languageToString(locale.language());

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -334,7 +334,7 @@ CertificateInfoWidget::CertificateInfoWidget(const QSslCertificate &cert, QWidge
ui->issuedByO->setText(showCertInfo(cert.issuerInfo(QSslCertificate::Organization))); ui->issuedByO->setText(showCertInfo(cert.issuerInfo(QSslCertificate::Organization)));
ui->issuedByOU->setText(showCertInfo(cert.issuerInfo(QSslCertificate::OrganizationalUnitName))); ui->issuedByOU->setText(showCertInfo(cert.issuerInfo(QSslCertificate::OrganizationalUnitName)));
//Validity //Validity
QLocale locale = QLocale(mApp->currentLanguage()); QLocale locale = QLocale(mApp->currentLanguageFile());
ui->validityIssuedOn->setText(locale.toString(cert.effectiveDate(), "dddd d. MMMM yyyy")); ui->validityIssuedOn->setText(locale.toString(cert.effectiveDate(), "dddd d. MMMM yyyy"));
ui->validityExpiresOn->setText(locale.toString(cert.expiryDate(), "dddd d. MMMM yyyy")); ui->validityExpiresOn->setText(locale.toString(cert.expiryDate(), "dddd d. MMMM yyyy"));
} }

View File

@ -34,6 +34,10 @@
#include "qzsettings.h" #include "qzsettings.h"
#include "enhancedmenu.h" #include "enhancedmenu.h"
#ifdef USE_HUNSPELL
#include "qtwebkit/spellcheck/speller.h"
#endif
#include <QDir> #include <QDir>
#include <QTimer> #include <QTimer>
#include <QDesktopServices> #include <QDesktopServices>
@ -753,6 +757,16 @@ void WebView::createContextMenu(QMenu* menu, const QWebHitTestResult &hitTest, c
m_actionStop->setEnabled(isLoading()); m_actionStop->setEnabled(isLoading());
} }
int spellCheckActionCount = 0;
#ifdef USE_HUNSPELL
// Show spellcheck menu as the first
if (hitTest.isContentEditable() && !hitTest.isContentSelected()) {
mApp->speller()->populateContextMenu(menu, hitTest);
spellCheckActionCount = menu->actions().count();
}
#endif
if (!hitTest.linkUrl().isEmpty() && hitTest.linkUrl().scheme() != QLatin1String("javascript")) { if (!hitTest.linkUrl().isEmpty() && hitTest.linkUrl().scheme() != QLatin1String("javascript")) {
createLinkContextMenu(menu, hitTest); createLinkContextMenu(menu, hitTest);
} }
@ -766,7 +780,7 @@ void WebView::createContextMenu(QMenu* menu, const QWebHitTestResult &hitTest, c
} }
if (hitTest.isContentEditable()) { if (hitTest.isContentEditable()) {
if (menu->isEmpty()) { if (menu->actions().count() == spellCheckActionCount) {
QMenu* pageMenu = page()->createStandardContextMenu(); QMenu* pageMenu = page()->createStandardContextMenu();
int i = 0; int i = 0;
@ -939,7 +953,7 @@ void WebView::createSelectedTextContextMenu(QMenu* menu, const QWebHitTestResult
menu->addAction(QIcon::fromTheme("mail-message-new"), tr("Send text..."), this, SLOT(sendLinkByMail()))->setData(selectedText); menu->addAction(QIcon::fromTheme("mail-message-new"), tr("Send text..."), this, SLOT(sendLinkByMail()))->setData(selectedText);
menu->addSeparator(); menu->addSeparator();
QString langCode = mApp->currentLanguage().left(2); QString langCode = mApp->currentLanguageFile().left(2);
QUrl googleTranslateUrl = QUrl(QString("http://translate.google.com/#auto|%1|%2").arg(langCode, selectedText)); QUrl googleTranslateUrl = QUrl(QString("http://translate.google.com/#auto|%1|%2").arg(langCode, selectedText));
Action* gtwact = new Action(QIcon(":icons/sites/translate.png"), tr("Google Translate")); Action* gtwact = new Action(QIcon(":icons/sites/translate.png"), tr("Google Translate"));
gtwact->setData(googleTranslateUrl); gtwact->setData(googleTranslateUrl);