From 7f7eb09b3535ed8e9620922ecdca9a0758e983d2 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Thu, 8 Jun 2023 21:33:16 +0300 Subject: [PATCH] kdeui: spelling classes reimplementation not leaking enchant dictionaries, simpler implementation and its not spread across 2 libraries (kdecore and kdeui) Signed-off-by: Ivailo Monev --- CMakeLists.txt | 3 +- includes/CMakeLists.txt | 30 +- includes/KSpellBackgroundChecker | 1 + includes/KSpellConfigWidget | 1 + includes/KSpellDialog | 1 + includes/KSpellDictionaryComboBox | 1 + includes/KSpellHighlighter | 1 + includes/KSpeller | 1 + includes/Sonnet/ConfigDialog | 1 - includes/Sonnet/ConfigWidget | 1 - includes/Sonnet/Dialog | 1 - includes/Sonnet/DictionaryComboBox | 1 - includes/Sonnet/Highlighter | 1 - kdecore/CMakeLists.txt | 32 -- kdecore/sonnet/backgroundchecker.cpp | 171 ------- kdecore/sonnet/backgroundchecker.h | 133 ------ kdecore/sonnet/backgroundengine.cpp | 117 ----- kdecore/sonnet/backgroundengine_p.h | 80 ---- kdecore/sonnet/enchantclient.cpp | 99 ---- kdecore/sonnet/enchantclient_p.h | 57 --- kdecore/sonnet/enchantdict.cpp | 110 ----- kdecore/sonnet/enchantdict_p.h | 63 --- kdecore/sonnet/filter.cpp | 311 ------------ kdecore/sonnet/filter_p.h | 120 ----- kdecore/sonnet/globals.cpp | 98 ---- kdecore/sonnet/globals.h | 49 -- kdecore/sonnet/loader.cpp | 251 ---------- kdecore/sonnet/loader_p.h | 123 ----- kdecore/sonnet/settings.cpp | 262 ---------- kdecore/sonnet/settings_p.h | 87 ---- kdecore/sonnet/speller.cpp | 296 ------------ kdecore/sonnet/speller.h | 153 ------ kdecore/sonnet/tests/CMakeLists.txt | 29 -- kdecore/sonnet/tests/test.cpp | 97 ---- kdecore/sonnet/tests/test_config.cpp | 40 -- kdecore/sonnet/tests/test_core.cpp | 172 ------- kdecore/sonnet/tests/test_core.h | 32 -- kdecore/sonnet/tests/test_dialog.cpp | 67 --- kdecore/sonnet/tests/test_dialog.h | 42 -- kdecore/sonnet/tests/test_filter.cpp | 161 ------- kdecore/sonnet/tests/test_filter.h | 34 -- kdeui/CMakeLists.txt | 39 +- kdeui/fonts/sampleedit_p.h | 1 + kdeui/sonnet/configdialog.cpp | 100 ---- kdeui/sonnet/configdialog.h | 85 ---- kdeui/sonnet/configui.ui | 112 ----- kdeui/sonnet/configwidget.cpp | 142 ------ kdeui/sonnet/configwidget.h | 79 --- kdeui/sonnet/dialog.cpp | 452 ------------------ kdeui/sonnet/dialog.h | 166 ------- kdeui/sonnet/dictionarycombobox.cpp | 115 ----- kdeui/sonnet/dictionarycombobox.h | 102 ---- kdeui/sonnet/highlighter.cpp | 427 ----------------- kdeui/sonnet/highlighter.h | 161 ------- kdeui/sonnet/sonnetui.ui | 290 ----------- kdeui/sonnet/tests/CMakeLists.txt | 40 -- kdeui/sonnet/tests/backgroundtest.cpp | 169 ------- kdeui/sonnet/tests/backgroundtest.h | 45 -- kdeui/sonnet/tests/test_config.cpp | 40 -- kdeui/sonnet/tests/test_configdialog.cpp | 42 -- kdeui/sonnet/tests/test_dialog.cpp | 64 --- kdeui/sonnet/tests/test_dialog.h | 40 -- .../sonnet/tests/test_dictionarycombobox.cpp | 79 --- kdeui/sonnet/tests/test_highlighter.cpp | 71 --- kdeui/sonnet/tests/test_highlighter.h | 41 -- kdeui/spell/kspellbackgroundchecker.cpp | 165 +++++++ kdeui/spell/kspellbackgroundchecker.h | 58 +++ kdeui/spell/kspellconfigwidget.cpp | 131 +++++ kdeui/spell/kspellconfigwidget.h | 53 ++ kdeui/spell/kspelldialog.cpp | 308 ++++++++++++ kdeui/spell/kspelldialog.h | 68 +++ kdeui/spell/kspelldictionarycombobox.cpp | 71 +++ kdeui/spell/kspelldictionarycombobox.h | 47 ++ kdeui/spell/kspeller.cpp | 247 ++++++++++ kdeui/spell/kspeller.h | 61 +++ kdeui/spell/kspellhighlighter.cpp | 119 +++++ kdeui/spell/kspellhighlighter.h | 58 +++ kdeui/widgets/keditlistwidget.h | 8 +- kdeui/widgets/ktextedit.cpp | 139 ++---- kdeui/widgets/ktextedit.h | 66 +-- kdewidgets/kde.widgets | 6 +- kutils/kdeglobals.kcfg | 14 +- 82 files changed, 1489 insertions(+), 6362 deletions(-) create mode 100644 includes/KSpellBackgroundChecker create mode 100644 includes/KSpellConfigWidget create mode 100644 includes/KSpellDialog create mode 100644 includes/KSpellDictionaryComboBox create mode 100644 includes/KSpellHighlighter create mode 100644 includes/KSpeller delete mode 100644 includes/Sonnet/ConfigDialog delete mode 100644 includes/Sonnet/ConfigWidget delete mode 100644 includes/Sonnet/Dialog delete mode 100644 includes/Sonnet/DictionaryComboBox delete mode 100644 includes/Sonnet/Highlighter delete mode 100644 kdecore/sonnet/backgroundchecker.cpp delete mode 100644 kdecore/sonnet/backgroundchecker.h delete mode 100644 kdecore/sonnet/backgroundengine.cpp delete mode 100644 kdecore/sonnet/backgroundengine_p.h delete mode 100644 kdecore/sonnet/enchantclient.cpp delete mode 100644 kdecore/sonnet/enchantclient_p.h delete mode 100644 kdecore/sonnet/enchantdict.cpp delete mode 100644 kdecore/sonnet/enchantdict_p.h delete mode 100644 kdecore/sonnet/filter.cpp delete mode 100644 kdecore/sonnet/filter_p.h delete mode 100644 kdecore/sonnet/globals.cpp delete mode 100644 kdecore/sonnet/globals.h delete mode 100644 kdecore/sonnet/loader.cpp delete mode 100644 kdecore/sonnet/loader_p.h delete mode 100644 kdecore/sonnet/settings.cpp delete mode 100644 kdecore/sonnet/settings_p.h delete mode 100644 kdecore/sonnet/speller.cpp delete mode 100644 kdecore/sonnet/speller.h delete mode 100644 kdecore/sonnet/tests/CMakeLists.txt delete mode 100644 kdecore/sonnet/tests/test.cpp delete mode 100644 kdecore/sonnet/tests/test_config.cpp delete mode 100644 kdecore/sonnet/tests/test_core.cpp delete mode 100644 kdecore/sonnet/tests/test_core.h delete mode 100644 kdecore/sonnet/tests/test_dialog.cpp delete mode 100644 kdecore/sonnet/tests/test_dialog.h delete mode 100644 kdecore/sonnet/tests/test_filter.cpp delete mode 100644 kdecore/sonnet/tests/test_filter.h delete mode 100644 kdeui/sonnet/configdialog.cpp delete mode 100644 kdeui/sonnet/configdialog.h delete mode 100644 kdeui/sonnet/configui.ui delete mode 100644 kdeui/sonnet/configwidget.cpp delete mode 100644 kdeui/sonnet/configwidget.h delete mode 100644 kdeui/sonnet/dialog.cpp delete mode 100644 kdeui/sonnet/dialog.h delete mode 100644 kdeui/sonnet/dictionarycombobox.cpp delete mode 100644 kdeui/sonnet/dictionarycombobox.h delete mode 100644 kdeui/sonnet/highlighter.cpp delete mode 100644 kdeui/sonnet/highlighter.h delete mode 100644 kdeui/sonnet/sonnetui.ui delete mode 100644 kdeui/sonnet/tests/CMakeLists.txt delete mode 100644 kdeui/sonnet/tests/backgroundtest.cpp delete mode 100644 kdeui/sonnet/tests/backgroundtest.h delete mode 100644 kdeui/sonnet/tests/test_config.cpp delete mode 100644 kdeui/sonnet/tests/test_configdialog.cpp delete mode 100644 kdeui/sonnet/tests/test_dialog.cpp delete mode 100644 kdeui/sonnet/tests/test_dialog.h delete mode 100644 kdeui/sonnet/tests/test_dictionarycombobox.cpp delete mode 100644 kdeui/sonnet/tests/test_highlighter.cpp delete mode 100644 kdeui/sonnet/tests/test_highlighter.h create mode 100644 kdeui/spell/kspellbackgroundchecker.cpp create mode 100644 kdeui/spell/kspellbackgroundchecker.h create mode 100644 kdeui/spell/kspellconfigwidget.cpp create mode 100644 kdeui/spell/kspellconfigwidget.h create mode 100644 kdeui/spell/kspelldialog.cpp create mode 100644 kdeui/spell/kspelldialog.h create mode 100644 kdeui/spell/kspelldictionarycombobox.cpp create mode 100644 kdeui/spell/kspelldictionarycombobox.h create mode 100644 kdeui/spell/kspeller.cpp create mode 100644 kdeui/spell/kspeller.h create mode 100644 kdeui/spell/kspellhighlighter.cpp create mode 100644 kdeui/spell/kspellhighlighter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index db44e6dc..0e9c8eb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -340,7 +340,6 @@ set(KDE4_KDECORE_INCLUDES ${CMAKE_SOURCE_DIR}/kdecore/sycoca ${CMAKE_SOURCE_DIR}/kdecore/text ${CMAKE_SOURCE_DIR}/kdecore/util - ${CMAKE_SOURCE_DIR}/kdecore/sonnet ${CMAKE_BINARY_DIR}/kdecore ${QT_INCLUDES} ${_KDE4_PLATFORM_INCLUDE_DIRS} @@ -363,7 +362,7 @@ set(KDE4_KDEUI_INCLUDES ${CMAKE_SOURCE_DIR}/kdeui/paged ${CMAKE_SOURCE_DIR}/kdeui/plotting ${CMAKE_SOURCE_DIR}/kdeui/shortcuts - ${CMAKE_SOURCE_DIR}/kdeui/sonnet + ${CMAKE_SOURCE_DIR}/kdeui/spell ${CMAKE_SOURCE_DIR}/kdeui/util ${CMAKE_SOURCE_DIR}/kdeui/widgets ${CMAKE_SOURCE_DIR}/kdeui/windowmanagement diff --git a/includes/CMakeLists.txt b/includes/CMakeLists.txt index 13c2137d..d29ab754 100644 --- a/includes/CMakeLists.txt +++ b/includes/CMakeLists.txt @@ -358,6 +358,12 @@ install( KPty KPtyDevice KPtyProcess + KSpeller + KSpellHighlighter + KSpellDialog + KSpellDictionaryComboBox + KSpellConfigWidget + KSpellBackgroundChecker DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE COMPONENT Devel ) @@ -434,18 +440,6 @@ install( COMPONENT Devel ) - -#install( -# FILES -# Sonnet/GuessLanguage -# Sonnet/UnicodeData -# Sonnet/TextBreaks -# Sonnet/Spell -# DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/Sonnet -# COMPONENT Devel -#) - - install( FILES KTextEditor/Attribute @@ -518,18 +512,6 @@ install( COMPONENT Devel ) - -install( - FILES - Sonnet/ConfigDialog - Sonnet/ConfigWidget - Sonnet/Dialog - Sonnet/DictionaryComboBox - Sonnet/Highlighter - DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/Sonnet - COMPONENT Devel -) - install( FILES Plasma/AbstractRunner diff --git a/includes/KSpellBackgroundChecker b/includes/KSpellBackgroundChecker new file mode 100644 index 00000000..d685484e --- /dev/null +++ b/includes/KSpellBackgroundChecker @@ -0,0 +1 @@ +#include "../kspellbackgroundchecker.h" diff --git a/includes/KSpellConfigWidget b/includes/KSpellConfigWidget new file mode 100644 index 00000000..be8aa636 --- /dev/null +++ b/includes/KSpellConfigWidget @@ -0,0 +1 @@ +#include "../kspellconfigwidget.h" diff --git a/includes/KSpellDialog b/includes/KSpellDialog new file mode 100644 index 00000000..1a8ad4bc --- /dev/null +++ b/includes/KSpellDialog @@ -0,0 +1 @@ +#include "../kspelldialog.h" diff --git a/includes/KSpellDictionaryComboBox b/includes/KSpellDictionaryComboBox new file mode 100644 index 00000000..ede7a478 --- /dev/null +++ b/includes/KSpellDictionaryComboBox @@ -0,0 +1 @@ +#include "../kspelldictionarycombobox.h" diff --git a/includes/KSpellHighlighter b/includes/KSpellHighlighter new file mode 100644 index 00000000..9e291323 --- /dev/null +++ b/includes/KSpellHighlighter @@ -0,0 +1 @@ +#include "../kspellhighlighter.h" diff --git a/includes/KSpeller b/includes/KSpeller new file mode 100644 index 00000000..87dcf3fc --- /dev/null +++ b/includes/KSpeller @@ -0,0 +1 @@ +#include "../kspeller.h" diff --git a/includes/Sonnet/ConfigDialog b/includes/Sonnet/ConfigDialog deleted file mode 100644 index 69970610..00000000 --- a/includes/Sonnet/ConfigDialog +++ /dev/null @@ -1 +0,0 @@ -#include "../../sonnet/configdialog.h" diff --git a/includes/Sonnet/ConfigWidget b/includes/Sonnet/ConfigWidget deleted file mode 100644 index 38bdb6ef..00000000 --- a/includes/Sonnet/ConfigWidget +++ /dev/null @@ -1 +0,0 @@ -#include "../../sonnet/configwidget.h" diff --git a/includes/Sonnet/Dialog b/includes/Sonnet/Dialog deleted file mode 100644 index aab1c961..00000000 --- a/includes/Sonnet/Dialog +++ /dev/null @@ -1 +0,0 @@ -#include "../../sonnet/dialog.h" diff --git a/includes/Sonnet/DictionaryComboBox b/includes/Sonnet/DictionaryComboBox deleted file mode 100644 index 7e55f41b..00000000 --- a/includes/Sonnet/DictionaryComboBox +++ /dev/null @@ -1 +0,0 @@ -#include "../../sonnet/dictionarycombobox.h" diff --git a/includes/Sonnet/Highlighter b/includes/Sonnet/Highlighter deleted file mode 100644 index 0668222c..00000000 --- a/includes/Sonnet/Highlighter +++ /dev/null @@ -1 +0,0 @@ -#include "../../sonnet/highlighter.h" diff --git a/kdecore/CMakeLists.txt b/kdecore/CMakeLists.txt index 41c9f308..9ad54c6e 100644 --- a/kdecore/CMakeLists.txt +++ b/kdecore/CMakeLists.txt @@ -25,7 +25,6 @@ include_directories( # for kglobalsettings header ${KDE4_KDEUI_INCLUDES} ${QT_INCLUDES} - ${CMAKE_CURRENT_SOURCE_DIR}/sonnet ) # kdecore_OPTIONAL_SRCS is used to collect source files @@ -37,24 +36,9 @@ set(kdecore_OPTIONAL_LIBS) add_definitions(-DQT_NO_CAST_FROM_ASCII) -# compile Enchant if available -if(ENCHANT_FOUND) - include_directories( - ${ENCHANT_INCLUDE_DIR} - "${ENCHANT_INCLUDE_DIR}/.." - ) - set(kdecore_OPTIONAL_SRCS - ${kdecore_OPTIONAL_SRCS} - sonnet/enchantclient.cpp - sonnet/enchantdict.cpp - ) - set(kdecore_OPTIONAL_LIBS ${kdecore_OPTIONAL_LIBS} ${ENCHANT_LIBRARIES}) -endif() - add_subdirectory(kconfig_compiler) if(ENABLE_TESTING) add_subdirectory(tests) - add_subdirectory(sonnet/tests) endif() ########### next target ############### @@ -133,13 +117,6 @@ set(kdecore_LIB_SRCS services/yacc.c services/lex.c services/kplugininfo.cpp - sonnet/loader.cpp - sonnet/speller.cpp - sonnet/filter.cpp - sonnet/settings.cpp - sonnet/backgroundchecker.cpp - sonnet/backgroundengine.cpp - sonnet/globals.cpp localization/kcatalog.cpp localization/kcharsets.cpp @@ -314,15 +291,6 @@ install( COMPONENT Devel ) -install( - FILES - sonnet/backgroundchecker.h - sonnet/speller.h - sonnet/globals.h - DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/sonnet - COMPONENT Devel -) - install( FILES services/kplugininfo.desktop diff --git a/kdecore/sonnet/backgroundchecker.cpp b/kdecore/sonnet/backgroundchecker.cpp deleted file mode 100644 index b531ebdf..00000000 --- a/kdecore/sonnet/backgroundchecker.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * backgroundchecker.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "backgroundchecker.h" - -#include "loader_p.h" -#include "backgroundengine_p.h" -#include "filter_p.h" -#include "settings_p.h" - -#include - -using namespace Sonnet; - -class BackgroundChecker::Private -{ -public: - BackgroundEngine *engine; - QString currentText; -}; - - -BackgroundChecker::BackgroundChecker(QObject *parent) - : QObject(parent), - d(new Private) -{ - d->engine = new BackgroundEngine(this); - connect(d->engine, SIGNAL(misspelling(QString,int)), - SIGNAL(misspelling(QString,int))); - connect(d->engine, SIGNAL(done()), - SLOT(slotEngineDone())); -} - -BackgroundChecker::BackgroundChecker(const Speller &speller, QObject *parent) - : QObject(parent), - d(new Private) -{ - d->engine = new BackgroundEngine(this); - d->engine->setSpeller(speller); - connect(d->engine, SIGNAL(misspelling(QString,int)), - SIGNAL(misspelling(QString,int))); - connect(d->engine, SIGNAL(done()), - SLOT(slotEngineDone())); -} - -BackgroundChecker::~BackgroundChecker() -{ - delete d; -} - -void BackgroundChecker::restore(KConfig *config) -{ - Loader *loader = Loader::openLoader(); - loader->settings()->restore(config); - d->engine->filter()->setSettings(loader->settings()); -} - -void BackgroundChecker::setText(const QString &text) -{ - d->currentText = text; - d->engine->setText(text); - d->engine->start(); -} - -void BackgroundChecker::start() -{ - d->currentText = fetchMoreText(); - // ## what if d->currentText.isEmpty()? - //kDebug()<<"Sonnet BackgroundChecker: starting with : \"" << d->currentText << "\""; - d->engine->setText(d->currentText); - d->engine->start(); -} - -void BackgroundChecker::stop() -{ - d->engine->stop(); -} - -QString BackgroundChecker::fetchMoreText() -{ - return QString(); -} - -void BackgroundChecker::finishedCurrentFeed() -{ -} - -void BackgroundChecker::setSpeller(const Speller &speller) -{ - d->engine->setSpeller(speller); -} - -Speller BackgroundChecker::speller() const -{ - return d->engine->speller(); -} - -bool BackgroundChecker::checkWord(const QString &word) const -{ - return d->engine->checkWord( word ); -} - -bool BackgroundChecker::addWordToPersonal(const QString &word) -{ - return d->engine->addWord(word); -} - -QStringList BackgroundChecker::suggest(const QString &word) const -{ - return d->engine->suggest(word); -} - -void BackgroundChecker::changeLanguage(const QString &lang) -{ - d->engine->changeLanguage(lang); -} - -void BackgroundChecker::continueChecking() -{ - d->engine->continueChecking(); -} - -void BackgroundChecker::slotEngineDone() -{ - finishedCurrentFeed(); - d->currentText = fetchMoreText(); - - if ( d->currentText.isNull() ) { - emit done(); - } else { - d->engine->setText( d->currentText ); - d->engine->start(); - } -} - -QString BackgroundChecker::text() const -{ - return d->engine->filter()->buffer(); -} - - -QString BackgroundChecker::currentContext() const -{ - return d->engine->filter()->context(); -} - -void Sonnet::BackgroundChecker::replace(int start, const QString &oldText, - const QString &newText) -{ - Word w(oldText, start); - d->engine->filter()->replace(w, newText); -} - -#include "moc_backgroundchecker.cpp" diff --git a/kdecore/sonnet/backgroundchecker.h b/kdecore/sonnet/backgroundchecker.h deleted file mode 100644 index b4c5106d..00000000 --- a/kdecore/sonnet/backgroundchecker.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * backgroundchecker.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_BACKGROUNDCHECKER_H -#define SONNET_BACKGROUNDCHECKER_H - -#include "speller.h" - -#include - -#include - -/** - * The sonnet namespace. - */ -namespace Sonnet -{ - class Speller; - - /** - * - * BackgroundChecker is used to perform spell checking without - * blocking the application. You can use it as is by calling - * the checkText function or subclass it and reimplement - * getMoreText function. - * - * The misspelling signal is emitted whenever a misspelled word - * is found. The background checker stops right before emitting - * the signal. So the parent has to call continueChecking function - * to resume the checking. - * - * done signal is emitted when whole text is spell checked. - * - * @author Zack Rusin - * @short class used for spell checking in the background - */ - class KDECORE_EXPORT BackgroundChecker : public QObject - { - Q_OBJECT - public: - explicit BackgroundChecker(QObject *parent =0); - explicit BackgroundChecker(const Speller &speller, QObject *parent =0); - ~BackgroundChecker(); - - /** - * This method is used to spell check static text. - * It automatically invokes start(). - * - * Use fetchMoreText() with start() to spell check a stream. - */ - void setText(const QString &text); - QString text() const; - - QString currentContext() const; - - Speller speller() const; - void setSpeller(const Speller &speller); - - bool checkWord(const QString &word) const; - QStringList suggest(const QString &word) const; - bool addWordToPersonal(const QString &word); - - void restore(KConfig *config); - - public Q_SLOTS: - virtual void start(); - virtual void stop(); - void replace(int start, const QString &oldText, - const QString &newText); - void changeLanguage(const QString &lang); - - /** - * After emitting misspelling signal the background - * checker stops. The catcher is responsible for calling - * continueChecking function to resume checking. - */ - virtual void continueChecking(); - - Q_SIGNALS: - /** - * Emitted whenever a misspelled word is found - */ - void misspelling(const QString &word, int start); - - /** - * Emitted after the whole text has been spell checked. - */ - void done(); - - protected: - /** - * This function is called to get the text to spell check. - * It will be called continuesly until it returns QString() - * in which case the done() signal is emitted. - * Note: the start parameter in mispelling() is not a combined - * position but a position in the last string returned - * by fetchMoreText. You need to store the state in the derivatives. - */ - virtual QString fetchMoreText(); - - /** - * This function will be called whenever the background checker - * will be finished text which it got from fetchMoreText. - */ - virtual void finishedCurrentFeed(); - - protected Q_SLOTS: - void slotEngineDone(); - private: - class Private; - Private *const d; - }; - -} - -#endif diff --git a/kdecore/sonnet/backgroundengine.cpp b/kdecore/sonnet/backgroundengine.cpp deleted file mode 100644 index 9971041f..00000000 --- a/kdecore/sonnet/backgroundengine.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "backgroundengine_p.h" - -#include "filter_p.h" - -#include - -#include - -using namespace Sonnet; - -BackgroundEngine::BackgroundEngine(QObject *parent) - : QObject(parent), m_filter(Filter::defaultFilter()) -{ -} - -BackgroundEngine::~BackgroundEngine() -{ - delete m_filter; -} - -void BackgroundEngine::setSpeller(const Speller &speller) -{ - m_dict = speller; -} - -void BackgroundEngine::setText(const QString &text) -{ - m_filter->setBuffer(text); -} - -QString BackgroundEngine::text() const -{ - return m_filter->buffer(); -} - -void BackgroundEngine::changeLanguage(const QString &lang) -{ - m_dict.setLanguage(lang); -} - -QString BackgroundEngine::language() const -{ - return m_dict.language(); -} - -void BackgroundEngine::setFilter(Filter *filter) -{ - QString oldText = m_filter->buffer(); - m_filter = filter; - m_filter->setBuffer(oldText); -} - -void BackgroundEngine::start() -{ - QTimer::singleShot(0, this, SLOT(checkNext())); -} - -void BackgroundEngine::stop() -{ -} - -void BackgroundEngine::continueChecking() -{ - QTimer::singleShot(0, this, SLOT(checkNext())); -} - -void BackgroundEngine::checkNext() -{ - Word w = m_filter->nextWord(); - if (w.end) { - emit done(); - return; - } - - if (Q_UNLIKELY( m_dict.isMisspelled(w.word) )) { - //kDebug()<<"found misspelling "<< w.word; - emit misspelling(w.word, w.start); - //wait for the handler. the parent will decide itself when to continue - } else - continueChecking(); -} - -bool BackgroundEngine::checkWord(const QString &word) const -{ - return m_dict.isCorrect(word); -} - -bool BackgroundEngine::addWord(const QString &word) -{ - return m_dict.addToPersonal(word); -} - -QStringList BackgroundEngine::suggest(const QString &word) const -{ - return m_dict.suggest(word); -} - -#include "moc_backgroundengine_p.cpp" diff --git a/kdecore/sonnet/backgroundengine_p.h b/kdecore/sonnet/backgroundengine_p.h deleted file mode 100644 index ac5abb3b..00000000 --- a/kdecore/sonnet/backgroundengine_p.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * backgroundengine.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_BACKGROUNDENGINE_P_H -#define SONNET_BACKGROUNDENGINE_P_H - -#include "speller.h" -#include "loader_p.h" - -#include -#include - -namespace Sonnet -{ - class Filter; - class Loader; - class BackgroundEngine : public QObject - { - Q_OBJECT - public: - explicit BackgroundEngine(QObject *parent); - ~BackgroundEngine(); - - void setSpeller(const Speller &speller); - Speller speller() const { return m_dict; } - - void setText(const QString &); - QString text() const; - - void changeLanguage(const QString &); - QString language() const; - - void setFilter(Filter *filter); - Filter *filter() const { return m_filter; } - - void start(); - void continueChecking(); - void stop(); - - bool checkWord(const QString &word) const; - QStringList suggest(const QString &word) const; - bool addWord(const QString &word); - Q_SIGNALS: - - /** - * Emitted when a misspelling is found. - */ - void misspelling(const QString&, int); - - /** - * Emitted when all words have been checked. - */ - void done(); - - protected Q_SLOTS: - void checkNext(); - private: - Filter *m_filter; - Speller m_dict; - }; -} - -#endif // SONNET_BACKGROUNDENGINE_P_H diff --git a/kdecore/sonnet/enchantclient.cpp b/kdecore/sonnet/enchantclient.cpp deleted file mode 100644 index 61a87862..00000000 --- a/kdecore/sonnet/enchantclient.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * Copyright 2006 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "enchantclient_p.h" -#include "enchantdict_p.h" - -#include - -namespace Sonnet -{ - -static void enchantDictDescribeFn(const char * const lang_tag, - const char * const provider_name, - const char * const provider_desc, - const char * const provider_file, - void * user_data) -{ - QSpellEnchantClient *client = reinterpret_cast(user_data); - //qDebug()<addLanguage(QString::fromLatin1(lang_tag)); - -} - -QSpellEnchantClient::QSpellEnchantClient(QObject *parent) - : QObject(parent) -{ - m_broker = enchant_broker_init(); - enchant_broker_list_dicts(m_broker, - enchantDictDescribeFn, - this); -} - -QSpellEnchantClient::~QSpellEnchantClient() -{ - enchant_broker_free(m_broker); -} - -QSpellEnchantDict *QSpellEnchantClient::createSpeller(const QString &language) -{ - EnchantDict *dict = enchant_broker_request_dict(m_broker, language.toUtf8()); - - if (!dict) { -#ifndef NDEBUG - const char *err = enchant_broker_get_error(m_broker); - qDebug()<<"Couldn't create speller for"< - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef QSPELL_ENCHANTCLIENT_H -#define QSPELL_ENCHANTCLIENT_H - -#include -#include -#include - -namespace Sonnet -{ - class QSpellEnchantDict; - - class QSpellEnchantClient: public QObject - { - Q_OBJECT - public: - QSpellEnchantClient(QObject *parent); - ~QSpellEnchantClient(); - - QString name() const { - return QString::fromLatin1("Enchant"); - } - - QSpellEnchantDict *createSpeller(const QString &language); - - QStringList languages() const; - - void addLanguage(const QString &lang); - - void removeDictRef(EnchantDict *dict); - - private: - EnchantBroker *m_broker; - QSet m_languages; - QHash m_dictRefs; - }; -} - -#endif diff --git a/kdecore/sonnet/enchantdict.cpp b/kdecore/sonnet/enchantdict.cpp deleted file mode 100644 index efd2b1c5..00000000 --- a/kdecore/sonnet/enchantdict.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * Copyright 2006 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "enchantdict_p.h" -#include "enchantclient_p.h" - -#include -#include - -namespace Sonnet -{ - -QSpellEnchantDict::QSpellEnchantDict(QSpellEnchantClient *client, - EnchantDict *dict, - const QString &language) - : m_dict(dict), - m_client(client) -{ -} - -QSpellEnchantDict::~QSpellEnchantDict() -{ - //Enchant caches dictionaries, so it will always return the same one. - // therefore we do not want to delete the EnchantDict here but in the - // client when it knows that nothing is using it anymore - m_client->removeDictRef(m_dict); -} - -bool QSpellEnchantDict::isCorrect(const QString &word) const -{ - QByteArray data = word.toUtf8(); - return !enchant_dict_check(m_dict, data.constData(), data.length()); -} - -QStringList QSpellEnchantDict::suggest(const QString &word) const -{ - /* Needed for Unicode conversion */ - QTextCodec *codec = QTextCodec::codecForName("utf8"); - - QByteArray data = word.toUtf8(); - size_t number = 0; - char **suggestions = - enchant_dict_suggest(m_dict, data.constData(), data.length(), - &number); - - QStringList qsug; - for (size_t i = 0; i < number; ++i) { - qsug.append(codec->toUnicode(suggestions[i])); - } - - if (suggestions && number) - enchant_dict_free_string_list(m_dict, suggestions); - return qsug; -} - -bool QSpellEnchantDict::checkAndSuggest(const QString &word, - QStringList &suggestions) const -{ - bool c = isCorrect(word); - if (!c) - suggestions = suggest(word); - return c; -} - -bool QSpellEnchantDict::storeReplacement(const QString &bad, - const QString &good) -{ - QByteArray baddata = bad.toUtf8(); - QByteArray gooddata = good.toUtf8(); - enchant_dict_store_replacement(m_dict, - baddata.constData(), baddata.length(), - gooddata.constData(), gooddata.length()); - return true; -} - -bool QSpellEnchantDict::addToPersonal(const QString &word) -{ - enchant_dict_add(m_dict, word.toUtf8(), word.toUtf8().length()); - return true; -} - -bool QSpellEnchantDict::addToSession(const QString &word) -{ - enchant_dict_add_to_session(m_dict, word.toUtf8(), - word.toUtf8().length()); - return true; -} - -QString QSpellEnchantDict::language() const -{ - return m_language; -} - -} diff --git a/kdecore/sonnet/enchantdict_p.h b/kdecore/sonnet/enchantdict_p.h deleted file mode 100644 index 538ec61f..00000000 --- a/kdecore/sonnet/enchantdict_p.h +++ /dev/null @@ -1,63 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * Copyright 2006 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef QSPELL_ENCHANTDICT_H -#define QSPELL_ENCHANTDICT_H - -#include -#include - -namespace Sonnet -{ - class QSpellEnchantClient; - - class QSpellEnchantDict - { - public: - ~QSpellEnchantDict(); - - bool isCorrect(const QString &word) const; - - QStringList suggest(const QString &word) const; - - bool checkAndSuggest(const QString& word, - QStringList &suggestions) const; - - bool storeReplacement(const QString &bad, - const QString &good); - - bool addToPersonal(const QString &word); - bool addToSession(const QString &word); - QString language() const; - - protected: - friend class QSpellEnchantClient; - QSpellEnchantDict(const QString &lang); - QSpellEnchantDict(QSpellEnchantClient *client, - EnchantDict *dict, - const QString &language); - - private: - EnchantDict *m_dict; - QSpellEnchantClient *m_client; - QString m_language; - }; -} - -#endif diff --git a/kdecore/sonnet/filter.cpp b/kdecore/sonnet/filter.cpp deleted file mode 100644 index 50ada2a3..00000000 --- a/kdecore/sonnet/filter.cpp +++ /dev/null @@ -1,311 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * filter.cpp - * - * Copyright (C) 2004 Zack Rusin - * Copyright (C) 2010 Michel Ludwig - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include "filter_p.h" - -#include "settings_p.h" - -#include -#include - -namespace Sonnet -{ - -static Word endWord; - -class Filter::Private -{ -public: - // The reason it's not in the class directly is that - // I'm not 100% sure that having the settings() here is - // the way i want to be doing this. - Settings *settings; -}; - -Filter* Filter::defaultFilter() -{ - return new Filter(); -} - -Word Filter::end() -{ - return endWord; -} - -Filter::Filter() - : d(new Private) -{ - d->settings = 0; -} - -Filter::~Filter() -{ - delete d; -} - -void Filter::setSettings( Settings *conf ) -{ - d->settings = conf; -} - -Settings *Filter::settings() const -{ - return d->settings; -} - -void Filter::restart() -{ - m_finder.toStart(); -} - -void Filter::setBuffer( const QString& buffer ) -{ - m_buffer = buffer; - m_finder = QTextBoundaryFinder(QTextBoundaryFinder::Word, m_buffer); -} - -QString Filter::buffer() const -{ - return m_buffer; -} - -bool Filter::atEnd() const -{ - return m_finder.position() >= m_buffer.length() || m_finder.position() < 0; -} - -// we don't want to spell check empty words, or single-char words of the form -// '<', '=', etc. -static bool 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; -} - -static bool finderNextWord(QTextBoundaryFinder &finder, QString &word, int &bufferStart) -{ - QTextBoundaryFinder::BoundaryReasons boundary = finder.boundaryReasons(); - int start = finder.position(); - int end = finder.position(); - bool inWord = (boundary & QTextBoundaryFinder::StartWord) != 0; - while (finder.toNextBoundary() > 0) { - boundary = finder.boundaryReasons(); - if ((boundary & QTextBoundaryFinder::EndWord) && inWord) { - end = finder.position(); - QString str = finder.string().mid(start, end - start); - if (isValidWord(str)) { - word = str; - bufferStart = start; -#if 0 - kDebug() << "Word at " << start << " word = '" - << str << "', len = " << str.length(); -#endif - return true; - } - inWord = false; - } - if ((boundary & QTextBoundaryFinder::StartWord)) { - start = finder.position(); - inWord = true; - } - } - return false; -} - -static bool finderWordAt(QTextBoundaryFinder &finder, - int at, - QString &word, int &bufferStart) -{ - int oldPosition = finder.position(); - - finder.setPosition(at); - if (!finder.isAtBoundary() || (finder.boundaryReasons() & QTextBoundaryFinder::EndWord)) { - if (finder.toPreviousBoundary() <= 0) { - /* QTextBoundaryIterator doesn't consider start of the string - * a boundary so we need to rewind to the beginning to catch - * the first word */ - if (at > 0 && finder.string().length() > 0) { - finder.toStart(); - } else - return false; - } - } - bool ret = finderNextWord(finder, word, bufferStart); - finder.setPosition(oldPosition); - return ret; -} - -Word Filter::nextWord() const -{ - QString foundWord; - int start; - bool allUppercase = false; - bool runTogether = false; - - if (!finderNextWord(m_finder, foundWord, start)) - return Filter::end(); - - allUppercase = ( foundWord == foundWord.toUpper() ); - - //TODO implement runtogether correctly. - //We must ask to sonnet plugins to do it and not directly here. - - if ( shouldBeSkipped( allUppercase, runTogether, foundWord ) ) - return nextWord(); - return Word( foundWord, start ); -} - -Word Filter::wordAtPosition( unsigned int pos ) const -{ - QString foundWord; - int start; - if (!finderWordAt(m_finder, pos, foundWord, start)) - return Filter::end(); - return Word( foundWord, start ); -} - - -void Filter::setCurrentPosition( int i ) -{ - QString word; - int pos; - - //to make sure we're at an reasonable word boundary - if (!finderWordAt(m_finder, i, word, pos)) { - return; - } - m_finder.setPosition(pos); -} - -int Filter::currentPosition() const -{ - return m_finder.position(); -} - -void Filter::replace( const Word& w, const QString& newWord) -{ - int oldLen = w.word.length(); - - //start spell checkin from the just correct word - m_buffer = m_buffer.replace( w.start, oldLen, newWord ); - m_finder = QTextBoundaryFinder(QTextBoundaryFinder::Word, - m_buffer); - m_finder.setPosition(w.start); -} - -QString Filter::context() const -{ - int len = 60; - //we don't want the expression underneath casted to an unsigned int - //which would cause it to always evaluate to false - int signedPosition = m_finder.position(); - bool begin = (signedPosition - len/2)<=0; - - - QString buffer = m_buffer; - Word word = wordAtPosition( m_finder.position() ); - buffer = buffer.replace( word.start, word.word.length(), - QString::fromLatin1( "%1" ).arg( word.word ) ); - - QString context; - if ( begin ) - context = QString::fromLatin1("%1...") - .arg( buffer.mid( 0, len ) ); - else - context = QString::fromLatin1("...%1...") - .arg( buffer.mid( m_finder.position() - 20, len ) ); - - context.replace( QLatin1Char('\n'), QLatin1Char(' ') ); - - return context; -} - -bool Filter::trySkipLinks() const -{ - QChar currentChar; - int currentPosition = m_finder.position(); - - if (currentPosition < 0 || currentPosition >= m_buffer.length()) - return false; - currentChar = m_buffer.at( currentPosition ); - - int length = m_buffer.length(); - //URL - if so skip - if ( currentChar == QLatin1Char(':') - && (currentPosition+1 < length) - && (m_buffer.at( ++currentPosition ) == QLatin1Char('/') || ( currentPosition + 1 ) >= length ) ) { - //in both cases url is considered finished at the first whitespace occurrence - //TODO hey, "http://en.wikipedia.org/wiki/Main Page" --Nick Shaforostoff - while ( !m_buffer.at( currentPosition++ ).isSpace() && currentPosition < length ) - ; - m_finder.setPosition(currentPosition); - return true; - } - - //Email - if so skip - if ( currentChar == QLatin1Char('@')) { - while ( ++currentPosition < length && !m_buffer.at( currentPosition ).isSpace() ) - ; - m_finder.setPosition(currentPosition); - return true; - } - - return false; -} - -bool Filter::ignore( const QString& word ) const -{ - return d->settings && d->settings->ignore( word ); -} - -bool Filter::shouldBeSkipped( bool wordWasUppercase, bool wordWasRunTogether, - const QString& foundWord ) const -{ - bool checkUpper = ( d->settings ) ? - d->settings->checkUppercase () : true; - - bool skipRunTogether = ( d->settings ) ? - d->settings->skipRunTogether() : true; - - if ( trySkipLinks() ) - return true; - - if ( wordWasUppercase && !checkUpper ) - return true; - - if ( wordWasRunTogether && skipRunTogether ) - return true; - - return ignore( foundWord ); -} - -} diff --git a/kdecore/sonnet/filter_p.h b/kdecore/sonnet/filter_p.h deleted file mode 100644 index a04ffa94..00000000 --- a/kdecore/sonnet/filter_p.h +++ /dev/null @@ -1,120 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/* - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef SONNET_FILTER_P_H -#define SONNET_FILTER_P_H - -#include -#include -#include - -namespace Sonnet -{ - class Settings; - - /** - * Structure abstracts the word and its position in the - * parent text. - * - * @author Zack Rusin - * @short struct represents word - */ - struct KDECORE_EXPORT Word - { - Word() : start( 0 ), end( true ) - {} - - Word( const QString& w, int st, bool e = false ) - : word( w ), start( st ), end( e ) - {} - Word( const Word& other ) - : word( other.word ), start( other.start ), - end( other.end ) - {} - - QString word; - int start; - bool end; - }; - - /** - * Filter is used to split text into words which - * will be spell checked. - * - * @author Zack Rusin - * @short used to split text into words - */ - class KDECORE_EXPORT Filter - { - public: - static Filter *defaultFilter(); - public: - Filter(); - virtual ~Filter(); - - static Word end(); - - /** - * Sets the Settings object for this Filter - */ - void setSettings(Settings*); - - /** - * Returns currently used Settings object - */ - Settings *settings() const; - - bool atEnd() const; - - void setBuffer( const QString& buffer ); - QString buffer() const; - - void restart(); - - virtual Word nextWord() const; - virtual Word wordAtPosition( unsigned int pos ) const; - - virtual void setCurrentPosition( int ); - virtual int currentPosition() const; - virtual void replace( const Word& w, const QString& newWord ); - - /** - * Should return the sentence containing the current word - */ - virtual QString context() const; - protected: - bool trySkipLinks() const; - bool ignore( const QString& word ) const; - bool shouldBeSkipped( bool wordWasUppercase, bool wordWasRunTogether, - const QString& foundWord ) const; - - protected: - QString m_buffer; - mutable QTextBoundaryFinder m_finder; - - private: - class Private; - Private* const d; - }; - -} - -#endif // SONNET_FILTER_P_H diff --git a/kdecore/sonnet/globals.cpp b/kdecore/sonnet/globals.cpp deleted file mode 100644 index 70b8443c..00000000 --- a/kdecore/sonnet/globals.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2008 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "globals.h" - -#include "speller.h" -#include "filter_p.h" -#include "loader_p.h" -#include "settings_p.h" - -#include - -#include -#include -#include -#include - -#include - -namespace Sonnet { -/* a very silly implementation: uses all available dictionaries - * to check the text, the one with the least amount of misspelling - * is likely the language we're looking for. (unless of course - * someone is a real terrible speller). - */ -QString detectLanguage(const QString &sentence) -{ - Speller speller; - QMap dicts = speller.availableDictionaries(); - QMap correctHits; - QSet seenLangs; - { - QMapIterator itr(dicts); - while (itr.hasNext()) { - itr.next(); - seenLangs.insert(itr.value()); - } - } - - QVector spellers(seenLangs.count()); - { - QSet::const_iterator itr = seenLangs.constBegin(); - for (int i = 0; i < spellers.count(); ++i) { - spellers[i].setLanguage(*itr); - ++itr; - } - } - - Filter f; - f.setBuffer(sentence); - while (!f.atEnd()) { - Word word = f.nextWord(); - - if (!word.word.isEmpty()) { - for (int i = 0; i < spellers.count(); ++i) { - if (spellers[i].isCorrect(word.word)) - correctHits[spellers[i].language()] += 1; - } - } - } - - QMap::const_iterator max = correctHits.constBegin(); - for (QMap::const_iterator itr = correctHits.constBegin(); - itr != correctHits.constEnd(); ++itr) { - if (itr.value() > max.value()) - max = itr; - } - return max.key(); -} - -// SLOW!!! -// TODO: cache this value! And then use some dbus signal to notify all apps when -// changing the default language changes. -QString defaultLanguageName() -{ - Loader *loader = Loader::openLoader(); - KConfig config(QString::fromLatin1("sonnetrc")); - loader->settings()->restore(&config); - - return loader->languageNameForCode(loader->settings()->defaultLanguage()); -} - -} diff --git a/kdecore/sonnet/globals.h b/kdecore/sonnet/globals.h deleted file mode 100644 index d6ce8a34..00000000 --- a/kdecore/sonnet/globals.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2008 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_GLOBALS_H -#define SONNET_GLOBALS_H - -#include - -#include - -namespace Sonnet { - - /** - * The function will return the language code for the - * language in which it thinks the sentence which - * has been passed to it is. - * - * @since 4.2 - */ - extern KDECORE_EXPORT QString detectLanguage(const QString &sentence); - - /** - * @return the default language which is stored in the sonnetrc config file. - * This is the language the user has set globally in the control - * center. - * Note that this returns the localized language name, not the - * dictionary name/language code. - * - * @since 4.2 - */ - extern KDECORE_EXPORT QString defaultLanguageName(); -} - -#endif diff --git a/kdecore/sonnet/loader.cpp b/kdecore/sonnet/loader.cpp deleted file mode 100644 index 63131b73..00000000 --- a/kdecore/sonnet/loader.cpp +++ /dev/null @@ -1,251 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * - * Copyright (C) 2003 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "loader_p.h" -#include "settings_p.h" -#include "enchantclient_p.h" - -#include -#include -#include -#include - -namespace Sonnet -{ - -class Loader::Private -{ -public: - Settings *settings; - - // - QMap > languageClients; - QStringList clients; - - QStringList languagesNameCache; -}; - -K_GLOBAL_STATIC(Loader, s_loader) - -Loader *Loader::openLoader() -{ - if (s_loader.isDestroyed()) { - return 0; - } - - return s_loader; -} - -Loader::Loader() - :d(new Private()) -{ - d->settings = new Settings(this); - KConfig config(QString::fromLatin1("sonnetrc")); - d->settings->restore(&config); - - QSpellEnchantClient *client = new QSpellEnchantClient(this); - d->clients.append(client->name()); - - foreach (const QString &itr, client->languages()) { - d->languageClients[itr].prepend(client); - } -} - -Loader::~Loader() -{ - //kDebug()<<"Removing loader : "<< this; - delete d->settings; - d->settings = 0; - delete d; -} - -QSpellEnchantDict *Loader::createSpeller(const QString& language, - const QString& clientName) const -{ - QString plang = language; - - if (plang.isEmpty()) { - plang = d->settings->defaultLanguage(); - } - - const QList lClients = d->languageClients[plang]; - - if (lClients.isEmpty()) { - kError() << "No language dictionaries for the language : " << plang; - return 0; - } - - QListIterator itr(lClients); - while (itr.hasNext()) { - QSpellEnchantClient* item = itr.next(); - if (!clientName.isEmpty()) { - if (clientName == item->name()) { - return item->createSpeller(plang); - } - } else { - //the first one is the one with the highest - //reliability - return item->createSpeller(plang); - } - } - - return 0; -} - -QStringList Loader::clients() const -{ - return d->clients; -} - -QStringList Loader::languages() const -{ - return d->languageClients.keys(); -} - -QString Loader::languageNameForCode(const QString &langCode) const -{ - QString currentDictionary = langCode, // e.g. en_GB-ize-wo_accents - lISOName, // language ISO name - cISOName, // country ISO name - variantName, // dictionary variant name e.g. w_accents - localizedLang, // localized language - localizedCountry; // localized country - QByteArray variantEnglish; // dictionary variant in English - - struct variantListType - { - const char* variantShortName; - const char* variantEnglishName; - }; - - const variantListType variantList[] = { - { "40", I18N_NOOP2("dictionary variant", "40") }, // what does 40 mean? - { "60", I18N_NOOP2("dictionary variant", "60") }, // what does 60 mean? - { "80", I18N_NOOP2("dictionary variant", "80") }, // what does 80 mean? - { "ise", I18N_NOOP2("dictionary variant", "-ise suffixes") }, - { "ize", I18N_NOOP2("dictionary variant", "-ize suffixes") }, - { "ise-w_accents", I18N_NOOP2("dictionary variant", "-ise suffixes and with accents") }, - { "ise-wo_accents", I18N_NOOP2("dictionary variant", "-ise suffixes and without accents") }, - { "ize-w_accents", I18N_NOOP2("dictionary variant", "-ize suffixes and with accents") }, - { "ize-wo_accents", I18N_NOOP2("dictionary variant", "-ize suffixes and without accents") }, - { "lrg", I18N_NOOP2("dictionary variant", "large") }, - { "med", I18N_NOOP2("dictionary variant", "medium") }, - { "sml", I18N_NOOP2("dictionary variant", "small") }, - { "variant_0", I18N_NOOP2("dictionary variant", "variant 0") }, - { "variant_1", I18N_NOOP2("dictionary variant", "variant 1") }, - { "variant_2", I18N_NOOP2("dictionary variant", "variant 2") }, - { "wo_accents", I18N_NOOP2("dictionary variant", "without accents") }, - { "w_accents", I18N_NOOP2("dictionary variant", "with accents") }, - { "ye", I18N_NOOP2("dictionary variant", "with ye") }, - { "yeyo", I18N_NOOP2("dictionary variant", "with yeyo") }, - { "yo", I18N_NOOP2("dictionary variant", "with yo") }, - { "extended", I18N_NOOP2("dictionary variant", "extended") }, - { 0, 0 } - }; - - const int minusPos = currentDictionary.indexOf(QLatin1Char('-')); - const int underscorePos = currentDictionary.indexOf(QLatin1Char('_')); - if (underscorePos != -1 && underscorePos <= 3) { - cISOName = currentDictionary.mid(underscorePos + 1, 2); - lISOName = currentDictionary.left(underscorePos); - if ( minusPos != -1 ) - variantName = currentDictionary.right( - currentDictionary.length() - minusPos - 1); - } else { - if ( minusPos != -1 ) { - variantName = currentDictionary.right( - currentDictionary.length() - minusPos - 1); - lISOName = currentDictionary.left(minusPos); - } - else - lISOName = currentDictionary; - } - localizedLang = KGlobal::locale()->languageCodeToName(lISOName); - if (localizedLang.isEmpty()) - localizedLang = lISOName; - if (!cISOName.isEmpty()) { - if (!KGlobal::locale()->countryCodeToName(cISOName).isEmpty()) - localizedCountry = KGlobal::locale()->countryCodeToName(cISOName); - else - localizedCountry = cISOName; - } - if (!variantName.isEmpty()) { - int variantCount = 0; - while (variantList[variantCount].variantShortName != 0) - if (QLatin1String(variantList[variantCount].variantShortName) == variantName) - break; - else - variantCount++; - if (variantList[variantCount].variantShortName != 0) - variantEnglish = variantList[variantCount].variantEnglishName; - else - variantEnglish = variantName.toLatin1(); - } - if (!cISOName.isEmpty() && !variantName.isEmpty()) - return i18nc( - "dictionary name. %1-language, %2-country and %3 variant name", - "%1 (%2) [%3]", localizedLang, localizedCountry, - i18nc( "dictionary variant", variantEnglish)); - else if (!cISOName.isEmpty()) - return i18nc( - "dictionary name. %1-language and %2-country name", - "%1 (%2)", localizedLang, localizedCountry); - else if (!variantName.isEmpty()) - return i18nc( - "dictionary name. %1-language and %2-variant name", - "%1 [%2]", localizedLang, - i18nc("dictionary variant", variantEnglish)); - else - return localizedLang; -} - -QStringList Loader::languageNames() const -{ - /* For whatever reason languages() might change. So, - * to be in sync with it let's do the following check. - */ - if (d->languagesNameCache.count() == languages().count() ) - return d->languagesNameCache; - - QStringList allLocalizedDictionaries; - const QStringList allDictionaries = languages(); - - for (QStringList::ConstIterator it = allDictionaries.begin(); - it != allDictionaries.end(); ++it) { - allLocalizedDictionaries.append(languageNameForCode(*it)); - } - // cache the list - d->languagesNameCache = allLocalizedDictionaries; - return allLocalizedDictionaries; -} - -Settings* Loader::settings() const -{ - return d->settings; -} - -void Loader::changed() -{ - emit configurationChanged(); -} - -} - -#include "moc_loader_p.cpp" diff --git a/kdecore/sonnet/loader_p.h b/kdecore/sonnet/loader_p.h deleted file mode 100644 index dd626308..00000000 --- a/kdecore/sonnet/loader_p.h +++ /dev/null @@ -1,123 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/* - * - * Copyright (C) 2003 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_LOADER_P_H -#define SONNET_LOADER_P_H - -#include -#include - -#include -#include -#include - -class KService; -namespace Sonnet -{ - class Settings; - class QSpellEnchantDict; - - /** - * \internal - * @short Class used to deal with dictionaries - * - * This class manages all dictionaries. It's the top level - * Sonnet class, you can think of it as the kernel or manager - * of the Sonnet architecture. - */ - class KDECORE_EXPORT Loader : public QObject - { - Q_OBJECT - public: - /** - * Constructs the loader. - * - * It's very important that you leave the return value in a Loader::Ptr. - * Loader is reference counted so if you don't want to have it deleted - * under you simply have to hold it in a Loader::Ptr for as long as - * you're using it. - */ - static Loader *openLoader(); - - public: - Loader(); - ~Loader(); - - /** - * Returns dictionary for the given language and preferred client. - * - * @param language specifies the language of the dictionary. If an - * empty string will be passed the default language will - * be used. Has to be one of the values returned by - * \ref languages() - * @param client specifies the preferred client. If no client is - * specified a client which supports the given - * language is picked. If a few clients supports - * the same language the one with the biggest - * reliability value is returned. - * - */ - QSpellEnchantDict *createSpeller( - const QString& language = QString(), - const QString& client = QString()) const; - - /** - * Returns names of all supported clients (e.g. ISpell, ASpell) - */ - QStringList clients() const; - - /** - * Returns a list of supported languages. - */ - QStringList languages() const; - - /** - * Returns a localized list of names of supported languages. - */ - QStringList languageNames() const; - - /** - * @param langCode the dictionary name/language code, e.g. en_gb - * @return the localized language name, e.g. "British English" - * @since 4.2 - */ - QString languageNameForCode(const QString &langCode) const; - - /** - * Returns the Settings object used by the loader. - */ - Settings *settings() const; - Q_SIGNALS: - /** - * Signal is emitted whenever the Settings object - * associated with this Loader changes. - */ - void configurationChanged(); - - protected: - friend class Settings; - void changed(); - private: - class Private; - Private *const d; - }; -} - -#endif // SONNET_LOADER_P_H diff --git a/kdecore/sonnet/settings.cpp b/kdecore/sonnet/settings.cpp deleted file mode 100644 index 1af91c01..00000000 --- a/kdecore/sonnet/settings.cpp +++ /dev/null @@ -1,262 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * - * Copyright (C) 2003 Zack Rusin - * Copyright (C) 2006 Laurent Montel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "settings_p.h" - -#include "loader_p.h" - -#include -#include -#include -#include -#include - -#include -#include - -namespace Sonnet -{ - -class Settings::Private -{ -public: - Loader* loader; //can't be a Ptr since we don't want to hold a ref on it - bool modified; - - QString defaultLanguage; - QString defaultClient; - - bool checkUppercase; - bool skipRunTogether; - bool backgroundCheckerEnabled; - bool checkerEnabledByDefault; - - int disablePercentage; - int disableWordCount; - - QStringList ignore; -}; - -Settings::Settings(Loader *loader) - : d(new Private()) -{ - d->loader = loader; - - d->modified = false; - d->checkerEnabledByDefault = false; -} - -Settings::~Settings() -{ - delete d; -} - -void Settings::setDefaultLanguage(const QString &lang) -{ - const QStringList cs = d->loader->languages(); - if (cs.indexOf(lang) != -1 && - d->defaultLanguage != lang) { - d->defaultLanguage = lang; - //readIgnoreList(); - d->modified = true; - d->loader->changed(); - } -} - -QString Settings::defaultLanguage() const -{ - return d->defaultLanguage; -} - -void Settings::setDefaultClient(const QString &client) -{ - //Different from setDefaultLanguage because - //the number of clients can't be even close - //as big as the number of languages - if (d->loader->clients().contains(client)) { - d->defaultClient = client; - d->modified = true; - d->loader->changed(); - } -} - -QString Settings::defaultClient() const -{ - return d->defaultClient; -} - -void Settings::setCheckUppercase(bool check) -{ - if (d->checkUppercase != check) { - d->modified = true; - d->checkUppercase = check; - } -} - -bool Settings::checkUppercase() const -{ - return d->checkUppercase; -} - -void Settings::setSkipRunTogether(bool skip) -{ - if (d->skipRunTogether != skip) { - d->modified = true; - d->skipRunTogether = skip; - } -} - -bool Settings::skipRunTogether() const -{ - return d->skipRunTogether; -} - -void Settings::setCheckerEnabledByDefault(bool check) -{ - if (d->checkerEnabledByDefault != check) { - d->modified = true; - d->checkerEnabledByDefault = check; - } -} - -bool Settings::checkerEnabledByDefault() const -{ - return d->checkerEnabledByDefault; -} - -void Settings::setBackgroundCheckerEnabled(bool enable) -{ - if (d->backgroundCheckerEnabled != enable) { - d->modified = true; - d->backgroundCheckerEnabled = enable; - } -} - -bool Settings::backgroundCheckerEnabled() const -{ - return d->backgroundCheckerEnabled; -} - -void Settings::setCurrentIgnoreList(const QStringList &ignores) -{ - setQuietIgnoreList(ignores); - d->modified = true; -} - -void Settings::setQuietIgnoreList(const QStringList &ignores) -{ - d->ignore = ignores; -} - -QStringList Settings::currentIgnoreList() const -{ - return d->ignore; -} - -void Settings::addWordToIgnore(const QString &word) -{ - if (!d->ignore.contains(word)) { - d->modified = true; - d->ignore.append( word ); - } -} - -bool Settings::ignore( const QString& word ) -{ - return d->ignore.contains( word ); -} - -void Settings::readIgnoreList(KConfig *config) -{ - const KConfigGroup conf(config, "Spelling"); - const QString ignoreEntry = QString::fromLatin1( "ignore_%1" ).arg(d->defaultLanguage); - const QStringList ignores = conf.readEntry(ignoreEntry, QStringList()); - setQuietIgnoreList(ignores); -} - -int Settings::disablePercentageWordError() const -{ - return d->disablePercentage; -} - -int Settings::disableWordErrorCount() const -{ - return d->disableWordCount; -} - -void Settings::save(KConfig *config) -{ - KConfigGroup conf(config, "Spelling"); - conf.writeEntry("defaultClient", d->defaultClient); - conf.writeEntry("defaultLanguage", d->defaultLanguage); - conf.writeEntry("checkUppercase", d->checkUppercase); - conf.writeEntry("skipRunTogether", d->skipRunTogether); - conf.writeEntry("backgroundCheckerEnabled", d->backgroundCheckerEnabled); - conf.writeEntry("checkerEnabledByDefault", d->checkerEnabledByDefault); - QString defaultLanguage = QString::fromLatin1( "ignore_%1" ).arg(d->defaultLanguage); - if(conf.hasKey(defaultLanguage) && d->ignore.isEmpty()) - conf.deleteEntry(defaultLanguage); - else if(!d->ignore.isEmpty()) - conf.writeEntry(defaultLanguage, d->ignore); - - conf.sync(); -} - -void Settings::restore(KConfig *config) -{ - KConfigGroup conf(config, "Spelling"); - d->defaultClient = conf.readEntry("defaultClient", - QString()); - d->defaultLanguage = conf.readEntry( - "defaultLanguage", KGlobal::locale()->language()); - - //same defaults are in the default filter (filter.cpp) - d->checkUppercase = conf.readEntry( - "checkUppercase", true); - - d->skipRunTogether = conf.readEntry( - "skipRunTogether", true); - - d->backgroundCheckerEnabled = conf.readEntry( - "backgroundCheckerEnabled", true); - - d->checkerEnabledByDefault = conf.readEntry( - "checkerEnabledByDefault", false); - - d->disablePercentage = conf.readEntry("Sonnet_AsYouTypeDisablePercentage", 42); - d->disableWordCount = conf.readEntry("Sonnet_AsYouTypeDisableWordCount", 100); - - readIgnoreList(config); -} - - -bool Settings::modified() const -{ - return d->modified; -} - -void Settings::setModified(bool modified) -{ - d->modified = modified; -} - -} - diff --git a/kdecore/sonnet/settings_p.h b/kdecore/sonnet/settings_p.h deleted file mode 100644 index c73b6ca6..00000000 --- a/kdecore/sonnet/settings_p.h +++ /dev/null @@ -1,87 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/* - * - * Copyright (C) 2003 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_SETTINGS_P_H -#define SONNET_SETTINGS_P_H - -#include -#include -#include - -class KConfig; - -namespace Sonnet -{ - class Loader; - - /** - * Settings class - */ - class KDECORE_EXPORT Settings - { - public: - ~Settings(); - - bool modified() const; - void setModified(bool modified); - - void setDefaultLanguage(const QString &lang); - QString defaultLanguage() const; - - void setDefaultClient(const QString &client); - QString defaultClient() const; - - void setCheckUppercase(bool); - bool checkUppercase() const; - - void setSkipRunTogether(bool); - bool skipRunTogether() const; - - void setBackgroundCheckerEnabled(bool); - bool backgroundCheckerEnabled() const; - - void setCheckerEnabledByDefault(bool); - bool checkerEnabledByDefault() const; - - void setCurrentIgnoreList(const QStringList &ignores); - void addWordToIgnore(const QString &word); - QStringList currentIgnoreList() const; - bool ignore(const QString &word); - - void save(KConfig *config); - void restore(KConfig *config); - - int disablePercentageWordError() const; - int disableWordErrorCount() const; - - private: - void readIgnoreList(KConfig *config); - void setQuietIgnoreList(const QStringList &ignores); - - private: - friend class Loader; - Settings(Loader *loader); - private: - class Private; - Private *const d; - }; -} - -#endif // SONNET_SETTINGS_P_H diff --git a/kdecore/sonnet/speller.cpp b/kdecore/sonnet/speller.cpp deleted file mode 100644 index 223376c5..00000000 --- a/kdecore/sonnet/speller.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/** - * - * Copyright (C) 2007 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "speller.h" - -#include "loader_p.h" -#include "settings_p.h" -#include "enchantclient_p.h" -#include "enchantdict_p.h" - -#include -#include -#include -#include -#include -#include - -namespace Sonnet -{ - -class Speller::Private -{ -public: - ~Private() - { - delete dict; - dict = 0; - } - void init(const QString &lang) - { - Loader *loader = Loader::openLoader(); - settings = loader->settings(); - - language = lang; - - if (language.isEmpty()) - language = settings->defaultLanguage(); - - dict = loader->createSpeller(language); - } - bool isValid() - { - if (settings->modified()) { - recreateDict(); - settings->setModified(false); - } - return dict; - } - void recreateDict() - { - delete dict; - dict = Loader::openLoader()->createSpeller(language); - } - - QSpellEnchantDict *dict; - Settings *settings; - - QString language; -}; - -Speller::Speller(const QString &lang) - : d(new Private) -{ - d->init(lang); -} - - -Speller::~Speller() -{ - //qDebug()<<"deleting "<language = speller.language(); - d->init(d->language); -} - - -Speller & Speller::operator=(const Speller &speller) -{ - d->language = speller.language(); - d->recreateDict(); - return *this; -} - - -bool Speller::isCorrect(const QString &word) const -{ - if (!d->isValid()) - return true; - return d->dict->isCorrect(word); -} - - -bool Speller::isMisspelled(const QString &word) const -{ - if (!d->isValid()) - return false; - return !d->dict->isCorrect(word); -} - -QStringList Speller::suggest(const QString &word) const -{ - if (!d->isValid()) - return QStringList(); - return d->dict->suggest(word); -} - -bool Speller::checkAndSuggest(const QString &word, - QStringList &suggestions) const -{ - if (!d->isValid()) - return true; - return d->dict->checkAndSuggest(word, suggestions); -} - - -bool Speller::storeReplacement(const QString &bad, - const QString &good) -{ - if (!d->isValid()) - return false; - return d->dict->storeReplacement(bad, good); -} - - -bool Speller::addToPersonal(const QString &word) -{ - if (!d->isValid()) - return false; - return d->dict->addToPersonal(word); -} - - -bool Speller::addToSession(const QString &word) -{ - if (!d->isValid()) - return false; - return d->dict->addToSession(word); -} - - -QString Speller::language() const -{ - if (!d->isValid()) - return QString(); - return d->dict->language(); -} - - -void Speller::save(KConfig *config) -{ - if (d->settings) { - d->settings->save(config); - } -} - - -void Speller::restore(KConfig *config) -{ - if (d->settings) { - d->settings->restore(config); - d->recreateDict(); - } -} - - -QStringList Speller::availableBackends() const -{ - Loader *l = Loader::openLoader(); - return l->clients(); -} - - -QStringList Speller::availableLanguages() const -{ - Loader *l = Loader::openLoader(); - return l->languages(); -} - - -QStringList Speller::availableLanguageNames() const -{ - Loader *l = Loader::openLoader(); - return l->languageNames(); -} - - -void Speller::setDefaultLanguage(const QString &lang) -{ - d->settings->setDefaultLanguage(lang); -} - -QString Speller::defaultLanguage() const -{ - return d->settings->defaultLanguage(); -} - -void Speller::setDefaultClient(const QString &client) -{ - d->settings->setDefaultClient(client); -} - -QString Speller::defaultClient() const -{ - return d->settings->defaultClient(); -} - -void Speller::setAttribute(Attribute attr, bool b) -{ - switch (attr) { - case CheckUppercase: - d->settings->setCheckUppercase(b); - break; - case SkipRunTogether: - d->settings->setSkipRunTogether(b); - break; - } -} - - -bool Speller::testAttribute(Attribute attr) const -{ - switch (attr) { - case CheckUppercase: - return d->settings->checkUppercase(); - case SkipRunTogether: - return d->settings->skipRunTogether(); - } - return false; -} - -bool Speller::isValid() const -{ - return d->dict; -} - -void Speller::setLanguage(const QString &lang) -{ - d->language = lang; - d->recreateDict(); -} - -QMap Sonnet::Speller::availableDictionaries() const -{ - Loader *l = Loader::openLoader(); - QMap langs; - - foreach (QString tag, l->languages()) { // no const& because tag is modified below - tag = tag.mid(0, tag.indexOf(QLatin1Char('-'))); - int underscorePos = tag.indexOf(QLatin1Char('_')); - QString cIsoName, lIsoName; - if (underscorePos != -1 && underscorePos <= 3) { - cIsoName = tag.mid(underscorePos + 1, 2); - lIsoName = tag.left(underscorePos); - } else { - lIsoName = tag; - } - //QLocale loc(tag); - QString description; - - if (!cIsoName.isEmpty()) - description= QString::fromLatin1("%1 (%2)") - .arg(KGlobal::locale()->languageCodeToName(lIsoName)) - .arg(KGlobal::locale()->countryCodeToName(cIsoName)); - else - description= KGlobal::locale()->languageCodeToName(lIsoName); - //qDebug()<<"Dict is "< -#include -#include -#include - -using namespace Sonnet; - -int main( int argc, char** argv ) -{ - QCoreApplication app(argc,argv); - - Speller dict("en_US"); - - kDebug()<< "Clients are " << dict.availableBackends(); - kDebug()<< "Languages are " << dict.availableLanguages(); - - QStringList words; - - words << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted"; - - QElapsedTimer mtime; - mtime.start(); - for (QStringList::Iterator itr = words.begin(); - itr != words.end(); ++itr) { - if (!dict.isCorrect(*itr)) { - //kDebug()<<"Word " << *itr <<" is misspelled"; - QStringList sug = dict.suggest(*itr); - //kDebug()<<"Suggestions : "< - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "configdialog.h" - -#include -#include -using namespace Sonnet; - -int main( int argc, char** argv ) -{ - KCmdLineArgs::init( argc, argv, "SonnetTest", 0, ki18n("SonnetTest"), 0 ); - - KApplication app(argc, argv, "SonnetTest"); - - SettingsDialog *dialog = new SettingsDialog( 0 ); - - dialog->show(); - - app.setMainWidget( dialog ); - - return app.exec(); -} diff --git a/kdecore/sonnet/tests/test_core.cpp b/kdecore/sonnet/tests/test_core.cpp deleted file mode 100644 index 42d32e60..00000000 --- a/kdecore/sonnet/tests/test_core.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// krazy:excludeall=spelling -/** - * - * Copyright 2007 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include "test_core.h" -#include "speller.h" -#include "globals.h" - -#include -#include -#include - -QTEST_KDEMAIN_CORE( SonnetCoreTest ) - -using namespace Sonnet; - -void SonnetCoreTest::testCore() -{ - Speller dict("en_US"); - - kDebug()<< "Clients are " << dict.availableBackends(); - kDebug()<< "Languages are " << dict.availableLanguages(); - kDebug()<< "Language names are " << dict.availableLanguageNames(); - kDebug()<< "Language dicts " << dict.availableDictionaries(); - - QStringList words; - - words << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted" - << "hello" << "helo" << "enviroment" << "guvernment" << "farted"; - - QElapsedTimer mtime; - mtime.start(); - for (QStringList::Iterator itr = words.begin(); - itr != words.end(); ++itr) { - if (!dict.isCorrect(*itr)) { - //kDebug()<<"Word " << *itr <<" is misspelled"; - QStringList sug = dict.suggest(*itr); - //kDebug()<<"Suggestions : "< - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef TEST_CORE_H -#define TEST_CORE_H - -#include - -class SonnetCoreTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void testCore(); - void testCore2(); -}; - -#endif diff --git a/kdecore/sonnet/tests/test_dialog.cpp b/kdecore/sonnet/tests/test_dialog.cpp deleted file mode 100644 index ddf739db..00000000 --- a/kdecore/sonnet/tests/test_dialog.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// krazy:excludeall=spelling -/** - * test_dialog.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "test_dialog.h" -#include "moc_test_dialog.cpp" - -#include "backgroundchecker.h" -#include "filter_p.h" - -#include -#include -#include -using namespace Sonnet; - -TestDialog::TestDialog() - : QObject( 0 ) -{ - -} - -void TestDialog::check( const QString& buffer ) -{ - Sonnet::Dialog *dlg = new Sonnet::Dialog( - new BackgroundChecker( this ), 0); - connect( dlg, SIGNAL(done(QString)), - SLOT(doneChecking(QString)) ); - dlg->setBuffer( buffer ); - dlg->show(); -} - -void TestDialog::doneChecking( const QString& buf ) -{ - kDebug()<<"Done with :"<quit(); -} - -int main( int argc, char** argv ) -{ - //KApplication::disableAutoDcopRegistration(); - KCmdLineArgs::init( argc, argv, "test_dialog", 0, ki18n("test_dialog"), 0); - KApplication app; // with GUI - - TestDialog test; - test.check( "This is a sample buffer. Whih this thingg will " - "be checkin for misstakes. Whih, Enviroment, govermant. Whih." - ); - - return app.exec(); -} diff --git a/kdecore/sonnet/tests/test_dialog.h b/kdecore/sonnet/tests/test_dialog.h deleted file mode 100644 index 583b27b7..00000000 --- a/kdecore/sonnet/tests/test_dialog.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * test_dialog.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef TEST_DIALOG_H -#define TEST_DIALOG_H - -#include "dialog.h" -#include "loader_p.h" - -#include - -class TestDialog : public QObject -{ - Q_OBJECT -public: - TestDialog(); - -public Q_SLOTS: - void check( const QString& buffer ); - void doneChecking( const QString& ); -private: - Sonnet::Loader *m_loader; -}; - -#endif diff --git a/kdecore/sonnet/tests/test_filter.cpp b/kdecore/sonnet/tests/test_filter.cpp deleted file mode 100644 index b9adb8c6..00000000 --- a/kdecore/sonnet/tests/test_filter.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/** - * test_filter.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include "test_filter.h" -#include "filter_p.h" - -#include -#include -#include -#include - -QTEST_KDEMAIN_CORE( SonnetFilterTest ) - -using namespace Sonnet; - -struct Hit { - Hit( const QString& w, int s ) : word( w ), start( s ) {} - QString word; - int start; -}; - -void SonnetFilterTest::testFilter() -{ - QString buffer( "This is a sample buffer.Please test me . He's don't Le'Clerk." ); - QList hits; - hits.append( Hit( "This", 0 ) ); - hits.append( Hit( "is", 5 ) ); - hits.append( Hit( "a", 12 ) ); - hits.append( Hit( "sample", 14 ) ); - hits.append( Hit( "buffer", 21 ) ); - hits.append( Hit( "Please", 28 ) ); - hits.append( Hit( "test", 35 ) ); - hits.append( Hit( "me", 40 ) ); - hits.append( Hit( "He's", 49 ) ); - hits.append( Hit( "don't", 54 ) ); - hits.append( Hit( "Le'Clerk", 60 ) ); - - Filter filter; - filter.setBuffer( buffer ); - - Word w; - int hitNumber = 0; - while ( ! (w=filter.nextWord()).end ) { - QCOMPARE( w.word, hits[hitNumber].word ); - QCOMPARE( w.start, hits[hitNumber].start ); - //kDebug()<< "Found word \""<< w.word << "\" which starts at position " << w.start; - ++hitNumber; - } - QCOMPARE( hitNumber, hits.count() ); - - // ? filter.setBuffer( buffer ); -} - - -void SonnetFilterTest::testWordAt() -{ - QString buffer( "This is a sample buffer.Please test me . He's don't Le'Clerk." ); - QList hits; - hits.append( Hit( "This", 0 ) ); - hits.append( Hit( "is", 5 ) ); - hits.append( Hit( "a", 12 ) ); - hits.append( Hit( "Please", 28 ) ); - hits.append( Hit( "me", 40 ) ); - - Filter filter; - filter.setBuffer( buffer ); - Word word; - - word = filter.wordAtPosition(3); - QCOMPARE( word.word, hits[0].word ); - QCOMPARE( word.start, hits[0].start ); - - word = filter.wordAtPosition(5); - QCOMPARE( word.word, hits[1].word ); - QCOMPARE( word.start, hits[1].start ); - - word = filter.wordAtPosition(12); - QCOMPARE( word.word, hits[2].word ); - QCOMPARE( word.start, hits[2].start ); - - word = filter.wordAtPosition(29); - QCOMPARE( word.word, hits[3].word ); - QCOMPARE( word.start, hits[3].start ); - - word = filter.wordAtPosition(42); - QCOMPARE( word.word, hits[4].word ); - QCOMPARE( word.start, hits[4].start ); - -} - -static QVector -convertToUnicode(const QString &str) -{ - QVector unicode; - for (int i = 0; i < str.length(); ++i) - unicode += str[i].unicode(); - return unicode; -} - -void SonnetFilterTest::testIndic() -{ - QString buffer; - QList hits; - hits.append( Hit( QString::fromUtf8("मराठी"), 0 ) ); - hits.append( Hit( QString::fromUtf8("भाषा"), 6 ) ); - hits.append( Hit( QString::fromUtf8("महाराष्ट्र"), 11 ) ); - hits.append( Hit( QString::fromUtf8("व"), 22 ) ); - hits.append( Hit( QString::fromUtf8("गोवा"), 24 ) ); - hits.append( Hit( QString::fromUtf8("राज्याची"), 29 ) ); - hits.append( Hit( QString::fromUtf8("राजभाषा"), 38 ) ); - hits.append( Hit( QString::fromUtf8("असून"), 46 ) ); - hits.append( Hit( QString::fromUtf8("सुमारे"), 51 ) ); - //hits.append( Hit( QString::fromUtf8("९"), 58 ) ); // This is the number 9, so we don't spell-check it - hits.append( Hit( QString::fromUtf8("कोटी"), 60 ) ); - hits.append( Hit( QString::fromUtf8("लोकांची"), 65 ) ); - hits.append( Hit( QString::fromUtf8("मातृभाषा"), 73 ) ); - hits.append( Hit( QString::fromUtf8("आहे"), 82 ) ); - hits.append( Hit( QString::fromUtf8("मराठी"), 87 ) ); - hits.append( Hit( QString::fromUtf8("भाषा"), 93 ) ); - hits.append( Hit( QString::fromUtf8("कमीत"), 98 ) ); - hits.append( Hit( QString::fromUtf8("कमी"), 103 ) ); - //hits.append( Hit( QString::fromUtf8("१०००"), 107 ) ); // just a number - hits.append( Hit( QString::fromUtf8("वर्षापासून"), 112 ) ); - hits.append( Hit( QString::fromUtf8("अस्तित्वात"), 123 ) ); - hits.append( Hit( QString::fromUtf8("आहे"), 134 ) ); - - buffer = QString::fromUtf8("मराठी भाषा महाराष्ट्र व गोवा राज्याची राजभाषा असून सुमारे ९ कोटी लोकांची मातृभाषा आहे. मराठी भाषा कमीत कमी १००० वर्षापासून अस्तित्वात आहे."); - - Filter filter; - filter.setBuffer( buffer ); - Word w; - int hitNumber = 0; - while ( ! (w=filter.nextWord()).end ) { - QVector unicode = convertToUnicode(w.word); - //qDebug()<< "Found word \""<< unicode << "\" which starts at position " << w.start <<", len = "< - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef TEST_FILTER_H -#define TEST_FILTER_H - -#include - -class SonnetFilterTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void testFilter(); - void testWordAt(); - void testIndic(); -}; - -#endif diff --git a/kdeui/CMakeLists.txt b/kdeui/CMakeLists.txt index ad8a3c41..36228050 100644 --- a/kdeui/CMakeLists.txt +++ b/kdeui/CMakeLists.txt @@ -3,7 +3,6 @@ project(kdeui) include_directories( ${CMAKE_SOURCE_DIR}/interfaces ${CMAKE_SOURCE_DIR}/interfaces/kregexpeditor - ${CMAKE_SOURCE_DIR}/kdecore/sonnet ${CMAKE_SOURCE_DIR}/kdeui ${KDE4_KDECORE_INCLUDES} actions @@ -20,7 +19,7 @@ include_directories( paged plotting shortcuts - sonnet + spell util widgets windowmanagement @@ -29,7 +28,11 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/util ) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/widgets) +include_directories( + ${CMAKE_CURRENT_BINARY_DIR}/widgets + ${ENCHANT_INCLUDE_DIR} + "${ENCHANT_INCLUDE_DIR}/.." +) if (X11_Xkb_FOUND AND X11_Xkbfile_FOUND) set(HAVE_XKB TRUE) @@ -41,7 +44,6 @@ configure_file( if(ENABLE_TESTING) add_subdirectory( tests ) - add_subdirectory( sonnet/tests ) endif() ########### next target ############### @@ -172,11 +174,12 @@ set(kdeui_LIB_SRCS shortcuts/kglobalshortcutinfo_dbus.cpp shortcuts/kacceleratormanager.cpp shortcuts/kcheckaccelerators.cpp - sonnet/dialog.cpp - sonnet/configwidget.cpp - sonnet/highlighter.cpp - sonnet/configdialog.cpp - sonnet/dictionarycombobox.cpp + spell/kspeller.cpp + spell/kspellhighlighter.cpp + spell/kspelldialog.cpp + spell/kspelldictionarycombobox.cpp + spell/kspellconfigwidget.cpp + spell/kspellbackgroundchecker.cpp util/kcompletion.cpp util/kcompletionbase.cpp util/kcrash.cpp @@ -324,6 +327,7 @@ add_library(kdeui ${LIBRARY_TYPE} ${kdeui_LIB_SRCS}) target_link_libraries(kdeui PRIVATE ${X11_LIBRARIES} ${KDEUI_EXTRA_LIBS} + ${ENCHANT_LIBRARIES} ) target_link_libraries(kdeui PUBLIC @@ -487,6 +491,12 @@ install( shortcuts/kglobalshortcutinfo.h shortcuts/kglobalshortcutinfo_p.h shortcuts/kacceleratormanager.h + spell/kspeller.h + spell/kspellhighlighter.h + spell/kspelldialog.h + spell/kspelldictionarycombobox.h + spell/kspellconfigwidget.h + spell/kspellbackgroundchecker.h util/kaccelgen.h util/kcompletion.h util/kcrash.h @@ -578,17 +588,6 @@ install( COMPONENT Devel ) -install( - FILES - sonnet/dialog.h - sonnet/highlighter.h - sonnet/configdialog.h - sonnet/configwidget.h - sonnet/dictionarycombobox.h - DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/sonnet - COMPONENT Devel -) - install( PROGRAMS preparetips DESTINATION ${KDE4_BIN_INSTALL_DIR} diff --git a/kdeui/fonts/sampleedit_p.h b/kdeui/fonts/sampleedit_p.h index bfdb714d..c880774f 100644 --- a/kdeui/fonts/sampleedit_p.h +++ b/kdeui/fonts/sampleedit_p.h @@ -27,6 +27,7 @@ #include #include #include +#include #include diff --git a/kdeui/sonnet/configdialog.cpp b/kdeui/sonnet/configdialog.cpp deleted file mode 100644 index 9ab7459b..00000000 --- a/kdeui/sonnet/configdialog.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/** - * configdialog.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "configdialog.h" -#include "configwidget.h" - -#include - -using namespace Sonnet; - -class ConfigDialog::Private -{ -public: - Private( ConfigDialog *parent ) - : q( parent ) {} - ConfigWidget *ui; - ConfigDialog *q; - void slotConfigChanged(); -}; - -void ConfigDialog::Private::slotConfigChanged() -{ - emit q->languageChanged( ui->language() ); -} - -ConfigDialog::ConfigDialog(KConfig *config, QWidget *parent) - : KDialog(parent), - d(new Private(this)) -{ - setObjectName( "SonnetConfigDialog" ); - setModal( true ); - setCaption( i18n( "Spell Checking Configuration" ) ); - setButtons( Help | Ok /*| Apply*/ | Cancel ); - setDefaultButton( Ok ); - - init(config); -} - -ConfigDialog::~ConfigDialog() -{ - delete d; -} - -void ConfigDialog::init(KConfig *config) -{ - d->ui = new ConfigWidget(config, this); - setMainWidget(d->ui); - setHelp(QString(),"kcontrol/spellchecking"); - connect(this, SIGNAL(okClicked()), - this, SLOT(slotOk())); - /* - connect(this, SIGNAL(applyClicked()), - this, SLOT(slotApply())); - */ - connect(d->ui, SIGNAL(configChanged()), - this, SLOT(slotConfigChanged())); - - connect(d->ui, SIGNAL(configChanged()), - this, SIGNAL(configChanged())); -} - -void ConfigDialog::slotOk() -{ - d->ui->save(); - accept(); -} - -void ConfigDialog::slotApply() -{ - d->ui->save(); -} - -void ConfigDialog::setLanguage( const QString &language ) -{ - d->ui->setLanguage( language ); -} - -QString ConfigDialog::language() const -{ - return d->ui->language(); -} - -#include "moc_configdialog.cpp" diff --git a/kdeui/sonnet/configdialog.h b/kdeui/sonnet/configdialog.h deleted file mode 100644 index 0aefdf4f..00000000 --- a/kdeui/sonnet/configdialog.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * configdialog.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_CONFIGDIALOG_H -#define SONNET_CONFIGDIALOG_H - -#include -#include - -namespace Sonnet -{ - /// The sonnet ConfigDialog - class KDEUI_EXPORT ConfigDialog : public KDialog - { - Q_OBJECT - public: - ConfigDialog(KConfig *config, - QWidget *parent); - ~ConfigDialog(); - - /** - * Sets the language/dictionary that will be selected by default - * in this config dialog. - * This overrides the setting in the config file. - * - * @param language the language which will be selected by default. - * @since 4.1 - */ - void setLanguage( const QString &language ); - /** - * return selected language - * @since 4.8.1 - */ - QString language() const; - - protected Q_SLOTS: - virtual void slotOk(); - virtual void slotApply(); - - Q_SIGNALS: - - /** - * This is emitted all the time when we change config and not just language - * - * @param language the language which the user has selected - * @since 4.1 - */ - - void languageChanged( const QString &language ); - - /** - * This is emitted when configChanged - * @since 4.8.1 - */ - void configChanged(); - - private: - void init(KConfig *config); - private: - class Private; - friend class Private; - Private *const d; - Q_DISABLE_COPY(ConfigDialog) - Q_PRIVATE_SLOT(d, void slotConfigChanged()) - }; -} - -#endif diff --git a/kdeui/sonnet/configui.ui b/kdeui/sonnet/configui.ui deleted file mode 100644 index 2903d6e9..00000000 --- a/kdeui/sonnet/configui.ui +++ /dev/null @@ -1,112 +0,0 @@ - - - Zack Rusin <zack@kde.org> - Licensed under GNU LGPL - SonnetConfigUI - - - - 0 - 0 - 577 - 441 - - - - - 0 - - - - - - 0 - 0 - - - - - - - - Options - - - - - - Enable &background spellchecking - - - - - - - &Automatic spell checking enabled by default - - - - - - - Skip all &uppercase words - - - - - - - S&kip run-together words - - - - - - - - - - Default language: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Ignored Words - - - - - - Ignored Words - - - - - - - - - - - KEditListWidget - QWidget -
keditlistwidget.h
-
- - KComboBox - QComboBox -
kcombobox.h
-
- - Sonnet::DictionaryComboBox - KComboBox -
sonnet/dictionarycombobox.h
-
-
- -
diff --git a/kdeui/sonnet/configwidget.cpp b/kdeui/sonnet/configwidget.cpp deleted file mode 100644 index 43071309..00000000 --- a/kdeui/sonnet/configwidget.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/** - * configwidget.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "configwidget.h" -#include "ui_configui.h" - -#include "loader_p.h" -#include "settings_p.h" - -#include -#include -#include - -#include -#include - -using namespace Sonnet; - -class ConfigWidget::Private -{ -public: - Loader *loader; - Ui_SonnetConfigUI ui; - QWidget *wdg; - KConfig *config; -}; - -ConfigWidget::ConfigWidget(KConfig *config, QWidget *parent) - : QWidget(parent), - d(new Private) -{ - d->loader = Loader::openLoader(); - d->loader->settings()->restore(config); - d->config = config; - - QVBoxLayout *layout = new QVBoxLayout( this ); - layout->setMargin( 0 ); - layout->setObjectName( "SonnetConfigUILayout" ); - d->wdg = new QWidget( this ); - d->ui.setupUi( d->wdg ); - - //QStringList clients = d->loader->clients(); - d->ui.m_langCombo->setCurrentByDictionary( d->loader->settings()->defaultLanguage() ); - //d->ui->m_clientCombo->insertStringList( clients ); - d->ui.m_skipUpperCB->setChecked( !d->loader->settings()->checkUppercase() ); - d->ui.m_skipRunTogetherCB->setChecked( d->loader->settings()->skipRunTogether() ); - d->ui.m_checkerEnabledByDefaultCB->setChecked( d->loader->settings()->checkerEnabledByDefault() ); - QStringList ignoreList = d->loader->settings()->currentIgnoreList(); - ignoreList.sort(); - d->ui.m_ignoreListBox->insertStringList( ignoreList ); - d->ui.m_bgSpellCB->setChecked( d->loader->settings()->backgroundCheckerEnabled() ); - d->ui.m_bgSpellCB->hide();//hidden by default - connect( d->ui.m_ignoreListBox, SIGNAL(changed()), SLOT(slotChanged()) ); - - layout->addWidget( d->wdg ); - connect(d->ui.m_langCombo, SIGNAL(dictionaryChanged(QString)), this, SIGNAL(configChanged())); - connect(d->ui.m_bgSpellCB, SIGNAL(clicked(bool)),this,SIGNAL(configChanged())); - connect(d->ui.m_skipUpperCB, SIGNAL(clicked(bool)), this, SIGNAL(configChanged())); - connect(d->ui.m_skipRunTogetherCB, SIGNAL(clicked(bool)), this, SIGNAL(configChanged())); - connect(d->ui.m_checkerEnabledByDefaultCB, SIGNAL(clicked(bool)), this, SIGNAL(configChanged())); - connect(d->ui.m_ignoreListBox, SIGNAL(changed()), this, SIGNAL(configChanged())); -} - -ConfigWidget::~ConfigWidget() -{ - delete d; -} - -void ConfigWidget::save() -{ - if (d->ui.m_langCombo->count() ) { - d->loader->settings()->setDefaultLanguage( d->ui.m_langCombo->currentDictionary() ); - } - d->loader->settings()->setCheckUppercase( - !d->ui.m_skipUpperCB->isChecked() ); - d->loader->settings()->setSkipRunTogether( - d->ui.m_skipRunTogetherCB->isChecked() ); - d->loader->settings()->setBackgroundCheckerEnabled( - d->ui.m_bgSpellCB->isChecked() ); - d->loader->settings()->setCheckerEnabledByDefault( - d->ui.m_checkerEnabledByDefaultCB->isChecked() ); - - d->loader->settings()->save(d->config); -} - -void ConfigWidget::slotChanged() -{ - d->loader->settings()->setCurrentIgnoreList( - d->ui.m_ignoreListBox->items() ); -} - -void ConfigWidget::setBackgroundCheckingButtonShown( bool b ) -{ - d->ui.m_bgSpellCB->setVisible( b ); -} - -bool ConfigWidget::backgroundCheckingButtonShown() const -{ - return !d->ui.m_bgSpellCB->isHidden(); -} - -void ConfigWidget::slotDefault() -{ - d->ui.m_skipUpperCB->setChecked( false ); - d->ui.m_skipRunTogetherCB->setChecked( false ); - d->ui.m_checkerEnabledByDefaultCB->setChecked( false ); - d->ui.m_bgSpellCB->setChecked( true ); - d->ui.m_ignoreListBox->clear(); -} - -void ConfigWidget::setLanguage( const QString &language ) -{ - d->ui.m_langCombo->setCurrentByDictionary( language ); -} - -QString ConfigWidget::language() const -{ - if ( d->ui.m_langCombo->count() ) { - return d->ui.m_langCombo->currentDictionary(); - } else { - return QString(); - } -} - -#include "moc_configwidget.cpp" diff --git a/kdeui/sonnet/configwidget.h b/kdeui/sonnet/configwidget.h deleted file mode 100644 index 8f9abcf6..00000000 --- a/kdeui/sonnet/configwidget.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_CONFIGWIDGET_H -#define SONNET_CONFIGWIDGET_H - -#include -#include - -class KConfig; - -namespace Sonnet -{ - /// The sonnet ConfigWidget - class KDEUI_EXPORT ConfigWidget : public QWidget - { - Q_OBJECT - public: - ConfigWidget(KConfig *config, QWidget *parent); - ~ConfigWidget(); - - bool backgroundCheckingButtonShown() const; - - /** - * Sets the language/dictionary that will be selected by default - * in this config widget. - * This overrides the setting in the config file. - * - * @param language the language which will be selected by default. - * @since 4.1 - */ - void setLanguage( const QString &language ); - - /** - * Get the currently selected language for spell checking. Returns an empty string if - * kdelibs was built without any spellchecking plugins. - * @return the language currently selected in the language combobox - * @since 4.1 - */ - QString language() const; - - public Q_SLOTS: - void save(); - void setBackgroundCheckingButtonShown( bool ); - void slotDefault(); - protected Q_SLOTS: - void slotChanged(); - - Q_SIGNALS: - /** - * Signal sends when config was changed - * @since 4.1 - */ - void configChanged(); - - private: - class Private; - friend class Private; - Private* const d; - }; -} - -#endif diff --git a/kdeui/sonnet/dialog.cpp b/kdeui/sonnet/dialog.cpp deleted file mode 100644 index 9a034236..00000000 --- a/kdeui/sonnet/dialog.cpp +++ /dev/null @@ -1,452 +0,0 @@ -/** - * dialog.cpp - * - * Copyright (C) 2003 Zack Rusin - * Copyright (C) 2009-2010 Michel Ludwig - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "dialog.h" -#include "ui_sonnetui.h" - -#include "backgroundchecker.h" -#include "speller.h" -#include "filter_p.h" -#include "settings_p.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - -namespace Sonnet -{ - -//to initially disable sorting in the suggestions listview -#define NONSORTINGCOLUMN 2 - -class ReadOnlyStringListModel: public QStringListModel -{ -public: - ReadOnlyStringListModel(QObject* parent):QStringListModel(parent){} - Qt::ItemFlags flags(const QModelIndex& index) const {Q_UNUSED(index); return Qt::ItemIsEnabled | Qt::ItemIsSelectable;} -}; - -class Dialog::Private -{ -public: - Ui_SonnetUi ui; - ReadOnlyStringListModel *suggestionsModel; - QWidget *wdg; - KProgressDialog *progressDialog; - QString originalBuffer; - BackgroundChecker *checker; - - Word currentWord; - QMap replaceAllMap; - bool restart;//used when text is distributed across several qtextedits, eg in KAider - - QMap dictsMap; - - int progressDialogTimeout; - bool showCompletionMessageBox; - bool spellCheckContinuedAfterReplacement; - bool canceled; - - void deleteProgressDialog(bool directly) - { - if (progressDialog) - { - progressDialog->hide(); - if (directly) - { - delete progressDialog; - } - else - { - progressDialog->deleteLater(); - } - progressDialog = NULL; - } - } -}; - -Dialog::Dialog(BackgroundChecker *checker, - QWidget *parent) - : KDialog(parent), - d(new Private) -{ - setModal(true); - setCaption(i18nc("@title:window", "Check Spelling")); - setButtons(Help | Cancel | User1); - setButtonGuiItem(User1, KGuiItem(i18nc("@action:button", "&Finished"))); - - setDefaultButton(User1); - d->checker = checker; - - d->canceled = false; - d->showCompletionMessageBox = false; - d->spellCheckContinuedAfterReplacement = true; - d->progressDialogTimeout = -1; - d->progressDialog = NULL; - - initGui(); - initConnections(); - setMainWidget(d->wdg); - setHelp(QString(),"sonnet"); -} - -Dialog::~Dialog() -{ - delete d; -} - -void Dialog::initConnections() -{ - connect( d->ui.m_addBtn, SIGNAL(clicked()), - SLOT(slotAddWord()) ); - connect( d->ui.m_replaceBtn, SIGNAL(clicked()), - SLOT(slotReplaceWord()) ); - connect( d->ui.m_replaceAllBtn, SIGNAL(clicked()), - SLOT(slotReplaceAll()) ); - connect( d->ui.m_skipBtn, SIGNAL(clicked()), - SLOT(slotSkip()) ); - connect( d->ui.m_skipAllBtn, SIGNAL(clicked()), - SLOT(slotSkipAll()) ); - connect( d->ui.m_suggestBtn, SIGNAL(clicked()), - SLOT(slotSuggest()) ); - connect( d->ui.m_language, SIGNAL(activated(QString)), - SLOT(slotChangeLanguage(QString)) ); - connect( d->ui.m_suggestions, SIGNAL(clicked(QModelIndex)), - SLOT(slotSelectionChanged(QModelIndex)) ); - connect( d->checker, SIGNAL(misspelling(QString,int)), - SLOT(slotMisspelling(QString,int)) ); - connect( d->checker, SIGNAL(done()), - SLOT(slotDone()) ); - connect( d->ui.m_suggestions, SIGNAL(doubleClicked(QModelIndex)), - SLOT(slotReplaceWord()) ); - connect( this, SIGNAL(user1Clicked()), this, SLOT(slotFinished()) ); - connect( this, SIGNAL(cancelClicked()),this, SLOT(slotCancel()) ); - connect( d->ui.m_replacement, SIGNAL(returnPressed()), this, SLOT(slotReplaceWord()) ); - connect( d->ui.m_autoCorrect, SIGNAL(clicked()), - SLOT(slotAutocorrect()) ); - // button use by kword/kpresenter - // hide by default - d->ui.m_autoCorrect->hide(); -} - -void Dialog::initGui() -{ - d->wdg = new QWidget(this); - d->ui.setupUi(d->wdg); - setGuiEnabled(false); - - //d->ui.m_suggestions->setSorting( NONSORTINGCOLUMN ); - fillDictionaryComboBox(); - d->restart = false; - - d->suggestionsModel=new ReadOnlyStringListModel(this); - d->ui.m_suggestions->setModel(d->suggestionsModel); -} - -void Dialog::activeAutoCorrect( bool _active ) -{ - if ( _active ) - d->ui.m_autoCorrect->show(); - else - d->ui.m_autoCorrect->hide(); -} - -void Dialog::showProgressDialog(int timeout) -{ - d->progressDialogTimeout = timeout; -} - -void Dialog::showSpellCheckCompletionMessage( bool b ) -{ - d->showCompletionMessageBox = b; -} - -void Dialog::setSpellCheckContinuedAfterReplacement( bool b ) -{ - d->spellCheckContinuedAfterReplacement = b; -} - -void Dialog::slotAutocorrect() -{ - setGuiEnabled(false); - setProgressDialogVisible(true); - kDebug(); - emit autoCorrect(d->currentWord.word, d->ui.m_replacement->text() ); - slotReplaceWord(); -} - -void Dialog::setGuiEnabled(bool b) -{ - d->wdg->setEnabled(b); -} - -void Dialog::setProgressDialogVisible(bool b) -{ - if (!b) - { - d->deleteProgressDialog(true); - } - else if(d->progressDialogTimeout >= 0) - { - if (d->progressDialog) - { - return; - } - d->progressDialog = new KProgressDialog(this, i18nc("@title:window", "Check Spelling"), - i18nc("progress label", "Spell checking in progress...")); - d->progressDialog->setModal(true); - d->progressDialog->setAutoClose(false); - d->progressDialog->setAutoReset(false); - // create an 'indefinite' progress box as we currently cannot get progress feedback from - // the speller - d->progressDialog->progressBar()->reset(); - d->progressDialog->progressBar()->setRange(0, 0); - d->progressDialog->progressBar()->setValue(0); - connect(d->progressDialog, SIGNAL(cancelClicked()), this, SLOT(slotCancel())); - d->progressDialog->setMinimumDuration(d->progressDialogTimeout); - } -} - -void Dialog::slotFinished() -{ - kDebug(); - setProgressDialogVisible(false); - emit stop(); - //FIXME: should we emit done here? - emit done(d->checker->text()); - emit spellCheckStatus(i18n("Spell check stopped.")); - accept(); -} - -void Dialog::slotCancel() -{ - kDebug(); - d->canceled = true; - d->deleteProgressDialog(false); // this method can be called in response to - // pressing 'Cancel' on the dialog - emit cancel(); - emit spellCheckStatus(i18n("Spell check canceled.")); - reject(); -} - -QString Dialog::originalBuffer() const -{ - return d->originalBuffer; -} - -QString Dialog::buffer() const -{ - return d->checker->text(); -} - -void Dialog::setBuffer(const QString &buf) -{ - d->originalBuffer = buf; - //it is possible to change buffer inside slot connected to done() signal - d->restart = true; -} - -void Dialog::fillDictionaryComboBox() -{ - Speller speller = d->checker->speller(); - d->dictsMap = speller.availableDictionaries(); - QStringList langs = d->dictsMap.keys(); - d->ui.m_language->clear(); - d->ui.m_language->addItems(langs); - updateDictionaryComboBox(); -} - -void Dialog::updateDictionaryComboBox() -{ - Speller speller = d->checker->speller(); - d->ui.m_language->setCurrentIndex(d->dictsMap.values().indexOf(speller.language())); -} - -void Dialog::updateDialog( const QString& word ) -{ - d->ui.m_unknownWord->setText( word ); - d->ui.m_contextLabel->setText( d->checker->currentContext() ); - const QStringList suggs = d->checker->suggest( word ); - - if (suggs.isEmpty()) - d->ui.m_replacement->clear(); - else - d->ui.m_replacement->setText( suggs.first() ); - fillSuggestions( suggs ); -} - -void Dialog::show() -{ - kDebug()<<"Showing dialog"; - d->canceled = false; - fillDictionaryComboBox(); - updateDictionaryComboBox(); - if (d->originalBuffer.isEmpty()) - { - d->checker->start(); - } - else - { - d->checker->setText(d->originalBuffer); - } - setProgressDialogVisible(true); -} - -void Dialog::slotAddWord() -{ - setGuiEnabled(false); - setProgressDialogVisible(true); - d->checker->addWordToPersonal(d->currentWord.word); - d->checker->continueChecking(); -} - -void Dialog::slotReplaceWord() -{ - setGuiEnabled(false); - setProgressDialogVisible(true); - QString replacementText = d->ui.m_replacement->text(); - emit replace( d->currentWord.word, d->currentWord.start, - replacementText ); - - if( d->spellCheckContinuedAfterReplacement ) { - d->checker->replace(d->currentWord.start, - d->currentWord.word, - replacementText); - d->checker->continueChecking(); - } - else { - d->checker->stop(); - } -} - -void Dialog::slotReplaceAll() -{ - setGuiEnabled(false); - setProgressDialogVisible(true); - d->replaceAllMap.insert( d->currentWord.word, - d->ui.m_replacement->text() ); - slotReplaceWord(); -} - -void Dialog::slotSkip() -{ - setGuiEnabled(false); - setProgressDialogVisible(true); - d->checker->continueChecking(); -} - -void Dialog::slotSkipAll() -{ - setGuiEnabled(false); - setProgressDialogVisible(true); - //### do we want that or should we have a d->ignoreAll list? - Speller speller = d->checker->speller(); - speller.addToPersonal(d->currentWord.word); - d->checker->setSpeller(speller); - d->checker->continueChecking(); -} - -void Dialog::slotSuggest() -{ - QStringList suggs = d->checker->suggest( d->ui.m_replacement->text() ); - fillSuggestions( suggs ); -} - -void Dialog::slotChangeLanguage(const QString &lang) -{ - Speller speller = d->checker->speller(); - QString languageCode = d->dictsMap[lang]; - if (!languageCode.isEmpty()) { - d->checker->changeLanguage(languageCode); - slotSuggest(); - emit languageChanged(languageCode); - } -} - -void Dialog::slotSelectionChanged(const QModelIndex &item) -{ - d->ui.m_replacement->setText( item.data().toString() ); -} - -void Dialog::fillSuggestions( const QStringList& suggs ) -{ - d->suggestionsModel->setStringList(suggs); -} - -void Dialog::slotMisspelling(const QString& word, int start) -{ - setGuiEnabled(true); - setProgressDialogVisible(false); - emit misspelling(word, start); - //NOTE this is HACK I had to introduce because BackgroundChecker lacks 'virtual' marks on methods - //this dramatically reduces spellchecking time in Lokalize - //as this doesn't fetch suggestions for words that are present in msgid - if (!updatesEnabled()) - return; - - kDebug()<<"Dialog misspelling!!"; - d->currentWord = Word( word, start ); - if ( d->replaceAllMap.contains( word ) ) { - d->ui.m_replacement->setText( d->replaceAllMap[ word ] ); - slotReplaceWord(); - } else { - updateDialog( word ); - } - KDialog::show(); -} - -void Dialog::slotDone() -{ - d->restart=false; - emit done(d->checker->text()); - if (d->restart) - { - updateDictionaryComboBox(); - d->checker->setText(d->originalBuffer); - d->restart=false; - } - else - { - setProgressDialogVisible(false); - kDebug()<<"Dialog done!"; - emit spellCheckStatus(i18n("Spell check complete.")); - accept(); - if(!d->canceled && d->showCompletionMessageBox) - { - KMessageBox::information(this, i18n("Spell check complete."), i18nc("@title:window", "Check Spelling")); - } - } -} - -} - -#include "moc_dialog.cpp" diff --git a/kdeui/sonnet/dialog.h b/kdeui/sonnet/dialog.h deleted file mode 100644 index 6d8f38ad..00000000 --- a/kdeui/sonnet/dialog.h +++ /dev/null @@ -1,166 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- -/* - * dialog.h - * - * Copyright (C) 2003 Zack Rusin - * Copyright (C) 2009-2010 Michel Ludwig - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_DIALOG_H -#define SONNET_DIALOG_H - -#include - -#include -#include - -namespace Sonnet -{ - class BackgroundChecker; - - /** - * @short Spellcheck dialog - * - * \code - * Sonnet::Dialog dlg = new Sonnet::Dialog( - * new Sonnet::BackgroundChecker(this), this); - * //connect signals - * ... - * dlg->setBuffer( someText ); - * dlg->show(); - * \endcode - * - * You can change buffer inside a slot connected to done() signal - * and spellcheck will continue with new data automatically. - */ - class KDEUI_EXPORT Dialog : public KDialog - { - Q_OBJECT - public: - Dialog(BackgroundChecker *checker, - QWidget *parent); - ~Dialog(); - - QString originalBuffer() const; - QString buffer() const; - - void show(); - void activeAutoCorrect(bool _active); - - // Hide warning about done(), which is a slot in QDialog and a signal here. - using KDialog::done; - - /** - * Controls whether an (indefinite) progress dialog is shown when the spell - * checking takes longer than the given time to complete. By default no - * progress dialog is shown. If the progress dialog is set to be shown, no - * time consuming operation (for example, showing a notification message) should - * be performed in a slot connected to the 'done' signal as this might trigger - * the progress dialog unnecessarily. - * - * @param timeout time after which the progress dialog should appear; a negative - * value can be used to hide it - * @since 4.4 - */ - void showProgressDialog(int timeout = 500); - - /** - * Controls whether a message box indicating the completion of the spell checking - * is shown or not. By default it is not shown. - * - * @since 4.4 - */ - void showSpellCheckCompletionMessage( bool b = true ); - - /** - * Controls whether the spell checking is continued after the replacement of a - * misspelled word has been performed. By default it is continued. - * - * @since 4.4 - */ - void setSpellCheckContinuedAfterReplacement( bool b ); - - public Q_SLOTS: - void setBuffer(const QString &); - - Q_SIGNALS: - /** - * The dialog won't be closed if you setBuffer() in slot connected to this signal - * - * Also emitted after stop() signal - */ - void done( const QString& newBuffer ); - void misspelling( const QString& word, int start ); - void replace( const QString& oldWord, int start, - const QString& newWord ); - - void stop(); - void cancel(); - void autoCorrect( const QString & currentWord, const QString & replaceWord ); - - /** - * Signal sends when spell checking is finished/stopped/completed - * @since 4.1 - */ - void spellCheckStatus(const QString &); - - /** - * Emitted when the user changes the language used for spellchecking, - * which is shown in a combobox of this dialog. - * - * @param dictionary the new language the user selected - * @since 4.1 - */ - void languageChanged( const QString &language ); - - private Q_SLOTS: - void slotMisspelling(const QString& word, int start ); - void slotDone(); - - void slotFinished(); - void slotCancel(); - - void slotAddWord(); - void slotReplaceWord(); - void slotReplaceAll(); - void slotSkip(); - void slotSkipAll(); - void slotSuggest(); - void slotChangeLanguage( const QString& ); - void slotSelectionChanged(const QModelIndex &); - void slotAutocorrect(); - - void setGuiEnabled(bool b); - void setProgressDialogVisible(bool b); - - private: - void updateDialog( const QString& word ); - void fillDictionaryComboBox(); - void updateDictionaryComboBox(); - void fillSuggestions( const QStringList& suggs ); - void initConnections(); - void initGui(); - void continueChecking(); - - private: - class Private; - Private* const d; - Q_DISABLE_COPY( Dialog ) - }; -} - -#endif diff --git a/kdeui/sonnet/dictionarycombobox.cpp b/kdeui/sonnet/dictionarycombobox.cpp deleted file mode 100644 index 416bbb76..00000000 --- a/kdeui/sonnet/dictionarycombobox.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2003 Ingo Kloecker - * Copyright (c) 2008 Tom Albers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA -*/ - -#include "dictionarycombobox.h" - -#include -#include - -namespace Sonnet -{ - -//@cond PRIVATE -class DictionaryComboBox::Private -{ - public: - Private( DictionaryComboBox* combo ) : q( combo ) {}; - DictionaryComboBox* q; - void slotDictionaryChanged( int idx ); -}; - -void DictionaryComboBox::Private::slotDictionaryChanged( int idx ) -{ - kDebug() << idx; - emit q->dictionaryChanged( q->itemData( idx ).toString() ); - emit q->dictionaryNameChanged( q->itemText( idx ) ); -} -//@endcon - -DictionaryComboBox::DictionaryComboBox( QWidget * parent ) - : KComboBox( parent ), d( new DictionaryComboBox::Private( this ) ) -{ - reloadCombo(); - connect( this, SIGNAL(activated(int)), - SLOT(slotDictionaryChanged(int)) ); -} - -DictionaryComboBox::~DictionaryComboBox() -{ - delete d; -} - -QString DictionaryComboBox::currentDictionaryName() const -{ - return currentText(); -} - -QString DictionaryComboBox::currentDictionary() const -{ - return itemData( currentIndex() ).toString(); -} - -void DictionaryComboBox::setCurrentByDictionaryName( const QString & name ) -{ - if ( name.isEmpty() || name == currentText() ) - return; - - int idx = findText( name ); - if ( idx == -1 ) { - kDebug() << "name not found" << name; - return; - } - - setCurrentIndex( idx ); - d->slotDictionaryChanged( idx ); -} - -void DictionaryComboBox::setCurrentByDictionary( const QString & dictionary ) -{ - if ( dictionary.isEmpty() || dictionary == itemData( currentIndex() ).toString() ) - return; - - int idx = findData( dictionary ); - if ( idx == -1 ) { - kDebug() << "dictionary not found" << dictionary; - return; - } - - setCurrentIndex( idx ); - d->slotDictionaryChanged( idx ); -} - -void DictionaryComboBox::reloadCombo() -{ - clear(); - Sonnet::Speller* speller = new Sonnet::Speller(); - QMap dictionaries = speller->availableDictionaries(); - QMapIterator i( dictionaries ); - while ( i.hasNext() ) { - i.next(); - kDebug() << "Populate combo:" << i.key() << ":" << i.value(); - addItem( i.key(), i.value() ); - } - delete speller; -} - -} - -#include "moc_dictionarycombobox.cpp" diff --git a/kdeui/sonnet/dictionarycombobox.h b/kdeui/sonnet/dictionarycombobox.h deleted file mode 100644 index 82a807c1..00000000 --- a/kdeui/sonnet/dictionarycombobox.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2003 Ingo Kloecker - * Copyright (c) 2008 Tom Albers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA -*/ - -#ifndef SONNET_DICTIONARYCOMBOBOX_H -#define SONNET_DICTIONARYCOMBOBOX_H - -#include "kdeui_export.h" - -#include - -namespace Sonnet -{ - -/** - * @short A combo box for selecting the dictionary used for spell checking. - * @author Ingo Kloecker - * @author Tom Albers - * @since 4.2 - **/ - -class KDEUI_EXPORT DictionaryComboBox : public KComboBox -{ - Q_OBJECT -public: - - /** - * Constructor - */ - explicit DictionaryComboBox( QWidget * parent=0 ); - - /** - * Destructor - */ - ~DictionaryComboBox(); - - /** - * Clears the widget and reloads the dictionaries from Sonnet. - * Remember to set the dictionary you want selected after calling this function. - */ - void reloadCombo(); - - /** - * Returns the current dictionary name, for example "German (Switzerland)" - */ - QString currentDictionaryName() const; - - /** - * Returns the current dictionary, for example "de_CH" - */ - QString currentDictionary() const; - - /** - * Sets the current dictionaryName to the given dictionaryName - */ - void setCurrentByDictionaryName( const QString & dictionaryName ); - - /** - * Sets the current dictionary to the given dictionary. - */ - void setCurrentByDictionary( const QString & dictionary ); - -Q_SIGNALS: - /** - * @em Emitted whenever the current dictionary changes. Either - * by user intervention or on setCurrentByDictionaryName() or on - * setCurrentByDictionary(). For example "de_CH". - */ - void dictionaryChanged( const QString & dictionary ); - - /** - * @em Emitted whenever the current dictionary changes. Either - * by user intervention or on setCurrentByDictionaryName() or on - * setCurrentByDictionary(). For example "German (Switzerland)". - */ - void dictionaryNameChanged( const QString & dictionaryName ); - -private: - class Private; - Private* const d; - Q_PRIVATE_SLOT(d, void slotDictionaryChanged( int ) ) -}; - -} - -#endif diff --git a/kdeui/sonnet/highlighter.cpp b/kdeui/sonnet/highlighter.cpp deleted file mode 100644 index 198ae639..00000000 --- a/kdeui/sonnet/highlighter.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/** - * highlighter.cpp - * - * Copyright (C) 2004 Zack Rusin - * Copyright (C) 2006 Laurent Montel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include "highlighter.h" -#include "moc_highlighter.cpp" - -#include "speller.h" -#include "loader_p.h" -#include "filter_p.h" -#include "settings_p.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Sonnet { - -class Highlighter::Private -{ -public: - ~Private(); - Filter *filter; - Loader *loader; - Speller *dict; - QHash dictCache; - QTextEdit *edit; - bool active; - bool automatic; - bool completeRehighlightRequired; - bool intraWordEditing; - bool spellCheckerFound; //cached d->dict->isValid() value - int disablePercentage; - int disableWordCount; - int wordCount, errorCount; - QTimer *rehighlightRequest; - QColor spellColor; -}; - -Highlighter::Private::~Private() -{ - qDeleteAll(dictCache); - delete filter; -} - -Highlighter::Highlighter(QTextEdit *textEdit, - const QString& configFile, - const QColor& _col) - : QSyntaxHighlighter(textEdit), - d(new Private) -{ - d->filter = Filter::defaultFilter(); - d->edit = textEdit; - d->active = true; - d->automatic = true; - d->wordCount = 0; - d->errorCount = 0; - d->intraWordEditing = false; - d->completeRehighlightRequired = false; - d->spellColor = _col.isValid() ? _col : Qt::red; - - textEdit->installEventFilter( this ); - textEdit->viewport()->installEventFilter( this ); - - d->loader = Loader::openLoader(); - - //Do not load an empty settings file as it will cause the spellchecker to fail - //if the KGlobal::locale()->language() (default value) spellchecker is not installed, - //and we have a global sonnetrc file with a spellcheck lang installed which could be used. - if (!configFile.isEmpty()) { - KConfig conf(configFile); - if (conf.hasGroup("Spelling")) { - d->loader->settings()->restore(&conf); - d->filter->setSettings(d->loader->settings()); - } - } - - d->dict = new Sonnet::Speller(); - d->spellCheckerFound = d->dict->isValid(); - d->rehighlightRequest = new QTimer(this); - connect( d->rehighlightRequest, SIGNAL(timeout()), - this, SLOT(slotRehighlight())); - - if(!d->spellCheckerFound) - return; - - d->dictCache.insert(d->dict->language(), d->dict); - - d->disablePercentage = d->loader->settings()->disablePercentageWordError(); - d->disableWordCount = d->loader->settings()->disableWordErrorCount(); - - //Add kde personal word - const QStringList l = Highlighter::personalWords(); - for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { - d->dict->addToSession( *it ); - } - d->completeRehighlightRequired = true; - d->rehighlightRequest->setInterval(0); - d->rehighlightRequest->setSingleShot(true); - d->rehighlightRequest->start(); -} - -Highlighter::~Highlighter() -{ - delete d; -} - -bool Highlighter::spellCheckerFound() const -{ - return d->spellCheckerFound; -} - -void Highlighter::slotRehighlight() -{ - kDebug() << "Highlighter::slotRehighlight()"; - if (d->completeRehighlightRequired) { - d->wordCount = 0; - d->errorCount = 0; - rehighlight(); - - } else { - //rehighlight the current para only (undo/redo safe) - QTextCursor cursor = d->edit->textCursor(); - cursor.insertText( "" ); - } - //if (d->checksDone == d->checksRequested) - //d->completeRehighlightRequired = false; - QTimer::singleShot( 0, this, SLOT(slotAutoDetection())); -} - - -QStringList Highlighter::personalWords() -{ - QStringList l; - l.append( "KMail" ); - l.append( "KOrganizer" ); - l.append( "KAddressBook" ); - l.append( "KWebKit" ); - l.append( "KIO" ); - l.append( "KJS" ); - l.append( "Konqueror" ); - l.append( "Sonnet" ); - l.append( "Kontact" ); - l.append( "Qt" ); - return l; -} - -bool Highlighter::automatic() const -{ - return d->automatic; -} - -bool Highlighter::intraWordEditing() const -{ - return d->intraWordEditing; -} - -void Highlighter::setIntraWordEditing( bool editing ) -{ - d->intraWordEditing = editing; -} - - -void Highlighter::setAutomatic( bool automatic ) -{ - if ( automatic == d->automatic ) - return; - - d->automatic = automatic; - if ( d->automatic ) - slotAutoDetection(); -} - -void Highlighter::slotAutoDetection() -{ - bool savedActive = d->active; - - //don't disable just because 1 of 4 is misspelled. - if (d->automatic && d->wordCount >= 10) { - // tme = Too many errors - bool tme = (d->errorCount >= d->disableWordCount) && ( - d->errorCount * 100 >= d->disablePercentage * d->wordCount); - if (d->active && tme) { - d->active = false; - } else if (!d->active && !tme) { - d->active = true; - } - } - - if (d->active != savedActive) { - if (d->active) { - emit activeChanged(i18n("As-you-type spell checking enabled.")); - } else { - emit activeChanged(i18n( "Too many misspelled words. " - "As-you-type spell checking disabled.")); - } - - d->completeRehighlightRequired = true; - d->rehighlightRequest->setInterval(100); - d->rehighlightRequest->setSingleShot(true); - kDebug()<<" Highlighter::slotAutoDetection :"<active; - } - -} - -void Highlighter::setActive( bool active ) -{ - if ( active == d->active ) - return; - d->active = active; - rehighlight(); - - - if ( d->active ) - emit activeChanged( i18n("As-you-type spell checking enabled.") ); - else - emit activeChanged( i18n("As-you-type spell checking disabled.") ); -} - -bool Highlighter::isActive() const -{ - return d->active; -} - -void Highlighter::highlightBlock(const QString &text) -{ - if (text.isEmpty() || !d->active || !d->spellCheckerFound) - return; - - d->filter->setBuffer( text ); - Word w = d->filter->nextWord(); - while ( !w.end ) { - ++d->wordCount; - if (d->dict->isMisspelled(w.word)) { - ++d->errorCount; - setMisspelled(w.start, w.word.length()); - } else - unsetMisspelled(w.start, w.word.length()); - w = d->filter->nextWord(); - } - //QTimer::singleShot( 0, this, SLOT(checkWords()) ); - setCurrentBlockState(0); -} - -QString Highlighter::currentLanguage() const -{ - return d->dict->language(); -} - -void Highlighter::setCurrentLanguage(const QString &lang) -{ - if (!d->dictCache.contains(lang)) { - d->dict = new Speller(*d->dict); - d->dict->setLanguage(lang); - if (d->dict->isValid()) { - d->dictCache.insert(lang, d->dict); - } else { - d->spellCheckerFound = false; - kDebug()<<"No dictionary for \"" - <dict = d->dictCache[lang]; - d->spellCheckerFound = d->dict->isValid(); - d->wordCount = 0; - d->errorCount = 0; - if (d->automatic) - slotAutoDetection(); -} - -void Highlighter::setMisspelled(int start, int count) -{ - QTextCharFormat format; - format.setFontUnderline(true); - format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); - format.setUnderlineColor(d->spellColor); - setFormat(start, count, format); -} - -void Highlighter::unsetMisspelled( int start, int count ) -{ - setFormat(start, count, QTextCharFormat()); -} - -bool Highlighter::eventFilter( QObject *o, QEvent *e) -{ -#if 0 - if (o == textEdit() && (e->type() == QEvent::FocusIn)) { - if ( d->globalConfig ) { - QString skey = spellKey(); - if ( d->spell && d->spellKey != skey ) { - d->spellKey = skey; - KDictSpellingHighlighter::dictionaryChanged(); - } - } - } -#endif - if (!d->spellCheckerFound) - return false; - if (o == d->edit && (e->type() == QEvent::KeyPress)) { - QKeyEvent *k = static_cast(e); - //d->autoReady = true; - if (d->rehighlightRequest->isActive()) // try to stay out of the users way - d->rehighlightRequest->start( 500 ); - if ( k->key() == Qt::Key_Enter || - k->key() == Qt::Key_Return || - k->key() == Qt::Key_Up || - k->key() == Qt::Key_Down || - k->key() == Qt::Key_Left || - k->key() == Qt::Key_Right || - k->key() == Qt::Key_PageUp || - k->key() == Qt::Key_PageDown || - k->key() == Qt::Key_Home || - k->key() == Qt::Key_End || - (( k->modifiers()== Qt::ControlModifier ) && - ((k->key() == Qt::Key_A) || - (k->key() == Qt::Key_B) || - (k->key() == Qt::Key_E) || - (k->key() == Qt::Key_N) || - (k->key() == Qt::Key_P))) ) { - if ( intraWordEditing() ) { - setIntraWordEditing( false ); - d->completeRehighlightRequired = true; - d->rehighlightRequest->setInterval(500); - d->rehighlightRequest->setSingleShot(true); - d->rehighlightRequest->start(); - } -#if 0 - if (d->checksDone != d->checksRequested) { - // Handle possible change of paragraph while - // words are pending spell checking - d->completeRehighlightRequired = true; - d->rehighlightRequest->start( 500, true ); - } -#endif - } else { - setIntraWordEditing( true ); - } - if ( k->key() == Qt::Key_Space || - k->key() == Qt::Key_Enter || - k->key() == Qt::Key_Return ) { - QTimer::singleShot( 0, this, SLOT(slotAutoDetection())); - } - } - - else if ( o == d->edit->viewport() && - ( e->type() == QEvent::MouseButtonPress )) { - //d->autoReady = true; - if ( intraWordEditing() ) { - setIntraWordEditing( false ); - d->completeRehighlightRequired = true; - d->rehighlightRequest->setInterval(0); - d->rehighlightRequest->setSingleShot(true); - d->rehighlightRequest->start(); - } - } - return false; -} - -void Highlighter::addWordToDictionary(const QString &word) -{ - d->dict->addToPersonal(word); -} - -void Highlighter::ignoreWord(const QString &word) -{ - d->dict->addToSession(word); -} - -QStringList Highlighter::suggestionsForWord(const QString &word, int max) -{ - QStringList suggestions = d->dict->suggest(word); - if ( max != -1 ) { - while ( suggestions.count() > max ) - suggestions.removeLast(); - } - return suggestions; -} - -bool Highlighter::isWordMisspelled(const QString &word) -{ - return d->dict->isMisspelled(word); -} - -void Highlighter::setMisspelledColor(const QColor &color) -{ - d->spellColor = color; -} - -bool Highlighter::checkerEnabledByDefault() const -{ - return d->loader->settings()->checkerEnabledByDefault(); -} - - -} diff --git a/kdeui/sonnet/highlighter.h b/kdeui/sonnet/highlighter.h deleted file mode 100644 index 512d6c06..00000000 --- a/kdeui/sonnet/highlighter.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * highlighter.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef SONNET_HIGHLIGHTER_H -#define SONNET_HIGHLIGHTER_H - -#include -#include -#include - -#include - -namespace Sonnet -{ - /// The Sonnet Highlighter - class KDEUI_EXPORT Highlighter : public QSyntaxHighlighter - { - Q_OBJECT - public: - explicit Highlighter(QTextEdit *textEdit, - const QString &configFile = QString(), - const QColor &col=QColor()); - ~Highlighter(); - - bool spellCheckerFound() const; - - QString currentLanguage() const; - void setCurrentLanguage(const QString &lang); - - static QStringList personalWords(); - - /** - * @short Enable/Disable spell checking. - * - * If @p active is true then spell checking is enabled; otherwise it - * is disabled. Note that you have to disable automatic (de)activation - * with @ref setAutomatic() before you change the state of spell - * checking if you want to persistently enable/disable spell - * checking. - * - * @param active if true, then spell checking is enabled - * - * @see isActive(), setAutomatic() - */ - void setActive(bool active); - - /** - * Returns the state of spell checking. - * - * @return true if spell checking is active - * - * @see setActive() - */ - bool isActive() const; - - bool automatic() const; - - void setAutomatic(bool automatic); - - /** - * Adds the given word permanently to the dictionary. It will never - * be marked as misspelled again, even after restarting the application. - * - * @param word the word which will be added to the dictionary - * @since 4.1 - */ - void addWordToDictionary(const QString &word); - - /** - * Ignores the given word. This word will not be marked misspelled for - * this session. It will again be marked as misspelled when creating - * new highlighters. - * - * @param word the word which will be ignored - * @since 4.1 - */ - void ignoreWord(const QString &word); - - /** - * Returns a list of suggested replacements for the given misspelled word. - * If the word is not misspelled, the list will be empty. - * - * @param word the misspelled word - * @param max at most this many suggestions will be returned. If this is - * -1, as many suggestions as the spell backend supports will - * be returned. - * @return a list of suggested replacements for the word - * @since 4.1 - */ - QStringList suggestionsForWord(const QString &word, int max = 10 ); - - /** - * Checks if a given word is marked as misspelled by the highlighter. - * - * @param word the word to be checked - * @return true if the given word is misspelled. - * @since 4.1 - */ - bool isWordMisspelled(const QString &word); - - /** - * Sets the color in which the highlighter underlines misspelled words. - * @since 4.2 - */ - void setMisspelledColor(const QColor &color); - - /** - * Return true if checker is enabled by default - * @since 4.5 - */ - bool checkerEnabledByDefault() const; - - Q_SIGNALS: - - /** - * Emitted when as-you-type spell checking is enabled or disabled. - * - * @param description is a i18n description of the new state, - * with an optional reason - */ - void activeChanged(const QString &description); - - protected: - - virtual void highlightBlock(const QString &text); - virtual void setMisspelled(int start, int count); - virtual void unsetMisspelled(int start, int count); - - bool eventFilter(QObject *o, QEvent *e); - bool intraWordEditing() const; - void setIntraWordEditing(bool editing); - - public Q_SLOTS: - void slotAutoDetection(); - void slotRehighlight(); - private: - class Private; - Private *const d; - Q_DISABLE_COPY( Highlighter ) - }; - -} - -#endif diff --git a/kdeui/sonnet/sonnetui.ui b/kdeui/sonnet/sonnetui.ui deleted file mode 100644 index f022ab7f..00000000 --- a/kdeui/sonnet/sonnetui.ui +++ /dev/null @@ -1,290 +0,0 @@ - - SonnetUi - - - - 0 - 0 - 481 - 311 - - - - - 5 - 5 - 0 - 0 - - - - - 430 - 300 - - - - - - - <qt><p>This word was considered to be an "unknown word" because it does not match any entry in the dictionary currently in use. It may also be a word in a foreign language.</p> -<p>If the word is not misspelled, you may add it to the dictionary by clicking <b>Add to Dictionary</b>. If you do not want to add the unknown word to the dictionary, but you want to leave it unchanged, click <b>Ignore</b> or <b>Ignore All</b>.</p> -<p>However, if the word is misspelled, you can try to find the correct replacement in the list below. If you cannot find a replacement there, you may type it in the text box below, and click <b>Replace</b> or <b>Replace All</b>.</p> -</qt> - - - Unknown word: - - - - - - - Unknown word - - - <qt><p>This word was considered to be an "unknown word" because it does not match any entry in the dictionary currently in use. It may also be a word in a foreign language.</p> -<p>If the word is not misspelled, you may add it to the dictionary by clicking <b>Add to Dictionary</b>. If you do not want to add the unknown word to the dictionary, but you want to leave it unchanged, click <b>Ignore</b> or <b>Ignore All</b>.</p> -<p>However, if the word is misspelled, you can try to find the correct replacement in the list below. If you cannot find a replacement there, you may type it in the text box below, and click <b>Replace</b> or <b>Replace All</b>.</p> -</qt> - - - <b>misspelled</b> - - - - - - - <qt> -<p>Select the language of the document you are proofing here.</p> -</qt> - - - &Language: - - - m_language - - - - - - - Text excerpt showing the unknown word in its context. - - - <qt> -<p>Here you can see a text excerpt showing the unknown word in its context. If this information is not sufficient to choose the best replacement for the unknown word, you can click on the document you are proofing, read a larger part of the text and then return here to continue proofing.</p> -</qt> - - - QFrame::Box - - - ... the <b>misspelled</b> word shown in context ... - - - Qt::AlignCenter - - - - - - - <qt> -<p>The unknown word was detected and considered unknown because it is not included in the dictionary.<br> -Click here if you consider the unknown word not to be misspelled, and you want to avoid wrongly detecting it again in the future. If you want to let it remain as is, but not add it to the dictionary, then click <b>Ignore</b> or <b>Ignore All</b> instead.</p> -</qt> - - - << Add to Dictionary - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 74 - 20 - - - - - - - - Suggestion List - - - <qt> -<p>If the unknown word is misspelled, you should check if the correction for it is available and if it is, click on it. If none of the words in this list is a good replacement you may type the correct word in the edit box above.</p> -<p>To correct this word click <b>Replace</b> if you want to correct only this occurrence or <b>Replace All</b> if you want to correct all occurrences.</p> -</qt> - - - Adjust - - - - Suggested Words - - - - - - - - <qt> -<p>If the unknown word is misspelled, you should type the correction for your misspelled word here or select it from the list below.</p> -<p>You can then click <b>Replace</b> if you want to correct only this occurrence of the word or <b>Replace All</b> if you want to correct all occurrences.</p> -</qt> - - - Replace &with: - - - m_replacement - - - - - - - <qt> -<p>If the unknown word is misspelled, you should type the correction for your misspelled word here or select it from the list below.</p> -<p>You can then click <b>Replace</b> if you want to correct only this occurrence of the word or <b>Replace All</b> if you want to correct all occurrences.</p> -</qt> - - - - - - - Language Selection - - - <qt> -<p>Select the language of the document you are proofing here.</p> -</qt> - - - - - - - 0 - - - 6 - - - - - S&uggest - - - - - - - <qt> -<p>Click here to replace this occurrence of the unknown text with the text in the edit box above (to the left).</p> -</qt> - - - &Replace - - - - - - - <qt> -<p>Click here to replace all occurrences of the unknown text with the text in the edit box above (to the left).</p> -</qt> - - - R&eplace All - - - - - - - <qt> -<p>Click here to let this occurrence of the unknown word remain as is.</p> -<p>This action is useful when the word is a name, an acronym, a foreign word or any other unknown word that you want to use but not add to the dictionary.</p> -</qt> - - - &Ignore - - - - - - - <qt> -<p>Click here to let all occurrences of the unknown word remain as they are.</p> -<p>This action is useful when the word is a name, an acronym, a foreign word or any other unknown word that you want to use but not add to the dictionary.</p> -</qt> - - - I&gnore All - - - - - - - <qt> -<p>Click here to let all occurrences of the unknown word remain as they are.</p> -<p>This action is useful when the word is a name, an acronym, a foreign word or any other unknown word that you want to use but not add to the dictionary.</p> -</qt> - - - Autocorrect - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - - - m_addBtn - m_replacement - m_suggestBtn - m_replaceBtn - m_replaceAllBtn - m_skipBtn - m_skipAllBtn - m_suggestions - m_language - - - diff --git a/kdeui/sonnet/tests/CMakeLists.txt b/kdeui/sonnet/tests/CMakeLists.txt deleted file mode 100644 index 1ebe26fb..00000000 --- a/kdeui/sonnet/tests/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -########### next target ############### - -set(backgroundtest_SRCS backgroundtest.cpp) - -kde4_add_manual_test(backgroundtest ${backgroundtest_SRCS}) - -target_link_libraries(backgroundtest ${KDE4_KDEUI_LIBS}) - - -########### next target ############### - -set(test_dialog_SRCS test_dialog.cpp) - -kde4_add_manual_test(test_dialog ${test_dialog_SRCS}) - -target_link_libraries(test_dialog ${KDE4_KDEUI_LIBS} ) - - -########### next target ############### - -set(test_highlighter_SRCS test_highlighter.cpp) - -kde4_add_manual_test(test_highlighter ${test_highlighter_SRCS}) - -target_link_libraries(test_highlighter ${KDE4_KDEUI_LIBS} ) - - -########### next target ############### - -set(test_configdialog_SRCS test_configdialog.cpp) - -kde4_add_manual_test(test_configdialog ${test_configdialog_SRCS}) - -target_link_libraries(test_configdialog ${KDE4_KDEUI_LIBS} ) - -########### next target ############### - -kde4_add_manual_test(test_dictionarycombobox test_dictionarycombobox.cpp) - -target_link_libraries(test_dictionarycombobox ${KDE4_KDEUI_LIBS}) diff --git a/kdeui/sonnet/tests/backgroundtest.cpp b/kdeui/sonnet/tests/backgroundtest.cpp deleted file mode 100644 index 7381a04e..00000000 --- a/kdeui/sonnet/tests/backgroundtest.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/** - * backgroundtest.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "backgroundtest.h" -#include "moc_backgroundtest.cpp" - -#include "speller.h" -using namespace Sonnet; - -#include -#include -#include -const char *text = "Rationale \ -========= \ - \ -This code is intended to provide an implementation of the W3C's XPath \ -specification for KHTML. XPath isn't particularly useful on its own, however\ -it is an essential building block for the implementation of other standards \ -like XSLT and XQuery. XPath is supported to a greater or lesser extent by both\ -IE and Mozilla so it is likely to become increasingly important over the next\ -few years.\ - \ -Why write another XPath implementation? \ -======================================= \ - \ -The are already a number of XPath implementations available under free \ -licenses including Mozilla's, libxml2, Xerces and probably others, so it is \ -reasonable to ask why there should be another one. \ - \ -It would certainly be possible to integrate one of these implementations into\ -KHTML, but it would actually be quite a lot of work. I looked at all of the\ -implementations mentioned with a view to using this approach before I decided\ -to start from scratch.\ - \ -Mozilla XPath\ --------------\ - \ -Seems to be incomplete, and though the code was originally standalone it now\ -seems to be tied to the mozilla codebase quite tightly. This makes porting it\ -a lot of work, and makes working with the mozilla team on fixing bugs\ -etc. hard as the code bases would have diverged quite a lot.\ - \ -Xerces XPath (C++ version)\ ---------------------------\ - \ -The Xerces code seemed pretty clean and was reasonably understandable, however\ -it doesn't seem to be used very much which greatly reduces the utility. As\ -with the mozilla code, porting it to use KHTML's DOM would take a fair bit of \ -work. The main issue here being that Xerces is based around pointers to Nodes\ -rather than implicitly shared Node objects.\ - \ -libxml2 \ -------- \ - \ -This is the most obvious library to reuse as it is currently used to generate\ -the KDE documentation, and is also a very complete and fast\ -implementation. The down side of using this code is that it would either need\ -" -"a new DOM implementation in KHTML (which used the libxml2 structures), a \ -wrapper library that made on of the DOM trees support the API of the other, or\ -binding layer that parsed the XML twice and somehow maintained a mapping\ -between the two DOM trees. Unfortunately the documentation of this library is\ -less than great, which would add to the problems.\ - \ -The C++ wrappers to libxml2 are considerably closer to what I was looking\ -for. They are well documented and have a well structured API. Unfortunately\ -using this library still requires some mechanism to integrate the two\ -underlying DOM implementations.\ - \ -KHTML XPath\ ------------ \ - \ -There are some advantages to the XPath implementation Zack and I are working\ -on, namely: \ - \ -- Ease of integration with the rest of kjs/khtml.\ -- Use of dom2 traversal (which will also be available to use directly).\ -- C++ rather than C and a wrapper (reducing the overheads).\ -- The code is clean and uses familiar types and idioms. \ - \ -We intend the code to be build on top of the DOM api rather than tying it\ -directly to the Qt or KHTML XML implementations. This will allow us to take\ -advantage of any improvements that might be made to the underlying parser\ -etc. The DOM2 traversal APIs provide a set of classes that map almost directly \ -to the XPath location steps, since we need to implement these facilities\ -anyway writing the relatively small amount of code needed to support XPath\ -seems sensible.\ - \ -Building \ -========\ - \ -This code needs to live in a subdir off the khtml directory in kdelibs. The\ -subdir should be called 'xpath'. The easiest way to regenerate the makefiles\ -is to go to the root of the kdelibs tree and run: \ - create_makefiles khtml/xpath\ - \ -This code is intended to compile, but not to work.\ - \ -Usage \ -===== \ - \ -./test_xpath simple.xml\ -./test_values\ -./test_functions \ - \ -Notes\ -===== \ - \ -apidoc Duh! It's the docs \ -working Stuff that I'm mining for ideas\ -\ -Discussion\ -========== \ - \ -If you want to talk about this code feel free to mail us."; - -BackgroundTest::BackgroundTest() - : QObject( 0 ) -{ - m_checker = new BackgroundChecker(this); - connect(m_checker, SIGNAL(done()), - SLOT(slotDone())); - connect(m_checker, SIGNAL(misspelling(QString,int)), - SLOT(slotMisspelling(QString,int))); - m_len = strlen( text ); - m_checker->setText(text); - m_timer.start(); -} - -void BackgroundTest::slotDone() -{ - kDebug()<<"Text of length "<continueChecking(); -} - - -int main( int argc, char** argv ) -{ - KCmdLineArgs::init( argc, argv, "SonnetTest", 0, ki18n("SonnetTest"), 0 ); - KApplication app; - - BackgroundTest test; - - return app.exec(); -} diff --git a/kdeui/sonnet/tests/backgroundtest.h b/kdeui/sonnet/tests/backgroundtest.h deleted file mode 100644 index 79ebcf12..00000000 --- a/kdeui/sonnet/tests/backgroundtest.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * backgroundtest.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef BACKGROUNDTEST_H -#define BACKGROUNDTEST_H - -#include -#include - -#include "backgroundchecker.h" - -class BackgroundTest : public QObject -{ - Q_OBJECT -public: - BackgroundTest(); - -protected Q_SLOTS: - void slotDone(); - void slotMisspelling( const QString& word, int start ); - -private: - Sonnet::BackgroundChecker *m_checker; - QElapsedTimer m_timer; - int m_len; -}; - -#endif diff --git a/kdeui/sonnet/tests/test_config.cpp b/kdeui/sonnet/tests/test_config.cpp deleted file mode 100644 index 14656af8..00000000 --- a/kdeui/sonnet/tests/test_config.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/** - * test_config.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "configdialog.h" - -#include -#include -using namespace Sonnet; - -int main( int argc, char** argv ) -{ - KCmdLineArgs::init( argc, argv, "SonnetTest", 0, ki18n("SonnetTest"), 0 ); - - KApplication app(argc, argv, "SonnetTest"); - - SettingsDialog *dialog = new SettingsDialog( 0 ); - - dialog->show(); - - app.setMainWidget( dialog ); - - return app.exec(); -} diff --git a/kdeui/sonnet/tests/test_configdialog.cpp b/kdeui/sonnet/tests/test_configdialog.cpp deleted file mode 100644 index 6f2f16e7..00000000 --- a/kdeui/sonnet/tests/test_configdialog.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - * test_configdialog.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "configdialog.h" -#include "speller.h" - -#include -#include -#include -#include -using namespace Sonnet; - -int main( int argc, char** argv ) -{ - //KApplication::disableAutoDcopRegistration(); - KCmdLineArgs::init( argc, argv, "test_configdialog", 0, ki18n("test_configdialog"), 0); - KApplication app; // with GUI - - KConfig config("sonnetrc"); - ConfigDialog *dialog = new ConfigDialog(&config, 0); - - dialog->show(); - - return app.exec(); -} diff --git a/kdeui/sonnet/tests/test_dialog.cpp b/kdeui/sonnet/tests/test_dialog.cpp deleted file mode 100644 index 52e86d1d..00000000 --- a/kdeui/sonnet/tests/test_dialog.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * test_dialog.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "test_dialog.h" -#include "moc_test_dialog.cpp" - -#include "backgroundchecker.h" - -#include -#include -#include -using namespace Sonnet; - -TestDialog::TestDialog() - : QObject(0) -{ -} - -void TestDialog::check( const QString& buffer ) -{ - Sonnet::Dialog *dlg = new Sonnet::Dialog( - new BackgroundChecker(this), 0); - connect(dlg, SIGNAL(done(QString)), - SLOT(doneChecking(QString))); - dlg->setBuffer(buffer); - dlg->show(); -} - -void TestDialog::doneChecking( const QString& buf ) -{ - kDebug()<<"Done with :"<quit(); -} - -int main( int argc, char** argv ) -{ - //KApplication::disableAutoDcopRegistration(); - KCmdLineArgs::init( argc, argv, "test_dialog", 0, ki18n("test_dialog"), 0); - KApplication app; // with GUI - - TestDialog test; - test.check( "This is a sample buffer. Whih this thingg will " - "be checkin for misstakes. Whih, Enviroment, govermant. Whih." - ); - - return app.exec(); -} diff --git a/kdeui/sonnet/tests/test_dialog.h b/kdeui/sonnet/tests/test_dialog.h deleted file mode 100644 index 542d3771..00000000 --- a/kdeui/sonnet/tests/test_dialog.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * test_dialog.h - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef TEST_DIALOG_H -#define TEST_DIALOG_H - -#include "dialog.h" -#include "loader_p.h" - -#include - -class TestDialog : public QObject -{ - Q_OBJECT -public: - TestDialog(); - -public Q_SLOTS: - void check( const QString& buffer ); - void doneChecking( const QString& ); -}; - -#endif diff --git a/kdeui/sonnet/tests/test_dictionarycombobox.cpp b/kdeui/sonnet/tests/test_dictionarycombobox.cpp deleted file mode 100644 index 00a92a4d..00000000 --- a/kdeui/sonnet/tests/test_dictionarycombobox.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "dictionarycombobox.h" - -#include -#include -#include - -#include -#include - -using namespace Sonnet; - -class DictionaryComboBoxTest : public QWidget -{ - Q_OBJECT - public: - DictionaryComboBoxTest() - { - QHBoxLayout *topLayout = new QHBoxLayout( this ); - dcb = new DictionaryComboBox( this ); - topLayout->addWidget( dcb ); - connect( dcb, SIGNAL(dictionaryChanged(QString)), SLOT(dictChanged(QString)) ); - connect( dcb, SIGNAL(dictionaryNameChanged(QString)), SLOT(dictNameChanged(QString)) ); - QPushButton *btn = new QPushButton( "Dump", this ); - topLayout->addWidget( btn ); - connect( btn, SIGNAL(clicked()), SLOT(dump()) ); - } - - public slots: - void dump() - { - kDebug() << "Current dictionary: " << dcb->currentDictionary(); - kDebug() << "Current dictionary name: " << dcb->currentDictionaryName(); - } - - void dictChanged( const QString &name ) - { - kDebug() << "Current dictionary changed: " << name; - } - - void dictNameChanged( const QString &name ) - { - kDebug() << "Current dictionary name changed: " << name; - } - - private: - DictionaryComboBox *dcb; -}; - -int main( int argc, char** argv ) -{ - KCmdLineArgs::init( argc, argv, "SonnetTest", 0, ki18n("SonnetTest"), 0 ); - KApplication app; - - DictionaryComboBoxTest *test = new DictionaryComboBoxTest(); - test->show(); - - return app.exec(); -} - -#include "test_dictionarycombobox.moc" diff --git a/kdeui/sonnet/tests/test_highlighter.cpp b/kdeui/sonnet/tests/test_highlighter.cpp deleted file mode 100644 index 556bf428..00000000 --- a/kdeui/sonnet/tests/test_highlighter.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * test_highlighter.cpp - * - * Copyright (C) 2004 Zack Rusin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "highlighter.h" -#include "test_highlighter.h" -#include "moc_test_highlighter.cpp" -#include "filter_p.h" - -#include -#include -#include -#include -#include -#include -#include - -TestSpell::TestSpell() - : QTextEdit() -{ - hl = new Sonnet::Highlighter( this ); -} - -void TestSpell::contextMenuEvent(QContextMenuEvent *e) -{ - kDebug()<<"TestSpell::contextMenuEvent\n"; - QMenu *popup = createStandardContextMenu(); - QMenu *subMenu = new QMenu( popup ); - subMenu->setTitle( "Text highlighting" ); - connect( subMenu, SIGNAL(triggered(QAction*)),this, SLOT(slotActivate()) ); - QAction *action = new QAction( "active or not", popup ); - popup->addSeparator(); - popup->addMenu( subMenu ); - subMenu->addAction(action); - popup->exec(e->globalPos()); - delete popup; -} - -void TestSpell::slotActivate() -{ - kDebug()<<"Activate or not highlight :"; - hl->setActive(!hl->isActive()); -} - -int main( int argc, char** argv ) -{ - KCmdLineArgs::init( argc, argv, "SonnetTest", 0, ki18n("SonnetTest"), 0 ); - - KApplication app; - - QTextEdit *test = new TestSpell(); - test->show(); - - return app.exec(); -} diff --git a/kdeui/sonnet/tests/test_highlighter.h b/kdeui/sonnet/tests/test_highlighter.h deleted file mode 100644 index bd1e188e..00000000 --- a/kdeui/sonnet/tests/test_highlighter.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * test_highlighter.h - * - * Copyright (C) 2006 Laurent Montel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef KTESTSPELL_H -#define KTESTSPELL_H - -#include "highlighter.h" -#include "filter_p.h" -#include - -#include -class TestSpell : public QTextEdit -{ - Q_OBJECT -public: - TestSpell(); -public Q_SLOTS: - void slotActivate(); -protected: - virtual void contextMenuEvent( QContextMenuEvent * ); - Sonnet::Highlighter *hl; -}; -#endif diff --git a/kdeui/spell/kspellbackgroundchecker.cpp b/kdeui/spell/kspellbackgroundchecker.cpp new file mode 100644 index 00000000..cb52638f --- /dev/null +++ b/kdeui/spell/kspellbackgroundchecker.cpp @@ -0,0 +1,165 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kspellbackgroundchecker.h" +#include "kspeller.h" +#include "kdebug.h" + +#include +#include + +class KSpellBackgroundCheckerThread : public QThread +{ + Q_OBJECT +public: + KSpellBackgroundCheckerThread(KConfig *config, QObject *parent, const QString &lang, const QString &text); + + void run() final; + + void interrupt(); + +Q_SIGNALS: + void misspelling(const QString &word, int start); + +private: + bool m_interrupt; + QString m_text; + KSpeller m_speller; +}; + +KSpellBackgroundCheckerThread::KSpellBackgroundCheckerThread(KConfig *config, QObject *parent, const QString &lang, const QString &text) + : QThread(parent), + m_interrupt(false), + m_text(text), + m_speller(config) +{ + // qDebug() << Q_FUNC_INFO << lang; + m_speller.setDictionary(lang); +} + +void KSpellBackgroundCheckerThread::run() +{ + // qDebug() << Q_FUNC_INFO << m_text.size() << m_text; + QTextBoundaryFinder finder(QTextBoundaryFinder::Word, m_text); + int wordstart = 0; + while (finder.toNextBoundary() >= 0) { + if (m_interrupt) { + break; + } + QTextBoundaryFinder::BoundaryReasons boundary = finder.boundaryReasons(); + if (boundary & QTextBoundaryFinder::StartWord) { + wordstart = finder.position(); + } + if (boundary & QTextBoundaryFinder::EndWord) { + QString word = m_text.mid(wordstart, finder.position() - wordstart); + if (word.size() < 2) { + continue; + } + if (word.at(word.size() - 1).isPunct()) { + word = word.mid(0, word.size() - 1); + } + // qDebug() << Q_FUNC_INFO << boundary << wordstart << finder.position() << word; + if (!m_speller.check(word)) { + emit misspelling(word, wordstart); + } + } + } +} + +void KSpellBackgroundCheckerThread::interrupt() +{ + m_interrupt = true; +} + +class KSpellBackgroundCheckerPrivate +{ +public: + KSpellBackgroundCheckerPrivate(KConfig *config); + + QString text; + QString language; + KSpellBackgroundCheckerThread* spellerthread; + KConfig* spellerconfig; +}; + +KSpellBackgroundCheckerPrivate::KSpellBackgroundCheckerPrivate(KConfig *config) + : spellerthread(nullptr), + spellerconfig(config) +{ +} + +KSpellBackgroundChecker::KSpellBackgroundChecker(KConfig *config, QObject *parent) + : QObject(parent), + d(new KSpellBackgroundCheckerPrivate(config)) +{ + d->language = KSpeller::defaultLanguage(); +} + +KSpellBackgroundChecker::~KSpellBackgroundChecker() +{ + delete d; +} + +void KSpellBackgroundChecker::setText(const QString &text) +{ + d->text = text; + start(); +} + +QString KSpellBackgroundChecker::text() const +{ + return d->text; +} + +void KSpellBackgroundChecker::start() +{ + stop(); + // qDebug() << Q_FUNC_INFO; + d->spellerthread = new KSpellBackgroundCheckerThread(d->spellerconfig, this, d->language, d->text); + connect( + d->spellerthread, SIGNAL(finished()), + this, SIGNAL(done()) + ); + connect( + d->spellerthread, SIGNAL(misspelling(QString,int)), + this, SIGNAL(misspelling(QString,int)) + ); + d->spellerthread->start(); +} + +void KSpellBackgroundChecker::stop() +{ + // qDebug() << Q_FUNC_INFO << d->spellerthread; + if (d->spellerthread) { + d->spellerthread->interrupt(); + d->spellerthread->deleteLater(); + d->spellerthread = nullptr; + } +} + +void KSpellBackgroundChecker::changeLanguage(const QString &lang) +{ + d->language = lang; + if (d->language.isEmpty()) { + kWarning() << "Attempting to set language to empty"; + d->language = KSpeller::defaultLanguage(); + } +} + +#include "moc_kspellbackgroundchecker.cpp" +#include "kspellbackgroundchecker.moc" diff --git a/kdeui/spell/kspellbackgroundchecker.h b/kdeui/spell/kspellbackgroundchecker.h new file mode 100644 index 00000000..188f5f96 --- /dev/null +++ b/kdeui/spell/kspellbackgroundchecker.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSPELLBACKGROUNDCHECKER_H +#define KSPELLBACKGROUNDCHECKER_H + +#include "kdeui_export.h" +#include "kconfig.h" + +#include + +class KSpellBackgroundCheckerPrivate; + +/*! + Class to check spelling in the background. + + @since 4.23 +*/ +class KDEUI_EXPORT KSpellBackgroundChecker : public QObject +{ + Q_OBJECT +public: + KSpellBackgroundChecker(KConfig *config, QObject *parent = nullptr); + ~KSpellBackgroundChecker(); + + void setText(const QString &text); + QString text() const; + +public Q_SLOTS: + void start(); + void stop(); + void changeLanguage(const QString &lang); + +Q_SIGNALS: + void misspelling(const QString &word, int start); + void done(); + +private: + Q_DISABLE_COPY(KSpellBackgroundChecker); + KSpellBackgroundCheckerPrivate *d; +}; + +#endif // KSPELLBACKGROUNDCHECKER_H diff --git a/kdeui/spell/kspellconfigwidget.cpp b/kdeui/spell/kspellconfigwidget.cpp new file mode 100644 index 00000000..0b7fb2ab --- /dev/null +++ b/kdeui/spell/kspellconfigwidget.cpp @@ -0,0 +1,131 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kspellconfigwidget.h" +#include "kspeller.h" +#include "kspelldictionarycombobox.h" +#include "kconfig.h" +#include "kconfiggroup.h" +#include "klocale.h" +#include "keditlistwidget.h" +#include "klineedit.h" +#include "kdebug.h" + +#include +#include +#include +#include + +class KSpellConfigWidgetPrivate +{ +public: + KSpellConfigWidgetPrivate(KConfig *config); + + KConfig* config; + QCheckBox* enablebox; + KSpellDictionaryComboBox* dictionarybox; + KEditListWidget* wordslistedit; +}; + +KSpellConfigWidgetPrivate::KSpellConfigWidgetPrivate(KConfig *kconfig) + : config(kconfig), + enablebox(nullptr), + dictionarybox(nullptr), + wordslistedit(nullptr) +{ +} + +KSpellConfigWidget::KSpellConfigWidget(KConfig *config, QWidget *parent) + : QWidget(parent), + d(new KSpellConfigWidgetPrivate(config)) +{ + QVBoxLayout* layout = new QVBoxLayout(this); + + QGroupBox* dictionarygroup = new QGroupBox(this); + dictionarygroup->setTitle(i18n("General")); + QGridLayout* dictionarylayout = new QGridLayout(dictionarygroup); + d->enablebox = new QCheckBox(this); + d->enablebox->setText(i18n("Automatic spell checking enabled by default")); + dictionarylayout->addWidget(d->enablebox, 0, 0, 1, 2); + QLabel* dictionarylabel = new QLabel(i18n("Default language:"), d->dictionarybox); + dictionarylayout->addWidget(dictionarylabel, 1, 0); + d->dictionarybox = new KSpellDictionaryComboBox(d->dictionarybox); + d->dictionarybox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + dictionarylayout->addWidget(d->dictionarybox, 1, 1); + + QGroupBox* wordgroup = new QGroupBox(this); + wordgroup->setTitle(i18n("Ignored Words")); + QGridLayout* wordlayout = new QGridLayout(wordgroup); + d->wordslistedit = new KEditListWidget(wordgroup); + d->wordslistedit->lineEdit()->setPlaceholderText(i18n("Type word here to add it to the personal ignore list")); + wordlayout->addWidget(d->wordslistedit, 0, 0); + + layout->addWidget(dictionarygroup); + layout->addWidget(wordgroup); + + connect( + d->enablebox, SIGNAL(stateChanged(int)), + this, SIGNAL(configChanged()) + ); + connect( + d->dictionarybox, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(configChanged()) + ); + connect( + d->wordslistedit, SIGNAL(changed()), + this, SIGNAL(configChanged()) + ); + + if (!config) { + kWarning() << "Null config passed"; + return; + } + KConfigGroup spellgroup = config->group("Spelling"); + d->enablebox->setChecked(spellgroup.readEntry("checkerEnabledByDefault", false)); + d->dictionarybox->setCurrentByDictionary(spellgroup.readEntry("defaultLanguage", KSpeller::defaultLanguage())); + d->wordslistedit->setItems(spellgroup.readEntry("personalWords", QStringList())); +} + +KSpellConfigWidget::~KSpellConfigWidget() +{ + delete d; +} + +void KSpellConfigWidget::save() +{ + if (!d->config) { + return; + } + KConfigGroup spellgroup = d->config->group("Spelling"); + spellgroup.writeEntry("checkerEnabledByDefault", d->enablebox->isChecked()); + spellgroup.writeEntry("defaultLanguage", d->dictionarybox->currentDictionary()); + spellgroup.writeEntry("personalWords", d->wordslistedit->items()); +} + +void KSpellConfigWidget::slotDefault() +{ + if (!d->config) { + return; + } + KConfigGroup spellgroup = d->config->group("Spelling"); + spellgroup.writeEntry("checkerEnabledByDefault", false); + spellgroup.writeEntry("defaultLanguage", KSpeller::defaultLanguage()); + spellgroup.writeEntry("personalWords", QStringList()); +} + +#include "moc_kspellconfigwidget.cpp" diff --git a/kdeui/spell/kspellconfigwidget.h b/kdeui/spell/kspellconfigwidget.h new file mode 100644 index 00000000..a9b80fe3 --- /dev/null +++ b/kdeui/spell/kspellconfigwidget.h @@ -0,0 +1,53 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSPELLCONFIGWIDGET_H +#define KSPELLCONFIGWIDGET_H + +#include "kdeui_export.h" +#include "kconfig.h" + +#include + +class KSpellConfigWidgetPrivate; + +/*! + Widget to show and change spelling configuration. + + @since 4.23 +*/ +class KDEUI_EXPORT KSpellConfigWidget : public QWidget +{ + Q_OBJECT +public: + KSpellConfigWidget(KConfig *config, QWidget *parent = nullptr); + ~KSpellConfigWidget(); + +public Q_SLOTS: + void save(); + void slotDefault(); + +Q_SIGNALS: + void configChanged(); + +private: + Q_DISABLE_COPY(KSpellConfigWidget); + KSpellConfigWidgetPrivate *d; +}; + +#endif // KSPELLCONFIGWIDGET_H diff --git a/kdeui/spell/kspelldialog.cpp b/kdeui/spell/kspelldialog.cpp new file mode 100644 index 00000000..9444b157 --- /dev/null +++ b/kdeui/spell/kspelldialog.cpp @@ -0,0 +1,308 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kspelldialog.h" +#include "kspeller.h" +#include "klocale.h" +#include "klistwidget.h" +#include "kpushbutton.h" +#include "kmessagebox.h" +#include "kdebug.h" + +#include +#include +#include +#include +#include + +class KSpellDialogThread : public QThread +{ + Q_OBJECT +public: + KSpellDialogThread(QObject *parent, KSpeller *speller, const QString &text); + + void run() final; + + void interrupt(); + + void findNext(); + int position() const; + +Q_SIGNALS: + void foundWord(const QString &word); + void atEnd(); + +private: + bool m_interrupt; + QString m_text; + KSpeller* m_speller; + QTextBoundaryFinder m_finder; + bool m_findprevious; + bool m_findnext; + int m_wordstart; +}; + +KSpellDialogThread::KSpellDialogThread(QObject *parent, KSpeller *speller, const QString &text) + : QThread(parent), + m_interrupt(false), + m_text(text), + m_speller(speller), + m_finder(QTextBoundaryFinder::Word, text), + m_findnext(false), + m_wordstart(0) +{ + // qDebug() << Q_FUNC_INFO << lang; +} + +void KSpellDialogThread::run() +{ + while (!m_interrupt) { + if (m_findnext) { + // kDebug() << "Looking for the next word"; + const int finderresult = m_finder.toNextBoundary(); + if (finderresult < 0) { + m_findnext = false; + emit atEnd(); + continue; + } + + QTextBoundaryFinder::BoundaryReasons boundary = m_finder.boundaryReasons(); + if (boundary & QTextBoundaryFinder::StartWord) { + m_wordstart = m_finder.position(); + } + if (boundary & QTextBoundaryFinder::EndWord) { + QString word = m_text.mid(m_wordstart, m_finder.position() - m_wordstart); + if (word.size() < 2) { + continue; + } + if (word.at(word.size() - 1).isPunct()) { + word = word.mid(0, word.size() - 1); + } + // qDebug() << Q_FUNC_INFO << boundary << m_wordstart << m_finder.position() << word; + if (!m_speller->check(word)) { + m_findnext = false; + emit foundWord(word); + } + } + } else { + // kDebug() << "Busy loop for 200ms"; + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + QThread::msleep(100); + } + } +} + +void KSpellDialogThread::interrupt() +{ + m_interrupt = true; +} + +void KSpellDialogThread::findNext() +{ + m_findnext = true; +} + +int KSpellDialogThread::position() const +{ + return m_finder.position(); +} + +class KSpellDialogPrivate +{ +public: + KSpellDialogPrivate(KConfig *config); + + QWidget* dialogwidget; + QGridLayout* layout; + QLabel* misspelledlabel; + QLabel* wordlabel; + KListWidget* suggestionswidget; + KPushButton* correctbutton; + KPushButton* nextbutton; + bool showcompletionmessage; + bool continueaftercorrect; + QString text; + KSpeller speller; + KSpellDialogThread* spellerthread; +}; + +KSpellDialogPrivate::KSpellDialogPrivate(KConfig *config) + : dialogwidget(nullptr), + layout(nullptr), + misspelledlabel(nullptr), + wordlabel(nullptr), + suggestionswidget(nullptr), + correctbutton(nullptr), + nextbutton(nullptr), + showcompletionmessage(false), + continueaftercorrect(false), + speller(config), + spellerthread(nullptr) +{ +} + +KSpellDialog::KSpellDialog(KConfig *config, QWidget *parent) + : KDialog(parent), + d(new KSpellDialogPrivate(config)) +{ + d->dialogwidget = new QWidget(this); + d->layout = new QGridLayout(d->dialogwidget); + d->layout->setSpacing(KDialog::spacingHint()); + + d->misspelledlabel = new QLabel(i18n("Misspelled word:"), this); + d->layout->addWidget(d->misspelledlabel, 0, 0); + d->wordlabel = new QLabel(QString::fromLatin1("..."), this); + d->wordlabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + d->layout->addWidget(d->wordlabel, 0, 1); + + d->suggestionswidget = new KListWidget(this); + d->layout->addWidget(d->suggestionswidget, 1, 0, 5, 1); + + d->correctbutton = new KPushButton(i18n("Correct"), this); + d->correctbutton->setIcon(KIcon("edit-node")); // TODO: or tools-check-spelling? + connect( + d->correctbutton, SIGNAL(pressed()), + this, SLOT(_correct()) + ); + d->layout->addWidget(d->correctbutton, 1, 1); + + d->nextbutton = new KPushButton(i18n("Next"), this); + d->nextbutton->setIcon(KIcon("go-next")); + connect( + d->nextbutton, SIGNAL(pressed()), + this, SLOT(_next()) + ); + d->layout->addWidget(d->nextbutton, 2, 1); + + setMainWidget(d->dialogwidget); +} + +KSpellDialog::~KSpellDialog() +{ + if (d->spellerthread) { + d->spellerthread->interrupt(); + d->spellerthread->wait(); + delete d->spellerthread; + } + delete d; +} + +void KSpellDialog::showSpellCheckCompletionMessage(bool b) +{ + d->showcompletionmessage = b; +} + +void KSpellDialog::setSpellCheckContinuedAfterReplacement(bool b) +{ + d->continueaftercorrect = b; +} + +QString KSpellDialog::buffer() const +{ + return d->text; +} + +void KSpellDialog::setBuffer(const QString &buffer) +{ + d->text = buffer; + if (d->spellerthread) { + d->spellerthread->interrupt(); + d->spellerthread->wait(); + delete d->spellerthread; + } + d->spellerthread = new KSpellDialogThread(this, &d->speller, d->text); + connect( + d->spellerthread, SIGNAL(foundWord(QString)), + this, SLOT(_suggest(QString)) + ); + connect( + d->spellerthread, SIGNAL(atEnd()), + this, SLOT(_done()) + ); + d->spellerthread->start(); + _next(); +} + +void KSpellDialog::changeLanguage(const QString &lang) +{ + d->speller.setDictionary(lang); + emit languageChanged(lang); +} + +void KSpellDialog::slotButtonClicked(int button) +{ + if (d->spellerthread) { + d->spellerthread->interrupt(); + d->spellerthread->wait(); + delete d->spellerthread; + d->spellerthread = nullptr; + } + KDialog::slotButtonClicked(button); +} + +void KSpellDialog::_correct() +{ + QListWidgetItem* suggestionitem = d->suggestionswidget->currentItem(); + Q_ASSERT(suggestionitem); + const QString word = d->wordlabel->text(); + emit replace(word, d->spellerthread->position() - word.size(), suggestionitem->text()); + if (d->continueaftercorrect) { + kDebug() << "Spell checking continues.."; + _next(); + } +} + +void KSpellDialog::_next() +{ + Q_ASSERT(d->spellerthread); + kDebug() << "Looking for the next word"; + d->spellerthread->findNext(); +} + +void KSpellDialog::_done() +{ + kDebug() << "Done checking"; + Q_ASSERT(d->spellerthread); + d->spellerthread->interrupt(); + d->spellerthread->wait(); + delete d->spellerthread; + d->spellerthread = nullptr; + KMessageBox::information(this, i18n("Spell check complete."), i18nc("@title:window", "Check Spelling")); + KDialog::accept(); +} + +void KSpellDialog::_suggest(const QString &word) +{ + kDebug() << "Got a word from the checker" << word; + d->wordlabel->setText(word); + d->suggestionswidget->clear(); + const QStringList suggestions = d->speller.suggest(word); + foreach (const QString &suggestion, suggestions) { + d->suggestionswidget->addItem(suggestion); + } + if (suggestions.isEmpty()) { + d->correctbutton->setEnabled(false); + } else { + d->correctbutton->setEnabled(true); + d->suggestionswidget->setCurrentRow(0); + } + emit misspelling(word, d->spellerthread->position() - word.size()); +} + +#include "moc_kspelldialog.cpp" +#include "kspelldialog.moc" diff --git a/kdeui/spell/kspelldialog.h b/kdeui/spell/kspelldialog.h new file mode 100644 index 00000000..35e94da2 --- /dev/null +++ b/kdeui/spell/kspelldialog.h @@ -0,0 +1,68 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSPELLDIALOG_H +#define KSPELLDIALOG_H + +#include "kdeui_export.h" +#include "kdialog.h" + +class KSpellDialogPrivate; + +/*! + Dialog to check spelling and apply correction interactively. + + @since 4.23 +*/ +class KDEUI_EXPORT KSpellDialog : public KDialog +{ + Q_OBJECT +public: + KSpellDialog(KConfig *config, QWidget *parent = nullptr); + ~KSpellDialog(); + + void showSpellCheckCompletionMessage(bool b = true); + void setSpellCheckContinuedAfterReplacement(bool b); + + QString buffer() const; + +public Q_SLOTS: + void setBuffer(const QString &buffer); + void changeLanguage(const QString &lang); + +Q_SIGNALS: + void misspelling(const QString &word, int start); + void replace(const QString &oldWord, int start, const QString &newWord); + void languageChanged(const QString &language); + +protected Q_SLOTS: + // reimplementation + virtual void slotButtonClicked(int button); + +private Q_SLOTS: + void _correct(); + void _next(); + void _done(); + void _suggest(const QString &word); + +private: + Q_DISABLE_COPY(KSpellDialog); + KSpellDialogPrivate *d; +}; + +#endif // KSPELLDIALOG_H diff --git a/kdeui/spell/kspelldictionarycombobox.cpp b/kdeui/spell/kspelldictionarycombobox.cpp new file mode 100644 index 00000000..4e265e0f --- /dev/null +++ b/kdeui/spell/kspelldictionarycombobox.cpp @@ -0,0 +1,71 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kspelldictionarycombobox.h" +#include "kspeller.h" +#include "kglobal.h" +#include "klocale.h" +#include "kdebug.h" + +KSpellDictionaryComboBox::KSpellDictionaryComboBox(QWidget *parent) + : KComboBox(parent) +{ + const QStringList dictionaries = KSpeller(KGlobal::config().data()).dictionaries(); + foreach (const QString &dictionary, dictionaries) { + const int underscoreindex = dictionary.indexOf(QLatin1Char('_')); + if (underscoreindex > 0) { + const QString language = dictionary.mid(0, underscoreindex); + const QString country = dictionary.mid(underscoreindex + 1, dictionary.size() - underscoreindex - 1); + // qDebug() << Q_FUNC_INFO << dictionary << language << country; + const QString dictionarytext = QString::fromLatin1("%1 (%2)") + .arg(KGlobal::locale()->languageCodeToName(language)) + .arg(KGlobal::locale()->countryCodeToName(country)); + KComboBox::addItem(dictionarytext, dictionary); + } else { + KComboBox::addItem(KGlobal::locale()->languageCodeToName(dictionary), dictionary); + } + } + connect( + this, SIGNAL(currentIndexChanged(int)), + this, SLOT(_dictionaryChanged(int)) + ); + connect( + this, SIGNAL(currentIndexChanged(QString)), + this, SIGNAL(dictionaryNameChanged(QString)) + ); +} + +QString KSpellDictionaryComboBox::currentDictionary() const +{ + return KComboBox::itemData(KComboBox::currentIndex()).toString(); +} + +void KSpellDictionaryComboBox::setCurrentByDictionary(const QString &dictionary) +{ + const int dictionaryindex = KComboBox::findData(dictionary); + if (dictionaryindex >= 0) { + KComboBox::setCurrentIndex(dictionaryindex); + } +} + +void KSpellDictionaryComboBox::_dictionaryChanged(const int index) +{ + emit dictionaryChanged(KComboBox::itemData(index).toString()); +} + +#include "moc_kspelldictionarycombobox.cpp" diff --git a/kdeui/spell/kspelldictionarycombobox.h b/kdeui/spell/kspelldictionarycombobox.h new file mode 100644 index 00000000..266a4cf7 --- /dev/null +++ b/kdeui/spell/kspelldictionarycombobox.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSPELLDICTIONARYCOMBOBOX_H +#define KSPELLDICTIONARYCOMBOBOX_H + +#include "kdeui_export.h" +#include "kcombobox.h" + +/*! + Widget to show and choose from available spelling dictionaries. + + @since 4.23 +*/ +class KDEUI_EXPORT KSpellDictionaryComboBox : public KComboBox +{ + Q_OBJECT +public: + KSpellDictionaryComboBox(QWidget *parent = nullptr); + + QString currentDictionary() const; + void setCurrentByDictionary(const QString &dictionary); + +Q_SIGNALS: + void dictionaryChanged(const QString &dictionary); + void dictionaryNameChanged(const QString &dictionaryName); + +private Q_SLOTS: + void _dictionaryChanged(const int index); +}; + +#endif // KSPELLDICTIONARYCOMBOBOX_H diff --git a/kdeui/spell/kspeller.cpp b/kdeui/spell/kspeller.cpp new file mode 100644 index 00000000..82acb6d0 --- /dev/null +++ b/kdeui/spell/kspeller.cpp @@ -0,0 +1,247 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kspeller.h" +#include "kconfiggroup.h" +#include "kdebug.h" + +#include + +#include + +class KSpellerPrivate +{ +public: + KSpellerPrivate(KConfig *config); + ~KSpellerPrivate(); + + static void dictsCallback(const char* const lang_tag, + const char* const provider_name, + const char* const provider_desc, + const char* const provider_file, + void* user_data); + + KConfig* config; + QString dictionary; + QStringList dictionaries; + QStringList personalwords; + + EnchantBroker* enchantbroker; + EnchantDict* enchantdict; +}; + +KSpellerPrivate::KSpellerPrivate(KConfig *kconfig) + : config(kconfig), + enchantbroker(nullptr), + enchantdict(nullptr) +{ + enchantbroker = enchant_broker_init(); + if (!enchantbroker) { + kWarning() << "Could not create broker"; + return; + } + enchant_broker_list_dicts( + enchantbroker, + KSpellerPrivate::dictsCallback, + this + ); +} + +KSpellerPrivate::~KSpellerPrivate() +{ + if (enchantbroker) { + if (enchantdict) { + enchant_broker_free_dict(enchantbroker, enchantdict); + } + enchant_broker_free(enchantbroker); + } +} + +void KSpellerPrivate::dictsCallback(const char* const lang_tag, + const char* const provider_name, + const char* const provider_desc, + const char* const provider_file, + void* user_data) +{ + // qDebug() << Q_FUNC_INFO << lang_tag << provider_name << provider_desc << provider_file; + Q_UNUSED(provider_name); + Q_UNUSED(provider_desc); + Q_UNUSED(provider_file); + KSpellerPrivate* kspellprivate = static_cast(user_data); + Q_ASSERT(kspellprivate); + kspellprivate->dictionaries.append(QString::fromLatin1(lang_tag)); +} + +KSpeller::KSpeller(KConfig *config, QObject *parent) + : QObject(parent), + d(new KSpellerPrivate(config)) +{ + if (!config) { + setDictionary(KSpeller::defaultLanguage()); + kWarning() << "Null config passed"; + return; + } + KConfigGroup spellgroup = config->group("Spelling"); + setDictionary(spellgroup.readEntry("defaultLanguage", KSpeller::defaultLanguage())); + const QStringList personalWords = spellgroup.readEntry("personalWords", QStringList()); + foreach (const QString &word, personalWords) { + addToPersonal(word); + } +} + +KSpeller::~KSpeller() +{ + if (d->config) { + KConfigGroup spellgroup = d->config->group("Spelling"); + spellgroup.writeEntry("personalWords", d->personalwords); + } + delete d; +} + +QString KSpeller::dictionary() const +{ + return d->dictionary; +} + +QStringList KSpeller::dictionaries() const +{ + return d->dictionaries; +} + +bool KSpeller::setDictionary(const QString &dictionary) +{ + if (!d->enchantbroker || dictionary.isEmpty()) { + return false; + } + if (d->enchantdict) { + enchant_broker_free_dict(d->enchantbroker, d->enchantdict); + d->enchantdict = nullptr; + } + const QByteArray dictionarybytes = dictionary.toUtf8(); + d->enchantdict = enchant_broker_request_dict(d->enchantbroker, dictionarybytes.constData()); + if (!d->enchantdict) { + kWarning() << "Could not create dictionary" << enchant_broker_get_error(d->enchantbroker); + return false; + } + d->dictionary = dictionary; + return true; +} + +bool KSpeller::check(const QString &word) +{ + if (!d->enchantdict) { + return true; + } + const QByteArray wordbytes = word.toUtf8(); + const int enchantresult = enchant_dict_check( + d->enchantdict, + wordbytes.constData(), wordbytes.size() + ); + if (enchantresult < 0) { + kWarning() << "Could not check word" << enchant_dict_get_error(d->enchantdict); + return true; + } + return (enchantresult == 0); +} + +QStringList KSpeller::suggest(const QString &word) +{ + QStringList result; + if (!d->enchantdict) { + return result; + } + const QByteArray wordbytes = word.toUtf8(); + size_t enchantsuggestions = 0; + char **enchantwords = enchant_dict_suggest( + d->enchantdict, + wordbytes.constData(), wordbytes.size(), + &enchantsuggestions + ); + for (size_t i = 0; i < enchantsuggestions; i++) { + result.append(QString::fromUtf8(enchantwords[i])); + ::free(enchantwords[i]); + } + return result; +} + +bool KSpeller::addToPersonal(const QString &word) +{ + if (!d->enchantdict) { + return false; + } + const QByteArray wordbytes = word.toUtf8(); + enchant_dict_add( + d->enchantdict, + wordbytes.constData(), wordbytes.size() + ); + d->personalwords.append(word); + return true; +} + +bool KSpeller::removeFromPersonal(const QString &word) +{ + if (!d->enchantdict) { + return false; + } + const QByteArray wordbytes = word.toUtf8(); + enchant_dict_remove( + d->enchantdict, + wordbytes.constData(), wordbytes.size() + ); + d->personalwords.removeAll(word); + return true; +} +bool KSpeller::addToSession(const QString &word) +{ + if (!d->enchantdict) { + return false; + } + const QByteArray wordbytes = word.toUtf8(); + enchant_dict_add_to_session( + d->enchantdict, + wordbytes.constData(), wordbytes.size() + ); + return true; +} + +bool KSpeller::removeFromSession(const QString &word) +{ + if (!d->enchantdict) { + return false; + } + const QByteArray wordbytes = word.toUtf8(); + enchant_dict_remove_from_session( + d->enchantdict, + wordbytes.constData(), wordbytes.size() + ); + return true; +} + +QString KSpeller::defaultLanguage() +{ + // NOTE: enchant_get_user_language() just returns the value of some environment variable used + // to specify localizations language and C.UTF-8 is not valid dictionary for example + QString result = QLocale::system().name(); + if (result == QLatin1String("C")) { + result = QLatin1String("en"); + } + // qDebug() << Q_FUNC_INFO << result; + return result; +} + +#include "moc_kspeller.cpp" diff --git a/kdeui/spell/kspeller.h b/kdeui/spell/kspeller.h new file mode 100644 index 00000000..a9976dfd --- /dev/null +++ b/kdeui/spell/kspeller.h @@ -0,0 +1,61 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSPELLER_H +#define KSPELLER_H + +#include "kdeui_export.h" +#include "kconfig.h" + +#include +#include + +class KSpellerPrivate; + +/*! + Class to check spelling and query for corrections. + + @since 4.23 +*/ +class KDEUI_EXPORT KSpeller : public QObject +{ + Q_OBJECT +public: + KSpeller(KConfig *config, QObject *parent = nullptr); + ~KSpeller(); + + QStringList dictionaries() const; + QString dictionary() const; + bool setDictionary(const QString &dictionary); + + bool check(const QString &word); + QStringList suggest(const QString &word); + + bool addToPersonal(const QString &word); + bool removeFromPersonal(const QString &word); + bool addToSession(const QString &word); + bool removeFromSession(const QString &word); + + static QString defaultLanguage(); + +private: + Q_DISABLE_COPY(KSpeller); + KSpellerPrivate *d; +}; + +#endif // KSPELLER_H diff --git a/kdeui/spell/kspellhighlighter.cpp b/kdeui/spell/kspellhighlighter.cpp new file mode 100644 index 00000000..ffdd1dba --- /dev/null +++ b/kdeui/spell/kspellhighlighter.cpp @@ -0,0 +1,119 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kspellhighlighter.h" +#include "kspeller.h" +#include "kdebug.h" + +#include + +class KSpellHighlighterPrivate +{ +public: + KSpellHighlighterPrivate(KConfig *config); + + KSpeller speller; +}; + +KSpellHighlighterPrivate::KSpellHighlighterPrivate(KConfig *config) + : speller(config) +{ +} + +KSpellHighlighter::KSpellHighlighter(KConfig *config, QTextEdit *parent) + : QSyntaxHighlighter(parent), + d(new KSpellHighlighterPrivate(config)) +{ +} + +KSpellHighlighter::~KSpellHighlighter() +{ + delete d; +} + +QString KSpellHighlighter::currentLanguage() const +{ + return d->speller.dictionary(); +} + +void KSpellHighlighter::setCurrentLanguage(const QString &lang) +{ + d->speller.setDictionary(lang); +} + +void KSpellHighlighter::addWordToDictionary(const QString &word) +{ + d->speller.addToPersonal(word); +} + +void KSpellHighlighter::ignoreWord(const QString &word) +{ + d->speller.addToSession(word); +} + +QStringList KSpellHighlighter::suggestionsForWord(const QString &word, int max) +{ + QStringList result = d->speller.suggest(word); + // qDebug() << Q_FUNC_INFO << result << max; + while (result.size() > max) { + result.removeLast(); + } + return result; +} + +bool KSpellHighlighter::isWordMisspelled(const QString &word) +{ + return !d->speller.check(word); +} + +void KSpellHighlighter::highlightBlock(const QString &text) +{ + // qDebug() << Q_FUNC_INFO << text.size() << d->speller.dictionary(); + if (text.isEmpty() || d->speller.dictionary().isEmpty()) { + return; + } + QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text); + int wordstart = 0; + while (finder.toNextBoundary() >= 0) { + QTextBoundaryFinder::BoundaryReasons boundary = finder.boundaryReasons(); + if (boundary & QTextBoundaryFinder::StartWord) { + wordstart = finder.position(); + } + if (boundary & QTextBoundaryFinder::EndWord) { + QString word = text.mid(wordstart, finder.position() - wordstart); + if (word.size() < 2) { + continue; + } + if (word.at(word.size() - 1).isPunct()) { + word = word.mid(0, word.size() - 1); + } + if (!d->speller.check(word)) { + QTextCharFormat format; + format.setFontUnderline(true); + format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); + format.setUnderlineColor(QColor(Qt::red)); + setFormat(wordstart, word.size(), format); + } else { + setFormat(wordstart, word.size(), QTextCharFormat()); + } + } + } +} + + +#include "moc_kspellhighlighter.cpp" diff --git a/kdeui/spell/kspellhighlighter.h b/kdeui/spell/kspellhighlighter.h new file mode 100644 index 00000000..ee0de5ec --- /dev/null +++ b/kdeui/spell/kspellhighlighter.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSPELLHIGHLIGHTER_H +#define KSPELLHIGHLIGHTER_H + +#include "kdeui_export.h" +#include "kconfig.h" + +#include + +class KSpellHighlighterPrivate; + +/*! + Class to check spelling and highlight misspelled words. + + @since 4.23 +*/ +class KDEUI_EXPORT KSpellHighlighter : public QSyntaxHighlighter +{ + Q_OBJECT +public: + KSpellHighlighter(KConfig *config, QTextEdit *parent); + ~KSpellHighlighter(); + + QString currentLanguage() const; + void setCurrentLanguage(const QString &lang); + + void addWordToDictionary(const QString &word); + void ignoreWord(const QString &word); + QStringList suggestionsForWord(const QString &word, int max = 10); + bool isWordMisspelled(const QString &word); + +protected: + // reimplementation + virtual void highlightBlock(const QString &text); + +private: + Q_DISABLE_COPY(KSpellHighlighter); + KSpellHighlighterPrivate *d; +}; + +#endif // KSPELLHIGHLIGHTER_H diff --git a/kdeui/widgets/keditlistwidget.h b/kdeui/widgets/keditlistwidget.h index 2258c7f2..4c0dcbfb 100644 --- a/kdeui/widgets/keditlistwidget.h +++ b/kdeui/widgets/keditlistwidget.h @@ -23,13 +23,13 @@ #include -#include -#include +#include +#include +#include +#include class KLineEdit; class KComboBox; -#include -#include class KEditListWidgetPrivate; /** diff --git a/kdeui/widgets/ktextedit.cpp b/kdeui/widgets/ktextedit.cpp index 16bb5212..4830174b 100644 --- a/kdeui/widgets/ktextedit.cpp +++ b/kdeui/widgets/ktextedit.cpp @@ -30,9 +30,6 @@ #include #include -#include -#include -#include "backgroundchecker.h" #include #include #include @@ -50,6 +47,8 @@ #include #include #include +#include +#include #include class KTextEdit::Private @@ -61,14 +60,12 @@ class KTextEdit::Private checkSpellingEnabled( false ), findReplaceEnabled(true), showTabAction(true), - showAutoCorrectionButton(false), highlighter( 0 ), findDlg(0),find(0),repDlg(0),replace(0), findIndex(0), repIndex(0), lastReplacedPosition(-1) { - //Check the default sonnet settings to see if spellchecking should be enabled. - KConfig sonnetKConfig("sonnetrc"); - KConfigGroup group(&sonnetKConfig, "Spelling"); - checkSpellingEnabled = group.readEntry("checkerEnabledByDefault", false); + //Check the default settings to see if spellchecking should be enabled. + KConfigGroup spellgroup(KGlobal::config(), "Spelling"); + checkSpellingEnabled = spellgroup.readEntry("checkerEnabledByDefault", false); // i18n: Placeholder text in text edit widgets is the text appearing // before any user input, briefly explaining to the user what to type @@ -101,7 +98,6 @@ class KTextEdit::Private void spellCheckerMisspelling( const QString &text, int pos ); void spellCheckerCorrected( const QString &, int,const QString &); - void spellCheckerAutoCorrect(const QString&,const QString&); void spellCheckerCanceled(); void spellCheckerFinished(); void toggleAutoSpellCheck(); @@ -134,66 +130,58 @@ class KTextEdit::Private bool checkSpellingEnabled : 1; bool findReplaceEnabled: 1; bool showTabAction: 1; - bool showAutoCorrectionButton: 1; QTextDocumentFragment originalDoc; - QString spellCheckingConfigFileName; QString spellCheckingLanguage; - Sonnet::Highlighter *highlighter; + KSpellHighlighter *highlighter; KFindDialog *findDlg; KFind *find; KReplaceDialog *repDlg; KReplace *replace; int findIndex, repIndex; int lastReplacedPosition; - KConfig *sonnetKConfig; }; void KTextEdit::Private::checkSpelling(bool force) { - if(parent->document()->isEmpty()) - { - KMessageBox::information(parent, i18n("Nothing to spell check.")); - if(force) { - emit parent->spellCheckingFinished(); - } - return; - } - Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker; - if(!spellCheckingLanguage.isEmpty()) - backgroundSpellCheck->changeLanguage(spellCheckingLanguage); - Sonnet::Dialog *spellDialog = new Sonnet::Dialog( - backgroundSpellCheck, force ? parent : 0); - backgroundSpellCheck->setParent(spellDialog); - spellDialog->setAttribute(Qt::WA_DeleteOnClose, true); - spellDialog->activeAutoCorrect(showAutoCorrectionButton); - connect(spellDialog, SIGNAL(replace(QString,int,QString)), - parent, SLOT(spellCheckerCorrected(QString,int,QString))); - connect(spellDialog, SIGNAL(misspelling(QString,int)), - parent, SLOT(spellCheckerMisspelling(QString,int))); - connect(spellDialog, SIGNAL(autoCorrect(QString,QString)), - parent, SLOT(spellCheckerAutoCorrect(QString,QString))); - connect(spellDialog, SIGNAL(done(QString)), - parent, SLOT(spellCheckerFinished())); - connect(spellDialog, SIGNAL(cancel()), - parent, SLOT(spellCheckerCanceled())); - //Laurent in sonnet/dialog.cpp we emit done(QString) too => it calls here twice spellCheckerFinished not necessary - /* - connect(spellDialog, SIGNAL(stop()), - parent, SLOT(spellCheckerFinished())); - */ - connect(spellDialog, SIGNAL(spellCheckStatus(QString)), - parent, SIGNAL(spellCheckStatus(QString))); - connect(spellDialog, SIGNAL(languageChanged(QString)), - parent, SIGNAL(languageChanged(QString))); - if(force) { - connect(spellDialog, SIGNAL(done(QString)),parent, SIGNAL(spellCheckingFinished())); - connect(spellDialog, SIGNAL(cancel()), parent, SIGNAL(spellCheckingCanceled())); - //Laurent in sonnet/dialog.cpp we emit done(QString) too => it calls here twice spellCheckerFinished not necessary - //connect(spellDialog, SIGNAL(stop()), parent, SIGNAL(spellCheckingFinished())); - } - originalDoc = QTextDocumentFragment(parent->document()); - spellDialog->setBuffer(parent->toPlainText()); - spellDialog->show(); + if (parent->document()->isEmpty()) { + KMessageBox::information(parent, i18n("Nothing to spell check.")); + if (force) { + emit parent->spellCheckingFinished(); + } + return; + } + KSpellDialog *spellDialog = new KSpellDialog(KGlobal::config().data(), force ? parent : 0); + if (!spellCheckingLanguage.isEmpty()) { + spellDialog->changeLanguage(spellCheckingLanguage); + } + spellDialog->setAttribute(Qt::WA_DeleteOnClose, true); + connect( + spellDialog, SIGNAL(replace(QString,int,QString)), + parent, SLOT(spellCheckerCorrected(QString,int,QString)) + ); + connect( + spellDialog, SIGNAL(misspelling(QString,int)), + parent, SLOT(spellCheckerMisspelling(QString,int)) + ); + connect( + spellDialog, SIGNAL(accepted()), + parent, SLOT(spellCheckerFinished()) + ); + connect( + spellDialog, SIGNAL(rejected()), + parent, SLOT(spellCheckerCanceled()) + ); + connect( + spellDialog, SIGNAL(languageChanged(QString)), + parent, SIGNAL(languageChanged(QString)) + ); + if (force) { + connect(spellDialog, SIGNAL(accepted()), parent, SIGNAL(spellCheckingFinished())); + connect(spellDialog, SIGNAL(rejected()), parent, SIGNAL(spellCheckingCanceled())); + } + originalDoc = QTextDocumentFragment(parent->document()); + spellDialog->setBuffer(parent->toPlainText()); + spellDialog->show(); } @@ -206,11 +194,6 @@ void KTextEdit::Private::spellCheckerCanceled() spellCheckerFinished(); } -void KTextEdit::Private::spellCheckerAutoCorrect(const QString& currentWord,const QString& autoCorrectWord) -{ - emit parent->spellCheckerAutoCorrect(currentWord, autoCorrectWord); -} - void KTextEdit::Private::spellCheckerMisspelling( const QString &text, int pos ) { //kDebug()<<"TextEdit::Private::spellCheckerMisspelling :"<spellCheckingConfigFileName = _fileName; -} - const QString& KTextEdit::spellCheckingLanguage() const { return d->spellCheckingLanguage; @@ -348,20 +326,6 @@ void KTextEdit::setSpellCheckingLanguage(const QString &_language) } } -void KTextEdit::showSpellConfigDialog(const QString &configFileName, - const QString &windowIcon) -{ - KConfig config(configFileName); - Sonnet::ConfigDialog dialog(&config, this); - if (!d->spellCheckingLanguage.isEmpty()) - dialog.setLanguage(d->spellCheckingLanguage); - if (!windowIcon.isEmpty()) - dialog.setWindowIcon(KIcon(windowIcon)); - if(dialog.exec()) { - setSpellCheckingLanguage( dialog.language() ); - } -} - bool KTextEdit::event(QEvent* ev) { if (ev->type() == QEvent::ShortcutOverride) { @@ -696,18 +660,18 @@ void KTextEdit::wheelEvent( QWheelEvent *event ) void KTextEdit::createHighlighter() { - setHighlighter(new Sonnet::Highlighter(this, d->spellCheckingConfigFileName)); + setHighlighter(new KSpellHighlighter(KGlobal::config().data(), this)); } -Sonnet::Highlighter* KTextEdit::highlighter() const +KSpellHighlighter* KTextEdit::highlighter() const { return d->highlighter; } -void KTextEdit::setHighlighter(Sonnet::Highlighter *_highLighter) +void KTextEdit::setHighlighter(KSpellHighlighter *highLighter) { delete d->highlighter; - d->highlighter = _highLighter; + d->highlighter = highLighter; } void KTextEdit::setCheckSpellingEnabled(bool check) @@ -1095,9 +1059,4 @@ void KTextEdit::paintEvent(QPaintEvent *ev) } } -void KTextEdit::showAutoCorrectButton(bool show) -{ - d->showAutoCorrectionButton = show; -} - #include "moc_ktextedit.cpp" diff --git a/kdeui/widgets/ktextedit.h b/kdeui/widgets/ktextedit.h index d12fc257..7aa706c0 100644 --- a/kdeui/widgets/ktextedit.h +++ b/kdeui/widgets/ktextedit.h @@ -21,7 +21,7 @@ #define KTEXTEDIT_H #include -#include +#include #include #define HAVE_SHOWTABACTION 1 @@ -111,26 +111,10 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses */ void highlightWord( int length, int pos ); - /** - * Allows to override the config file where the settings for spell checking, - * like the current language or encoding, are stored. - * By default, the global config file (kdeglobals) is used, to share - * spell check settings between all applications. - * - * This has to be called before any spell checking is initiated. - * - * @param fileName the URL of the config file which will be used to - * read spell settings - * @bug this has no effect for the spell dialog, only for the background - * check - */ - void setSpellCheckingConfigFileName(const QString &fileName); - /** * Allows to create a specific highlighter if reimplemented. * - * By default, it creates a normal highlighter, based on the config - * file given to setSpellCheckingConfigFileName(). + * By default, it creates a normal highlighter. * * This highlighter is set each time spell checking is toggled on by * calling setCheckSpellingEnabled(), but can later be overridden by calling @@ -138,7 +122,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses * * @see setHighlighter() * @see highlighter() - * @see setSpellCheckingConfigFileName() */ virtual void createHighlighter(); @@ -150,7 +133,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses * @see setHighlighter() * @see createHighlighter() */ - Sonnet::Highlighter* highlighter() const; + KSpellHighlighter* highlighter() const; /** * Sets a custom backgound spell highlighter for this text edit. @@ -165,7 +148,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses * @see createHighlighter() * @param highLighter the new highlighter which will be used now */ - void setHighlighter(Sonnet::Highlighter *_highLighter); + void setHighlighter(KSpellHighlighter *_highLighter); /** * Return standard KTextEdit popupMenu @@ -208,11 +191,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses */ void showTabAction(bool show); - /** - * @since 4.10 - */ - void showAutoCorrectButton(bool show); - /** * @since 4.10 * create a modal spellcheck dialogbox and spellCheckingFinished signal we sent when @@ -228,12 +206,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses */ void checkSpellingChanged( bool ); - /** - * Signal sends when spell checking is finished/stopped/completed - * @since 4.1 - */ - void spellCheckStatus(const QString &); - /** * Emitted when the user changes the language in the spellcheck dialog * shown by checkSpelling() or when calling setSpellCheckingLanguage(). @@ -259,12 +231,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses void aboutToShowContextMenu(QMenu* menu); /** - * @since 4.10 - */ - void spellCheckerAutoCorrect(const QString& currentWord, const QString& autoCorrectWord); - - /** - * signal spellCheckingFinished is sent when we finish spell check or we click on "Terminate" button in sonnet dialogbox + * signal spellCheckingFinished is sent when we finish spell check or we click on "Terminate" button in speller dialogbox * @since 4.10 */ void spellCheckingFinished(); @@ -288,28 +255,12 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses void setSpellCheckingLanguage(const QString &language); /** - * Show a dialog to check the spelling. The spellCheckStatus() signal - * will be emitted when the spell checking dialog is closed. + * Show a dialog to check the spelling. The spellCheckingFinished() or + * spellCheckingCanceled() signal will be emitted when the spell checking + * dialog is closed. */ void checkSpelling(); - /** - * Opens a Sonnet::ConfigDialog for this text edit. The config settings the - * user makes are read from and stored to the given config file. - * The spellcheck language of the config dialog is set to the current spellcheck - * language of the textedit. If the user changes the language in that dialog, - * the languageChanged() signal is emitted. - * - * @param configFileName The file which is used to store and load the config - * settings - * @param windowIcon the icon which is used for the titlebar of the spell dialog - * window. Can be empty, then no icon is set. - * - * @since 4.2 - */ - void showSpellConfigDialog(const QString &configFileName, - const QString &windowIcon = QString()); - /** * Create replace dialogbox * @since 4.1 @@ -380,7 +331,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses Q_PRIVATE_SLOT( d, void spellCheckerMisspelling( const QString&, int ) ) Q_PRIVATE_SLOT( d, void spellCheckerCorrected(const QString&, int,const QString&) ) Q_PRIVATE_SLOT( d, void spellCheckerCanceled()) - Q_PRIVATE_SLOT( d, void spellCheckerAutoCorrect(const QString&,const QString&) ) Q_PRIVATE_SLOT( d, void spellCheckerFinished() ) Q_PRIVATE_SLOT( d, void undoableClear() ) Q_PRIVATE_SLOT( d, void toggleAutoSpellCheck() ) diff --git a/kdewidgets/kde.widgets b/kdewidgets/kde.widgets index 1c48889e..fdbfe87c 100644 --- a/kdewidgets/kde.widgets +++ b/kdewidgets/kde.widgets @@ -337,11 +337,11 @@ ToolTip=URL Requester (KDE) WhatsThis=A widget holding a lineedit and a pushbutton. A "file open" dialog opened when clicking on the pushbutton Group=Input (KDE) -[Sonnet::DictionaryComboBox] -IncludeFile=sonnet/dictionarycombobox.h +[KSpellDictionaryComboBox] +IncludeFile=kspelldictionarycombobox.h ToolTip=Dictionary Combobox WhatsThis=A combobox to select a dictionary for spellchecking -Group=Sonnet (KDE) +Group=Spell (KDE) [KMediaWidget] ToolTip=Multimedia files player (KDE) diff --git a/kutils/kdeglobals.kcfg b/kutils/kdeglobals.kcfg index d159e3cd..5b4d854a 100644 --- a/kutils/kdeglobals.kcfg +++ b/kutils/kdeglobals.kcfg @@ -410,16 +410,14 @@ false + + + + + - - - - - - - - +