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 <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-08 21:33:16 +03:00
parent be20483256
commit 7f7eb09b35
82 changed files with 1489 additions and 6362 deletions

View file

@ -340,7 +340,6 @@ set(KDE4_KDECORE_INCLUDES
${CMAKE_SOURCE_DIR}/kdecore/sycoca ${CMAKE_SOURCE_DIR}/kdecore/sycoca
${CMAKE_SOURCE_DIR}/kdecore/text ${CMAKE_SOURCE_DIR}/kdecore/text
${CMAKE_SOURCE_DIR}/kdecore/util ${CMAKE_SOURCE_DIR}/kdecore/util
${CMAKE_SOURCE_DIR}/kdecore/sonnet
${CMAKE_BINARY_DIR}/kdecore ${CMAKE_BINARY_DIR}/kdecore
${QT_INCLUDES} ${QT_INCLUDES}
${_KDE4_PLATFORM_INCLUDE_DIRS} ${_KDE4_PLATFORM_INCLUDE_DIRS}
@ -363,7 +362,7 @@ set(KDE4_KDEUI_INCLUDES
${CMAKE_SOURCE_DIR}/kdeui/paged ${CMAKE_SOURCE_DIR}/kdeui/paged
${CMAKE_SOURCE_DIR}/kdeui/plotting ${CMAKE_SOURCE_DIR}/kdeui/plotting
${CMAKE_SOURCE_DIR}/kdeui/shortcuts ${CMAKE_SOURCE_DIR}/kdeui/shortcuts
${CMAKE_SOURCE_DIR}/kdeui/sonnet ${CMAKE_SOURCE_DIR}/kdeui/spell
${CMAKE_SOURCE_DIR}/kdeui/util ${CMAKE_SOURCE_DIR}/kdeui/util
${CMAKE_SOURCE_DIR}/kdeui/widgets ${CMAKE_SOURCE_DIR}/kdeui/widgets
${CMAKE_SOURCE_DIR}/kdeui/windowmanagement ${CMAKE_SOURCE_DIR}/kdeui/windowmanagement

View file

@ -358,6 +358,12 @@ install(
KPty KPty
KPtyDevice KPtyDevice
KPtyProcess KPtyProcess
KSpeller
KSpellHighlighter
KSpellDialog
KSpellDictionaryComboBox
KSpellConfigWidget
KSpellBackgroundChecker
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE
COMPONENT Devel COMPONENT Devel
) )
@ -434,18 +440,6 @@ install(
COMPONENT Devel COMPONENT Devel
) )
#install(
# FILES
# Sonnet/GuessLanguage
# Sonnet/UnicodeData
# Sonnet/TextBreaks
# Sonnet/Spell
# DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/Sonnet
# COMPONENT Devel
#)
install( install(
FILES FILES
KTextEditor/Attribute KTextEditor/Attribute
@ -518,18 +512,6 @@ install(
COMPONENT Devel COMPONENT Devel
) )
install(
FILES
Sonnet/ConfigDialog
Sonnet/ConfigWidget
Sonnet/Dialog
Sonnet/DictionaryComboBox
Sonnet/Highlighter
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/Sonnet
COMPONENT Devel
)
install( install(
FILES FILES
Plasma/AbstractRunner Plasma/AbstractRunner

View file

@ -0,0 +1 @@
#include "../kspellbackgroundchecker.h"

View file

@ -0,0 +1 @@
#include "../kspellconfigwidget.h"

1
includes/KSpellDialog Normal file
View file

@ -0,0 +1 @@
#include "../kspelldialog.h"

View file

@ -0,0 +1 @@
#include "../kspelldictionarycombobox.h"

View file

@ -0,0 +1 @@
#include "../kspellhighlighter.h"

1
includes/KSpeller Normal file
View file

@ -0,0 +1 @@
#include "../kspeller.h"

View file

@ -1 +0,0 @@
#include "../../sonnet/configdialog.h"

View file

@ -1 +0,0 @@
#include "../../sonnet/configwidget.h"

View file

@ -1 +0,0 @@
#include "../../sonnet/dialog.h"

View file

@ -1 +0,0 @@
#include "../../sonnet/dictionarycombobox.h"

View file

@ -1 +0,0 @@
#include "../../sonnet/highlighter.h"

View file

@ -25,7 +25,6 @@ include_directories(
# for kglobalsettings header # for kglobalsettings header
${KDE4_KDEUI_INCLUDES} ${KDE4_KDEUI_INCLUDES}
${QT_INCLUDES} ${QT_INCLUDES}
${CMAKE_CURRENT_SOURCE_DIR}/sonnet
) )
# kdecore_OPTIONAL_SRCS is used to collect source files # kdecore_OPTIONAL_SRCS is used to collect source files
@ -37,24 +36,9 @@ set(kdecore_OPTIONAL_LIBS)
add_definitions(-DQT_NO_CAST_FROM_ASCII) 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) add_subdirectory(kconfig_compiler)
if(ENABLE_TESTING) if(ENABLE_TESTING)
add_subdirectory(tests) add_subdirectory(tests)
add_subdirectory(sonnet/tests)
endif() endif()
########### next target ############### ########### next target ###############
@ -133,13 +117,6 @@ set(kdecore_LIB_SRCS
services/yacc.c services/yacc.c
services/lex.c services/lex.c
services/kplugininfo.cpp 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/kcatalog.cpp
localization/kcharsets.cpp localization/kcharsets.cpp
@ -314,15 +291,6 @@ install(
COMPONENT Devel COMPONENT Devel
) )
install(
FILES
sonnet/backgroundchecker.h
sonnet/speller.h
sonnet/globals.h
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/sonnet
COMPONENT Devel
)
install( install(
FILES FILES
services/kplugininfo.desktop services/kplugininfo.desktop

View file

@ -1,171 +0,0 @@
/**
* backgroundchecker.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kdebug.h>
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"

View file

@ -1,133 +0,0 @@
/*
* backgroundchecker.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kdecore_export.h>
#include <QtCore/QObject>
/**
* 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 <zack@kde.org>
* @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

View file

@ -1,117 +0,0 @@
/**
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kdebug.h>
#include <QtCore/QTimer>
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"

View file

@ -1,80 +0,0 @@
/*
* backgroundengine.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QObject>
#include <QtCore/QStringList>
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

View file

@ -1,99 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
* Copyright 2006 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QDebug>
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<QSpellEnchantClient*>(user_data);
//qDebug()<<lang_tag<<provider_name<<provider_desc<<provider_file;
Q_UNUSED(provider_name);
Q_UNUSED(provider_desc);
Q_UNUSED(provider_file);
client->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"<<language<<": "<<err;
#endif
return 0;
} else {
//Enchant caches dictionaries, so it will always return the same one.
int refs = m_dictRefs[dict];
++refs;
m_dictRefs[dict] = refs;
return new QSpellEnchantDict(this, dict, language);
}
}
QStringList QSpellEnchantClient::languages() const
{
return m_languages.toList();
}
void QSpellEnchantClient::addLanguage(const QString &lang)
{
m_languages.insert(lang);
}
void QSpellEnchantClient::removeDictRef(EnchantDict *dict)
{
int refs = m_dictRefs[dict];
--refs;
m_dictRefs[dict] = refs;
if (refs <= 0) {
m_dictRefs.remove(dict);
enchant_broker_free_dict(m_broker, dict);
}
}
}
#include "moc_enchantclient_p.cpp"

View file

@ -1,57 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
* Copyright 2006 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QSet>
#include <QtCore/qvariant.h>
#include <enchant.h>
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<QString> m_languages;
QHash<EnchantDict*, int> m_dictRefs;
};
}
#endif

View file

@ -1,110 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
* Copyright 2006 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QTextCodec>
#include <QtCore/QDebug>
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;
}
}

View file

@ -1,63 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
* Copyright 2006 Zack Rusin <zack@kde.org>
*
* 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 <QStringList>
#include <enchant.h>
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

View file

@ -1,311 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
* filter.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
* Copyright (C) 2010 Michel Ludwig <michel.ludwig@kdemail.net>
*
* 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 <kglobal.h>
#include <kdebug.h>
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( "<b>%1</b>" ).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 );
}
}

View file

@ -1,120 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/*
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QTextBoundaryFinder>
#include <QtCore/QString>
#include <kdecore_export.h>
namespace Sonnet
{
class Settings;
/**
* Structure abstracts the word and its position in the
* parent text.
*
* @author Zack Rusin <zack@kde.org>
* @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 <zack@kde.org>
* @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

View file

@ -1,98 +0,0 @@
/*
* Copyright (C) 2008 Zack Rusin <zack@kde.org>
*
* 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 <kconfig.h>
#include <QMap>
#include <QVector>
#include <QSet>
#include <QDebug>
#include <memory>
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<QString, QString> dicts = speller.availableDictionaries();
QMap<QString, int> correctHits;
QSet<QString> seenLangs;
{
QMapIterator<QString, QString> itr(dicts);
while (itr.hasNext()) {
itr.next();
seenLangs.insert(itr.value());
}
}
QVector<Speller> spellers(seenLangs.count());
{
QSet<QString>::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<QString, int>::const_iterator max = correctHits.constBegin();
for (QMap<QString, int>::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());
}
}

View file

@ -1,49 +0,0 @@
/*
* Copyright (C) 2008 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QString>
#include <kdecore_export.h>
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

View file

@ -1,251 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
*
* 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 <klocale.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kglobal.h>
namespace Sonnet
{
class Loader::Private
{
public:
Settings *settings;
// <language, Clients with that language >
QMap<QString, QList<QSpellEnchantClient*> > 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<QSpellEnchantClient*> lClients = d->languageClients[plang];
if (lClients.isEmpty()) {
kError() << "No language dictionaries for the language : " << plang;
return 0;
}
QListIterator<QSpellEnchantClient*> 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"

View file

@ -1,123 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/*
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
*
* 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 <kdecore_export.h>
#include <ksharedptr.h>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QString>
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

View file

@ -1,262 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
* Copyright (C) 2006 Laurent Montel <montel@kde.org>
*
* 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 <kconfig.h>
#include <kconfiggroup.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <QtCore/QMap>
#include <QtCore/qstringlist.h>
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;
}
}

View file

@ -1,87 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/*
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QStringList>
#include <QtCore/QString>
#include <kdecore_export.h>
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

View file

@ -1,296 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/**
*
* Copyright (C) 2007 Zack Rusin <zack@kde.org>
*
* 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 <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include <QLocale>
#include <QSet>
#include <QDebug>
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 "<<this;
delete d;
}
Speller::Speller(const Speller &speller)
: d(new Private)
{
d->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<QString, QString> Sonnet::Speller::availableDictionaries() const
{
Loader *l = Loader::openLoader();
QMap<QString, QString> 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 "<<tag<<" ( "<<loc.name()<<")"<<", descr = "<<description;
langs.insert(description, tag);
}
return langs;
}
}

View file

@ -1,153 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/*
*
* Copyright (C) 2007 Zack Rusin <zack@kde.org>
*
* 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_SPELLER_H
#define SONNET_SPELLER_H
#include <QtCore/QStringList>
#include <QtCore/QString>
#include <kdecore_export.h>
class KConfig;
namespace Sonnet
{
/**
* Spell checker object.
*
* @short class used for actuall spell checking
*/
class KDECORE_EXPORT Speller
{
public:
Speller(const QString &lang=QString());
~Speller();
Speller(const Speller &speller);
Speller &operator=(const Speller &speller);
/**
* Returns true if the speller supports currently selected
* language.
*/
bool isValid() const;
/**
* Sets the language supported by this speller.
*/
void setLanguage(const QString &lang);
/**
* Returns language supported by this speller.
*/
QString language() const;
/**
* Checks the given word.
* @return false if the word is misspelled. true otherwise
*/
bool isCorrect(const QString &word) const;
/**
* Checks the given word.
* @return true if the word is misspelled. false otherwise
*/
bool isMisspelled(const QString &word) const;
/**
* Fetches suggestions for the word.
*
* @return list of all suggestions for the word
*/
QStringList suggest(const QString &word) const;
/**
* Convience method calling isCorrect() and suggest()
* if the word isn't correct.
*/
bool checkAndSuggest(const QString &word,
QStringList &suggestions) const;
/**
* Stores user defined good replacement for the bad word.
* @returns true on success
*/
bool storeReplacement(const QString &bad,
const QString &good);
/**
* Adds word to the list of of personal words.
* @return true on success
*/
bool addToPersonal(const QString &word);
/**
* Adds word to the words recognizable in the current session.
* @return true on success
*/
bool addToSession(const QString &word);
public: // Configuration API
enum Attribute {
CheckUppercase,
SkipRunTogether
};
void save(KConfig *config);
void restore(KConfig *config);
/**
* Returns names of all supported backends (e.g. ISpell, ASpell)
*/
QStringList availableBackends() const;
/**
* Returns a list of supported languages.
*
* Note: use availableDictionaries
*/
QStringList availableLanguages() const;
/**
* Returns a localized list of names of supported languages.
*
* Note: use availableDictionaries
*/
QStringList availableLanguageNames() const;
/**
* Returns a map of all available language descriptions and their
* codes
*/
QMap<QString, QString> availableDictionaries() const;
void setDefaultLanguage(const QString &lang);
QString defaultLanguage() const;
void setDefaultClient(const QString &client);
QString defaultClient() const;
void setAttribute(Attribute attr, bool b = true);
bool testAttribute(Attribute attr) const;
private:
class Private;
Private *const d;
};
}
#endif

View file

@ -1,29 +0,0 @@
remove_definitions(-DQT_NO_CAST_FROM_ASCII)
########### next target ###############
# TODO automate and merge with test_filter?
set(test_suggest_SRCS test.cpp)
kde4_add_manual_test(test_suggest ${test_suggest_SRCS})
target_link_libraries(test_suggest ${KDE4_KDECORE_LIBS})
########### unittests ###############
MACRO(SONNET_UNIT_TESTS)
FOREACH(_testname ${ARGN})
kde4_add_test(sonnet-${_testname} ${_testname}.cpp)
target_link_libraries(sonnet-${_testname}
${KDE4_KDECORE_LIBS}
${QT_QTTEST_LIBRARY}
${QT_QTXML_LIBRARY}
)
ENDFOREACH(_testname)
ENDMACRO(SONNET_UNIT_TESTS)
SONNET_UNIT_TESTS(
test_filter
test_core
)

View file

@ -1,97 +0,0 @@
// krazy:excludeall=spelling
/**
* test.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QCoreApplication>
#include <QElapsedTimer>
#include <kdebug.h>
#include <kcmdlineargs.h>
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 : "<<sug;
}
}
//mtime.stop();
kDebug()<<"Elapsed time is "<<mtime.elapsed();
return 0;
}

View file

@ -1,40 +0,0 @@
/**
* test_config.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kdebug.h>
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();
}

View file

@ -1,172 +0,0 @@
// krazy:excludeall=spelling
/**
*
* Copyright 2007 Zack Rusin <zack@kde.org>
*
* 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 <qtest_kde.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
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 : "<<sug;
}
}
//mtime.stop();
kDebug()<<"Elapsed time is "<<mtime.elapsed();
kDebug()<<"Detecting language ...";
QString sentence = QString::fromLatin1("QClipboard features some convenience functions to access common data types: setText() allows the exchange of Unicode text and setPixmap() and setImage() allows the exchange of QPixmaps and QImages between applications.");
kDebug()<<"\tlang is "<<Sonnet::detectLanguage(sentence);
}
void SonnetCoreTest::testCore2()
{
Speller dict("de_DE");
if (!dict.availableDictionaries().contains("German")) {
QSKIP("This test requires a german spelling dictionary", SkipSingle);
return;
}
kDebug()<< "Clients are " << dict.availableBackends();
kDebug()<< "Languages are " << dict.availableLanguages();
kDebug()<< "Language names are " << dict.availableLanguageNames();
kDebug()<< "Language dicts " << dict.availableDictionaries();
QStringList words;
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
words << "Hallo" << "halo" << "Umgebunp" << "Regirung" << "bet";
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 : "<<sug;
}
}
//mtime.stop();
kDebug()<<"Elapsed time is "<<mtime.elapsed();
kDebug()<<"Detecting language ...";
QString sentence = QString::fromUtf8("Möchten Sie wirklich alle Werkzeugleisten dieser Anwendung auf ihre Voreinstellungen zurücksetzen? Die Änderung wird sofort wirksam.");
kDebug()<<"\tlang is "<<Sonnet::detectLanguage(sentence);
}
#include "moc_test_core.cpp"

View file

@ -1,32 +0,0 @@
/**
* Copyright 2007 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QObject>
class SonnetCoreTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCore();
void testCore2();
};
#endif

View file

@ -1,67 +0,0 @@
// krazy:excludeall=spelling
/**
* test_dialog.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kcmdlineargs.h>
#include <kdebug.h>
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 :"<<buf;
qApp->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();
}

View file

@ -1,42 +0,0 @@
/**
* test_dialog.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QObject>
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

View file

@ -1,161 +0,0 @@
/**
* test_filter.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <qtest_kde.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
#include <QTextBoundaryFinder>
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<Hit> 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<Hit> 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<ushort>
convertToUnicode(const QString &str)
{
QVector<ushort> unicode;
for (int i = 0; i < str.length(); ++i)
unicode += str[i].unicode();
return unicode;
}
void SonnetFilterTest::testIndic()
{
QString buffer;
QList<Hit> 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<ushort> unicode = convertToUnicode(w.word);
//qDebug()<< "Found word \""<< unicode << "\" which starts at position " << w.start <<", len = "<<w.word.length();
QCOMPARE( w.word, hits[hitNumber].word );
QCOMPARE( w.start, hits[hitNumber].start );
++hitNumber;
}
QCOMPARE( hitNumber, hits.count() );
}
#include "moc_test_filter.cpp"

View file

@ -1,34 +0,0 @@
/**
* Copyright (C) 2006 David Faure <faure@kde.org>
*
* 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 <QObject>
class SonnetFilterTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testFilter();
void testWordAt();
void testIndic();
};
#endif

View file

@ -3,7 +3,6 @@ project(kdeui)
include_directories( include_directories(
${CMAKE_SOURCE_DIR}/interfaces ${CMAKE_SOURCE_DIR}/interfaces
${CMAKE_SOURCE_DIR}/interfaces/kregexpeditor ${CMAKE_SOURCE_DIR}/interfaces/kregexpeditor
${CMAKE_SOURCE_DIR}/kdecore/sonnet
${CMAKE_SOURCE_DIR}/kdeui ${CMAKE_SOURCE_DIR}/kdeui
${KDE4_KDECORE_INCLUDES} ${KDE4_KDECORE_INCLUDES}
actions actions
@ -20,7 +19,7 @@ include_directories(
paged paged
plotting plotting
shortcuts shortcuts
sonnet spell
util util
widgets widgets
windowmanagement windowmanagement
@ -29,7 +28,11 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}/util ${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) if (X11_Xkb_FOUND AND X11_Xkbfile_FOUND)
set(HAVE_XKB TRUE) set(HAVE_XKB TRUE)
@ -41,7 +44,6 @@ configure_file(
if(ENABLE_TESTING) if(ENABLE_TESTING)
add_subdirectory( tests ) add_subdirectory( tests )
add_subdirectory( sonnet/tests )
endif() endif()
########### next target ############### ########### next target ###############
@ -172,11 +174,12 @@ set(kdeui_LIB_SRCS
shortcuts/kglobalshortcutinfo_dbus.cpp shortcuts/kglobalshortcutinfo_dbus.cpp
shortcuts/kacceleratormanager.cpp shortcuts/kacceleratormanager.cpp
shortcuts/kcheckaccelerators.cpp shortcuts/kcheckaccelerators.cpp
sonnet/dialog.cpp spell/kspeller.cpp
sonnet/configwidget.cpp spell/kspellhighlighter.cpp
sonnet/highlighter.cpp spell/kspelldialog.cpp
sonnet/configdialog.cpp spell/kspelldictionarycombobox.cpp
sonnet/dictionarycombobox.cpp spell/kspellconfigwidget.cpp
spell/kspellbackgroundchecker.cpp
util/kcompletion.cpp util/kcompletion.cpp
util/kcompletionbase.cpp util/kcompletionbase.cpp
util/kcrash.cpp util/kcrash.cpp
@ -324,6 +327,7 @@ add_library(kdeui ${LIBRARY_TYPE} ${kdeui_LIB_SRCS})
target_link_libraries(kdeui PRIVATE target_link_libraries(kdeui PRIVATE
${X11_LIBRARIES} ${X11_LIBRARIES}
${KDEUI_EXTRA_LIBS} ${KDEUI_EXTRA_LIBS}
${ENCHANT_LIBRARIES}
) )
target_link_libraries(kdeui PUBLIC target_link_libraries(kdeui PUBLIC
@ -487,6 +491,12 @@ install(
shortcuts/kglobalshortcutinfo.h shortcuts/kglobalshortcutinfo.h
shortcuts/kglobalshortcutinfo_p.h shortcuts/kglobalshortcutinfo_p.h
shortcuts/kacceleratormanager.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/kaccelgen.h
util/kcompletion.h util/kcompletion.h
util/kcrash.h util/kcrash.h
@ -578,17 +588,6 @@ install(
COMPONENT Devel 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( install(
PROGRAMS preparetips PROGRAMS preparetips
DESTINATION ${KDE4_BIN_INSTALL_DIR} DESTINATION ${KDE4_BIN_INSTALL_DIR}

View file

@ -27,6 +27,7 @@
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QSize> #include <QSize>
#include <QTextFrame>
#include <kdebug.h> #include <kdebug.h>

View file

@ -1,100 +0,0 @@
/**
* configdialog.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <klocale.h>
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"

View file

@ -1,85 +0,0 @@
/*
* configdialog.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kdialog.h>
#include <kconfig.h>
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

View file

@ -1,112 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>Zack Rusin &lt;zack@kde.org&gt;</author>
<comment>Licensed under GNU LGPL</comment>
<class>SonnetConfigUI</class>
<widget class="QWidget" name="SonnetConfigUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>577</width>
<height>441</height>
</rect>
</property>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="Sonnet::DictionaryComboBox" name="m_langCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox1">
<property name="title">
<string>Options</string>
</property>
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="m_bgSpellCB">
<property name="text">
<string>Enable &amp;background spellchecking</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="m_checkerEnabledByDefaultCB">
<property name="text">
<string>&amp;Automatic spell checking enabled by default</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="m_skipUpperCB">
<property name="text">
<string>Skip all &amp;uppercase words</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="m_skipRunTogetherCB">
<property name="text">
<string>S&amp;kip run-together words</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Default language:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Ignored Words</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="KEditListWidget" name="m_ignoreListBox">
<property name="title" stdset="0">
<string>Ignored Words</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KEditListWidget</class>
<extends>QWidget</extends>
<header>keditlistwidget.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
<customwidget>
<class>Sonnet::DictionaryComboBox</class>
<extends>KComboBox</extends>
<header>sonnet/dictionarycombobox.h</header>
</customwidget>
</customwidgets>
<connections/>
</ui>

View file

@ -1,142 +0,0 @@
/**
* configwidget.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kcombobox.h>
#include <kconfig.h>
#include <klocale.h>
#include <QtGui/QCheckBox>
#include <QtGui/QLayout>
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"

View file

@ -1,79 +0,0 @@
/*
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtGui/QWidget>
#include <kdeui_export.h>
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

View file

@ -1,452 +0,0 @@
/**
* dialog.cpp
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
* Copyright (C) 2009-2010 Michel Ludwig <michel.ludwig@kdemail.net>
*
* 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 <kconfig.h>
#include <kguiitem.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kprogressdialog.h>
#include <kdebug.h>
#include <QtGui/QListView>
#include <QtGui/QStringListModel>
#include <QtGui/QPushButton>
#include <QtGui/QComboBox>
#include <QtGui/QLabel>
#include <QtCore/QTimer>
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<QString, QString> replaceAllMap;
bool restart;//used when text is distributed across several qtextedits, eg in KAider
QMap<QString, QString> 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"

View file

@ -1,166 +0,0 @@
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
/*
* dialog.h
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
* Copyright (C) 2009-2010 Michel Ludwig <michel.ludwig@kdemail.net>
*
* 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 <kdialog.h>
#include <QListWidgetItem>
#include <QModelIndex>
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

View file

@ -1,115 +0,0 @@
/*
* Copyright (c) 2003 Ingo Kloecker <kloecker@kde.org>
* Copyright (c) 2008 Tom Albers <tomalbers@kde.nl>
*
* 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 <kdebug.h>
#include <sonnet/speller.h>
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<QString, QString> dictionaries = speller->availableDictionaries();
QMapIterator<QString, QString> 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"

View file

@ -1,102 +0,0 @@
/*
* Copyright (c) 2003 Ingo Kloecker <kloecker@kde.org>
* Copyright (c) 2008 Tom Albers <tomalbers@kde.nl>
*
* 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 <kcombobox.h>
namespace Sonnet
{
/**
* @short A combo box for selecting the dictionary used for spell checking.
* @author Ingo Kloecker <kloecker@kde.org>
* @author Tom Albers <tomalbers@kde.nl>
* @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

View file

@ -1,427 +0,0 @@
/**
* highlighter.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
* Copyright (C) 2006 Laurent Montel <montel@kde.org>
*
* 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 <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <QTextEdit>
#include <QtGui/qtextformat.h>
#include <QTimer>
#include <QColor>
#include <QHash>
#include <QTextCursor>
#include <QEvent>
#include <QtGui/qevent.h>
#include <QApplication>
namespace Sonnet {
class Highlighter::Private
{
public:
~Private();
Filter *filter;
Loader *loader;
Speller *dict;
QHash<QString, Speller*> 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 :"<<d->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 \""
<<lang
<<"\" staying with the current language.";
return;
}
}
d->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<QKeyEvent *>(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();
}
}

View file

@ -1,161 +0,0 @@
/*
* highlighter.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtGui/QSyntaxHighlighter>
#include <QtCore/QStringList>
#include <kdeui_export.h>
#include <QTextEdit>
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

View file

@ -1,290 +0,0 @@
<ui version="4.0" >
<class>SonnetUi</class>
<widget class="QWidget" name="SonnetUi" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>481</width>
<height>311</height>
</rect>
</property>
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>5</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>430</width>
<height>300</height>
</size>
</property>
<layout class="QGridLayout" >
<item row="1" column="0" colspan="2" >
<widget class="QLabel" name="textLabel2" >
<property name="whatsThis" >
<string>&lt;qt>&lt;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.&lt;/p>
&lt;p>If the word is not misspelled, you may add it to the dictionary by clicking &lt;b>Add to Dictionary&lt;/b>. If you do not want to add the unknown word to the dictionary, but you want to leave it unchanged, click &lt;b>Ignore&lt;/b> or &lt;b>Ignore All&lt;/b>.&lt;/p>
&lt;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 &lt;b>Replace&lt;/b> or &lt;b>Replace All&lt;/b>.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>Unknown word:</string>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QLabel" name="m_unknownWord" >
<property name="toolTip" >
<string>Unknown word</string>
</property>
<property name="whatsThis" >
<string>&lt;qt>&lt;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.&lt;/p>
&lt;p>If the word is not misspelled, you may add it to the dictionary by clicking &lt;b>Add to Dictionary&lt;/b>. If you do not want to add the unknown word to the dictionary, but you want to leave it unchanged, click &lt;b>Ignore&lt;/b> or &lt;b>Ignore All&lt;/b>.&lt;/p>
&lt;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 &lt;b>Replace&lt;/b> or &lt;b>Replace All&lt;/b>.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>&lt;b>misspelled&lt;/b></string>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QLabel" name="textLabel5" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Select the language of the document you are proofing here.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>&amp;Language:</string>
</property>
<property name="buddy" >
<cstring>m_language</cstring>
</property>
</widget>
</item>
<item row="0" column="0" colspan="6" >
<widget class="QLabel" name="m_contextLabel" >
<property name="toolTip" >
<string>Text excerpt showing the unknown word in its context.</string>
</property>
<property name="whatsThis" >
<string>&lt;qt>
&lt;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.&lt;/p>
&lt;/qt></string>
</property>
<property name="frameShape" >
<enum>QFrame::Box</enum>
</property>
<property name="text" >
<string>... the &lt;b>misspelled&lt;/b> word shown in context ...</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="4" colspan="2" >
<widget class="QPushButton" name="m_addBtn" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>The unknown word was detected and considered unknown because it is not included in the dictionary.&lt;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 &lt;b>Ignore&lt;/b> or &lt;b>Ignore All&lt;/b> instead.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>&lt;&lt; Add to Dictionary</string>
</property>
</widget>
</item>
<item row="1" column="3" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>74</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="5" >
<widget class="QListView" name="m_suggestions" >
<property name="toolTip" >
<string>Suggestion List</string>
</property>
<property name="whatsThis" >
<string>&lt;qt>
&lt;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.&lt;/p>
&lt;p>To correct this word click &lt;b>Replace&lt;/b> if you want to correct only this occurrence or &lt;b>Replace All&lt;/b> if you want to correct all occurrences.&lt;/p>
&lt;/qt></string>
</property>
<property name="resizeMode" >
<enum>Adjust</enum>
</property>
<column>
<property name="text" >
<string>Suggested Words</string>
</property>
</column>
</widget>
</item>
<item row="2" column="0" colspan="2" >
<widget class="QLabel" name="textLabel4" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>If the unknown word is misspelled, you should type the correction for your misspelled word here or select it from the list below.&lt;/p>
&lt;p>You can then click &lt;b>Replace&lt;/b> if you want to correct only this occurrence of the word or &lt;b>Replace All&lt;/b> if you want to correct all occurrences.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>Replace &amp;with:</string>
</property>
<property name="buddy" >
<cstring>m_replacement</cstring>
</property>
</widget>
</item>
<item row="2" column="2" colspan="3" >
<widget class="KLineEdit" name="m_replacement" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>If the unknown word is misspelled, you should type the correction for your misspelled word here or select it from the list below.&lt;/p>
&lt;p>You can then click &lt;b>Replace&lt;/b> if you want to correct only this occurrence of the word or &lt;b>Replace All&lt;/b> if you want to correct all occurrences.&lt;/p>
&lt;/qt></string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="4" >
<widget class="KComboBox" name="m_language" >
<property name="toolTip" >
<string>Language Selection</string>
</property>
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Select the language of the document you are proofing here.&lt;/p>
&lt;/qt></string>
</property>
</widget>
</item>
<item rowspan="3" row="2" column="5" >
<layout class="QVBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="m_suggestBtn" >
<property name="text" >
<string>S&amp;uggest</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_replaceBtn" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Click here to replace this occurrence of the unknown text with the text in the edit box above (to the left).&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>&amp;Replace</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_replaceAllBtn" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Click here to replace all occurrences of the unknown text with the text in the edit box above (to the left).&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>R&amp;eplace All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_skipBtn" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Click here to let this occurrence of the unknown word remain as is.&lt;/p>
&lt;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.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>&amp;Ignore</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_skipAllBtn" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Click here to let all occurrences of the unknown word remain as they are.&lt;/p>
&lt;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.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>I&amp;gnore All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_autoCorrect" >
<property name="whatsThis" >
<string>&lt;qt>
&lt;p>Click here to let all occurrences of the unknown word remain as they are.&lt;/p>
&lt;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.&lt;/p>
&lt;/qt></string>
</property>
<property name="text" >
<string>Autocorrect</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>m_addBtn</tabstop>
<tabstop>m_replacement</tabstop>
<tabstop>m_suggestBtn</tabstop>
<tabstop>m_replaceBtn</tabstop>
<tabstop>m_replaceAllBtn</tabstop>
<tabstop>m_skipBtn</tabstop>
<tabstop>m_skipAllBtn</tabstop>
<tabstop>m_suggestions</tabstop>
<tabstop>m_language</tabstop>
</tabstops>
<connections/>
</ui>

View file

@ -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})

View file

@ -1,169 +0,0 @@
/**
* backgroundtest.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
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 "<<m_len<<" checked in "
<< m_timer.elapsed() << " msec.";
QApplication::exit();
}
void BackgroundTest::slotMisspelling( const QString& word, int start )
{
kDebug()<<"Misspelling \""<< word << "\" at " << start;
m_checker->continueChecking();
}
int main( int argc, char** argv )
{
KCmdLineArgs::init( argc, argv, "SonnetTest", 0, ki18n("SonnetTest"), 0 );
KApplication app;
BackgroundTest test;
return app.exec();
}

View file

@ -1,45 +0,0 @@
/**
* backgroundtest.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QObject>
#include <QtCore/QElapsedTimer>
#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

View file

@ -1,40 +0,0 @@
/**
* test_config.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kdebug.h>
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();
}

View file

@ -1,42 +0,0 @@
/**
* test_configdialog.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kconfig.h>
#include <kcmdlineargs.h>
#include <kdebug.h>
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();
}

View file

@ -1,64 +0,0 @@
/**
* test_dialog.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kcmdlineargs.h>
#include <kdebug.h>
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 :"<<buf;
qApp->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();
}

View file

@ -1,40 +0,0 @@
/**
* test_dialog.h
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <QtCore/QObject>
class TestDialog : public QObject
{
Q_OBJECT
public:
TestDialog();
public Q_SLOTS:
void check( const QString& buffer );
void doneChecking( const QString& );
};
#endif

View file

@ -1,79 +0,0 @@
/*
Copyright (c) 2008 Volker Krause <vkrause@kde.org>
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 <kapplication.h>
#include <kcmdlineargs.h>
#include <kdebug.h>
#include <QHBoxLayout>
#include <QPushButton>
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"

View file

@ -1,71 +0,0 @@
/**
* test_highlighter.cpp
*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
*
* 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 <kapplication.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
#include <QTextEdit>
#include <QAction>
#include <QMenu>
#include <QtGui/qevent.h>
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();
}

View file

@ -1,41 +0,0 @@
/**
* test_highlighter.h
*
* Copyright (C) 2006 Laurent Montel <montel@kde.org>
*
* 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 <QTextEdit>
#include <QContextMenuEvent>
class TestSpell : public QTextEdit
{
Q_OBJECT
public:
TestSpell();
public Q_SLOTS:
void slotActivate();
protected:
virtual void contextMenuEvent( QContextMenuEvent * );
Sonnet::Highlighter *hl;
};
#endif

View file

@ -0,0 +1,165 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QThread>
#include <QTextBoundaryFinder>
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"

View file

@ -0,0 +1,58 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QObject>
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

View file

@ -0,0 +1,131 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QGridLayout>
#include <QLabel>
#include <QCheckBox>
#include <QGroupBox>
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"

View file

@ -0,0 +1,53 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QWidget>
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

View file

@ -0,0 +1,308 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QThread>
#include <QCoreApplication>
#include <QTextBoundaryFinder>
#include <QGridLayout>
#include <QLabel>
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"

View file

@ -0,0 +1,68 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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

View file

@ -0,0 +1,71 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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"

View file

@ -0,0 +1,47 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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

247
kdeui/spell/kspeller.cpp Normal file
View file

@ -0,0 +1,247 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QLocale>
#include <enchant.h>
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<KSpellerPrivate*>(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"

61
kdeui/spell/kspeller.h Normal file
View file

@ -0,0 +1,61 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QObject>
#include <QStringList>
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

View file

@ -0,0 +1,119 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QTextBoundaryFinder>
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"

View file

@ -0,0 +1,58 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
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 <QSyntaxHighlighter>
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

View file

@ -23,13 +23,13 @@
#include <kdeui_export.h> #include <kdeui_export.h>
#include <QtGui/QWidget> #include <QWidget>
#include <QtGui/QStringListModel> #include <QStringListModel>
#include <QListView>
#include <QPushButton>
class KLineEdit; class KLineEdit;
class KComboBox; class KComboBox;
#include <QListView>
#include <QPushButton>
class KEditListWidgetPrivate; class KEditListWidgetPrivate;
/** /**

View file

@ -30,9 +30,6 @@
#include <QTextCursor> #include <QTextCursor>
#include <QTextDocumentFragment> #include <QTextDocumentFragment>
#include <configdialog.h>
#include <dialog.h>
#include "backgroundchecker.h"
#include <kdebug.h> #include <kdebug.h>
#include <kaction.h> #include <kaction.h>
#include <kcursor.h> #include <kcursor.h>
@ -50,6 +47,8 @@
#include <kmessagebox.h> #include <kmessagebox.h>
#include <kmenu.h> #include <kmenu.h>
#include <kwindowsystem.h> #include <kwindowsystem.h>
#include <kspellhighlighter.h>
#include <kspelldialog.h>
#include <QDebug> #include <QDebug>
class KTextEdit::Private class KTextEdit::Private
@ -61,14 +60,12 @@ class KTextEdit::Private
checkSpellingEnabled( false ), checkSpellingEnabled( false ),
findReplaceEnabled(true), findReplaceEnabled(true),
showTabAction(true), showTabAction(true),
showAutoCorrectionButton(false),
highlighter( 0 ), findDlg(0),find(0),repDlg(0),replace(0), findIndex(0), repIndex(0), highlighter( 0 ), findDlg(0),find(0),repDlg(0),replace(0), findIndex(0), repIndex(0),
lastReplacedPosition(-1) lastReplacedPosition(-1)
{ {
//Check the default sonnet settings to see if spellchecking should be enabled. //Check the default settings to see if spellchecking should be enabled.
KConfig sonnetKConfig("sonnetrc"); KConfigGroup spellgroup(KGlobal::config(), "Spelling");
KConfigGroup group(&sonnetKConfig, "Spelling"); checkSpellingEnabled = spellgroup.readEntry("checkerEnabledByDefault", false);
checkSpellingEnabled = group.readEntry("checkerEnabledByDefault", false);
// i18n: Placeholder text in text edit widgets is the text appearing // i18n: Placeholder text in text edit widgets is the text appearing
// before any user input, briefly explaining to the user what to type // 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 spellCheckerMisspelling( const QString &text, int pos );
void spellCheckerCorrected( const QString &, int,const QString &); void spellCheckerCorrected( const QString &, int,const QString &);
void spellCheckerAutoCorrect(const QString&,const QString&);
void spellCheckerCanceled(); void spellCheckerCanceled();
void spellCheckerFinished(); void spellCheckerFinished();
void toggleAutoSpellCheck(); void toggleAutoSpellCheck();
@ -134,66 +130,58 @@ class KTextEdit::Private
bool checkSpellingEnabled : 1; bool checkSpellingEnabled : 1;
bool findReplaceEnabled: 1; bool findReplaceEnabled: 1;
bool showTabAction: 1; bool showTabAction: 1;
bool showAutoCorrectionButton: 1;
QTextDocumentFragment originalDoc; QTextDocumentFragment originalDoc;
QString spellCheckingConfigFileName;
QString spellCheckingLanguage; QString spellCheckingLanguage;
Sonnet::Highlighter *highlighter; KSpellHighlighter *highlighter;
KFindDialog *findDlg; KFindDialog *findDlg;
KFind *find; KFind *find;
KReplaceDialog *repDlg; KReplaceDialog *repDlg;
KReplace *replace; KReplace *replace;
int findIndex, repIndex; int findIndex, repIndex;
int lastReplacedPosition; int lastReplacedPosition;
KConfig *sonnetKConfig;
}; };
void KTextEdit::Private::checkSpelling(bool force) void KTextEdit::Private::checkSpelling(bool force)
{ {
if(parent->document()->isEmpty()) if (parent->document()->isEmpty()) {
{ KMessageBox::information(parent, i18n("Nothing to spell check."));
KMessageBox::information(parent, i18n("Nothing to spell check.")); if (force) {
if(force) { emit parent->spellCheckingFinished();
emit parent->spellCheckingFinished(); }
} return;
return; }
} KSpellDialog *spellDialog = new KSpellDialog(KGlobal::config().data(), force ? parent : 0);
Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker; if (!spellCheckingLanguage.isEmpty()) {
if(!spellCheckingLanguage.isEmpty()) spellDialog->changeLanguage(spellCheckingLanguage);
backgroundSpellCheck->changeLanguage(spellCheckingLanguage); }
Sonnet::Dialog *spellDialog = new Sonnet::Dialog( spellDialog->setAttribute(Qt::WA_DeleteOnClose, true);
backgroundSpellCheck, force ? parent : 0); connect(
backgroundSpellCheck->setParent(spellDialog); spellDialog, SIGNAL(replace(QString,int,QString)),
spellDialog->setAttribute(Qt::WA_DeleteOnClose, true); parent, SLOT(spellCheckerCorrected(QString,int,QString))
spellDialog->activeAutoCorrect(showAutoCorrectionButton); );
connect(spellDialog, SIGNAL(replace(QString,int,QString)), connect(
parent, SLOT(spellCheckerCorrected(QString,int,QString))); spellDialog, SIGNAL(misspelling(QString,int)),
connect(spellDialog, SIGNAL(misspelling(QString,int)), parent, SLOT(spellCheckerMisspelling(QString,int))
parent, SLOT(spellCheckerMisspelling(QString,int))); );
connect(spellDialog, SIGNAL(autoCorrect(QString,QString)), connect(
parent, SLOT(spellCheckerAutoCorrect(QString,QString))); spellDialog, SIGNAL(accepted()),
connect(spellDialog, SIGNAL(done(QString)), parent, SLOT(spellCheckerFinished())
parent, SLOT(spellCheckerFinished())); );
connect(spellDialog, SIGNAL(cancel()), connect(
parent, SLOT(spellCheckerCanceled())); spellDialog, SIGNAL(rejected()),
//Laurent in sonnet/dialog.cpp we emit done(QString) too => it calls here twice spellCheckerFinished not necessary parent, SLOT(spellCheckerCanceled())
/* );
connect(spellDialog, SIGNAL(stop()), connect(
parent, SLOT(spellCheckerFinished())); spellDialog, SIGNAL(languageChanged(QString)),
*/ parent, SIGNAL(languageChanged(QString))
connect(spellDialog, SIGNAL(spellCheckStatus(QString)), );
parent, SIGNAL(spellCheckStatus(QString))); if (force) {
connect(spellDialog, SIGNAL(languageChanged(QString)), connect(spellDialog, SIGNAL(accepted()), parent, SIGNAL(spellCheckingFinished()));
parent, SIGNAL(languageChanged(QString))); connect(spellDialog, SIGNAL(rejected()), parent, SIGNAL(spellCheckingCanceled()));
if(force) { }
connect(spellDialog, SIGNAL(done(QString)),parent, SIGNAL(spellCheckingFinished())); originalDoc = QTextDocumentFragment(parent->document());
connect(spellDialog, SIGNAL(cancel()), parent, SIGNAL(spellCheckingCanceled())); spellDialog->setBuffer(parent->toPlainText());
//Laurent in sonnet/dialog.cpp we emit done(QString) too => it calls here twice spellCheckerFinished not necessary spellDialog->show();
//connect(spellDialog, SIGNAL(stop()), parent, SIGNAL(spellCheckingFinished()));
}
originalDoc = QTextDocumentFragment(parent->document());
spellDialog->setBuffer(parent->toPlainText());
spellDialog->show();
} }
@ -206,11 +194,6 @@ void KTextEdit::Private::spellCheckerCanceled()
spellCheckerFinished(); 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 ) void KTextEdit::Private::spellCheckerMisspelling( const QString &text, int pos )
{ {
//kDebug()<<"TextEdit::Private::spellCheckerMisspelling :"<<text<<" pos :"<<pos; //kDebug()<<"TextEdit::Private::spellCheckerMisspelling :"<<text<<" pos :"<<pos;
@ -325,11 +308,6 @@ KTextEdit::~KTextEdit()
delete d; delete d;
} }
void KTextEdit::setSpellCheckingConfigFileName(const QString &_fileName)
{
d->spellCheckingConfigFileName = _fileName;
}
const QString& KTextEdit::spellCheckingLanguage() const const QString& KTextEdit::spellCheckingLanguage() const
{ {
return d->spellCheckingLanguage; 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) bool KTextEdit::event(QEvent* ev)
{ {
if (ev->type() == QEvent::ShortcutOverride) { if (ev->type() == QEvent::ShortcutOverride) {
@ -696,18 +660,18 @@ void KTextEdit::wheelEvent( QWheelEvent *event )
void KTextEdit::createHighlighter() 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; return d->highlighter;
} }
void KTextEdit::setHighlighter(Sonnet::Highlighter *_highLighter) void KTextEdit::setHighlighter(KSpellHighlighter *highLighter)
{ {
delete d->highlighter; delete d->highlighter;
d->highlighter = _highLighter; d->highlighter = highLighter;
} }
void KTextEdit::setCheckSpellingEnabled(bool check) 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" #include "moc_ktextedit.cpp"

View file

@ -21,7 +21,7 @@
#define KTEXTEDIT_H #define KTEXTEDIT_H
#include <kdeui_export.h> #include <kdeui_export.h>
#include <sonnet/highlighter.h> #include <kspellhighlighter.h>
#include <QtGui/QTextEdit> #include <QtGui/QTextEdit>
#define HAVE_SHOWTABACTION 1 #define HAVE_SHOWTABACTION 1
@ -111,26 +111,10 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
*/ */
void highlightWord( int length, int pos ); 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. * Allows to create a specific highlighter if reimplemented.
* *
* By default, it creates a normal highlighter, based on the config * By default, it creates a normal highlighter.
* file given to setSpellCheckingConfigFileName().
* *
* This highlighter is set each time spell checking is toggled on by * This highlighter is set each time spell checking is toggled on by
* calling setCheckSpellingEnabled(), but can later be overridden by calling * 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 setHighlighter()
* @see highlighter() * @see highlighter()
* @see setSpellCheckingConfigFileName()
*/ */
virtual void createHighlighter(); virtual void createHighlighter();
@ -150,7 +133,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
* @see setHighlighter() * @see setHighlighter()
* @see createHighlighter() * @see createHighlighter()
*/ */
Sonnet::Highlighter* highlighter() const; KSpellHighlighter* highlighter() const;
/** /**
* Sets a custom backgound spell highlighter for this text edit. * 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() * @see createHighlighter()
* @param highLighter the new highlighter which will be used now * @param highLighter the new highlighter which will be used now
*/ */
void setHighlighter(Sonnet::Highlighter *_highLighter); void setHighlighter(KSpellHighlighter *_highLighter);
/** /**
* Return standard KTextEdit popupMenu * Return standard KTextEdit popupMenu
@ -208,11 +191,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
*/ */
void showTabAction(bool show); void showTabAction(bool show);
/**
* @since 4.10
*/
void showAutoCorrectButton(bool show);
/** /**
* @since 4.10 * @since 4.10
* create a modal spellcheck dialogbox and spellCheckingFinished signal we sent when * 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 ); 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 * Emitted when the user changes the language in the spellcheck dialog
* shown by checkSpelling() or when calling setSpellCheckingLanguage(). * shown by checkSpelling() or when calling setSpellCheckingLanguage().
@ -259,12 +231,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
void aboutToShowContextMenu(QMenu* menu); void aboutToShowContextMenu(QMenu* menu);
/** /**
* @since 4.10 * signal spellCheckingFinished is sent when we finish spell check or we click on "Terminate" button in speller dialogbox
*/
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
* @since 4.10 * @since 4.10
*/ */
void spellCheckingFinished(); void spellCheckingFinished();
@ -288,28 +255,12 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
void setSpellCheckingLanguage(const QString &language); void setSpellCheckingLanguage(const QString &language);
/** /**
* Show a dialog to check the spelling. The spellCheckStatus() signal * Show a dialog to check the spelling. The spellCheckingFinished() or
* will be emitted when the spell checking dialog is closed. * spellCheckingCanceled() signal will be emitted when the spell checking
* dialog is closed.
*/ */
void checkSpelling(); 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 * Create replace dialogbox
* @since 4.1 * @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 spellCheckerMisspelling( const QString&, int ) )
Q_PRIVATE_SLOT( d, void spellCheckerCorrected(const QString&, int,const QString&) ) Q_PRIVATE_SLOT( d, void spellCheckerCorrected(const QString&, int,const QString&) )
Q_PRIVATE_SLOT( d, void spellCheckerCanceled()) 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 spellCheckerFinished() )
Q_PRIVATE_SLOT( d, void undoableClear() ) Q_PRIVATE_SLOT( d, void undoableClear() )
Q_PRIVATE_SLOT( d, void toggleAutoSpellCheck() ) Q_PRIVATE_SLOT( d, void toggleAutoSpellCheck() )

View file

@ -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 WhatsThis=A widget holding a lineedit and a pushbutton. A "file open" dialog opened when clicking on the pushbutton
Group=Input (KDE) Group=Input (KDE)
[Sonnet::DictionaryComboBox] [KSpellDictionaryComboBox]
IncludeFile=sonnet/dictionarycombobox.h IncludeFile=kspelldictionarycombobox.h
ToolTip=Dictionary Combobox ToolTip=Dictionary Combobox
WhatsThis=A combobox to select a dictionary for spellchecking WhatsThis=A combobox to select a dictionary for spellchecking
Group=Sonnet (KDE) Group=Spell (KDE)
[KMediaWidget] [KMediaWidget]
ToolTip=Multimedia files player (KDE) ToolTip=Multimedia files player (KDE)

View file

@ -410,16 +410,14 @@
<entry key="Sort reversed" type="Bool" name="Sort reversed" > <entry key="Sort reversed" type="Bool" name="Sort reversed" >
<default>false</default> <default>false</default>
</entry> </entry>
</group>
<group name="Spelling" >
<entry key="defaultLanguage" type="String" />
<entry key="checkerEnabledByDefault" type="bool" />
<entry key="personalWords" type="StringList" />
</group> </group>
<group name="Sonnet" >
<entry key="Sonnet_Client" type="String" />
<entry key="Sonnet_DictFromList" type="String" />
<entry key="Sonnet_Dictionary" type="String" />
<entry key="Sonnet_Encoding" type="String" />
<entry key="Sonnet_NoRootAffix" type="String" />
<entry key="Sonnet_RunTogether" type="String" />
</group>
<group name="Locale" > <group name="Locale" >
<entry key="Country" type="String" > <entry key="Country" type="String" >
<label>What country</label> <label>What country</label>