mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 10:46:35 +01:00
[spellcheck] Adding Speller object into MainApplication.
This commit is contained in:
parent
fc41e1516d
commit
074bd928c7
@ -53,6 +53,7 @@
|
||||
#include "checkboxdialog.h"
|
||||
#include "registerqappassociation.h"
|
||||
#include "html5permissions/html5permissionsmanager.h"
|
||||
#include "qtwebkit/spellcheck/speller.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <QFileOpenEvent>
|
||||
@ -92,6 +93,7 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||
, m_restoreManager(0)
|
||||
, m_proxyStyle(0)
|
||||
, m_html5permissions(0)
|
||||
, m_speller(0)
|
||||
, m_dbWriter(new DatabaseWriter(this))
|
||||
, m_uaManager(new UserAgentManager)
|
||||
, m_isPrivateSession(false)
|
||||
@ -496,6 +498,11 @@ QList<QupZilla*> MainApplication::mainWindows()
|
||||
return list;
|
||||
}
|
||||
|
||||
QString MainApplication::currentLanguage()
|
||||
{
|
||||
return m_activeLanguage;
|
||||
}
|
||||
|
||||
void MainApplication::sendMessages(Qz::AppMessageType mes, bool state)
|
||||
{
|
||||
emit message(mes, state);
|
||||
@ -814,6 +821,14 @@ HTML5PermissionsManager* MainApplication::html5permissions()
|
||||
return m_html5permissions;
|
||||
}
|
||||
|
||||
Speller* MainApplication::speller()
|
||||
{
|
||||
if (!m_speller) {
|
||||
m_speller = new Speller();
|
||||
}
|
||||
return m_speller;
|
||||
}
|
||||
|
||||
void MainApplication::startPrivateBrowsing()
|
||||
{
|
||||
QStringList args;
|
||||
@ -1089,4 +1104,5 @@ QString MainApplication::tempPath() const
|
||||
MainApplication::~MainApplication()
|
||||
{
|
||||
delete m_uaManager;
|
||||
delete m_speller;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ class UserAgentManager;
|
||||
class ProxyStyle;
|
||||
class RegisterQAppAssociation;
|
||||
class HTML5PermissionsManager;
|
||||
class Speller;
|
||||
|
||||
class QT_QUPZILLA_EXPORT MainApplication : public QtSingleApplication
|
||||
{
|
||||
@ -77,12 +78,13 @@ public:
|
||||
|
||||
inline static MainApplication* getInstance() { return static_cast<MainApplication*>(QCoreApplication::instance()); }
|
||||
inline QString currentProfilePath() { return m_activeProfil; }
|
||||
inline QString currentLanguage() { return m_activeLanguage; }
|
||||
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 checkSettingsDir();
|
||||
void destroyRestoreManager();
|
||||
void clearTempPath();
|
||||
@ -107,6 +109,7 @@ public:
|
||||
QNetworkDiskCache* networkCache();
|
||||
DesktopNotificationsFactory* desktopNotifications();
|
||||
HTML5PermissionsManager* html5permissions();
|
||||
Speller* speller();
|
||||
|
||||
DatabaseWriter* dbWriter() { return m_dbWriter; }
|
||||
UserAgentManager* uaManager() { return m_uaManager; }
|
||||
@ -167,6 +170,7 @@ private:
|
||||
RestoreManager* m_restoreManager;
|
||||
ProxyStyle* m_proxyStyle;
|
||||
HTML5PermissionsManager* m_html5permissions;
|
||||
Speller* m_speller;
|
||||
DatabaseWriter* m_dbWriter;
|
||||
UserAgentManager* m_uaManager;
|
||||
|
||||
|
@ -20,17 +20,12 @@
|
||||
|
||||
#include "spellcheck.h"
|
||||
#include "speller.h"
|
||||
#include "mainapplication.h"
|
||||
|
||||
SpellCheck::SpellCheck()
|
||||
: QWebSpellChecker()
|
||||
, m_speller(0)
|
||||
, m_speller(mApp->speller())
|
||||
{
|
||||
m_speller = new Speller();
|
||||
|
||||
if (!m_speller->initialize()) {
|
||||
delete m_speller;
|
||||
m_speller = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SpellCheck::isContinousSpellCheckingEnabled() const
|
||||
@ -176,8 +171,3 @@ bool SpellCheck::startOfWord(const QTextBoundaryFinder::BoundaryReasons &reasons
|
||||
(type & QTextBoundaryFinder::Word);
|
||||
#endif
|
||||
}
|
||||
|
||||
SpellCheck::~SpellCheck()
|
||||
{
|
||||
delete m_speller;
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ class SpellCheck : public QWebSpellChecker
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SpellCheck();
|
||||
~SpellCheck();
|
||||
explicit SpellCheck();
|
||||
|
||||
bool isContinousSpellCheckingEnabled() const;
|
||||
void toggleContinousSpellChecking();
|
||||
|
@ -16,165 +16,191 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "speller.h"
|
||||
#include "settings.h"
|
||||
#include "mainapplication.h"
|
||||
#include "qztools.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QTextCodec>
|
||||
#include <QTextStream>
|
||||
#include <QFile>
|
||||
#include <QRegExp>
|
||||
#include <QLocale>
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
|
||||
#include <hunspell/hunspell.hxx>
|
||||
|
||||
Hunspell* Speller::s_hunspell = 0;
|
||||
QTextCodec* Speller::s_codec = 0;
|
||||
QString Speller::s_dictionaryPath;
|
||||
QString Speller::s_langugage;
|
||||
bool Speller::s_initialized = false;
|
||||
|
||||
Speller::Speller()
|
||||
: m_textCodec(0)
|
||||
, m_hunspell(0)
|
||||
, m_enabled(false)
|
||||
{
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
bool Speller::initialize()
|
||||
bool Speller::isEnabled() const
|
||||
{
|
||||
if (s_initialized) {
|
||||
return s_hunspell != 0;
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
s_dictionaryPath = getDictionaryPath();
|
||||
s_langugage = parseLanguage(s_dictionaryPath);
|
||||
void Speller::loadSettings()
|
||||
{
|
||||
Settings settings;
|
||||
settings.beginGroup("SpellCheck");
|
||||
m_enabled = settings.value("enabled", true).toBool();
|
||||
m_dictionaryPath = settings.value("dictionaryPath", getDictionaryPath()).toString();
|
||||
m_language.code = settings.value("language", mApp->currentLanguage()).toString();
|
||||
m_language.name = nameForLanguage(m_language.code);
|
||||
settings.endGroup();
|
||||
|
||||
if (s_dictionaryPath.isEmpty() || s_langugage.isEmpty()) {
|
||||
qWarning() << "SpellCheck: Initialization failed!";
|
||||
return false;
|
||||
m_userDictionary.setFileName(mApp->currentProfilePath() + "userdictionary.txt");
|
||||
initialize();
|
||||
}
|
||||
|
||||
QString dicPath = s_dictionaryPath + ".dic";
|
||||
QString affPath = s_dictionaryPath + ".aff";
|
||||
void Speller::initialize()
|
||||
{
|
||||
delete m_hunspell;
|
||||
m_hunspell = 0;
|
||||
|
||||
s_hunspell = new Hunspell(affPath.toLocal8Bit().constData(),
|
||||
if (m_dictionaryPath.isEmpty()) {
|
||||
qWarning() << "SpellCheck: Cannot locate dictionary path!";
|
||||
return;
|
||||
}
|
||||
|
||||
QString dictionary = m_dictionaryPath + m_language.code;
|
||||
|
||||
if (!dictionaryExists(dictionary)) {
|
||||
qWarning() << "SpellCheck: Dictionaries for" << dictionary << "doesn't exists!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QString dicPath = dictionary + ".dic";
|
||||
const QString affPath = dictionary + ".aff";
|
||||
|
||||
m_hunspell = new Hunspell(affPath.toLocal8Bit().constData(),
|
||||
dicPath .toLocal8Bit().constData());
|
||||
|
||||
s_codec = QTextCodec::codecForName(s_hunspell->get_dic_encoding());
|
||||
m_textCodec = QTextCodec::codecForName(m_hunspell->get_dic_encoding());
|
||||
|
||||
qDebug() << "SpellCheck: Language =" << language();
|
||||
s_initialized = true;
|
||||
return true;
|
||||
if (m_userDictionary.exists()) {
|
||||
m_hunspell->add_dic(m_userDictionary.fileName().toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
QString Speller::backend() const
|
||||
{
|
||||
return QString("Hunspell");
|
||||
qDebug() << "SpellCheck: Language =" << language().code;
|
||||
}
|
||||
|
||||
QString Speller::language() const
|
||||
Speller::Language Speller::language() const
|
||||
{
|
||||
return s_langugage;
|
||||
return m_language;
|
||||
}
|
||||
|
||||
QList<Speller::Language> Speller::availableLanguages() const
|
||||
{
|
||||
QList<Language> languages;
|
||||
|
||||
QDirIterator it(m_dictionaryPath, QStringList("*.dic"),
|
||||
QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
|
||||
|
||||
while (it.hasNext()) {
|
||||
const QString affFilePath = it.next().replace(QLatin1String(".dic"), QLatin1String(".aff"));
|
||||
|
||||
if (!QFile(affFilePath).exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Language lang;
|
||||
lang.code = it.fileInfo().baseName();
|
||||
lang.name = nameForLanguage(lang.code);
|
||||
|
||||
languages.append(lang);
|
||||
}
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
void Speller::learnWord(const QString &word)
|
||||
{
|
||||
const char* encodedWord = s_codec->fromUnicode(word).constData();
|
||||
s_hunspell->add(encodedWord);
|
||||
if (!m_hunspell || !m_textCodec) {
|
||||
return;
|
||||
}
|
||||
|
||||
void Speller::ignoreWordInSpellDocument(const QString &word)
|
||||
{
|
||||
m_ignoredWords.append(word);
|
||||
const char* encodedWord = m_textCodec->fromUnicode(word).constData();
|
||||
m_hunspell->add(encodedWord);
|
||||
|
||||
if (!m_userDictionary.open(QFile::WriteOnly | QFile::Append)) {
|
||||
qWarning() << "SpellCheck: Cannot open file" << m_userDictionary.fileName() << "for writing!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_userDictionary.write(word.toUtf8());
|
||||
m_userDictionary.write("\n");
|
||||
m_userDictionary.close();
|
||||
}
|
||||
|
||||
bool Speller::isMisspelled(const QString &string)
|
||||
{
|
||||
if (m_ignoredWords.contains(string)) {
|
||||
if (!m_hunspell || !m_textCodec) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* encodedString = s_codec->fromUnicode(string).constData();
|
||||
return s_hunspell->spell(encodedString) == 0;
|
||||
const char* encodedString = m_textCodec->fromUnicode(string).constData();
|
||||
return m_hunspell->spell(encodedString) == 0;
|
||||
}
|
||||
|
||||
QStringList Speller::suggest(const QString &word)
|
||||
{
|
||||
if (!m_hunspell || !m_textCodec) {
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
char** suggestions;
|
||||
const char* encodedWord = s_codec->fromUnicode(word).constData();
|
||||
int count = s_hunspell->suggest(&suggestions, encodedWord);
|
||||
const char* encodedWord = m_textCodec->fromUnicode(word).constData();
|
||||
int count = m_hunspell->suggest(&suggestions, encodedWord);
|
||||
|
||||
QStringList suggests;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
suggests.append(s_codec->toUnicode(suggestions[i]));
|
||||
suggests.append(m_textCodec->toUnicode(suggestions[i]));
|
||||
}
|
||||
s_hunspell->free_list(&suggestions, count);
|
||||
m_hunspell->free_list(&suggestions, count);
|
||||
|
||||
return suggests;
|
||||
}
|
||||
|
||||
bool Speller::dictionaryExists(const QString &path)
|
||||
bool Speller::dictionaryExists(const QString &path) const
|
||||
{
|
||||
return QFile(path + ".dic").exists() &&
|
||||
QFile(path + ".aff").exists();
|
||||
}
|
||||
|
||||
QString Speller::parseLanguage(const QString &path)
|
||||
QString Speller::getDictionaryPath() const
|
||||
{
|
||||
if (path.contains(QLatin1Char('/'))) {
|
||||
int pos = path.lastIndexOf(QLatin1Char('/'));
|
||||
return path.mid(pos + 1);
|
||||
}
|
||||
else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
#ifdef QZ_WS_X11
|
||||
const QString defaultDicPath = "/usr/share/hunspell/";
|
||||
#else
|
||||
const QString defaultDicPath = mApp->DATADIR + "hunspell/";
|
||||
#endif
|
||||
|
||||
QString Speller::getDictionaryPath()
|
||||
{
|
||||
QString dictName;
|
||||
QString defaultDicPath = "/usr/share/hunspell/";
|
||||
|
||||
QString env = QString::fromLocal8Bit(qgetenv("DICTIONARY"));
|
||||
if (!env.isEmpty()) {
|
||||
if (env.contains(QLatin1Char(','))) {
|
||||
dictName = env.split(QLatin1Char(',')).first().trimmed();
|
||||
}
|
||||
else {
|
||||
dictName = env.trimmed();
|
||||
}
|
||||
|
||||
if (dictName.contains(QLatin1Char('/')) && dictionaryExists(dictName)) {
|
||||
return dictName;
|
||||
}
|
||||
}
|
||||
|
||||
QString dicPath = QString::fromLocal8Bit(qgetenv("DICPATH"));
|
||||
QString dicPath = QString::fromLocal8Bit(qgetenv("DICPATH")).trimmed();
|
||||
if (!dicPath.isEmpty() && !dicPath.endsWith(QLatin1Char('/'))) {
|
||||
dicPath.append(QLatin1Char('/'));
|
||||
}
|
||||
|
||||
if (!dicPath.isEmpty() && dictionaryExists(dicPath + dictName)) {
|
||||
return dicPath + dictName;
|
||||
return dicPath.isEmpty() ? defaultDicPath : dicPath;
|
||||
}
|
||||
|
||||
if (!dictName.isEmpty()) {
|
||||
if (dictionaryExists(defaultDicPath + dictName)) {
|
||||
return defaultDicPath + dictName;
|
||||
}
|
||||
QString Speller::nameForLanguage(const QString &code) const
|
||||
{
|
||||
QLocale loc = QLocale(code);
|
||||
QString name = QLocale::languageToString(loc.language());
|
||||
|
||||
if (loc.country() != QLocale::AnyCountry) {
|
||||
name.append(" / " + QLocale::countryToString(loc.country()));
|
||||
}
|
||||
|
||||
QString locale = QLocale::system().name();
|
||||
|
||||
if (dictionaryExists(dicPath + locale)) {
|
||||
return dicPath + locale;
|
||||
}
|
||||
else if (dictionaryExists(defaultDicPath + locale)) {
|
||||
return defaultDicPath + locale;
|
||||
}
|
||||
else {
|
||||
qWarning() << "SpellCheck: Cannot find dictionaries for" << defaultDicPath + locale;
|
||||
}
|
||||
|
||||
return QString();
|
||||
return name;
|
||||
}
|
||||
|
||||
Speller::~Speller()
|
||||
{
|
||||
delete m_hunspell;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define SPELLER_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
|
||||
class QTextCodec;
|
||||
class Hunspell;
|
||||
@ -26,32 +27,39 @@ class Hunspell;
|
||||
class Speller
|
||||
{
|
||||
public:
|
||||
struct Language {
|
||||
QString code;
|
||||
QString name;
|
||||
};
|
||||
|
||||
explicit Speller();
|
||||
~Speller();
|
||||
|
||||
bool initialize();
|
||||
bool isEnabled() const;
|
||||
void loadSettings();
|
||||
|
||||
QString backend() const;
|
||||
QString language() const;
|
||||
Language language() const;
|
||||
QList<Language> availableLanguages() const;
|
||||
|
||||
void learnWord(const QString &word);
|
||||
void ignoreWordInSpellDocument(const QString &word);
|
||||
|
||||
bool isMisspelled(const QString &string);
|
||||
QStringList suggest(const QString &word);
|
||||
|
||||
private:
|
||||
bool dictionaryExists(const QString &path);
|
||||
QString parseLanguage(const QString &path);
|
||||
QString getDictionaryPath();
|
||||
void initialize();
|
||||
|
||||
static Hunspell* s_hunspell;
|
||||
static QTextCodec* s_codec;
|
||||
static QString s_dictionaryPath;
|
||||
static QString s_langugage;
|
||||
static bool s_initialized;
|
||||
bool dictionaryExists(const QString &path) const;
|
||||
QString getDictionaryPath() const;
|
||||
QString nameForLanguage(const QString &code) const;
|
||||
|
||||
QStringList m_ignoredWords;
|
||||
QString m_dictionaryPath;
|
||||
QTextCodec* m_textCodec;
|
||||
Hunspell* m_hunspell;
|
||||
|
||||
QFile m_userDictionary;
|
||||
Language m_language;
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
#endif // SPELLER_H
|
||||
|
Loading…
Reference in New Issue
Block a user