aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/CMakeLists.txt4
-rw-r--r--src/modules/options/OptionsWidget_textEncoding.cpp93
-rw-r--r--src/modules/options/OptionsWidget_textEncoding.h2
-rw-r--r--src/modules/spellchecker/CMakeLists.txt8
-rw-r--r--src/modules/spellchecker/libkvispellchecker.cpp157
5 files changed, 252 insertions, 12 deletions
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index 57468051d..3ab0c1f29 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -52,6 +52,10 @@ if(COMPILE_PYTHON_SUPPORT)
subdirs(python)
endif()
+if(COMPILE_ENCHANT_SUPPORT)
+ subdirs(spellchecker)
+endif()
+
if(APPLE)
# This is a dirty trick ensure we get some code executed after the last module gets installed
subdirs(zzz_afterlastmodule)
diff --git a/src/modules/options/OptionsWidget_textEncoding.cpp b/src/modules/options/OptionsWidget_textEncoding.cpp
index eeaac0411..e6f8f7ab2 100644
--- a/src/modules/options/OptionsWidget_textEncoding.cpp
+++ b/src/modules/options/OptionsWidget_textEncoding.cpp
@@ -30,9 +30,11 @@
#include "KviQString.h"
#include "KviApplication.h"
#include "KviFileUtils.h"
+#include "KviKvsScript.h"
#include <QDir>
#include <QMessageBox>
+#include <QHeaderView>
QString g_szPrevSettedLocale;
@@ -42,19 +44,23 @@ OptionsWidget_textEncoding::OptionsWidget_textEncoding(QWidget * parent)
setObjectName("textencoding_options_widget");
createLayout();
+ KviTalGroupBox* gbox = addGroupBox(0,0,0,0,Qt::Horizontal,__tr2qs_ctx("Encoding","options"));
+ QGridLayout* grid = new QGridLayout;
+ gbox->setLayout(grid);
+
//server encoding
- addLabel(0,0,0,0,__tr2qs_ctx("Default server encoding:","options"));
+ grid->addWidget(addLabel(gbox,__tr2qs_ctx("Default server encoding:","options")),0,0);
- m_pSrvEncodingCombo = new QComboBox(this);
- addWidgetToLayout(m_pSrvEncodingCombo,1,0,1,0);
+ m_pSrvEncodingCombo = new QComboBox(gbox);
+ grid->addWidget(m_pSrvEncodingCombo,0,1);
m_pSrvEncodingCombo->addItem(__tr2qs_ctx("Use Language Encoding","options"));
//text encoding
- addLabel(0,1,0,1,__tr2qs_ctx("Default text encoding:","options"));
+ grid->addWidget(addLabel(gbox,__tr2qs_ctx("Default text encoding:","options")),1,0);
- m_pTextEncodingCombo = new QComboBox(this);
- addWidgetToLayout(m_pTextEncodingCombo,1,1,1,1);
+ m_pTextEncodingCombo = new QComboBox(gbox);
+ grid->addWidget(m_pTextEncodingCombo,1,1);
m_pTextEncodingCombo->addItem(__tr2qs_ctx("Use Language Encoding","options"));
@@ -78,14 +84,17 @@ OptionsWidget_textEncoding::OptionsWidget_textEncoding(QWidget * parent)
m_pTextEncodingCombo->setCurrentIndex(iTextMatch);
m_pSrvEncodingCombo->setCurrentIndex(iSrvMatch);
- addLabel(0,2,0,2,__tr2qs_ctx("Force language:","options"));
+ gbox = addGroupBox(0,1,0,1,Qt::Horizontal,__tr2qs_ctx("Language","options"));
+ grid = new QGridLayout;
+ gbox->setLayout(grid);
+
+ grid->addWidget(addLabel(gbox,__tr2qs_ctx("Force language:","options")),0,0);
- m_pForcedLocaleCombo = new QComboBox(this);
+ m_pForcedLocaleCombo = new QComboBox(gbox);
- addWidgetToLayout(m_pForcedLocaleCombo,1,2,1,2);
+ grid->addWidget(m_pForcedLocaleCombo,0,1);
- QLabel * l = new QLabel(__tr2qs_ctx("<b>Note:</b> You need to restart KVirc to apply a language changing","options"),this);
- addWidgetToLayout(l,0,3,1,3);
+ grid->addWidget(addLabel(gbox,__tr2qs_ctx("<b>Note:</b> You need to restart KVirc to apply a language changing","options")),1,0,1,2);
m_pForcedLocaleCombo->addItem(__tr2qs_ctx("Automatic detection","options"));
m_pForcedLocaleCombo->addItem(__tr2qs_ctx("en","options"));
@@ -124,7 +133,56 @@ OptionsWidget_textEncoding::OptionsWidget_textEncoding(QWidget * parent)
m_pForcedLocaleCombo->setCurrentIndex(1);
else
m_pForcedLocaleCombo->setCurrentIndex(iMatch);
- addRowSpacer(0,4,1,4);
+
+#ifdef COMPILE_ENCHANT_SUPPORT
+ {
+ gbox = addGroupBox(0,2,0,2,Qt::Horizontal,__tr2qs_ctx("Spell checker dictionaries","options"));
+
+ KviKvsVariant availableDictionaries;
+ KviKvsScript::evaluate("$spellchecker.availableDictionaries", NULL, NULL, &availableDictionaries);
+ const KviPointerHashTable<QString, KviKvsVariant>* hashTable = availableDictionaries.hash()->dict();
+ KviPointerHashTableIterator<QString, KviKvsVariant> iter(*hashTable);
+ QMap<QString, QString> dictMap;
+ for (bool b = iter.moveFirst(); b; b = iter.moveNext()) {
+ QString szDescription;
+ iter.current()->asString(szDescription);
+ dictMap[iter.currentKey()] = szDescription;
+ }
+
+ m_pSpellCheckerDictionaries = new QTableWidget(gbox);
+ m_pSpellCheckerDictionaries->setRowCount(dictMap.size());
+ m_pSpellCheckerDictionaries->setColumnCount(2);
+ QStringList header;
+ header << __tr2qs_ctx("Language code", "options");
+ header << __tr2qs_ctx("Provided by", "options");
+ m_pSpellCheckerDictionaries->setHorizontalHeaderLabels(header);
+#if (QT_VERSION >= 0x050000)
+ m_pSpellCheckerDictionaries->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+#else
+ m_pSpellCheckerDictionaries->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
+#endif
+ m_pSpellCheckerDictionaries->setSelectionBehavior(QAbstractItemView::SelectRows);
+ m_pSpellCheckerDictionaries->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_pSpellCheckerDictionaries->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ int row = 0;
+ for (QMap<QString, QString>::iterator it = dictMap.begin(); it != dictMap.end(); ++it, ++row) {
+ QTableWidgetItem* itemLang = new QTableWidgetItem(it.key());
+ itemLang->setCheckState(KVI_OPTION_STRINGLIST(KviOption_stringlistSpellCheckerDictionaries).contains(it.key()) ? Qt::Checked : Qt::Unchecked);
+ itemLang->setFlags(itemLang->flags() & ~Qt::ItemIsEditable);
+ m_pSpellCheckerDictionaries->setItem(row,0,itemLang);
+
+ QTableWidgetItem* itemDesc = new QTableWidgetItem(it.value());
+ itemDesc->setFlags(itemDesc->flags() & ~Qt::ItemIsEditable);
+ m_pSpellCheckerDictionaries->setItem(row,1,itemDesc);
+ }
+
+ m_pSpellCheckerDictionaries->resizeColumnsToContents();
+ m_pSpellCheckerDictionaries->resizeRowsToContents();
+ }
+#else
+ addRowSpacer(0,2,0,2);
+#endif
}
OptionsWidget_textEncoding::~OptionsWidget_textEncoding()
@@ -166,5 +224,16 @@ void OptionsWidget_textEncoding::commit()
}
/* if(!KviQString::equalCI(m_pForcedLocaleCombo->text(idx),m_szLanguage))
QMessageBox::information(0,"KVIrc",__tr2qs_ctx("You need to restart KVirc to apply a language changing","options"),QMessageBox::Ok);*/
+
+#ifdef COMPILE_ENCHANT_SUPPORT
+ QStringList wantedDictionaries;
+ for (int i = 0; i < m_pSpellCheckerDictionaries->rowCount(); ++i) {
+ if (m_pSpellCheckerDictionaries->item(i,0)->checkState() == Qt::Checked) {
+ wantedDictionaries << m_pSpellCheckerDictionaries->item(i,0)->text();
+ }
+ }
+ KVI_OPTION_STRINGLIST(KviOption_stringlistSpellCheckerDictionaries) = wantedDictionaries;
+ KviKvsScript::run("spellchecker.reloadDictionaries", NULL);
+#endif
}
diff --git a/src/modules/options/OptionsWidget_textEncoding.h b/src/modules/options/OptionsWidget_textEncoding.h
index 964ad606f..a16169c39 100644
--- a/src/modules/options/OptionsWidget_textEncoding.h
+++ b/src/modules/options/OptionsWidget_textEncoding.h
@@ -27,6 +27,7 @@
#include "KviOptionsWidget.h"
#include <QComboBox>
+#include <QTableWidget>
#define KVI_OPTIONS_WIDGET_ICON_OptionsWidget_textEncoding KviIconManager::TextEncoding
#define KVI_OPTIONS_WIDGET_NAME_OptionsWidget_textEncoding __tr2qs_no_lookup("Language")
@@ -45,6 +46,7 @@ protected:
QComboBox * m_pTextEncodingCombo;
QComboBox * m_pSrvEncodingCombo;
QComboBox * m_pForcedLocaleCombo;
+ QTableWidget * m_pSpellCheckerDictionaries;
public:
virtual void commit();
};
diff --git a/src/modules/spellchecker/CMakeLists.txt b/src/modules/spellchecker/CMakeLists.txt
new file mode 100644
index 000000000..34b241e0e
--- /dev/null
+++ b/src/modules/spellchecker/CMakeLists.txt
@@ -0,0 +1,8 @@
+# CMakeLists for src/modules/avatar
+
+set(kvispellchecker_SRCS
+ libkvispellchecker.cpp
+)
+
+set(kvi_module_name kvispellchecker)
+include(${CMAKE_SOURCE_DIR}/cmake/module.rules.txt)
diff --git a/src/modules/spellchecker/libkvispellchecker.cpp b/src/modules/spellchecker/libkvispellchecker.cpp
new file mode 100644
index 000000000..0a384d77a
--- /dev/null
+++ b/src/modules/spellchecker/libkvispellchecker.cpp
@@ -0,0 +1,157 @@
+//=============================================================================
+//
+// File : libkvispellchecker.cpp
+// Creation date : Thu Dec 26 2014 15:12:12 GMT by Alexey Sokolov
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright © 2014 Alexey Sokolov <sokolov@google.com>
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "KviModule.h"
+#include "KviOptions.h"
+#include <enchant.h>
+
+static EnchantBroker* g_pEnchantBroker = NULL;
+static KviPointerList<EnchantDict>* g_pEnchantDicts = NULL;
+
+/*
+ @doc: spellchecker.available_dictionaries
+ @type:
+ function
+ @title:
+ $spellchecker.available_dictionaries
+ @short:
+ Return available dictionaries.
+ @syntax:
+ <hash> $spellchecker.available_dictionaries
+ @description:
+ This function returns a hash. For every supported dictionary, key is the language code,
+ value is name of provider for that language (e.g. Aspell).
+*/
+static void spellchecker_enumerate_dicts(const char* szLang, const char* /*szName*/,
+ const char* szDesc, const char* /*szFile*/, void* pData) {
+ KviKvsHash* pHash = reinterpret_cast<KviKvsHash*>(pData);
+ pHash->set(szLang, new KviKvsVariant(szDesc));
+}
+static bool spellchecker_kvs_available_dictionaries(KviKvsModuleFunctionCall* c) {
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+ KviKvsHash* pHash = new KviKvsHash;
+ enchant_broker_list_dicts(g_pEnchantBroker, spellchecker_enumerate_dicts, pHash);
+ c->returnValue()->setHash(pHash);
+ return true;
+}
+
+/*
+ @doc: spellchecker.check
+ @type:
+ function
+ @title:
+ $spellchecker.check
+ @short:
+ Check a single work for spelling mistakes.
+ @syntax:
+ <bool> $spellchecker.check(<word:string>)
+ @description:
+ This function returns true if the word is spelled correctly.
+*/
+static bool spellchecker_kvs_check(KviKvsModuleFunctionCall* c) {
+ QString szWord;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("word", KVS_PT_STRING, 0, szWord)
+ KVSM_PARAMETERS_END(c)
+ QByteArray utf8 = szWord.toUtf8();
+ bool bResult = g_pEnchantDicts->isEmpty();
+ KviPointerListIterator<EnchantDict> it(*g_pEnchantDicts);
+ for (bool b = it.moveFirst(); b; b = it.moveNext()) {
+ bResult |= enchant_dict_check(*it, utf8.data(), utf8.size()) == 0;
+ }
+ c->returnValue()->setBoolean(bResult);
+ return true;
+}
+
+static void spellchecker_reload_dicts() {
+ while (!g_pEnchantDicts->isEmpty()) {
+ enchant_broker_free_dict(g_pEnchantBroker, g_pEnchantDicts->takeFirst());
+ }
+ const QStringList& wantedDictionaries = KVI_OPTION_STRINGLIST(KviOption_stringlistSpellCheckerDictionaries);
+ foreach(QString szLang, wantedDictionaries) {
+ EnchantDict* pDict = enchant_broker_request_dict(g_pEnchantBroker, szLang.toUtf8().data());
+ if (pDict) {
+ g_pEnchantDicts->append(pDict);
+ } else {
+ qDebug("Can't load spellchecker dictionary %s: %s", szLang.toUtf8().data(), enchant_broker_get_error(g_pEnchantBroker));
+ }
+ }
+}
+
+/*
+ @doc: spellchecker.reloadDictionaries
+ @type:
+ command
+ @title:
+ spellchecker.reloadDictionaries
+ @short:
+ Reload spell checker dictionaries
+ @syntax:
+ spellchecker.reloadDictionaries
+ @description:
+ Reload spell checker dictionaries
+*/
+static bool spellchecker_kvs_reload_dictionaries(KviKvsModuleCommandCall * c)
+{
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+ spellchecker_reload_dicts();
+ return true;
+}
+
+static bool spellchecker_module_init(KviModule* m) {
+ g_pEnchantBroker = enchant_broker_init();
+ g_pEnchantDicts = new KviPointerList<EnchantDict>(/* bAutoDelete = */ false);
+
+ spellchecker_reload_dicts();
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m, "reloadDictionaries", spellchecker_kvs_reload_dictionaries);
+ KVSM_REGISTER_FUNCTION(m, "availableDictionaries", spellchecker_kvs_available_dictionaries);
+ KVSM_REGISTER_FUNCTION(m, "check", spellchecker_kvs_check);
+ return true;
+}
+
+static bool spellchecker_module_cleanup(KviModule*) {
+ while (!g_pEnchantDicts->isEmpty()) {
+ enchant_broker_free_dict(g_pEnchantBroker, g_pEnchantDicts->takeFirst());
+ }
+ delete g_pEnchantDicts;
+ g_pEnchantDicts = NULL;
+ enchant_broker_free(g_pEnchantBroker);
+ g_pEnchantBroker = NULL;
+ return true;
+}
+
+KVIRC_MODULE(
+ "SpellChecker", // module name
+ "4.0.0", // module version
+ "Copyright (C) 2014 Alexey Sokolov (sokolov at google dot com)", // author & (C)
+ "Spell checker",
+ spellchecker_module_init,
+ 0,
+ 0,
+ spellchecker_module_cleanup,
+ 0
+)