diff options
Diffstat (limited to 'plugins/SpellChecker/src/dictionary.cpp')
-rw-r--r-- | plugins/SpellChecker/src/dictionary.cpp | 819 |
1 files changed, 26 insertions, 793 deletions
diff --git a/plugins/SpellChecker/src/dictionary.cpp b/plugins/SpellChecker/src/dictionary.cpp index efc294b33e..83bbefd5ce 100644 --- a/plugins/SpellChecker/src/dictionary.cpp +++ b/plugins/SpellChecker/src/dictionary.cpp @@ -19,695 +19,42 @@ Boston, MA 02111-1307, USA. #include "stdafx.h" -#define APPPATH L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s" -#define MUICACHE L"Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache" +///////////////////////////////////////////////////////////////////////////////////////// +// Dictionary class members - -// Additional languages that i could not find in Windows -struct { - wchar_t *language; - wchar_t *localized_name; -} aditionalLanguages[] = { - { L"tl_PH", LPGENW("Tagalog (Philippines)") }, - { L"de_frami_neu", LPGENW("German (Germany)") } -}; - -struct { - wchar_t *name; - wchar_t *key; -} otherHunspellApps[] = { - { L"Thunderbird", L"thunderbird.exe" }, - { L"Firefox", L"firefox.exe" } -}; - -struct { - char *name; - UINT codepage; -} codepages[] = { - { "ISO8859-1", 28591 }, - { "UTF-7", CP_UTF7 }, - { "UTF-8", CP_UTF8 }, - { "UTF7", CP_UTF7 }, - { "UTF8", CP_UTF8 }, - { "ISO8859-2", 28592 }, - { "ISO8859-3", 28593 }, - { "ISO8859-4", 28594 }, - { "ISO8859-5", 28595 }, - { "ISO8859-6", 28596 }, - { "ISO8859-7", 28597 }, - { "ISO8859-8", 28598 }, - { "ISO8859-9", 28599 }, - { "ASMO-708", 708 }, - { "DOS-720", 720 }, - { "iso-8859-6", 28596 }, - { "arabic", 28596 }, - { "csISOLatinArabic", 28596 }, - { "ECMA-114", 28596 }, - { "ISO_8859-6", 28596 }, - { "ISO_8859-6:1987", 28596 }, - { "iso-ir-127", 28596 }, - { "x-mac-arabic", 10004 }, - { "windows-1256", 1256 }, - { "cp1256", 1256 }, - { "ibm775", 775 }, - { "CP500", 775 }, - { "iso-8859-4", 28594 }, - { "csISOLatin4", 28594 }, - { "ISO_8859-4", 28594 }, - { "ISO_8859-4:1988", 28594 }, - { "iso-ir-110", 28594 }, - { "l4", 28594 }, - { "latin4", 28594 }, - { "windows-1257", 1257 }, - { "ibm852", 852 }, - { "cp852", 852 }, - { "iso-8859-2", 28592 }, - { "csISOLatin2", 28592 }, - { "iso_8859-2", 28592 }, - { "iso_8859-2:1987", 28592 }, - { "iso-ir-101", 28592 }, - { "l2", 28592 }, - { "latin2", 28592 }, - { "x-mac-ce", 10029 }, - { "windows-1250", 1250 }, - { "x-cp1250", 1250 }, - { "EUC-CN", 51936 }, - { "x-euc-cn", 51936 }, - { "gb2312", 936 }, - { "chinese", 936 }, - { "CN-GB", 936 }, - { "csGB2312", 936 }, - { "csGB231280", 936 }, - { "csISO58GB231280", 936 }, - { "GB_2312-80", 936 }, - { "GB231280", 936 }, - { "GB2312-80", 936 }, - { "GBK", 936 }, - { "iso-ir-58", 936 }, - { "hz-gb-2312", 52936 }, - { "x-mac-chinesesimp", 10008 }, - { "big5", 950 }, - { "cn-big5", 950 }, - { "csbig5", 950 }, - { "x-x-big5", 950 }, - { "x-Chinese-CNS", 20000 }, - { "x-Chinese-Eten", 20002 }, - { "x-mac-chinesetrad", 10002 }, - { "cp866", 866 }, - { "ibm866", 866 }, - { "iso-8859-5", 28595 }, - { "csISOLatin5", 28595 }, - { "csISOLatinCyrillic", 28595 }, - { "cyrillic", 28595 }, - { "ISO_8859-5", 28595 }, - { "ISO_8859-5:1988", 28595 }, - { "iso-ir-144", 28595 }, - { "l5", 28595 }, - { "KOI8-R", 20866 }, - { "csKOI8R", 20866 }, - { "koi", 20866 }, - { "koi8", 20866 }, - { "koi8r", 20866 }, - { "KOI8-U", 21866 }, - { "koi8-ru", 21866 }, - { "x-mac-cyrillic", 10007 }, - { "windows-1251", 1251 }, - { "Win1251", 1251 }, - { "x-cp1251", 1251 }, - { "x-Europa", 29001 }, - { "x-IA5-German", 20106 }, - { "ibm737", 737 }, - { "iso-8859-7", 28597 }, - { "csISOLatinGreek", 28597 }, - { "ECMA-118", 28597 }, - { "ELOT_928", 28597 }, - { "greek", 28597 }, - { "greek8", 28597 }, - { "ISO_8859-7", 28597 }, - { "ISO_8859-7:1987", 28597 }, - { "iso-ir-126", 28597 }, - { "x-mac-greek", 10006 }, - { "windows-1253", 1253 }, - { "ibm869", 869 }, - { "DOS-862", 862 }, - { "iso-8859-8-i", 38598 }, - { "logical", 38598 }, - { "iso-8859-8", 28598 }, - { "csISOLatinHebrew", 28598 }, - { "hebrew", 28598 }, - { "ISO_8859-8", 28598 }, - { "ISO_8859-8:1988", 28598 }, - { "ISO-8859-8", 28598 }, - { "iso-ir-138", 28598 }, - { "visual", 28598 }, - { "x-mac-hebrew", 10005 }, - { "windows-1255", 1255 }, - { "ISO_8859-8-I", 1255 }, - { "ISO-8859-8", 1255 }, - { "x-EBCDIC-Arabic", 20420 }, - { "x-EBCDIC-CyrillicRussian", 20880 }, - { "x-EBCDIC-CyrillicSerbianBulgarian", 21025 }, - { "x-EBCDIC-DenmarkNorway", 20277 }, - { "x-ebcdic-denmarknorway-euro", 1142 }, - { "x-EBCDIC-FinlandSweden", 20278 }, - { "x-ebcdic-finlandsweden-euro", 1143 }, - { "X-EBCDIC-France", 1143 }, - { "X-EBCDIC-France", 1143 }, - { "x-ebcdic-france-euro", 1147 }, - { "x-EBCDIC-Germany", 20273 }, - { "x-ebcdic-germany-euro", 1141 }, - { "x-EBCDIC-GreekModern", 875 }, - { "x-EBCDIC-Greek", 20423 }, - { "x-EBCDIC-Hebrew", 20424 }, - { "x-EBCDIC-Icelandic", 20871 }, - { "x-ebcdic-icelandic-euro", 1149 }, - { "x-ebcdic-international-euro", 1148 }, - { "x-EBCDIC-Italy", 20280 }, - { "x-ebcdic-italy-euro", 1144 }, - { "x-EBCDIC-JapaneseAndKana", 50930 }, - { "x-EBCDIC-JapaneseAndJapaneseLatin", 50939 }, - { "x-EBCDIC-JapaneseAndUSCanada", 50931 }, - { "x-EBCDIC-JapaneseKatakana", 20290 }, - { "x-EBCDIC-KoreanAndKoreanExtended", 50933 }, - { "x-EBCDIC-KoreanExtended", 20833 }, - { "CP870", 870 }, - { "x-EBCDIC-SimplifiedChinese", 50935 }, - { "X-EBCDIC-Spain", 20284 }, - { "x-ebcdic-spain-euro", 1145 }, - { "x-EBCDIC-Thai", 20838 }, - { "x-EBCDIC-TraditionalChinese", 50937 }, - { "CP1026", 1026 }, - { "x-EBCDIC-Turkish", 20905 }, - { "x-EBCDIC-UK", 20285 }, - { "x-ebcdic-uk-euro", 1146 }, - { "ebcdic-cp-us", 37 }, - { "x-ebcdic-cp-us-euro", 1140 }, - { "ibm861", 861 }, - { "x-mac-icelandic", 10079 }, - { "x-iscii-as", 57006 }, - { "x-iscii-be", 57003 }, - { "x-iscii-de", 57002 }, - { "x-iscii-gu", 57010 }, - { "x-iscii-ka", 57008 }, - { "x-iscii-ma", 57009 }, - { "x-iscii-or", 57007 }, - { "x-iscii-pa", 57011 }, - { "x-iscii-ta", 57004 }, - { "x-iscii-te", 57005 }, - { "euc-jp", 51932 }, - { "csEUCPkdFmtJapanese", 51932 }, - { "Extended_UNIX_Code_Packed_Format_for_Japanese", 51932 }, - { "x-euc", 51932 }, - { "x-euc-jp", 51932 }, - { "iso-2022-jp", 50220 }, - { "iso-2022-jp", 50222 }, - { "_iso-2022-jp$SIO", 50222 }, - { "csISO2022JP", 50221 }, - { "_iso-2022-jp", 50221 }, - { "x-mac-japanese", 10001 }, - { "shift_jis", 932 }, - { "csShiftJIS", 932 }, - { "csWindows31J", 932 }, - { "ms_Kanji", 932 }, - { "shift-jis", 932 }, - { "x-ms-cp932", 932 }, - { "x-sjis", 932 }, - { "ks_c_5601-1987", 949 }, - { "csKSC56011987", 949 }, - { "euc-kr", 949 }, - { "iso-ir-149", 949 }, - { "korean", 949 }, - { "ks_c_5601", 949 }, - { "ks_c_5601_1987", 949 }, - { "ks_c_5601-1989", 949 }, - { "KSC_5601", 949 }, - { "KSC5601", 949 }, - { "euc-kr", 51949 }, - { "csEUCKR", 51949 }, - { "iso-2022-kr", 50225 }, - { "csISO2022KR", 50225 }, - { "Johab", 1361 }, - { "x-mac-korean", 10003 }, - { "iso-8859-3", 28593 }, - { "csISO", 28593 }, - { "Latin3", 28593 }, - { "ISO_8859-3", 28593 }, - { "ISO_8859-3:1988", 28593 }, - { "iso-ir-109", 28593 }, - { "l3", 28593 }, - { "latin3", 28593 }, - { "iso-8859-15", 28605 }, - { "csISO", 28605 }, - { "Latin9", 28605 }, - { "ISO_8859-15", 28605 }, - { "l9", 28605 }, - { "latin9", 28605 }, - { "x-IA5-Norwegian", 20108 }, - { "IBM437", 437 }, - { "437", 437 }, - { "cp437", 437 }, - { "csPC8", 437 }, - { "CodePage437", 437 }, - { "x-IA5-Swedish", 20107 }, - { "windows-874", 874 }, - { "DOS-874", 874 }, - { "iso-8859-11", 874 }, - { "TIS-620", 874 }, - { "ibm857", 857 }, - { "iso-8859-9", 28599 }, - { "csISO", 28599 }, - { "Latin5", 28599 }, - { "ISO_8859-9", 28599 }, - { "ISO_8859-9:1989", 28599 }, - { "iso-ir-148", 28599 }, - { "l5", 28599 }, - { "latin5", 28599 }, - { "x-mac-turkish", 10081 }, - { "windows-1254", 1254 }, - { "ISO_8859-9", 1254 }, - { "ISO_8859-9:1989", 1254 }, - { "iso-8859-9", 1254 }, - { "iso-ir-148", 1254 }, - { "latin5", 1254 }, - { "unicode", 1200 }, - { "utf-16", 1200 }, - { "unicodeFFFE", 1201 }, - { "utf-7", 65000 }, - { "csUnicode11UTF7", 65000 }, - { "unicode-1-1-utf-7", 65000 }, - { "x-unicode-2-0-utf-7", 65000 }, - { "utf-8", 65001 }, - { "unicode-1-1-utf-8", 65001 }, - { "unicode-2-0-utf-8", 65001 }, - { "x-unicode-2-0-utf-8", 65001 }, - { "us-ascii", 20127 }, - { "ANSI_X3.4-1968", 20127 }, - { "ANSI_X3.4-1986", 20127 }, - { "ascii", 20127 }, - { "cp367", 20127 }, - { "csASCII", 20127 }, - { "IBM367", 20127 }, - { "ISO_646.irv:1991", 20127 }, - { "ISO646-US", 20127 }, - { "iso-ir-6us", 20127 }, - { "windows-1258", 1258 }, - { "ibm850", 850 }, - { "x-IA5", 20105 }, - { "iso-8859-1", 28591 }, - { "cp819", 28591 }, - { "csISO", 28591 }, - { "Latin1", 28591 }, - { "ibm819", 28591 }, - { "iso_8859-1", 28591 }, - { "iso_8859-1:1987", 28591 }, - { "iso-ir-100", 28591 }, - { "l1", 28591 }, - { "latin1", 28591 }, - { "macintosh", 10000 }, - { "Windows-1252", 1252 }, - { "ANSI_X3.4-1968", 1252 }, - { "ANSI_X3.4-1986", 1252 }, - { "ascii", 1252 }, - { "cp367", 1252 }, - { "cp819", 1252 }, - { "csASCII", 1252 }, - { "IBM367", 1252 }, - { "ibm819", 1252 }, - { "ISO_646.irv:1991", 1252 }, - { "iso_8859-1", 1252 }, - { "iso_8859-1:1987", 1252 }, - { "ISO646-US", 1252 }, - { "iso-ir-100", 1252 }, - { "iso-ir-6", 1252 }, - { "latin1", 1252 }, - { "us", 1252 }, - { "us-ascii", 1252 }, - { "x-ansi", 1252 }, - { "microsoft-cp1251", 1251 } -}; - -#define LANGUAGE_NOT_LOADED 1 -#define LANGUAGE_LOADING -1 -#define LANGUAGE_LOADED 0 - -void LoadThread(LPVOID hd); - -class HunspellDictionary : public Dictionary +Dictionary::Dictionary(const wchar_t *aLanguage, const wchar_t *aSource) { -protected: - wchar_t fileWithoutExtension[1024]; - wchar_t userPath[1024]; - volatile int loaded = LANGUAGE_NOT_LOADED; - Hunspell *hunspell = 0; - wchar_t *wordChars = 0; - UINT codePage = CP_ACP; - - void loadCustomDict() - { - wchar_t filename[1024]; - mir_snwprintf(filename, L"%s\\%s.cdic", userPath, language); - - FILE *file = _wfopen(filename, L"rb"); - if (file != nullptr) { - char tmp[1024]; - int c, pos = 0; - while ((c = fgetc(file)) != EOF) { - if (c == '\n' || c == '\r' || pos >= _countof(tmp) - 1) { - if (pos > 0) { - tmp[pos] = '\0'; - hunspell->add(tmp); - pos = 0; - } - } - else { - tmp[pos] = (char)c; - pos++; - } - } - fclose(file); - } - } - - void appendToCustomDict(const wchar_t *word) - { - CreateDirectoryTreeW(userPath); - - wchar_t filename[1024]; - mir_snwprintf(filename, L"%s\\%s.cdic", userPath, language); - - FILE *file = _wfopen(filename, L"ab"); - if (file != nullptr) { - char tmp[1024]; - toHunspell(tmp, word, _countof(tmp)); - fprintf(file, "%s\n", tmp); - fclose(file); - } - } - - virtual void addWordInternal(const wchar_t * word) - { - if (loaded != LANGUAGE_LOADED) - return; - - char hunspell_word[1024]; - toHunspell(hunspell_word, word, _countof(hunspell_word)); - - hunspell->add(hunspell_word); - } - - void toHunspell(char *hunspellWord, const wchar_t *word, size_t hunspellWordLen) - { - WideCharToMultiByte(codePage, 0, word, -1, hunspellWord, (int)hunspellWordLen, nullptr, nullptr); - } - - wchar_t* fromHunspell(const char *hunspellWord) - { - int len = MultiByteToWideChar(codePage, 0, hunspellWord, -1, nullptr, 0); - wchar_t *ret = (wchar_t *)malloc((len + 1) * sizeof(wchar_t)); - MultiByteToWideChar(codePage, 0, hunspellWord, -1, ret, len + 1); - return ret; - } - - wchar_t* fromHunspellAndFree(const char *hunspellWord) - { - if (hunspellWord == nullptr) - return nullptr; - - return fromHunspell(hunspellWord); - } - -public: - HunspellDictionary(wchar_t *aLanguage, wchar_t *aFileWithoutExtension, wchar_t *anUserPath, wchar_t *aSource) - { - mir_wstrncpy(language, aLanguage, _countof(language)); - mir_wstrncpy(fileWithoutExtension, aFileWithoutExtension, _countof(fileWithoutExtension)); - mir_wstrncpy(userPath, anUserPath, _countof(userPath)); - if (aSource == nullptr) - source[0] = '\0'; - else - mir_wstrncpy(source, aSource, _countof(source)); - - localized_name[0] = '\0'; - english_name[0] = '\0'; - full_name[0] = '\0'; - GetInfo(); - } - - virtual ~HunspellDictionary() - { - delete hunspell; - if (wordChars != nullptr) - free(wordChars); - } - - wchar_t* merge(wchar_t * s1, wchar_t *s2) - { - size_t len1 = mir_wstrlen(s1); - size_t len2 = mir_wstrlen(s2); - - wchar_t *ret; - if (len1 > 0 && len2 > 0) { - ret = (wchar_t *)malloc(sizeof(wchar_t) * (len1 + len2 + 1)); - mir_wstrncpy(ret, s1, len1 + 1); - mir_wstrncpy(&ret[len1], s2, len2 + 1); - - FREE(s1); - FREE(s2); - } - else if (len1 > 0) { - ret = s1; - FREE(s2); - } - else if (len2 > 0) { - ret = s2; - FREE(s1); - } - else { - ret = (wchar_t *)malloc(sizeof(wchar_t)); - ret[0] = 0; - - FREE(s1); - FREE(s2); - } - - // Remove duplicated chars - size_t last = mir_wstrlen(ret) - 1; - for (size_t i = 0; i <= last; i++) { - wchar_t c = ret[i]; - for (size_t j = last; j > i; j--) { - if (c != ret[j]) - continue; - if (j != last) - ret[j] = ret[last]; - ret[last] = '\0'; - last--; - } - } - - return ret; - } - - - void loadThread() - { - char dic[1024]; - char aff[1024]; - - - mir_snprintf(dic, "%S.dic", fileWithoutExtension); - mir_snprintf(aff, "%S.aff", fileWithoutExtension); - - - hunspell = new Hunspell(aff, dic); - - // Get codepage - const char *dic_enc = hunspell->get_dic_encoding(); - - wchar_t *hwordchars; - if (mir_strcmp(dic_enc, "UTF-8") == 0) { - codePage = CP_UTF8; - - const std::vector<w_char> wordchars_utf16 = hunspell->get_wordchars_utf16(); - hwordchars = fromHunspell((char *)&wordchars_utf16[0]); - } - else { - for (auto &it : codepages) { - if (_strcmpi(it.name, dic_enc) == 0) { - if (IsValidCodePage(it.codepage)) - codePage = it.codepage; - break; - } - } - - hwordchars = fromHunspell(hunspell->get_wordchars()); - } - - wchar_t *casechars = fromHunspellAndFree(get_casechars(dic_enc).c_str()); - wchar_t *try_string = fromHunspellAndFree(hunspell->get_try_string()); - - wordChars = merge(merge(casechars, hwordchars), try_string); - - // Make a suggestion to load hunspell internalls - char ** words = nullptr; - int count = hunspell->suggest(&words, "asdf"); - for (int i = 0; i < count; i++) - free(words[i]); - if (words != nullptr) - free(words); - - loadCustomDict(); - - loaded = LANGUAGE_LOADED; - } - - // Return TRUE if the word is correct - virtual BOOL spell(const wchar_t *word) - { - load(); - if (loaded != LANGUAGE_LOADED) - return TRUE; - - // TODO Check if it was generated by auto-replacement - - char hunspell_word[1024]; - toHunspell(hunspell_word, word, _countof(hunspell_word)); - - return hunspell->spell(hunspell_word); - } + mir_wstrncpy(language, aLanguage, _countof(language)); - // Return a list of suggestions to a word - virtual Suggestions suggest(const wchar_t * word) - { - Suggestions ret; + if (aSource == nullptr) + source[0] = '\0'; + else + mir_wstrncpy(source, aSource, _countof(source)); - load(); - if (loaded != LANGUAGE_LOADED) - return ret; - - char hunspell_word[1024]; - toHunspell(hunspell_word, word, _countof(hunspell_word)); - - char **words = nullptr; - int count = hunspell->suggest(&words, hunspell_word); - - if (count > 0 && words != nullptr) { - // Oki, lets make our array - 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); - - return ret; - } - - // Return a list of auto suggestions to a word - virtual Suggestions autoSuggest(const wchar_t * word) - { - Suggestions ret; - - load(); - if (loaded != LANGUAGE_LOADED) - return ret; - - char hunspell_word[1024]; - toHunspell(hunspell_word, word, _countof(hunspell_word)); - - char **words; - int count = hunspell->suggest(&words, hunspell_word); - if (count <= 0) - return ret; - - // Oki, lets make our array - for (int i = 0; i < count; i++) { - auto *p = fromHunspell(words[i]); - ret.push_back(p); - free(p); - free(words[i]); - } - free(words); - - return ret; - } - - // Return a list of auto suggestions to a word - // You have to free the list AND each item - virtual wchar_t * autoSuggestOne(const wchar_t * word) - { - load(); - if (loaded != LANGUAGE_LOADED) - return nullptr; - - char hunspell_word[1024]; - toHunspell(hunspell_word, word, _countof(hunspell_word)); - - char **words; - int count = hunspell->suggest(&words, hunspell_word); - if (count <= 0) - return nullptr; - - wchar_t *ret = fromHunspell(words[0]); - - // Oki, lets make our array - for (int i = 0; i < count; i++) - free(words[i]); - free(words); - - return ret; - } - - // Return TRUE if the char is a word char - virtual BOOL isWordChar(wchar_t c) - { - if (c == 0) - return FALSE; - - load(); - if (loaded != LANGUAGE_LOADED) - return TRUE; - - return wcschr(wordChars, c) != nullptr; - } - - // Assert that all needed data is loaded - virtual void load() - { - if (loaded == LANGUAGE_NOT_LOADED) { - loaded = LANGUAGE_LOADING; - mir_forkthread(LoadThread, this); - } - } - - virtual BOOL isLoaded() - { - return loaded == LANGUAGE_LOADED; - } + localized_name[0] = '\0'; + english_name[0] = '\0'; + full_name[0] = '\0'; +} - // Add a word to the user custom dict - virtual void addWord(const wchar_t * word) - { - addWordInternal(word); - appendToCustomDict(word); - } +Dictionary::~Dictionary() +{ + delete autoReplace; +} - // Add a word to the list of ignored words - virtual void ignoreWord(const wchar_t * word) - { - addWordInternal(word); - } -}; +///////////////////////////////////////////////////////////////////////////////////////// +// Additional languages that i could not find in Windows -void LoadThread(LPVOID hd) +struct { - HunspellDictionary *dict = (HunspellDictionary *)hd; - dict->loadThread(); + wchar_t *language; + wchar_t *localized_name; } +static aditionalLanguages[] = { + { L"tl_PH", LPGENW("Tagalog (Philippines)") }, + { L"de_frami_neu", LPGENW("German (Germany)") } +}; +///////////////////////////////////////////////////////////////////////////////////////// // To get the names of the languages void Dictionary::GetInfo() @@ -767,117 +114,3 @@ void Dictionary::GetInfo() 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 - wchar_t file[1024] = { 0 }; - mir_snwprintf(file, L"%s\\*.dic", path); - - BOOL found = FALSE; - - WIN32_FIND_DATA ffd = { 0 }; - HANDLE hFFD = FindFirstFile(file, &ffd); - if (hFFD != INVALID_HANDLE_VALUE) { - do { - mir_snwprintf(file, L"%s\\%s", path, ffd.cFileName); - - // Check .dic - uint32_t attrib = GetFileAttributes(file); - if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY)) - continue; - - // See if .aff exists too - mir_wstrcpy(&file[mir_wstrlen(file) - 4], L".aff"); - attrib = GetFileAttributes(file); - if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY)) - continue; - - ffd.cFileName[mir_wstrlen(ffd.cFileName) - 4] = '\0'; - - wchar_t *lang = ffd.cFileName; - - // Replace - for _ - for (size_t i = 0; i < mir_wstrlen(lang); i++) - if (lang[i] == '-') - lang[i] = '_'; - - // Check if dict is new - bool exists = false; - for (auto &it : dicts) - if (mir_wstrcmp(it->language, lang) == 0) { - exists = true; - break; - } - - if (!exists) { - found = TRUE; - file[mir_wstrlen(file) - 4] = '\0'; - dicts.insert(new HunspellDictionary(lang, file, user_path, source)); - } - } while (FindNextFile(hFFD, &ffd)); - - FindClose(hFFD); - } -} - -// Return a list of avaible languages -void GetAvaibleDictionaries(OBJLIST<Dictionary> &dicts, wchar_t *path, wchar_t *user_path) -{ - // Get miranda folder dicts - GetHunspellDictionariesFromFolder(dicts, path, user_path, nullptr); - - if (opts.use_other_apps_dicts) { - // Get other apps dicts - for (auto &it : otherHunspellApps) { - wchar_t key[1024]; - mir_snwprintf(key, APPPATH, it.key); - - HKEY hKey = nullptr; - LONG lResult = 0; - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &hKey)) { - DWORD size = _countof(key); - lResult = RegQueryValueEx(hKey, L"Path", nullptr, nullptr, (LPBYTE)key, &size); - RegCloseKey(hKey); - } - else { - // Not found in installed apps - Try MUICache - lResult = RegOpenKeyEx(HKEY_CURRENT_USER, MUICACHE, 0, KEY_QUERY_VALUE, &hKey); - if (ERROR_SUCCESS == lResult) { - DWORD numValues; - if (ERROR_SUCCESS != RegQueryInfoKey(hKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &numValues, nullptr, nullptr, nullptr, nullptr)) - numValues = 0; - - lResult = ERROR_NO_MORE_ITEMS; - for (uint32_t local = 0; local < numValues; local++) { - DWORD cchValue = _countof(key); - if (ERROR_SUCCESS != RegEnumValue(hKey, local, key, &cchValue, nullptr, nullptr, nullptr, nullptr)) - break; - key[cchValue] = 0; - wchar_t *pos; - if (pos = wcsrchr(key, '\\')) { - if (!mir_wstrcmpi(&pos[1], it.key)) { - pos[0] = 0; - lResult = ERROR_SUCCESS; - break; - } - } - } - RegCloseKey(hKey); - } - } - - if (ERROR_SUCCESS == lResult) { - wchar_t folder[1024]; - mir_snwprintf(folder, L"%s\\Dictionaries", key); - - GetHunspellDictionariesFromFolder(languages, folder, user_path, it.name); - } - } - } -} - -Dictionary::~Dictionary() -{ - delete autoReplace; -} |