Skip to content

Commit

Permalink
Bug fix prevent crashes when no system spell checker is available (Mu…
Browse files Browse the repository at this point in the history
…dlet#2422)

This message is an edited one from a squash and merge PR with two
commits combined into it.

This bug was actually discovered by accident because there was not a
default dictionary specified in the Host constructor initialiser list. However
the principle of handling things safely if there is a problem in setting up
the system spell checker should be adopted even after fixing that point.

This should close Mudlet#2413.

I also found another issue in that using the right click (context menu)
on the command line was feeding the word being checked to the user's
dictionary in the encoding that the system/mudlet provided dictionaty
was using - which need not be the UTF-8 encoding that the former will
always be using - that has been fixed herein as well.

I also found a couple of additional languages with system dictionaries
when I ran Mudlet on my Devuan Linux PC and have added them in.

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
  • Loading branch information
SlySven authored Mar 13, 2019
1 parent 5636965 commit 1b36bc4
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ Host::Host(int port, const QString& hostname, const QString& login, const QStrin
, mWideAmbigousWidthGlyphs(false)
, mSGRCodeHasColSpaceId(false)
, mServerMayRedefineColors(false)
, mSpellDic()
, mSpellDic(QStringLiteral("en_US"))
// DISABLED: - Prevent "None" option for user dictionary - changed to true and not changed anywhere else
, mEnableUserDictionary(true)
, mUseSharedDictionary(false)
Expand Down
70 changes: 45 additions & 25 deletions src/TCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,11 @@ void TCommandLine::slot_popupMenu()
c.removeSelectedText();
c.insertText(t);
c.clearSelection();
Hunspell_free_list(mpHost->mpConsole->getHunspellHandle_system(), &mpSystemSuggestionsList, mSystemDictionarySuggestionsCount);
Hunhandle* userDictionaryHandle = mpHost->mpConsole->getHunspellHandle_user();
auto systemDictionaryHandle = mpHost->mpConsole->getHunspellHandle_system();
if (systemDictionaryHandle) {
Hunspell_free_list(mpHost->mpConsole->getHunspellHandle_system(), &mpSystemSuggestionsList, mSystemDictionarySuggestionsCount);
}
auto userDictionaryHandle = mpHost->mpConsole->getHunspellHandle_user();
if (userDictionaryHandle) {
Hunspell_free_list(userDictionaryHandle, &mpUserSuggestionsList, mUserDictionarySuggestionsCount);
}
Expand All @@ -568,7 +571,6 @@ void TCommandLine::mousePressEvent(QMouseEvent* event)
auto codec = mpHost->mpConsole->getHunspellCodec_system();
auto handle_system = mpHost->mpConsole->getHunspellHandle_system();
auto handle_profile = mpHost->mpConsole->getHunspellHandle_user();
QByteArray encodedText = codec->fromUnicode(mSpellCheckedWord);
bool haveAddOption = false;
bool haveRemoveOption = false;
QAction* action_addWord = nullptr;
Expand Down Expand Up @@ -611,32 +613,41 @@ void TCommandLine::mousePressEvent(QMouseEvent* event)

QList<QAction*> spellings_system;
QList<QAction*> spellings_profile;
if (!Hunspell_spell(handle_system, encodedText.constData())) {
// The word is NOT in the main system dictionary:
if (handle_profile) {
// Have a user dictionary so check it:
if (!Hunspell_spell(handle_profile, mSpellCheckedWord.toUtf8().constData())) {
// The word is NOT in the profile one either - so enable add option
haveAddOption = true;
} else {
// However the word is in the profile one - so enable remove option
haveRemoveOption = true;
}

if (haveAddOption) {
action_addWord->setEnabled(true);
connect(action_addWord, &QAction::triggered, this, &TCommandLine::slot_addWord);
}
if (haveRemoveOption) {
action_removeWord->setEnabled(true);
connect(action_removeWord, &QAction::triggered, this, &TCommandLine::slot_removeWord);
if (handle_system && codec) {
QByteArray encodedText = codec->fromUnicode(mSpellCheckedWord);

if (!Hunspell_spell(handle_system, encodedText.constData())) {
// The word is NOT in the main system dictionary:
if (handle_profile) {
// Have a user dictionary so check it:
if (!Hunspell_spell(handle_profile, mSpellCheckedWord.toUtf8().constData())) {
// The word is NOT in the profile one either - so enable add option
haveAddOption = true;
} else {
// However the word is in the profile one - so enable remove option
haveRemoveOption = true;
}

if (haveAddOption) {
action_addWord->setEnabled(true);
connect(action_addWord, &QAction::triggered, this, &TCommandLine::slot_addWord);
}
if (haveRemoveOption) {
action_removeWord->setEnabled(true);
connect(action_removeWord, &QAction::triggered, this, &TCommandLine::slot_removeWord);
}
}
}

mSystemDictionarySuggestionsCount = Hunspell_suggest(handle_system, &mpSystemSuggestionsList, encodedText.constData());
} else {
mSystemDictionarySuggestionsCount = 0;
}

mSystemDictionarySuggestionsCount = Hunspell_suggest(handle_system, &mpSystemSuggestionsList, encodedText.constData());
if (handle_profile) {
mUserDictionarySuggestionsCount = Hunspell_suggest(handle_profile, &mpUserSuggestionsList, encodedText.constData());
mUserDictionarySuggestionsCount = Hunspell_suggest(handle_profile, &mpUserSuggestionsList, mSpellCheckedWord.toUtf8().constData());
} else {
mUserDictionarySuggestionsCount = 0;
}

if (mSystemDictionarySuggestionsCount) {
Expand Down Expand Up @@ -960,10 +971,19 @@ void TCommandLine::slot_addWord()

void TCommandLine::spellCheckWord(QTextCursor& c)
{
if (!mpHost||!mpHost->mEnableSpellCheck) {
return;
}

Hunhandle* systemDictionaryHandle = mpHost->mpConsole->getHunspellHandle_system();
if (!systemDictionaryHandle) {
return;
}

QTextCharFormat f;
c.select(QTextCursor::WordUnderCursor);
QByteArray encodedText = mpHost->mpConsole->getHunspellCodec_system()->fromUnicode(c.selectedText());
if (!Hunspell_spell(mpHost->mpConsole->getHunspellHandle_system(), encodedText.constData())) {
if (!Hunspell_spell(systemDictionaryHandle, encodedText.constData())) {
// Word is not in selected system dictionary
Hunhandle* userDictionaryhandle = mpHost->mpConsole->getHunspellHandle_user();
if (userDictionaryhandle) {
Expand Down
4 changes: 4 additions & 0 deletions src/mudlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ void mudlet::loadLanguagesMap()
{QStringLiteral("es_us"), tr("Spanish (United States)")},
{QStringLiteral("es_uy"), tr("Spanish (Uruguay)")},
{QStringLiteral("es_ve"), tr("Spanish (Venezuela)")},
{QStringLiteral("et"), tr("Estonian")},
{QStringLiteral("et_ee"), tr("Estonian (Estonia)")},
{QStringLiteral("eu"), tr("Basque")},
{QStringLiteral("eu_es"), tr("Basque (Spain)")},
{QStringLiteral("eu_fr"), tr("Basque (France)")},
Expand All @@ -289,6 +291,8 @@ void mudlet::loadLanguagesMap()
{QStringLiteral("hr_hr"), tr("Croatian (Croatia)")},
{QStringLiteral("hu"), tr("Hungarian")},
{QStringLiteral("hu_hu"), tr("Hungarian (Hungary)")},
{QStringLiteral("hy"), tr("Armenian")},
{QStringLiteral("hy_am"), tr("Armenian (Armenia)")},
{QStringLiteral("ie"), tr("Interlingue", "formerly known as Occidental, and not to be mistaken for Interlingua")},
{QStringLiteral("is"), tr("Icelandic")},
{QStringLiteral("is_is"), tr("Icelandic (Iceland)")},
Expand Down

0 comments on commit 1b36bc4

Please sign in to comment.