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:
parent
074bd928c7
commit
c3a0e1f13a
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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,
|
||||||
|
@ -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() &&
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user