diff options
author | Alexey Dokuchaev <danfe@FreeBSD.org> | 2019-04-07 14:45:50 +0000 |
---|---|---|
committer | Alexey Dokuchaev <danfe@FreeBSD.org> | 2019-04-07 14:45:50 +0000 |
commit | 59494c0dce2dcd9e8c41b6fcc9a47e6bf2940abd (patch) | |
tree | 5cd71b1da5008092a4a0623cca306c0a58e713b5 /net-im/psi | |
parent | 751dfb9495b6a6587fc2cf6e9bf8376b1b60aad4 (diff) | |
download | ports-59494c0dce2dcd9e8c41b6fcc9a47e6bf2940abd.tar.gz ports-59494c0dce2dcd9e8c41b6fcc9a47e6bf2940abd.zip |
Notes
Diffstat (limited to 'net-im/psi')
-rw-r--r-- | net-im/psi/Makefile | 6 | ||||
-rw-r--r-- | net-im/psi/distinfo | 6 | ||||
-rw-r--r-- | net-im/psi/files/hunspellchecker.cpp | 215 | ||||
-rw-r--r-- | net-im/psi/files/hunspellchecker.h | 71 | ||||
-rw-r--r-- | net-im/psi/files/patch-git_4b838c0 | 15 | ||||
-rw-r--r-- | net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.cpp | 37 | ||||
-rw-r--r-- | net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.h | 19 | ||||
-rw-r--r-- | net-im/psi/files/patch-src_msgmle.cpp | 116 | ||||
-rw-r--r-- | net-im/psi/files/patch-src_msgmle.h | 28 | ||||
-rw-r--r-- | net-im/psi/files/patch-src_options_opt__advanced.cpp | 66 | ||||
-rw-r--r-- | net-im/psi/files/patch-src_options_opt__advanced.ui | 29 |
11 files changed, 588 insertions, 20 deletions
diff --git a/net-im/psi/Makefile b/net-im/psi/Makefile index 727745a3bcc9..4866640ec735 100644 --- a/net-im/psi/Makefile +++ b/net-im/psi/Makefile @@ -2,8 +2,7 @@ # $FreeBSD$ PORTNAME= psi -DISTVERSION= 1.3 -PORTREVISION= 4 +PORTVERSION= 1.4 CATEGORIES= net-im MASTER_SITES= SF/${PORTNAME}/Psi/${PORTVERSION} @@ -43,6 +42,9 @@ ENCHANT_LIB_DEPENDS= libenchant.so:textproc/enchant ENCHANT_CMAKE_BOOL= USE_ENCHANT post-patch: +# Replace original Hunspell implementation with better alternative + @${CP} ${FILESDIR}/hunspellchecker.* \ + ${WRKSRC}/src/libpsi/tools/spellchecker # Avoid conflict with C++20 <version> by adding .txt suffix @${MV} ${WRKSRC}/version ${WRKSRC}/version.txt @${REINPLACE_CMD} -i .c++20 's,SOURCE_DIR}/version,&.txt,' \ diff --git a/net-im/psi/distinfo b/net-im/psi/distinfo index fe4e129d9b9d..c4956a95e707 100644 --- a/net-im/psi/distinfo +++ b/net-im/psi/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1508773121 -SHA256 (psi-1.3.tar.xz) = 59debd16e61ab1d4ff88aca9f41b9caaaca8395f1576418fb99214d5e2c6fa8b -SIZE (psi-1.3.tar.xz) = 2143076 +TIMESTAMP = 1541113245 +SHA256 (psi-1.4.tar.xz) = 761934c1c62daf69215f085ba24d7f9cd4db05ef0ad735383d68fb03d21571ad +SIZE (psi-1.4.tar.xz) = 2119840 diff --git a/net-im/psi/files/hunspellchecker.cpp b/net-im/psi/files/hunspellchecker.cpp new file mode 100644 index 000000000000..ed8eea8ef1cf --- /dev/null +++ b/net-im/psi/files/hunspellchecker.cpp @@ -0,0 +1,215 @@ +/* + * hunspellchecker.cpp + * + * Copyright (C) 2009 Alexander Tsvyashchenko + * + * 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 option) any later version. + * + * You can also redistribute and/or modify this program under the + * terms of the Psi License, specified in the accompanied COPYING + * file, as published by the Psi Project; either dated January 1st, + * 2005, or (at your option) 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 library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <QDir> +#include <QCoreApplication> +#include <QtDebug> +#include <QTextCodec> + +#include <hunspell/hunspell.hxx> +#include "hunspellchecker.h" + +HunSpellChecker::HunSpellChecker() +{ + QStringList dict_paths(getDictSearchPaths()); + + for (QStringList::const_iterator dict_path_it = dict_paths.begin(); dict_path_it != dict_paths.end(); ++dict_path_it) { + // Get all affixes present in given path. + QStringList affixes = QDir(*dict_path_it).entryList(QStringList("*.aff"), QDir::Files); + + for (QStringList::const_iterator affix_it = affixes.begin(); affix_it != affixes.end(); ++affix_it) { + QString base_name(QFileInfo(*affix_it).baseName()); + int sep_pos = base_name.indexOf("_"); + QString lang = sep_pos != -1 ? base_name.left(sep_pos) : base_name; + + if (!all_langs_.contains(lang)) + all_langs_.append(lang); + } + } +} + +void HunSpellChecker::clearSpellers() +{ + for (HunSpellers::const_iterator it = spellers_.begin(); it != spellers_.end(); ++it) + delete it.value().speller; + + spellers_.clear(); +} + +HunSpellChecker::~HunSpellChecker() +{ + clearSpellers(); +} + +bool HunSpellChecker::isCorrect(const QString& word) +{ + if (!spellers_.empty()) { + for (HunSpellers::const_iterator it = spellers_.begin(); it != spellers_.end(); ++it) { + QByteArray word_enc = it.value().codec -> fromUnicode(word); + if (it.value().speller -> spell(word_enc.constData()) != 0) + return true; + } + return false; + } + return true; +} + +QList<QString> HunSpellChecker::suggestions(const QString& word, const QString& lang, unsigned max_sugs) +{ + QList<QString> words; + + HunSpellers::const_iterator it = spellers_.find(lang); + + if (it != spellers_.end()) { + char** suggestions; + QByteArray word_enc = it.value().codec -> fromUnicode(word); + + if (int sugs_num = it.value().speller -> suggest(&suggestions, word_enc.constData())) { + int sugs_out = max_sugs ? std::min((int)max_sugs, sugs_num) : sugs_num; + for (int i = 0; i < sugs_out; ++i) { + words << it.value().codec -> toUnicode(suggestions[i]); + } + it.value().speller -> free_list(&suggestions, sugs_num); + } + } + + return words; +} + +// FIXME: hunspell keeps added words in memory only! +// To survive program exit they have to be saved/restored manually, +// which is not done here. +bool HunSpellChecker::add(const QString& word, const QString& lang) +{ + QString trimmed_word = word.trimmed(); + HunSpellers::const_iterator it = spellers_.find(lang); + + if(!trimmed_word.isEmpty() && it != spellers_.end()) { + QByteArray word_enc = it.value().codec -> fromUnicode(trimmed_word); + it.value().speller -> add(word_enc.constData()); + return true; + } + + return false; +} + +bool HunSpellChecker::available() const +{ + return true; +} + +bool HunSpellChecker::writable() const +{ + return true; +} + +QList<QString> HunSpellChecker::getAllLanguages() const +{ + return all_langs_; +} + +QList<QString> HunSpellChecker::getDictSearchPaths() const +{ + QStringList dict_paths(QString("%1/hunspell").arg(QCoreApplication::applicationDirPath())); + + // Paths taken from hunspell-1.2.8/src/tools/hunspell.cxx +#ifdef Q_OS_WIN32 + dict_paths << "C:/Hunspell"; +#else + dict_paths << + "/usr/local/share/hunspell" << + "/usr/share/myspell" << + "/usr/share/myspell/dicts"; +#endif + + return dict_paths; +} + +void HunSpellChecker::setActiveLanguages(const QList<QString>& langs) +{ + // Free all spellers not needed anymore. + for (HunSpellers::iterator it = spellers_.begin(); it != spellers_.end(); ) + { + if (!langs.contains(it.key())) + { + delete it.value().speller; + it = spellers_.erase(it); + } + else + ++it; + } + + QStringList dict_paths(getDictSearchPaths()); + + for (QStringList::const_iterator dict_path_it = dict_paths.begin(); dict_path_it != dict_paths.end(); ++dict_path_it) + { + for (QStringList::const_iterator lang_it = langs.begin(); lang_it != langs.end(); ++lang_it) + { + // Load dictionaries only for those languages that are not present already. + if (spellers_.contains(*lang_it)) + continue; + + // Get all affixes with names beginning with the specified language. + QStringList affixes = QDir(*dict_path_it).entryList(QStringList(QString("%1*.aff").arg(*lang_it)), QDir::Files); + + for (QStringList::const_iterator affix_it = affixes.begin(); affix_it != affixes.end(); ++affix_it) + { + QString base_name(QFileInfo(*affix_it).completeBaseName()); + + // Get all dictionaries with names beginning with the affix name. + QStringList dicts_all = QDir(*dict_path_it).entryList(QStringList(QString("%1*.dic").arg(base_name)), QDir::Files), + dicts_to_add; + + // Add all dictionaries except those that have corresponding more specific affix name: those should be + // handled separately, together with its affix file. + // + // So, for example, having en.aff, en.dic, en_XX.dic, en_YY.aff, en_YY.dic we should get in the result two + // hunspell objects, one with affix en.aff and dictionaries en.dic and en_XX.dic and the other one with + // affix en_YY.aff and dictionary en_YY.dic + for (QStringList::const_iterator dict_it = dicts_all.begin(); dict_it != dicts_all.end(); ++dict_it) + { + QString matching_affix(QString("%1.aff").arg(QFileInfo(*dict_it).completeBaseName())); + + if (matching_affix == *affix_it || !affixes.contains(matching_affix)) + dicts_to_add << *dict_it; + } + + if (dicts_to_add.size()) + { + Hunspell* speller = new Hunspell( + QString("%1/%2").arg(*dict_path_it, *affix_it).toLocal8Bit().constData(), + QString("%1/%2").arg(*dict_path_it, dicts_to_add[0]).toLocal8Bit().constData() + ); + + for (int i = 1; i < dicts_to_add.size(); ++i) + speller -> add_dic(QString("%1/%2").arg(*dict_path_it, dicts_to_add[i]).toLocal8Bit().constData()); + + spellers_.insert(*lang_it, HunSpellInfo(speller, QTextCodec::codecForName(speller -> get_dic_encoding()))); + } + } + } + } +} diff --git a/net-im/psi/files/hunspellchecker.h b/net-im/psi/files/hunspellchecker.h new file mode 100644 index 000000000000..8e1e85a59665 --- /dev/null +++ b/net-im/psi/files/hunspellchecker.h @@ -0,0 +1,71 @@ +/* + * hunspellchecker.h + * + * Copyright (C) 2009 Alexander Tsvyashchenko + * + * 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 option) any later version. + * + * You can also redistribute and/or modify this program under the + * terms of the Psi License, specified in the accompanied COPYING + * file, as published by the Psi Project; either dated January 1st, + * 2005, or (at your option) 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 library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef HUNSPELLCHECKER_H +#define HUNSPELLCHECKER_H + +#include <QList> +#include <QString> +#include <QMap> + +#include "spellchecker.h" + +class Hunspell; + +class HunSpellChecker : public SpellChecker +{ +public: + HunSpellChecker(); + ~HunSpellChecker(); + virtual QList<QString> suggestions(const QString&, const QString& lang, unsigned max_sugs); + virtual bool isCorrect(const QString&); + virtual bool add(const QString& word, const QString& lang); + virtual bool available() const; + virtual bool writable() const; + virtual QList<QString> getAllLanguages() const; + virtual void setActiveLanguages(const QList<QString>&); + +private: + struct HunSpellInfo + { + QTextCodec* codec; + Hunspell* speller; + + HunSpellInfo(Hunspell* speller, QTextCodec* codec): + speller(speller), codec(codec) {} + }; + + typedef QMap<QString, HunSpellInfo> HunSpellers; + + HunSpellers spellers_; + QList<QString> all_langs_; + +private: + void clearSpellers(); + QList<QString> getDictSearchPaths() const; +}; + +#endif diff --git a/net-im/psi/files/patch-git_4b838c0 b/net-im/psi/files/patch-git_4b838c0 deleted file mode 100644 index 29c7aab62d0b..000000000000 --- a/net-im/psi/files/patch-git_4b838c0 +++ /dev/null @@ -1,15 +0,0 @@ -From 4b838c04fa90ab56974bc4c57aaf7d4e80b8fff8 Mon Sep 17 00:00:00 2001 -From: Vitozz <thetvg@gmail.com> -Date: Mon, 28 May 2018 20:45:04 +0300 -Subject: [PATCH] Try to fix build with qt-5.11 - ---- src/accountmanagedlg.cpp.orig -+++ src/accountmanagedlg.cpp -@@ -28,6 +28,7 @@ - #include <QTimer> - #include <QHeaderView> - #include <QDropEvent> -+#include <QButtonGroup> - - #include "psicon.h" - #include "psiaccount.h" diff --git a/net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.cpp b/net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.cpp new file mode 100644 index 000000000000..d63a2c9540bc --- /dev/null +++ b/net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.cpp @@ -0,0 +1,37 @@ +--- src/libpsi/tools/spellchecker/spellchecker.cpp.orig 2018-11-02 00:37:04 UTC ++++ src/libpsi/tools/spellchecker/spellchecker.cpp +@@ -48,7 +48,7 @@ SpellChecker* SpellChecker::instance() + #elif defined(HAVE_ASPELL) + instance_ = new ASpellChecker(); + #elif defined(HAVE_HUNSPELL) +- instance_ = new HunspellChecker(); ++ instance_ = new HunSpellChecker(); + #else + instance_ = new SpellChecker(); + #endif +@@ -80,14 +80,23 @@ bool SpellChecker::isCorrect(const QString&) + return true; + } + +-QList<QString> SpellChecker::suggestions(const QString&) ++QList<QString> SpellChecker::suggestions(const QString&, const QString&, unsigned) + { + return QList<QString>(); + } + +-bool SpellChecker::add(const QString&) ++bool SpellChecker::add(const QString&, const QString&) + { + return false; ++} ++ ++QList<QString> SpellChecker::getAllLanguages() const ++{ ++ return QList<QString>(); ++} ++ ++void SpellChecker::setActiveLanguages(const QList<QString>&) ++{ + } + + SpellChecker* SpellChecker::instance_ = NULL; diff --git a/net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.h b/net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.h new file mode 100644 index 000000000000..bbab53d364dc --- /dev/null +++ b/net-im/psi/files/patch-src_libpsi_tools_spellchecker_spellchecker.h @@ -0,0 +1,19 @@ +--- src/libpsi/tools/spellchecker/spellchecker.h.orig 2018-11-02 00:37:04 UTC ++++ src/libpsi/tools/spellchecker/spellchecker.h +@@ -37,12 +37,11 @@ class SpellChecker : public QObject (public) + static SpellChecker* instance(); + virtual bool available() const; + virtual bool writable() const; +- virtual QList<QString> suggestions(const QString&); ++ virtual QList<QString> suggestions(const QString& word, const QString& lang, unsigned max_sugs); + virtual bool isCorrect(const QString&); +- virtual bool add(const QString&); +- +- virtual void setActiveLanguages(const QList<QString>& ) {} +- virtual QList<QString> getAllLanguages() const { return QList<QString>(); } ++ virtual bool add(const QString& word, const QString& lang); ++ virtual QList<QString> getAllLanguages() const; ++ virtual void setActiveLanguages(const QList<QString>&); + + protected: + SpellChecker(); diff --git a/net-im/psi/files/patch-src_msgmle.cpp b/net-im/psi/files/patch-src_msgmle.cpp new file mode 100644 index 000000000000..1166d2cdd830 --- /dev/null +++ b/net-im/psi/files/patch-src_msgmle.cpp @@ -0,0 +1,116 @@ +--- src/msgmle.cpp.orig 2018-11-02 00:15:39 UTC ++++ src/msgmle.cpp +@@ -257,12 +257,36 @@ bool ChatEdit::checkSpellingGloballyEnabled() + return (SpellChecker::instance()->available() && PsiOptions::instance()->getOption("options.ui.spell-check.enabled").toBool()); + } + ++QStringList ChatEdit::checkSpellingActiveLanguages() ++{ ++ return PsiOptions::instance()->getOption("options.ui.spell-check.langs").toString().split(QRegExp("\\s+|,|\\:"), QString::SkipEmptyParts); ++} ++ ++unsigned ChatEdit::checkSpellingMaxSuggestions() ++{ ++ return PsiOptions::instance()->getOption("options.ui.spell-check.maxsugs").toString().toInt(); ++} ++ + void ChatEdit::setCheckSpelling(bool b) + { + check_spelling_ = b; + if (check_spelling_) { + if (!spellhighlighter_) + spellhighlighter_ = new SpellHighlighter(document()); ++ all_langs_ = SpellChecker::instance()->getAllLanguages(); ++ langs_ = checkSpellingActiveLanguages(); ++ // No langs specified in options? ++ if (langs_.isEmpty()) { ++ QString env_lang(getenv("LANG")); ++ // Let's try to use the language specified in environment ... ++ if (!env_lang.isEmpty() && all_langs_.contains(env_lang)) ++ langs_.append(env_lang); ++ else // ... still no luck? Will use all available languages then. ++ langs_ = all_langs_; ++ } ++ SpellChecker::instance()->setActiveLanguages(langs_); ++ // If zero, means no limit (empty option also translates to zero). ++ max_sugs_ = checkSpellingMaxSuggestions(); + } + else { + delete spellhighlighter_; +@@ -335,19 +359,34 @@ void ChatEdit::contextMenuEvent(QContextMenuEvent *e) + tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); + QString selected_word = tc.selectedText(); + if (!selected_word.isEmpty() && !QRegExp("\\d+").exactMatch(selected_word) && !SpellChecker::instance()->isCorrect(selected_word)) { +- QList<QString> suggestions = SpellChecker::instance()->suggestions(selected_word); +- if (!suggestions.isEmpty() || SpellChecker::instance()->writable()) { +- QMenu spell_menu; ++ QMenu spell_menu; ++ foreach (QString lang, langs_) { ++ QList<QString> suggestions = SpellChecker::instance()->suggestions(selected_word, lang, max_sugs_); + if (!suggestions.isEmpty()) { ++ QAction* lang_name = spell_menu.addAction(tr("Language") + ": " + lang); ++ lang_name->setDisabled(true); + foreach(QString suggestion, suggestions) { + QAction* act_suggestion = spell_menu.addAction(suggestion); + connect(act_suggestion,SIGNAL(triggered()),SLOT(applySuggestion())); + } + spell_menu.addSeparator(); + } ++ } ++ if (!spell_menu.isEmpty() || SpellChecker::instance()->writable() || !all_langs_.isEmpty()) { + if (SpellChecker::instance()->writable()) { +- QAction* act_add = spell_menu.addAction(tr("Add to dictionary")); +- connect(act_add,SIGNAL(triggered()),SLOT(addToDictionary())); ++ foreach (QString lang, langs_) { ++ QAction* act_add = spell_menu.addAction(tr("Add to dictionary") + ": " + lang); ++ act_add->setData(lang); ++ connect(act_add,SIGNAL(triggered()),SLOT(addToDictionary())); ++ } ++ spell_menu.addSeparator(); ++ foreach (QString lang, all_langs_) { ++ QAction* act_lang_sel = spell_menu.addAction(tr("Use language") + ": " + lang); ++ act_lang_sel->setCheckable(true); ++ act_lang_sel->setChecked(langs_.contains(lang)); ++ act_lang_sel->setData(lang); ++ connect(act_lang_sel,SIGNAL(triggered()),SLOT(changedUseLang())); ++ } + } + spell_menu.exec(QCursor::pos()); + e->accept(); +@@ -397,18 +436,35 @@ void ChatEdit::applySuggestion() + */ + void ChatEdit::addToDictionary() + { ++ QAction* action = static_cast<QAction*>(sender()); + QTextCursor tc = cursorForPosition(last_click_); + int current_position = textCursor().position(); + + // Get the selected word + tc.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor); + tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); +- SpellChecker::instance()->add(tc.selectedText()); ++ SpellChecker::instance()->add(tc.selectedText(), action->data().toString()); + + // Put the cursor where it belongs + tc.clearSelection(); + tc.setPosition(current_position); + setTextCursor(tc); ++ ++ spellhighlighter_->rehighlight(); ++} ++ ++void ChatEdit::changedUseLang() ++{ ++ QAction* action = static_cast<QAction*>(sender()); ++ QString lang = action->data().toString(); ++ ++ if (langs_.contains(lang)) ++ langs_.removeAt(langs_.indexOf(lang)); ++ else ++ langs_.append(lang); ++ ++ SpellChecker::instance()->setActiveLanguages(langs_); ++ spellhighlighter_->rehighlight(); + } + + void ChatEdit::optionsChanged() diff --git a/net-im/psi/files/patch-src_msgmle.h b/net-im/psi/files/patch-src_msgmle.h new file mode 100644 index 000000000000..90650541852b --- /dev/null +++ b/net-im/psi/files/patch-src_msgmle.h @@ -0,0 +1,28 @@ +--- src/msgmle.h.orig 2018-11-02 00:15:39 UTC ++++ src/msgmle.h +@@ -54,6 +54,8 @@ class ChatEdit : public QTextEdit (public) + void setFont(const QFont &); + + static bool checkSpellingGloballyEnabled(); ++ static QStringList checkSpellingActiveLanguages(); ++ static unsigned checkSpellingMaxSuggestions(); + void setCheckSpelling(bool); + XMPP::HTMLElement toHTMLElement(); + bool isCorrection() { return correction; } +@@ -71,6 +73,7 @@ public slots: + protected slots: + void applySuggestion(); + void addToDictionary(); ++ void changedUseLang(); + void optionsChanged(); + void showHistoryMessageNext(); + void showHistoryMessagePrev(); +@@ -91,6 +94,8 @@ protected slots: (protected) + private: + QWidget *dialog_; + bool check_spelling_; ++ QList<QString> langs_, all_langs_; ++ unsigned max_sugs_; + SpellHighlighter* spellhighlighter_; + QPoint last_click_; + int previous_position_; diff --git a/net-im/psi/files/patch-src_options_opt__advanced.cpp b/net-im/psi/files/patch-src_options_opt__advanced.cpp new file mode 100644 index 000000000000..f338524023c9 --- /dev/null +++ b/net-im/psi/files/patch-src_options_opt__advanced.cpp @@ -0,0 +1,66 @@ +--- src/options/opt_advanced.cpp.orig 2018-11-02 00:15:39 UTC ++++ src/options/opt_advanced.cpp +@@ -45,6 +45,8 @@ QWidget *OptionsTabAdvanced::widget() + #endif + + d->ck_spell->setEnabled(SpellChecker::instance()->available()); ++ d->le_spellLangs->setEnabled(SpellChecker::instance()->available()); ++ d->le_spellMaxSugs->setEnabled(SpellChecker::instance()->available()); + + d->ck_messageevents->setWhatsThis( + tr("Enables the sending and requesting of message events such as " +@@ -60,6 +62,12 @@ QWidget *OptionsTabAdvanced::widget() + tr("Enables remote controlling your client from other locations")); + d->ck_spell->setWhatsThis( + tr("Check this option if you want your spelling to be checked")); ++ d->le_spellLangs->setWhatsThis( ++ tr("List here all languages you want your spell checker to use" ++ " when checking your spelling.")); ++ d->le_spellMaxSugs->setWhatsThis( ++ tr("Maximal number of suggestion words per language you want to see" ++ " in context menu when the word is misspelled.")); + d->ck_contactsMessageFormatting->setWhatsThis( + tr("If enabled, Psi will display incoming messages formatted in the style specified by the contact")); + d->ck_autocopy->setWhatsThis( +@@ -99,6 +107,10 @@ QWidget *OptionsTabAdvanced::widget() + connect(d->ck_messageevents,SIGNAL(toggled(bool)),d->ck_sendComposingEvents,SLOT(setEnabled(bool))); + d->ck_inactiveevents->setEnabled(d->ck_messageevents->isChecked()); + d->ck_sendComposingEvents->setEnabled(d->ck_messageevents->isChecked()); ++ connect(d->ck_spell,SIGNAL(toggled(bool)),d->le_spellLangs,SLOT(setEnabled(bool))); ++ connect(d->ck_spell,SIGNAL(toggled(bool)),d->le_spellMaxSugs,SLOT(setEnabled(bool))); ++ d->le_spellLangs->setEnabled(d->ck_spell->isChecked()); ++ d->le_spellMaxSugs->setEnabled(d->ck_spell->isChecked()); + + return w; + } +@@ -116,8 +128,11 @@ void OptionsTabAdvanced::applyOptions() + PsiOptions::instance()->setOption("options.ui.notifications.send-receipts", d->ck_sendReceipts->isChecked()); + PsiOptions::instance()->setOption("options.messages.dont-send-composing-events", d->ck_sendComposingEvents->isChecked()); + PsiOptions::instance()->setOption("options.external-control.adhoc-remote-control.enable", d->ck_rc->isChecked()); +- if ( SpellChecker::instance()->available() ) ++ if ( SpellChecker::instance()->available() ) { + PsiOptions::instance()->setOption("options.ui.spell-check.enabled",d->ck_spell->isChecked()); ++ PsiOptions::instance()->setOption("options.ui.spell-check.langs", d->le_spellLangs->text()); ++ PsiOptions::instance()->setOption("options.ui.spell-check.maxsugs", d->le_spellMaxSugs->text()); ++ } + PsiOptions::instance()->setOption("options.html.chat.render", d->ck_contactsMessageFormatting->isChecked()); + PsiOptions::instance()->setOption("options.ui.automatically-copy-selected-text", d->ck_autocopy->isChecked()); + PsiOptions::instance()->setOption("options.ui.contactlist.use-single-click", d->ck_singleclick->isChecked()); +@@ -145,10 +160,15 @@ void OptionsTabAdvanced::restoreOptions() + d->ck_sendReceipts->setChecked( PsiOptions::instance()->getOption("options.ui.notifications.send-receipts").toBool() ); + d->ck_sendComposingEvents->setChecked( PsiOptions::instance()->getOption("options.messages.dont-send-composing-events").toBool() ); + d->ck_rc->setChecked( PsiOptions::instance()->getOption("options.external-control.adhoc-remote-control.enable").toBool() ); +- if ( !SpellChecker::instance()->available() ) ++ if ( !SpellChecker::instance()->available() ) { + d->ck_spell->setChecked(false); +- else ++ d->le_spellLangs->setText(""); ++ d->le_spellMaxSugs->setText(""); ++ } else { + d->ck_spell->setChecked(PsiOptions::instance()->getOption("options.ui.spell-check.enabled").toBool()); ++ d->le_spellLangs->setText(PsiOptions::instance()->getOption("options.ui.spell-check.langs").toString()); ++ d->le_spellMaxSugs->setText(PsiOptions::instance()->getOption("options.ui.spell-check.maxsugs").toString()); ++ } + d->ck_contactsMessageFormatting->setChecked(PsiOptions::instance()->getOption("options.html.chat.render").toBool()); + d->ck_autocopy->setChecked( PsiOptions::instance()->getOption("options.ui.automatically-copy-selected-text").toBool() ); + d->ck_singleclick->setChecked( PsiOptions::instance()->getOption("options.ui.contactlist.use-single-click").toBool() ); diff --git a/net-im/psi/files/patch-src_options_opt__advanced.ui b/net-im/psi/files/patch-src_options_opt__advanced.ui new file mode 100644 index 000000000000..e1076f2b0cf4 --- /dev/null +++ b/net-im/psi/files/patch-src_options_opt__advanced.ui @@ -0,0 +1,29 @@ +--- src/options/opt_advanced.ui.orig 2018-11-02 00:15:39 UTC ++++ src/options/opt_advanced.ui +@@ -72,6 +72,26 @@ + </widget> + </item> + <item> ++ <widget class="QLabel" name="TextLabel3" > ++ <property name="text" > ++ <string>List of active spellchecker languages:</string> ++ </property> ++ </widget> ++ </item> ++ <item> ++ <widget class="QLineEdit" name="le_spellLangs" /> ++ </item> ++ <item> ++ <widget class="QLabel" name="TextLabel4" > ++ <property name="text" > ++ <string>Maximum suggestions per language:</string> ++ </property> ++ </widget> ++ </item> ++ <item> ++ <widget class="QLineEdit" name="le_spellMaxSugs" /> ++ </item> ++ <item> + <widget class="QCheckBox" name="ck_contactsMessageFormatting" > + <property name="text" > + <string>Use contacts' message formatting</string> |