From 6a5032eafd68dac892e8367811f4ac597a7536ea Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Fri, 24 Dec 2010 00:37:39 +0100 Subject: [PATCH] - added : "Add to Dictionary" and "Add to Ignore" context menu options --HG-- branch : Misc-Spellcheck --- indra/llui/llhunspell.cpp | 75 ++++++++++++++++++++++++++++++++++--- indra/llui/llhunspell.h | 14 ++++--- indra/llui/lllineeditor.cpp | 12 +++--- 3 files changed, 84 insertions(+), 17 deletions(-) diff --git a/indra/llui/llhunspell.cpp b/indra/llui/llhunspell.cpp index 9af6838e74..4c4c3c34e2 100644 --- a/indra/llui/llhunspell.cpp +++ b/indra/llui/llhunspell.cpp @@ -142,7 +142,7 @@ bool LLHunspellWrapper::setCurrentDictionary(const std::string& strDictionary) { delete m_pHunspell; m_pHunspell = NULL; - m_strDictionary = strDictionary; + m_strDictionaryName = m_strDictionaryFile = ""; m_IgnoreList.clear(); } @@ -160,23 +160,24 @@ bool LLHunspellWrapper::setCurrentDictionary(const std::string& strDictionary) if (sdDictInfo.has("name")) { - std::string strPathAff = m_strDictionaryPath + sdDictInfo["name"].asString() + ".aff"; - std::string strPathDic = m_strDictionaryPath + sdDictInfo["name"].asString() + ".dic"; + m_strDictionaryName = strDictionary; + m_strDictionaryFile = sdDictInfo["name"].asString(); + std::string strPathAff = m_strDictionaryPath + m_strDictionaryFile + ".aff"; + std::string strPathDic = m_strDictionaryPath + m_strDictionaryFile + ".dic"; m_pHunspell = new Hunspell(strPathAff.c_str(), strPathDic.c_str()); - m_strDictionary = strDictionary; // Add the custom dictionary (if there is one) if (sdDictInfo["has_custom"].asBoolean()) { - std::string strPathCustomDic = m_strDictionaryPath + sdDictInfo["name"].asString() + c_strDictCustomSuffix + ".dic"; + std::string strPathCustomDic = m_strDictionaryPath + m_strDictionaryFile + c_strDictCustomSuffix + ".dic"; m_pHunspell->add_dic(strPathCustomDic.c_str()); } // Load the ignore list (if there is one) if (sdDictInfo["has_ignore"].asBoolean()) { - llifstream fileDictIgnore(m_strDictionaryPath + sdDictInfo["name"].asString() + c_strDictIgnoreSuffix + ".dic", std::ios::in); + llifstream fileDictIgnore(m_strDictionaryPath + m_strDictionaryFile + c_strDictIgnoreSuffix + ".dic", std::ios::in); if (fileDictIgnore.is_open()) { std::string strWord; int idxLine = 0; @@ -197,6 +198,68 @@ bool LLHunspellWrapper::setCurrentDictionary(const std::string& strDictionary) return (NULL != m_pHunspell); } +// Checked: 2010-12-23 (Catznip-2.5.0a) | Added: Catznip-2.5.0a +void LLHunspellWrapper::addToCustomDictionary(const std::string& strWord) +{ + if (m_pHunspell) + m_pHunspell->add(strWord.c_str()); + addToDictFile(m_strDictionaryPath + m_strDictionaryFile + c_strDictCustomSuffix + ".dic", strWord); +} + +// Checked: 2010-12-23 (Catznip-2.5.0a) | Added: Catznip-2.5.0a +void LLHunspellWrapper::addToIgnoreList(const std::string& strWord) +{ + std::string strWordLower(strWord); + LLStringUtil::toLower(strWordLower); + if (std::find(m_IgnoreList.begin(), m_IgnoreList.end(), strWordLower) == m_IgnoreList.end()) + { + m_IgnoreList.push_back(strWordLower); + addToDictFile(m_strDictionaryPath + m_strDictionaryFile + c_strDictIgnoreSuffix + ".dic", strWordLower); + } +} + +// Checked: 2010-12-23 (Catznip-2.5.0a) | Added: Catznip-2.5.0a +void LLHunspellWrapper::addToDictFile(const std::string& strDictPath, const std::string& strWord) +{ + // TODO-Catznip: has to be a better way to add one word to the end and increment the line count? + std::vector wordList; + + // Read any existing words + if (gDirUtilp->fileExists(strDictPath)) + { + llifstream fileDictIn(strDictPath, std::ios::in); + if (fileDictIn.is_open()) + { + std::string strWord; int idxLine = 0; + while (getline(fileDictIn, strWord)) + { + // Skip over the first line since that's just a line count + if (0 != idxLine) + wordList.push_back(strWord); + idxLine++; + } + } + else + { + // TODO-Catznip: show error message? + return; + } + } + + // Add the new word to the end + wordList.push_back(strWord); + + // Recreate the file with the new line count and new word added + llofstream fileDictOut(strDictPath, std::ios::out | std::ios::trunc); + if (fileDictOut.is_open()) + { + fileDictOut << wordList.size() << std::endl; + for (std::vector::const_iterator itWord = wordList.begin(); itWord != wordList.end(); ++itWord) + fileDictOut << *itWord << std::endl; + fileDictOut.close(); + } +} + // ============================================================================ // Static member functions // diff --git a/indra/llui/llhunspell.h b/indra/llui/llhunspell.h index 2adbe2e780..46fe8aa65b 100644 --- a/indra/llui/llhunspell.h +++ b/indra/llui/llhunspell.h @@ -37,18 +37,21 @@ public: /* * Dictionary related functions */ - const std::string getCurrentDictionary() const { return m_strDictionary; } +public: + const std::string getCurrentDictionary() const { return m_strDictionaryName; } S32 getDictionaries(std::vector& strDictionaryList) const; - const std::string& getDictionaryPath() const { return m_strDictionaryPath; } S32 getInstalledDictionaries(std::vector& strDictionaryList) const; bool setCurrentDictionary(const std::string& strDictionary); - void addToDictionary(const std::string& strWord); - void addToIgnore(const std::string& strWord); + void addToCustomDictionary(const std::string& strWord); + void addToIgnoreList(const std::string& strWord); +protected: + void addToDictFile(const std::string& strDictPath, const std::string& strWord); /* * Static member functions */ +public: static bool useSpellCheck() { return s_fSpellCheck; } static void setUseSpellCheck(bool fSpellCheck); @@ -57,7 +60,8 @@ public: */ protected: Hunspell* m_pHunspell; - std::string m_strDictionary; + std::string m_strDictionaryName; + std::string m_strDictionaryFile; std::string m_strDictionaryPath; LLSD m_sdDictionaryMap; std::vector m_IgnoreList; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 95252ecc9d..933f647aee 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -563,24 +563,24 @@ void LLLineEditor::replaceWithSuggestion(U32 idxSuggestion) void LLLineEditor::addToDictionary() { - // TODO: implement this + if (canAddToDictionary()) + LLHunspellWrapper::instance().addToCustomDictionary(getMisspelledWord(mCursorPos)); } bool LLLineEditor::canAddToDictionary() const { - // TODO: implement this - return false; + return (useSpellCheck()) && (isMisspelledWord(mCursorPos)); } void LLLineEditor::addToIgnore() { - // TODO: implement this + if (canAddToIgnore()) + LLHunspellWrapper::instance().addToIgnoreList(getMisspelledWord(mCursorPos)); } bool LLLineEditor::canAddToIgnore() const { - // TODO: implement this - return false; + return (useSpellCheck()) && (isMisspelledWord(mCursorPos)); } std::string LLLineEditor::getMisspelledWord(U32 posCursor) const