summaryrefslogtreecommitdiff
path: root/plugins/SpellChecker/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/SpellChecker/src')
-rw-r--r--plugins/SpellChecker/src/ardialog.cpp2
-rw-r--r--plugins/SpellChecker/src/autoreplace.h5
-rw-r--r--plugins/SpellChecker/src/dictionary.cpp188
-rw-r--r--plugins/SpellChecker/src/dictionary.h39
-rw-r--r--plugins/SpellChecker/src/options.cpp21
-rw-r--r--plugins/SpellChecker/src/spellchecker.cpp58
-rw-r--r--plugins/SpellChecker/src/stdafx.h14
-rw-r--r--plugins/SpellChecker/src/utils.cpp78
8 files changed, 183 insertions, 222 deletions
diff --git a/plugins/SpellChecker/src/ardialog.cpp b/plugins/SpellChecker/src/ardialog.cpp
index 060fa80846..2ca79c0616 100644
--- a/plugins/SpellChecker/src/ardialog.cpp
+++ b/plugins/SpellChecker/src/ardialog.cpp
@@ -181,7 +181,7 @@ static INT_PTR CALLBACK AddReplacementDlgProc(HWND hwndDlg, UINT msg, WPARAM wPa
EnableWindow(GetDlgItem(hwndDlg, IDC_OLD_PS), FALSE);
}
- if (!variables_enabled) {
+ if (!g_plugin.hasVariables) {
ShowWindow(GetDlgItem(hwndDlg, IDC_VARIABLES), FALSE);
ShowWindow(GetDlgItem(hwndDlg, IDC_VAR_HELP), FALSE);
diff --git a/plugins/SpellChecker/src/autoreplace.h b/plugins/SpellChecker/src/autoreplace.h
index f3ce520e80..9427a38547 100644
--- a/plugins/SpellChecker/src/autoreplace.h
+++ b/plugins/SpellChecker/src/autoreplace.h
@@ -21,7 +21,6 @@ Boston, MA 02111-1307, USA.
#ifndef __AUTOREPLACE_H__
# define __AUTOREPLACE_H__
-
struct AutoReplacement
{
std::wstring replace;
@@ -31,9 +30,7 @@ struct AutoReplacement
AutoReplacement(const wchar_t *replace, BOOL useVariables);
};
-
-class Dictionary;
-
+struct Dictionary;
class AutoReplaceMap
{
diff --git a/plugins/SpellChecker/src/dictionary.cpp b/plugins/SpellChecker/src/dictionary.cpp
index 4c251a6682..efc294b33e 100644
--- a/plugins/SpellChecker/src/dictionary.cpp
+++ b/plugins/SpellChecker/src/dictionary.cpp
@@ -357,10 +357,10 @@ class HunspellDictionary : public Dictionary
protected:
wchar_t fileWithoutExtension[1024];
wchar_t userPath[1024];
- volatile int loaded;
- Hunspell *hunspell;
- wchar_t *wordChars;
- UINT codePage;
+ volatile int loaded = LANGUAGE_NOT_LOADED;
+ Hunspell *hunspell = 0;
+ wchar_t *wordChars = 0;
+ UINT codePage = CP_ACP;
void loadCustomDict()
{
@@ -433,8 +433,7 @@ protected:
if (hunspellWord == nullptr)
return nullptr;
- wchar_t *ret = fromHunspell(hunspellWord);
- return ret;
+ return fromHunspell(hunspellWord);
}
public:
@@ -448,14 +447,10 @@ public:
else
mir_wstrncpy(source, aSource, _countof(source));
- loaded = LANGUAGE_NOT_LOADED;
localized_name[0] = '\0';
english_name[0] = '\0';
full_name[0] = '\0';
- hunspell = nullptr;
- wordChars = nullptr;
- codePage = CP_ACP;
- autoReplace = nullptr;
+ GetInfo();
}
virtual ~HunspellDictionary()
@@ -534,7 +529,6 @@ public:
const std::vector<w_char> wordchars_utf16 = hunspell->get_wordchars_utf16();
hwordchars = fromHunspell((char *)&wordchars_utf16[0]);
-
}
else {
for (auto &it : codepages) {
@@ -584,7 +578,7 @@ public:
// Return a list of suggestions to a word
virtual Suggestions suggest(const wchar_t * word)
{
- Suggestions ret = {};
+ Suggestions ret;
load();
if (loaded != LANGUAGE_LOADED)
@@ -593,17 +587,19 @@ public:
char hunspell_word[1024];
toHunspell(hunspell_word, word, _countof(hunspell_word));
- char ** words = nullptr;
- ret.count = hunspell->suggest(&words, hunspell_word);
+ char **words = nullptr;
+ int count = hunspell->suggest(&words, hunspell_word);
- if (ret.count > 0 && words != nullptr) {
+ if (count > 0 && words != nullptr) {
// Oki, lets make our array
- ret.words = (wchar_t **)malloc(ret.count * sizeof(wchar_t *));
- for (unsigned i = 0; i < ret.count; i++) {
- ret.words[i] = fromHunspell(words[i]);
+ for (int i = 0; i < count; i++) {
+ auto *p = fromHunspell(words[i]);
+ ret.push_back(p);
+ free(p);
free(words[i]);
}
}
+
if (words != nullptr)
free(words);
@@ -613,7 +609,7 @@ public:
// Return a list of auto suggestions to a word
virtual Suggestions autoSuggest(const wchar_t * word)
{
- Suggestions ret = {};
+ Suggestions ret;
load();
if (loaded != LANGUAGE_LOADED)
@@ -622,17 +618,16 @@ public:
char hunspell_word[1024];
toHunspell(hunspell_word, word, _countof(hunspell_word));
- char ** words;
+ char **words;
int count = hunspell->suggest(&words, hunspell_word);
-
if (count <= 0)
return ret;
// Oki, lets make our array
- ret.count = count;
- ret.words = (wchar_t **)malloc(ret.count * sizeof(wchar_t *));
for (int i = 0; i < count; i++) {
- ret.words[i] = fromHunspell(words[i]);
+ auto *p = fromHunspell(words[i]);
+ ret.push_back(p);
+ free(p);
free(words[i]);
}
free(words);
@@ -693,7 +688,6 @@ public:
return loaded == LANGUAGE_LOADED;
}
-
// Add a word to the user custom dict
virtual void addWord(const wchar_t * word)
{
@@ -714,92 +708,66 @@ void LoadThread(LPVOID hd)
dict->loadThread();
}
-
-
-// To use with EnumLocalesProc :(
-LIST<Dictionary> *tmp_dicts;
-
// To get the names of the languages
-BOOL CALLBACK EnumLocalesProc(LPTSTR lpLocaleString)
+
+void Dictionary::GetInfo()
{
- wchar_t *stopped = nullptr;
- USHORT langID = (USHORT)wcstol(lpLocaleString, &stopped, 16);
-
- wchar_t ini[32];
- wchar_t end[32];
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SISO639LANGNAME, ini, _countof(ini));
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SISO3166CTRYNAME, end, _countof(end));
-
- wchar_t name[64];
- mir_snwprintf(name, L"%s_%s", ini, end);
-
- for (auto &dict : *tmp_dicts) {
- if (mir_wstrcmpi(dict->language, name) == 0) {
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SENGLANGUAGE, dict->english_name, _countof(dict->english_name));
-
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SLANGUAGE, dict->localized_name, _countof(dict->localized_name));
- if (dict->localized_name[0] == 0)
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SLOCALIZEDLANGUAGENAME, dict->localized_name, _countof(dict->localized_name));
- if (dict->localized_name[0] == 0)
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SNATIVEDISPLAYNAME, dict->localized_name, _countof(dict->localized_name));
- if (dict->localized_name[0] == 0 && dict->english_name[0] != 0) {
+ for (auto &it : g_plugin.locales) {
+ if (mir_wstrcmpi(language, it.first.c_str()) == 0) {
+ int langID = it.second;
+ GetLocaleInfoW(MAKELCID(langID, 0), LOCALE_SENGLANGUAGE, english_name, _countof(english_name));
+
+ GetLocaleInfoW(MAKELCID(langID, 0), LOCALE_SLANGUAGE, localized_name, _countof(localized_name));
+ if (localized_name[0] == 0)
+ GetLocaleInfoW(MAKELCID(langID, 0), LOCALE_SLOCALIZEDLANGUAGENAME, localized_name, _countof(localized_name));
+ if (localized_name[0] == 0)
+ GetLocaleInfoW(MAKELCID(langID, 0), LOCALE_SNATIVEDISPLAYNAME, localized_name, _countof(localized_name));
+ if (localized_name[0] == 0 && english_name[0] != 0) {
wchar_t country[1024];
- GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SENGCOUNTRY, country, _countof(country));
+ GetLocaleInfoW(MAKELCID(langID, 0), LOCALE_SENGCOUNTRY, country, _countof(country));
wchar_t localName[1024];
if (country[0] != 0)
- mir_snwprintf(localName, L"%s (%s)", dict->english_name, country);
+ mir_snwprintf(localName, L"%s (%s)", english_name, country);
else
- mir_wstrncpy(localName, dict->english_name, _countof(localName));
+ mir_wstrncpy(localName, english_name, _countof(localName));
- mir_wstrncpy(dict->localized_name, TranslateW(localName), _countof(dict->localized_name));
+ mir_wstrncpy(localized_name, TranslateW(localName), _countof(localized_name));
}
- if (dict->localized_name[0] != 0) {
- mir_snwprintf(dict->full_name, L"%s [%s]", dict->localized_name, dict->language);
- }
+ if (localized_name[0] != 0)
+ mir_snwprintf(full_name, L"%s [%s]", localized_name, language);
+
break;
}
}
- return TRUE;
-}
+ if (full_name[0] == '\0') {
+ DBVARIANT dbv;
-void GetDictsInfo(LIST<Dictionary> &dicts)
-{
- tmp_dicts = &dicts;
- EnumSystemLocales(EnumLocalesProc, LCID_SUPPORTED);
-
- // Try to get name from DB
- for (auto &dict : dicts) {
- if (dict->full_name[0] == '\0') {
- DBVARIANT dbv;
-
- char lang[128];
- WideCharToMultiByte(CP_ACP, 0, dict->language, -1, lang, sizeof(lang), nullptr, nullptr);
- if (!g_plugin.getWString(lang, &dbv)) {
- mir_wstrncpy(dict->localized_name, dbv.pwszVal, _countof(dict->localized_name));
- db_free(&dbv);
- }
+ char lang[128];
+ WideCharToMultiByte(CP_ACP, 0, language, -1, lang, sizeof(lang), nullptr, nullptr);
+ if (!g_plugin.getWString(lang, &dbv)) {
+ mir_wstrncpy(localized_name, dbv.pwszVal, _countof(localized_name));
+ db_free(&dbv);
+ }
- if (dict->localized_name[0] == '\0') {
- for (auto &it : aditionalLanguages) {
- if (!mir_wstrcmp(it.language, dict->language)) {
- mir_wstrncpy(dict->localized_name, TranslateW(it.localized_name), _countof(dict->localized_name));
- break;
- }
+ if (localized_name[0] == '\0') {
+ for (auto &it : aditionalLanguages) {
+ if (!mir_wstrcmp(it.language, language)) {
+ mir_wstrncpy(localized_name, TranslateW(it.localized_name), _countof(localized_name));
+ break;
}
}
-
- if (dict->localized_name[0] != '\0')
- mir_snwprintf(dict->full_name, L"%s [%s]", dict->localized_name, dict->language);
- else
- mir_wstrncpy(dict->full_name, dict->language, _countof(dict->full_name));
}
+
+ if (localized_name[0] != '\0')
+ mir_snwprintf(full_name, L"%s [%s]", localized_name, language);
+ else
+ mir_wstrncpy(full_name, language, _countof(full_name));
}
}
-
void GetHunspellDictionariesFromFolder(LIST<Dictionary> &dicts, wchar_t *path, wchar_t *user_path, wchar_t *source)
{
// Load the language files and create an array with then
@@ -853,9 +821,8 @@ void GetHunspellDictionariesFromFolder(LIST<Dictionary> &dicts, wchar_t *path, w
}
}
-
// Return a list of avaible languages
-void GetAvaibleDictionaries(LIST<Dictionary> &dicts, wchar_t *path, wchar_t *user_path)
+void GetAvaibleDictionaries(OBJLIST<Dictionary> &dicts, wchar_t *path, wchar_t *user_path)
{
// Get miranda folder dicts
GetHunspellDictionariesFromFolder(dicts, path, user_path, nullptr);
@@ -908,46 +875,9 @@ void GetAvaibleDictionaries(LIST<Dictionary> &dicts, wchar_t *path, wchar_t *use
}
}
}
-
- GetDictsInfo(dicts);
-
- // Yeah, yeah, yeah, I know, but this is the easiest way...
- SortedList *sl = (SortedList *)&dicts;
-
- // Sort dicts
- for (int i = 0; i < dicts.getCount(); i++) {
- for (int j = i + 1; j < dicts.getCount(); j++) {
- if (mir_wstrcmp(dicts[i]->full_name, dicts[j]->full_name) > 0) {
- Dictionary *dict = dicts[i];
- sl->items[i] = dicts[j];
- sl->items[j] = dict;
- }
- }
- }
-}
-
-
-// Free the list returned by GetAvaibleDictionaries
-void FreeDictionaries(LIST<Dictionary> &dicts)
-{
- for (auto &it : dicts)
- delete it;
- dicts.destroy();
}
Dictionary::~Dictionary()
{
delete autoReplace;
}
-
-// Free the list returned by GetAvaibleDictionaries
-void FreeSuggestions(Suggestions &suggestions)
-{
- for (size_t i = 0; i < suggestions.count; i++)
- free(suggestions.words[i]);
-
- free(suggestions.words);
-
- suggestions.words = nullptr;
- suggestions.count = 0;
-}
diff --git a/plugins/SpellChecker/src/dictionary.h b/plugins/SpellChecker/src/dictionary.h
index da70a6a4c2..35f94dc4f8 100644
--- a/plugins/SpellChecker/src/dictionary.h
+++ b/plugins/SpellChecker/src/dictionary.h
@@ -21,48 +21,45 @@ Boston, MA 02111-1307, USA.
#ifndef __DICTIONARY_H__
# define __DICTIONARY_H__
-
-struct Suggestions {
- wchar_t ** words;
- size_t count;
-};
-
+typedef std::vector<std::wstring> Suggestions;
// A Dictionary interface
// All dictionaries use a lazy interface
-class Dictionary {
-public:
+struct Dictionary
+{
wchar_t language[128];
wchar_t localized_name[128];
wchar_t english_name[128];
wchar_t full_name[256];
wchar_t source[128];
- AutoReplaceMap *autoReplace;
+ AutoReplaceMap *autoReplace = 0;
HANDLE hIcolib;
virtual ~Dictionary();
+ void GetInfo();
+
// Return TRUE if the word is correct
- virtual BOOL spell(const wchar_t *) = 0;
+ virtual BOOL spell(const wchar_t *word) = 0;
// Return a list of suggestions to a word
- virtual Suggestions suggest(const wchar_t * word) = 0;
+ virtual Suggestions suggest(const wchar_t *word) = 0;
// Return a list of auto suggestions to a word
- virtual Suggestions autoSuggest(const wchar_t * word) = 0;
+ virtual Suggestions autoSuggest(const wchar_t *word) = 0;
// Return a auto suggestions to a word
// You have to free the item
- virtual wchar_t * autoSuggestOne(const wchar_t * word) = 0;
+ virtual wchar_t* autoSuggestOne(const wchar_t *word) = 0;
// Return TRUE if the char is a word char
virtual BOOL isWordChar(wchar_t c) = 0;
// Add a word to the user custom dict
- virtual void addWord(const wchar_t * word) = 0;
+ virtual void addWord(const wchar_t *word) = 0;
// Add a word to the list of ignored words
- virtual void ignoreWord(const wchar_t * word) = 0;
+ virtual void ignoreWord(const wchar_t *word) = 0;
// Assert that all needed data is loaded
virtual void load() = 0;
@@ -71,17 +68,7 @@ public:
virtual BOOL isLoaded() = 0;
};
-
-
// Return a list of avaible languages
-void GetAvaibleDictionaries(LIST<Dictionary> &dicts, wchar_t *path, wchar_t *user_path);
-
-// Free the list returned by GetAvaibleDictionaries
-void FreeDictionaries(LIST<Dictionary> &dicts);
-
-// Free the list returned by GetAvaibleDictionaries
-void FreeSuggestions(Suggestions &suggestions);
-
-
+void GetAvaibleDictionaries(OBJLIST<Dictionary> &dicts, wchar_t *path, wchar_t *user_path);
#endif // __DICTIONARY_H__
diff --git a/plugins/SpellChecker/src/options.cpp b/plugins/SpellChecker/src/options.cpp
index c034205fda..4d3035dd64 100644
--- a/plugins/SpellChecker/src/options.cpp
+++ b/plugins/SpellChecker/src/options.cpp
@@ -93,7 +93,7 @@ void LoadOptions()
if (mir_wstrcmp(it->language, opts.default_language) == 0)
return;
- mir_wstrcpy(opts.default_language, languages[0]->language);
+ mir_wstrcpy(opts.default_language, languages[0].language);
}
static void DrawItem(LPDRAWITEMSTRUCT lpdis, Dictionary *dict)
@@ -166,10 +166,10 @@ static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
{
int sel = -1;
for (int i = 0; i < languages.getCount(); i++) {
- SendDlgItemMessage(hwndDlg, IDC_DEF_LANG, CB_ADDSTRING, 0, (LPARAM)languages[i]->full_name);
- SendDlgItemMessage(hwndDlg, IDC_DEF_LANG, CB_SETITEMDATA, i, (LPARAM)languages[i]);
+ SendDlgItemMessage(hwndDlg, IDC_DEF_LANG, CB_ADDSTRING, 0, (LPARAM)languages[i].full_name);
+ SendDlgItemMessage(hwndDlg, IDC_DEF_LANG, CB_SETITEMDATA, i, (LPARAM)&languages[i]);
- if (!mir_wstrcmp(opts.default_language, languages[i]->language))
+ if (!mir_wstrcmp(opts.default_language, languages[i].language))
sel = i;
}
SendDlgItemMessage(hwndDlg, IDC_DEF_LANG, CB_SETCURSEL, sel, 0);
@@ -202,9 +202,8 @@ static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
int sel = SendDlgItemMessage(hwndDlg, IDC_DEF_LANG, CB_GETCURSEL, 0, 0);
if (sel >= languages.getCount())
sel = 0;
- g_plugin.setWString("DefaultLanguage",
- (wchar_t *)languages[sel]->language);
- mir_wstrcpy(opts.default_language, languages[sel]->language);
+ g_plugin.setWString("DefaultLanguage", languages[sel].language);
+ mir_wstrcpy(opts.default_language, languages[sel].language);
}
}
break;
@@ -365,11 +364,11 @@ static INT_PTR CALLBACK AutoreplaceDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam
int sel = -1;
for (int i = 0; i < languages.getCount(); i++) {
- Dictionary *p = languages[i];
- SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_ADDSTRING, 0, (LPARAM)p->full_name);
- SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SETITEMDATA, i, (LPARAM)new AutoreplaceData(p));
+ auto &p = languages[i];
+ SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_ADDSTRING, 0, (LPARAM)p.full_name);
+ SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SETITEMDATA, i, (LPARAM)new AutoreplaceData(&p));
- if (!mir_wstrcmp(opts.default_language, p->language))
+ if (!mir_wstrcmp(opts.default_language, p.language))
sel = i;
}
SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SETCURSEL, sel, 0);
diff --git a/plugins/SpellChecker/src/spellchecker.cpp b/plugins/SpellChecker/src/spellchecker.cpp
index 703221c471..16213bc425 100644
--- a/plugins/SpellChecker/src/spellchecker.cpp
+++ b/plugins/SpellChecker/src/spellchecker.cpp
@@ -35,10 +35,16 @@ wchar_t *flagsDllFolder;
HBITMAP hCheckedBmp;
BITMAP bmpChecked;
-BOOL variables_enabled = FALSE;
BOOL loaded = FALSE;
-LIST<Dictionary> languages(1);
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static int CompareDicts(const Dictionary *p1, const Dictionary *p2)
+{
+ return mir_wstrcmpi(p1->full_name, p2->full_name);
+}
+
+OBJLIST<Dictionary> languages(1, CompareDicts);
/////////////////////////////////////////////////////////////////////////////////////////
@@ -62,6 +68,12 @@ CMPlugin::CMPlugin() :
// Functions ////////////////////////////////////////////////////////////////////////////
+static int OnModuleLoad(WPARAM, LPARAM)
+{
+ g_plugin.hasVariables = ServiceExists(MS_VARS_FORMATSTRING);
+ return 0;
+}
+
static int PreShutdown(WPARAM, LPARAM)
{
mir_free(dictionariesFolder);
@@ -73,8 +85,6 @@ static int PreShutdown(WPARAM, LPARAM)
// Called when all the modules are loaded
static int ModulesLoaded(WPARAM, LPARAM)
{
- variables_enabled = ServiceExists(MS_VARS_FORMATSTRING);
-
// Folders plugin support
if (hDictionariesFolder = FoldersRegisterCustomPathW(LPGEN("Spell Checker"), LPGEN("Dictionaries"), DICTIONARIES_FOLDER)) {
dictionariesFolder = (wchar_t *)mir_alloc(sizeof(wchar_t) * MAX_PATH);
@@ -159,6 +169,10 @@ static int ModulesLoaded(WPARAM, LPARAM)
HookEvent(ME_MSG_WINDOWPOPUP, MsgWindowPopup);
HookEvent(ME_MSG_ICONPRESSED, IconPressed);
+ HookEvent(ME_SYSTEM_MODULELOAD, OnModuleLoad);
+ HookEvent(ME_SYSTEM_MODULEUNLOAD, OnModuleLoad);
+ OnModuleLoad(0, 0);
+
StatusIconData sid = {};
sid.szModule = MODULENAME;
sid.hIconDisabled = IcoLib_GetIcon("spellchecker_disabled");
@@ -168,9 +182,9 @@ static int ModulesLoaded(WPARAM, LPARAM)
sid.dwId = i;
wchar_t tmp[128];
- mir_snwprintf(tmp, L"%s - %s", TranslateT("Spell Checker"), languages[i]->full_name);
+ mir_snwprintf(tmp, L"%s - %s", TranslateT("Spell Checker"), languages[i].full_name);
sid.szTooltip.w = tmp;
- sid.hIcon = (opts.use_flags) ? IcoLib_GetIconByHandle(languages[i]->hIcolib) : IcoLib_GetIcon("spellchecker_enabled");
+ sid.hIcon = (opts.use_flags) ? IcoLib_GetIconByHandle(languages[i].hIcolib) : IcoLib_GetIcon("spellchecker_enabled");
Srmm_AddIcon(&sid, &g_plugin);
}
@@ -189,6 +203,8 @@ static int ModulesLoaded(WPARAM, LPARAM)
////////////////////////////////////////////////////////////////////////////////////////
+static bool bComInited = false;
+
static IconItem iconList[] =
{
{ LPGEN("Enabled"), "spellchecker_enabled", IDI_CHECK },
@@ -196,8 +212,34 @@ static IconItem iconList[] =
{ LPGEN("Unknown"), "spellchecker_unknown", IDI_UNKNOWN_FLAG }
};
+static BOOL CALLBACK EnumLocalesProc(LPWSTR lpLocaleString)
+{
+ wchar_t *stopped = nullptr;
+ USHORT langID = (USHORT)wcstol(lpLocaleString, &stopped, 16);
+
+ wchar_t ini[32];
+ wchar_t end[32];
+ GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SISO639LANGNAME, ini, _countof(ini));
+ GetLocaleInfo(MAKELCID(langID, 0), LOCALE_SISO3166CTRYNAME, end, _countof(end));
+
+ wchar_t name[64];
+ mir_snwprintf(name, L"%s_%s", ini, end);
+ g_plugin.locales[name] = langID;
+ return TRUE;
+}
+
int CMPlugin::Load()
{
+ bComInited = SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED));
+ if (bComInited) {
+ if (FAILED(m_spellFactory.CoCreateInstance(__uuidof(SpellCheckerFactory), nullptr, CLSCTX_INPROC_SERVER))) {
+ bComInited = false;
+ CoUninitialize();
+ }
+ }
+
+ EnumSystemLocalesW(EnumLocalesProc, LCID_SUPPORTED);
+
// icons
g_plugin.registerIcon(LPGEN("Spell Checker"), iconList);
@@ -224,7 +266,9 @@ int CMPlugin::Load()
int CMPlugin::Unload()
{
DeleteObject(hCheckedBmp);
- FreeDictionaries(languages);
+ languages.destroy();
+ if (bComInited)
+ CoUninitialize();
return 0;
}
diff --git a/plugins/SpellChecker/src/stdafx.h b/plugins/SpellChecker/src/stdafx.h
index 41beb2c3e3..57eeba34e8 100644
--- a/plugins/SpellChecker/src/stdafx.h
+++ b/plugins/SpellChecker/src/stdafx.h
@@ -25,10 +25,12 @@ Boston, MA 02111-1307, USA.
#include <time.h>
#include <windows.h>
+#include <msapi/comptr.h>
#include <msapi/richedit5.h>
#include <tom.h>
#include <richole.h>
#include <commctrl.h>
+#include <spellcheck.h>
#include <map>
#include <vector>
@@ -77,13 +79,17 @@ struct CMPlugin : public PLUGIN<CMPlugin>
{
CMPlugin();
+ bool hasVariables;
+
+ std::map<std::wstring, int> locales;
+
+ CComPtr<ISpellChecker> m_speller;
+ CComPtr<ISpellCheckerFactory> m_spellFactory;
+
int Load() override;
int Unload() override;
};
-extern BOOL uinfoex_enabled;
-extern BOOL variables_enabled;
-
#define FREE(_m_) if (_m_ != NULL) { free(_m_); _m_ = NULL; }
#define ICON_SIZE 16
@@ -94,7 +100,7 @@ extern BOOL variables_enabled;
#define HOTKEY_ACTION_TOGGLE 1
-extern LIST<Dictionary> languages;
+extern OBJLIST<Dictionary> languages;
extern BITMAP bmpChecked;
extern HBITMAP hCheckedBmp;
diff --git a/plugins/SpellChecker/src/utils.cpp b/plugins/SpellChecker/src/utils.cpp
index 0c3e490112..daa9c2c67d 100644
--- a/plugins/SpellChecker/src/utils.cpp
+++ b/plugins/SpellChecker/src/utils.cpp
@@ -142,7 +142,7 @@ int FindURLEnd(Dialog *dlg, wchar_t *text, int start_pos, int *checked_until = n
}
-int ReplaceWord(Dialog *dlg, CHARRANGE &sel, wchar_t *new_word)
+int ReplaceWord(Dialog *dlg, CHARRANGE &sel, const wchar_t *new_word)
{
dlg->re->Stop();
dlg->re->ResumeUndo();
@@ -451,7 +451,7 @@ void LoadDictFromKbdl(Dialog *dlg)
int d = GetClosestLanguage(szKLName);
if (d >= 0) {
- dlg->lang = languages[d];
+ dlg->lang = &languages[d];
dlg->lang->load();
if (dlg->srmm)
@@ -806,7 +806,7 @@ void GetContactLanguage(Dialog *dlg)
}
if (i >= 0) {
- dlg->lang = languages[i];
+ dlg->lang = &languages[i];
dlg->lang->load();
}
else dlg->lang = nullptr;
@@ -815,7 +815,7 @@ void GetContactLanguage(Dialog *dlg)
void ModifyIcon(Dialog *dlg)
{
for (int i = 0; i < languages.getCount(); i++) {
- if (languages[i] == dlg->lang)
+ if (&languages[i] == dlg->lang)
Srmm_SetIconFlags(dlg->hContact, MODULENAME, i, dlg->enabled ? 0 : MBF_DISABLED);
else
Srmm_SetIconFlags(dlg->hContact, MODULENAME, i, MBF_HIDDEN);
@@ -894,7 +894,7 @@ void FreePopupData(Dialog *dlg)
DESTROY_MENY((*dlg->wrong_words)[i].hCorrectSubMenu);
DESTROY_MENY((*dlg->wrong_words)[i].hReplaceSubMenu);
- FreeSuggestions((*dlg->wrong_words)[i].suggestions);
+ (*dlg->wrong_words)[i].suggestions.clear();
}
delete dlg->wrong_words;
@@ -1048,19 +1048,20 @@ void AddMenuForWord(Dialog *dlg, const wchar_t *word, CHARRANGE &pos, HMENU hMen
data.hReplaceSubMenu = CreatePopupMenu();
- InsertMenu(data.hReplaceSubMenu, 0, MF_BYPOSITION, base + AUTOREPLACE_MENU_ID_BASE + suggestions.count, TranslateT("Other..."));
- if (suggestions.count > 0) {
+ int iCount = (int)suggestions.size();
+ InsertMenu(data.hReplaceSubMenu, 0, MF_BYPOSITION, base + AUTOREPLACE_MENU_ID_BASE + iCount, TranslateT("Other..."));
+ if (iCount > 0) {
InsertMenu(data.hReplaceSubMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
- for (int i = (int)suggestions.count - 1; i >= 0; i--)
- InsertMenu(data.hReplaceSubMenu, 0, MF_BYPOSITION, base + AUTOREPLACE_MENU_ID_BASE + i, suggestions.words[i]);
+ for (int i = iCount - 1; i >= 0; i--)
+ InsertMenu(data.hReplaceSubMenu, 0, MF_BYPOSITION, base + AUTOREPLACE_MENU_ID_BASE + i, suggestions[i].c_str());
}
AppendSubmenu(hMenu, data.hReplaceSubMenu, TranslateT("Always replace with"));
- InsertMenu(hMenu, 0, MF_BYPOSITION, base + suggestions.count + 1, TranslateT("Ignore all"));
- InsertMenu(hMenu, 0, MF_BYPOSITION, base + suggestions.count, TranslateT("Add to dictionary"));
+ InsertMenu(hMenu, 0, MF_BYPOSITION, base + iCount + 1, TranslateT("Ignore all"));
+ InsertMenu(hMenu, 0, MF_BYPOSITION, base + iCount, TranslateT("Add to dictionary"));
- if (suggestions.count > 0) {
+ if (iCount > 0) {
HMENU hSubMenu;
if (opts.cascade_corrections) {
hSubMenu = data.hCorrectSubMenu = CreatePopupMenu();
@@ -1071,8 +1072,8 @@ void AddMenuForWord(Dialog *dlg, const wchar_t *word, CHARRANGE &pos, HMENU hMen
hSubMenu = hMenu;
}
- for (int i = (int)suggestions.count - 1; i >= 0; i--)
- InsertMenu(hSubMenu, 0, MF_BYPOSITION, base + i, suggestions.words[i]);
+ for (int i = iCount - 1; i >= 0; i--)
+ InsertMenu(hSubMenu, 0, MF_BYPOSITION, base + i, suggestions[i].c_str());
}
if (!in_submenu && opts.show_wrong_word) {
@@ -1119,8 +1120,8 @@ void AddItemsToMenu(Dialog *dlg, HMENU hMenu, POINT pt, HWND hwndOwner)
// First add languages
for (int i = 0; i < languages.getCount(); i++)
- AppendMenu(dlg->hLanguageSubMenu, MF_STRING | (languages[i] == dlg->lang ? MF_CHECKED : 0),
- LANGUAGE_MENU_ID_BASE + i, languages[i]->full_name);
+ AppendMenu(dlg->hLanguageSubMenu, MF_STRING | (&languages[i] == dlg->lang ? MF_CHECKED : 0),
+ LANGUAGE_MENU_ID_BASE + i, languages[i].full_name);
AppendSubmenu(hMenu, dlg->hLanguageSubMenu, TranslateT("Language"));
}
@@ -1150,7 +1151,6 @@ void AddItemsToMenu(Dialog *dlg, HMENU hMenu, POINT pt, HWND hwndOwner)
}
}
-
static void AddWordToDictCallback(BOOL canceled, Dictionary *dict,
const wchar_t *find, const wchar_t *replace, BOOL useVariables,
const wchar_t *, void *param)
@@ -1165,8 +1165,7 @@ static void AddWordToDictCallback(BOOL canceled, Dictionary *dict,
PostMessage(hwndParent, WMU_DICT_CHANGED, 0, 0);
}
-
-BOOL HandleMenuSelection(Dialog *dlg, unsigned selection)
+BOOL HandleMenuSelection(Dialog *dlg, int selection)
{
BOOL ret = FALSE;
@@ -1174,13 +1173,13 @@ BOOL HandleMenuSelection(Dialog *dlg, unsigned selection)
ToggleEnabled(dlg);
ret = TRUE;
}
- else if (selection >= LANGUAGE_MENU_ID_BASE && selection < LANGUAGE_MENU_ID_BASE + (unsigned)languages.getCount()) {
+ else if (selection >= LANGUAGE_MENU_ID_BASE && selection < LANGUAGE_MENU_ID_BASE + languages.getCount()) {
SetNoUnderline(dlg);
if (dlg->hContact == 0)
- g_plugin.setWString(dlg->name, languages[selection - LANGUAGE_MENU_ID_BASE]->language);
+ g_plugin.setWString(dlg->name, languages[selection - LANGUAGE_MENU_ID_BASE].language);
else
- g_plugin.setWString(dlg->hContact, "TalkLanguage", languages[selection - LANGUAGE_MENU_ID_BASE]->language);
+ g_plugin.setWString(dlg->hContact, "TalkLanguage", languages[selection - LANGUAGE_MENU_ID_BASE].language);
GetContactLanguage(dlg);
@@ -1189,38 +1188,37 @@ BOOL HandleMenuSelection(Dialog *dlg, unsigned selection)
ret = TRUE;
}
- else if (selection > 0 && dlg->wrong_words != nullptr
- && selection >= WORD_MENU_ID_BASE
- && selection < (dlg->wrong_words->size() + 1) * WORD_MENU_ID_BASE) {
+ else if (selection > 0 && dlg->wrong_words != nullptr && selection >= WORD_MENU_ID_BASE && selection < (dlg->wrong_words->size() + 1) * WORD_MENU_ID_BASE) {
int pos = selection / WORD_MENU_ID_BASE;
selection -= pos * WORD_MENU_ID_BASE;
pos--; // 0 based
WrongWordPopupMenuData &data = (*dlg->wrong_words)[pos];
- if (selection < data.suggestions.count) {
+ int iCount = (int)data.suggestions.size();
+ if (selection < iCount) {
// TODO Assert that text hasn't changed
- ReplaceWord(dlg, data.pos, data.suggestions.words[selection]);
+ ReplaceWord(dlg, data.pos, data.suggestions[selection].c_str());
ret = TRUE;
}
- else if (selection == data.suggestions.count) {
+ else if (selection == iCount) {
dlg->lang->addWord(data.word);
ret = TRUE;
}
- else if (selection == data.suggestions.count + 1) {
+ else if (selection == iCount + 1) {
dlg->lang->ignoreWord(data.word);
ret = TRUE;
}
- else if (selection >= AUTOREPLACE_MENU_ID_BASE && selection < AUTOREPLACE_MENU_ID_BASE + data.suggestions.count + 1) {
+ else if (selection >= AUTOREPLACE_MENU_ID_BASE && selection < AUTOREPLACE_MENU_ID_BASE + iCount + 1) {
selection -= AUTOREPLACE_MENU_ID_BASE;
- if (selection == data.suggestions.count) {
+ if (selection == iCount) {
ShowAutoReplaceDialog(dlg->hwnd_owner != nullptr ? dlg->hwnd_owner : dlg->hwnd, FALSE,
- dlg->lang, data.word, nullptr, FALSE,
- TRUE, &AddWordToDictCallback, dlg->hwnd);
+ dlg->lang, data.word, nullptr, FALSE,
+ TRUE, &AddWordToDictCallback, dlg->hwnd);
}
else {
// TODO Assert that text hasn't changed
- ReplaceWord(dlg, data.pos, data.suggestions.words[selection]);
- dlg->lang->autoReplace->add(data.word, data.suggestions.words[selection]);
+ ReplaceWord(dlg, data.pos, data.suggestions[selection].c_str());
+ dlg->lang->autoReplace->add(data.word, data.suggestions[selection].c_str());
ret = TRUE;
}
}
@@ -1357,7 +1355,7 @@ int IconPressed(WPARAM hContact, LPARAM lParam)
// First add languages
for (int i = 0; i < languages.getCount(); i++)
- AppendMenu(hMenu, MF_STRING | (languages[i] == dlg->lang ? MF_CHECKED : 0), LANGUAGE_MENU_ID_BASE + i, languages[i]->full_name);
+ AppendMenu(hMenu, MF_STRING | (&languages[i] == dlg->lang ? MF_CHECKED : 0), LANGUAGE_MENU_ID_BASE + i, languages[i].full_name);
InsertMenu(hMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}
@@ -1412,12 +1410,12 @@ LRESULT CALLBACK MenuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
int pos = lpdis->itemID - LANGUAGE_MENU_ID_BASE;
- Dictionary *dict = languages[pos];
+ Dictionary *dict = &languages[pos];
COLORREF clrfore = SetTextColor(lpdis->hDC,
- GetSysColor(lpdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
+ GetSysColor(lpdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
COLORREF clrback = SetBkColor(lpdis->hDC,
- GetSysColor(lpdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_MENU));
+ GetSysColor(lpdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_MENU));
FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(lpdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_MENU));
@@ -1476,7 +1474,7 @@ LRESULT CALLBACK MenuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
int pos = lpmis->itemID - LANGUAGE_MENU_ID_BASE;
- Dictionary *dict = languages[pos];
+ Dictionary *dict = &languages[pos];
HDC hdc = GetDC(hwnd);