From 9bdb1d82f867147af44def8c1cca3dfb8259b99c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 11 May 2012 12:22:43 -0400 Subject: rename feature from "autocorrect" to "autoreplace", change names accordingly --- indra/newview/llautoreplace.cpp | 458 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 indra/newview/llautoreplace.cpp (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp new file mode 100644 index 0000000000..a5683e4190 --- /dev/null +++ b/indra/newview/llautoreplace.cpp @@ -0,0 +1,458 @@ +/** + * @file llautoreplace.cpp + * @brief Auto Replace Manager + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llautoreplace.h" +#include "llsdserialize.h" +#include "llboost.h" +#include "llcontrol.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" + +AutoReplace* AutoReplace::sInstance; + +AutoReplace::AutoReplace() +{ + sInstance = this; + sInstance->loadFromDisk(); +} + +AutoReplace::~AutoReplace() +{ + sInstance = NULL; +} + +void AutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) +{ + static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); + if(perform_autoreplace) + { + S32 wordStart = 0; + S32 wordEnd = cursorPos-1; + + if(wordEnd < 1) + return; + + LLWString text = inputText.getWString(); + + if(text.size()<1) + return; + + if(LLWStringUtil::isPartOfWord(text[wordEnd])) + return;//we only check on word breaks + + wordEnd--; + + if(LLWStringUtil::isPartOfWord(text[wordEnd])) + { + while ((wordEnd > 0) && (' ' != text[wordEnd-1])) + { + wordEnd--; + } + + wordStart=wordEnd; + + while ((wordEnd < (S32)text.length()) && (' ' != text[wordEnd])) + { + wordEnd++; + } + + std::string strLastWord = std::string(text.begin(), text.end()); + std::string lastTypedWord = strLastWord.substr(wordStart, wordEnd-wordStart); + std::string replaceedWord(replaceWord(lastTypedWord)); + + if(replaceedWord != lastTypedWord) + { + LLWString strNew = utf8str_to_wstring(replaceedWord); + LLWString strOld = utf8str_to_wstring(lastTypedWord); + int nDiff = strNew.size() - strOld.size(); + + //int wordStart = regText.find(lastTypedWord); + text.replace(wordStart,lastTypedWord.length(),strNew); + inputText = wstring_to_utf8str(text); + cursorPos+=nDiff; + } + } + } +} + +AutoReplace* AutoReplace::getInstance() +{ + if(sInstance)return sInstance; + else + { + sInstance = new AutoReplace(); + return sInstance; + } +} +void AutoReplace::save() +{ + saveToDisk(mAutoReplaces); +} +std::string AutoReplace::getFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings_autoreplace.xml"); + } + return path; +} +std::string AutoReplace::getDefaultFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_autoreplace.xml"); + } + return path; +} +LLSD AutoReplace::exportList(std::string listName) +{ + LLSD toReturn; + if(mAutoReplaces.has(listName)) + { + toReturn["listName"]=listName; + toReturn["data"]=mAutoReplaces[listName]["data"]; + toReturn["author"]=mAutoReplaces[listName]["author"]; + toReturn["wordStyle"]=mAutoReplaces[listName]["wordStyle"]; + toReturn["priority"]=mAutoReplaces[listName]["priority"]; + } + return toReturn; +} +BOOL AutoReplace::addReplacementList(LLSD newList) +{ + if(newList.has("listName")) + { + std::string name = newList["listName"]; + //if(!mAutoReplaces.has(name)){ + LLSD newPart; + newPart["data"]=newList["data"]; + newPart["enabled"]=TRUE; + newPart["announce"]=FALSE; + newPart["author"]=newList["author"]; + newPart["wordStyle"]=newList["wordStyle"]; + newPart["priority"]=newList["priority"].asInteger(); + llinfos << "adding new list with settings priority "<fileExists(filename)) + { + std::string defaultName = getDefaultFileName(); + llinfos << " user settings file doesnt exist, going to try and read default one from "<fileExists(defaultName)) + { + LLSD blankllsd; + llifstream file; + file.open(defaultName.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(blankllsd, file); + } + file.close(); + saveToDisk(blankllsd); + }else + saveToDisk(getExampleLLSD()); + } + else + { + llifstream file; + file.open(filename.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXML(mAutoReplaces, file); + } + file.close(); + } +} +void AutoReplace::saveToDisk(LLSD newSettings) +{ + mAutoReplaces=newSettings; + std::string filename=getFileName(); + llofstream file; + file.open(filename.c_str()); + LLSDSerialize::toPrettyXML(mAutoReplaces, file); + file.close(); +} +void AutoReplace::runTest() +{ + std::string startS("He just abandonned all his abilties"); + std::string endS = replaceWords(startS); + llinfos << "!!! Test of autoreplace; start with "< perform_autoreplace(gSavedSettings, "AutoReplace"); + if(!(perform_autoreplace))return currentWord; + //loop through priorities + for(int currentPriority = 10;currentPriority>=0;currentPriority--) + { + LLSD::map_const_iterator loc_it = mAutoReplaces.beginMap(); + LLSD::map_const_iterator loc_end = mAutoReplaces.endMap(); + for (; loc_it != loc_end; ++loc_it) + { + const std::string& location = (*loc_it).first; + //llinfos << "location is "< " << replacement.c_str() << llendl; + return replacement; + } + } + } + } + return currentWord; +} +std::string AutoReplace::replaceWords(std::string words) +{ + static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); + if(!(perform_autoreplace))return words; + //*TODO update this function to use the "wordStyle" thing, + //but so far this function is never used, so later + + boost_tokenizer tokens(words, boost::char_separator(" ")); + for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) + { + std::string currentWord(*token_iter); + LLSD::map_const_iterator loc_it = mAutoReplaces.beginMap(); + LLSD::map_const_iterator loc_end = mAutoReplaces.endMap(); + for (; loc_it != loc_end; ++loc_it) + { + const std::string& location = (*loc_it).first; + const LLSD& loc_map = (*loc_it).second; + if((loc_map["data"].has(currentWord))&&(loc_map["enabled"].asBoolean())) + { + std::string replacement = loc_map["data"][currentWord]; + if(loc_map["announce"].asBoolean()) + { + LLSD args; + //"[Before]" has been auto replaced by "[Replacement]" + // based on your [ListName] list. + args["BEFORE"] = currentWord; + args["LISTNAME"]=location; + args["REPLACEMENT"]=replacement; + LLNotificationsUtil::add("AutoReplace",args); + } + lldebugs << "found a word in list " << location.c_str() << " and it will replace " << currentWord.c_str() << " => " << replacement.c_str() << llendl; + int wordStart = words.find(currentWord); + words.replace(wordStart,currentWord.length(),replacement); + return replaceWords(words);//lol recursion! + } + } + } + return words; +} +BOOL AutoReplace::addEntryToList(std::string wrong, std::string right, std::string listName) +{ + // *HACK: Make sure the "Custom" list exists, because the design of this + // system prevents us from updating it by changing the original file... + if(mAutoReplaces.has(listName)) + { + mAutoReplaces[listName]["data"][wrong]=right; + return TRUE; + } + else if(listName == "Custom") + { + mAutoReplaces[listName]["announce"] = 0; + mAutoReplaces[listName]["author"] = "You"; + mAutoReplaces[listName]["data"][wrong] = right; + mAutoReplaces[listName]["enabled"] = 1; + mAutoReplaces[listName]["priority"] = 10; + mAutoReplaces[listName]["wordStyle"] = 1; + return TRUE; + } + + return FALSE; +} +BOOL AutoReplace::removeEntryFromList(std::string wrong, std::string listName) +{ + if(mAutoReplaces.has(listName)) + { + if(mAutoReplaces[listName]["data"].has(wrong)) + { + mAutoReplaces[listName]["data"].erase(wrong); + return TRUE; + } + } + return FALSE; +} + +LLSD AutoReplace::getExampleLLSD() +{ + LLSD toReturn; + + LLSD listone; + LLSD listtwo; + + LLSD itemOne; + itemOne["wrong"]="wrong1"; + itemOne["right"]="right1"; + listone[0]=itemOne; + + LLSD itemTwo; + itemTwo["wrong"]="wrong2"; + itemTwo["right"]="right2"; + listone[1]=itemTwo; + + toReturn["listOne"]=listone; + + + itemOne["wrong"]="secondwrong1"; + itemOne["right"]="secondright1"; + listone[0]=itemOne; + + itemTwo["wrong"]="secondwrong2"; + itemTwo["right"]="secondright2"; + listone[1]=itemTwo; + + toReturn["listTwo"]=listone; + + return toReturn; +} + -- cgit v1.2.3 From 6d9c0fab8f2c19fa624e3c1f697ee9c7f08d9245 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 11 May 2012 14:31:45 -0400 Subject: remove author tracking, non-wordstyle option, and notifications --- indra/newview/llautoreplace.cpp | 71 ----------------------------------------- 1 file changed, 71 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index a5683e4190..fa46f53e96 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -137,8 +137,6 @@ LLSD AutoReplace::exportList(std::string listName) { toReturn["listName"]=listName; toReturn["data"]=mAutoReplaces[listName]["data"]; - toReturn["author"]=mAutoReplaces[listName]["author"]; - toReturn["wordStyle"]=mAutoReplaces[listName]["wordStyle"]; toReturn["priority"]=mAutoReplaces[listName]["priority"]; } return toReturn; @@ -152,9 +150,6 @@ BOOL AutoReplace::addReplacementList(LLSD newList) LLSD newPart; newPart["data"]=newList["data"]; newPart["enabled"]=TRUE; - newPart["announce"]=FALSE; - newPart["author"]=newList["author"]; - newPart["wordStyle"]=newList["wordStyle"]; newPart["priority"]=newList["priority"].asInteger(); llinfos << "adding new list with settings priority "< " << replacement.c_str() << llendl; return replacement; } @@ -353,8 +297,6 @@ std::string AutoReplace::replaceWords(std::string words) { static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); if(!(perform_autoreplace))return words; - //*TODO update this function to use the "wordStyle" thing, - //but so far this function is never used, so later boost_tokenizer tokens(words, boost::char_separator(" ")); for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) @@ -369,16 +311,6 @@ std::string AutoReplace::replaceWords(std::string words) if((loc_map["data"].has(currentWord))&&(loc_map["enabled"].asBoolean())) { std::string replacement = loc_map["data"][currentWord]; - if(loc_map["announce"].asBoolean()) - { - LLSD args; - //"[Before]" has been auto replaced by "[Replacement]" - // based on your [ListName] list. - args["BEFORE"] = currentWord; - args["LISTNAME"]=location; - args["REPLACEMENT"]=replacement; - LLNotificationsUtil::add("AutoReplace",args); - } lldebugs << "found a word in list " << location.c_str() << " and it will replace " << currentWord.c_str() << " => " << replacement.c_str() << llendl; int wordStart = words.find(currentWord); words.replace(wordStart,currentWord.length(),replacement); @@ -399,12 +331,9 @@ BOOL AutoReplace::addEntryToList(std::string wrong, std::string right, std::stri } else if(listName == "Custom") { - mAutoReplaces[listName]["announce"] = 0; - mAutoReplaces[listName]["author"] = "You"; mAutoReplaces[listName]["data"][wrong] = right; mAutoReplaces[listName]["enabled"] = 1; mAutoReplaces[listName]["priority"] = 10; - mAutoReplaces[listName]["wordStyle"] = 1; return TRUE; } -- cgit v1.2.3 From 0d11c70e8e68ea2c33cdf01b56b6f2f81ed46f1e Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Sat, 12 May 2012 12:59:07 -0400 Subject: STORM-1738: fix class name and other coding standards issues --- indra/newview/llautoreplace.cpp | 107 +++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 40 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index fa46f53e96..10005aee9f 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -30,20 +30,20 @@ #include "llviewercontrol.h" #include "llnotificationsutil.h" -AutoReplace* AutoReplace::sInstance; +LLAutoReplace* LLAutoReplace::sInstance; -AutoReplace::AutoReplace() +LLAutoReplace::LLAutoReplace() { sInstance = this; sInstance->loadFromDisk(); } -AutoReplace::~AutoReplace() +LLAutoReplace::~LLAutoReplace() { sInstance = NULL; } -void AutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) +void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) { static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); if(perform_autoreplace) @@ -52,16 +52,22 @@ void AutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) S32 wordEnd = cursorPos-1; if(wordEnd < 1) + { return; - + } + LLWString text = inputText.getWString(); if(text.size()<1) + { return; - + } + if(LLWStringUtil::isPartOfWord(text[wordEnd])) + { return;//we only check on word breaks - + } + wordEnd--; if(LLWStringUtil::isPartOfWord(text[wordEnd])) @@ -80,11 +86,11 @@ void AutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) std::string strLastWord = std::string(text.begin(), text.end()); std::string lastTypedWord = strLastWord.substr(wordStart, wordEnd-wordStart); - std::string replaceedWord(replaceWord(lastTypedWord)); + std::string replacedWord(replaceWord(lastTypedWord)); - if(replaceedWord != lastTypedWord) + if(replacedWord != lastTypedWord) { - LLWString strNew = utf8str_to_wstring(replaceedWord); + LLWString strNew = utf8str_to_wstring(replacedWord); LLWString strOld = utf8str_to_wstring(lastTypedWord); int nDiff = strNew.size() - strOld.size(); @@ -97,20 +103,21 @@ void AutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) } } -AutoReplace* AutoReplace::getInstance() +LLAutoReplace* LLAutoReplace::getInstance() { - if(sInstance)return sInstance; - else + if(!sInstance) { - sInstance = new AutoReplace(); - return sInstance; + sInstance = new LLAutoReplace(); } + return sInstance; } -void AutoReplace::save() + +void LLAutoReplace::save() { saveToDisk(mAutoReplaces); } -std::string AutoReplace::getFileName() + +std::string LLAutoReplace::getFileName() { std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); @@ -120,7 +127,8 @@ std::string AutoReplace::getFileName() } return path; } -std::string AutoReplace::getDefaultFileName() + +std::string LLAutoReplace::getDefaultFileName() { std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); @@ -130,7 +138,8 @@ std::string AutoReplace::getDefaultFileName() } return path; } -LLSD AutoReplace::exportList(std::string listName) + +LLSD LLAutoReplace::exportList(std::string listName) { LLSD toReturn; if(mAutoReplaces.has(listName)) @@ -141,12 +150,12 @@ LLSD AutoReplace::exportList(std::string listName) } return toReturn; } -BOOL AutoReplace::addReplacementList(LLSD newList) + +BOOL LLAutoReplace::addReplacementList(LLSD newList) { if(newList.has("listName")) { std::string name = newList["listName"]; - //if(!mAutoReplaces.has(name)){ LLSD newPart; newPart["data"]=newList["data"]; newPart["enabled"]=TRUE; @@ -155,11 +164,11 @@ BOOL AutoReplace::addReplacementList(LLSD newList) mAutoReplaces[name]=newPart; return TRUE; - } return FALSE; } -BOOL AutoReplace::removeReplacementList(std::string listName) + +BOOL LLAutoReplace::removeReplacementList(std::string listName) { if(mAutoReplaces.has(listName)) { @@ -168,7 +177,8 @@ BOOL AutoReplace::removeReplacementList(std::string listName) } return FALSE; } -BOOL AutoReplace::setListEnabled(std::string listName, BOOL enabled) + +BOOL LLAutoReplace::setListEnabled(std::string listName, BOOL enabled) { if(mAutoReplaces.has(listName)) { @@ -178,7 +188,8 @@ BOOL AutoReplace::setListEnabled(std::string listName, BOOL enabled) return FALSE; } -BOOL AutoReplace::setListPriority(std::string listName, int priority) + +BOOL LLAutoReplace::setListPriority(std::string listName, int priority) { if(mAutoReplaces.has(listName)) { @@ -187,11 +198,13 @@ BOOL AutoReplace::setListPriority(std::string listName, int priority) } return FALSE; } -LLSD AutoReplace::getAutoReplaces() + +LLSD LLAutoReplace::getAutoReplaces() { return mAutoReplaces; } -void AutoReplace::loadFromDisk() + +void LLAutoReplace::loadFromDisk() { std::string filename=getFileName(); if (filename.empty()) @@ -214,8 +227,11 @@ void AutoReplace::loadFromDisk() } file.close(); saveToDisk(blankllsd); - }else - saveToDisk(getExampleLLSD()); + } + else + { + saveToDisk(getExampleLLSD()); + } } else { @@ -228,7 +244,8 @@ void AutoReplace::loadFromDisk() file.close(); } } -void AutoReplace::saveToDisk(LLSD newSettings) + +void LLAutoReplace::saveToDisk(LLSD newSettings) { mAutoReplaces=newSettings; std::string filename=getFileName(); @@ -237,7 +254,8 @@ void AutoReplace::saveToDisk(LLSD newSettings) LLSDSerialize::toPrettyXML(mAutoReplaces, file); file.close(); } -void AutoReplace::runTest() + +void LLAutoReplace::runTest() { std::string startS("He just abandonned all his abilties"); std::string endS = replaceWords(startS); @@ -245,7 +263,8 @@ void AutoReplace::runTest() } -BOOL AutoReplace::saveListToDisk(std::string listName, std::string fileName) + +BOOL LLAutoReplace::saveListToDisk(std::string listName, std::string fileName) { if(mAutoReplaces.has(listName)) { @@ -257,7 +276,8 @@ BOOL AutoReplace::saveListToDisk(std::string listName, std::string fileName) } return FALSE; } -LLSD AutoReplace::getAutoReplaceEntries(std::string listName) + +LLSD LLAutoReplace::getAutoReplaceEntries(std::string listName) { LLSD toReturn; if(mAutoReplaces.has(listName)) @@ -266,7 +286,8 @@ LLSD AutoReplace::getAutoReplaceEntries(std::string listName) } return toReturn; } -std::string AutoReplace::replaceWord(std::string currentWord) + +std::string LLAutoReplace::replaceWord(std::string currentWord) { static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); if(!(perform_autoreplace))return currentWord; @@ -293,11 +314,15 @@ std::string AutoReplace::replaceWord(std::string currentWord) } return currentWord; } -std::string AutoReplace::replaceWords(std::string words) + +std::string LLAutoReplace::replaceWords(std::string words) { static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); - if(!(perform_autoreplace))return words; - + if(!(perform_autoreplace)) + { + return words; + } + boost_tokenizer tokens(words, boost::char_separator(" ")); for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) { @@ -320,7 +345,8 @@ std::string AutoReplace::replaceWords(std::string words) } return words; } -BOOL AutoReplace::addEntryToList(std::string wrong, std::string right, std::string listName) + +BOOL LLAutoReplace::addEntryToList(std::string wrong, std::string right, std::string listName) { // *HACK: Make sure the "Custom" list exists, because the design of this // system prevents us from updating it by changing the original file... @@ -339,7 +365,8 @@ BOOL AutoReplace::addEntryToList(std::string wrong, std::string right, std::stri return FALSE; } -BOOL AutoReplace::removeEntryFromList(std::string wrong, std::string listName) + +BOOL LLAutoReplace::removeEntryFromList(std::string wrong, std::string listName) { if(mAutoReplaces.has(listName)) { @@ -352,7 +379,7 @@ BOOL AutoReplace::removeEntryFromList(std::string wrong, std::string listName) return FALSE; } -LLSD AutoReplace::getExampleLLSD() +LLSD LLAutoReplace::getExampleLLSD() { LLSD toReturn; -- cgit v1.2.3 From 04ab2cf43b5341900737f0d480bce0b8205add8e Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 23 May 2012 21:30:13 -0400 Subject: storm-1738: restructure code, preferences storage, preferences ui; ui not completely tested --- indra/newview/llautoreplace.cpp | 711 +++++++++++++++++++++++++++++----------- 1 file changed, 512 insertions(+), 199 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index 10005aee9f..0432bf735a 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llautoreplace.cpp * @brief Auto Replace Manager * @@ -10,12 +10,12 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -32,10 +32,10 @@ LLAutoReplace* LLAutoReplace::sInstance; +const char* LLAutoReplace::SETTINGS_FILE_NAME = "settings_autoreplace.xml"; + LLAutoReplace::LLAutoReplace() { - sInstance = this; - sInstance->loadFromDisk(); } LLAutoReplace::~LLAutoReplace() @@ -55,29 +55,27 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) { return; } - - LLWString text = inputText.getWString(); + LLWString text = inputText.getWString(); if(text.size()<1) { return; } - + if(LLWStringUtil::isPartOfWord(text[wordEnd])) { return;//we only check on word breaks } - - wordEnd--; - if(LLWStringUtil::isPartOfWord(text[wordEnd])) + wordEnd--; + if ( LLWStringUtil::isPartOfWord(text[wordEnd]) ) { while ((wordEnd > 0) && (' ' != text[wordEnd-1])) { wordEnd--; } - wordStart=wordEnd; + wordStart=wordEnd; while ((wordEnd < (S32)text.length()) && (' ' != text[wordEnd])) { @@ -86,7 +84,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) std::string strLastWord = std::string(text.begin(), text.end()); std::string lastTypedWord = strLastWord.substr(wordStart, wordEnd-wordStart); - std::string replacedWord(replaceWord(lastTypedWord)); + std::string replacedWord( mSettings.replaceWord(lastTypedWord) ); if(replacedWord != lastTypedWord) { @@ -94,7 +92,6 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) LLWString strOld = utf8str_to_wstring(lastTypedWord); int nDiff = strNew.size() - strOld.size(); - //int wordStart = regText.find(lastTypedWord); text.replace(wordStart,lastTypedWord.length(),strNew); inputText = wstring_to_utf8str(text); cursorPos+=nDiff; @@ -108,307 +105,623 @@ LLAutoReplace* LLAutoReplace::getInstance() if(!sInstance) { sInstance = new LLAutoReplace(); + sInstance->loadFromSettings(); } return sInstance; } -void LLAutoReplace::save() -{ - saveToDisk(mAutoReplaces); -} - -std::string LLAutoReplace::getFileName() +std::string LLAutoReplace::getUserSettingsFileName() { std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); if (!path.empty()) { - path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings_autoreplace.xml"); + path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, SETTINGS_FILE_NAME); } - return path; + return path; } -std::string LLAutoReplace::getDefaultFileName() +std::string LLAutoReplace::getAppSettingsFileName() { std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); if (!path.empty()) { - path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_autoreplace.xml"); + path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, SETTINGS_FILE_NAME); } - return path; + else + { + LL_ERRS("AutoReplace") << "Failed to get app settings directory name" << LL_ENDL; + } + return path; } -LLSD LLAutoReplace::exportList(std::string listName) +LLAutoReplaceSettings LLAutoReplace::getSettings() { - LLSD toReturn; - if(mAutoReplaces.has(listName)) - { - toReturn["listName"]=listName; - toReturn["data"]=mAutoReplaces[listName]["data"]; - toReturn["priority"]=mAutoReplaces[listName]["priority"]; - } - return toReturn; + return mSettings; +} + +void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings) +{ + mSettings.set(newSettings); } -BOOL LLAutoReplace::addReplacementList(LLSD newList) +void LLAutoReplace::loadFromSettings() { - if(newList.has("listName")) + std::string filename=getUserSettingsFileName(); + if (filename.empty()) + { + LL_INFOS("AutoReplace") << "no valid user settings directory." << LL_ENDL; + } + if(gDirUtilp->fileExists(filename)) { - std::string name = newList["listName"]; - LLSD newPart; - newPart["data"]=newList["data"]; - newPart["enabled"]=TRUE; - newPart["priority"]=newList["priority"].asInteger(); - llinfos << "adding new list with settings priority "<fileExists(defaultName)) + { + LLSD appDefault; + llifstream file; + file.open(defaultName.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(appDefault, file); + } + file.close(); - return TRUE; + if ( mSettings.setFromLLSD(appDefault) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL; + saveToUserSettings(appDefault); + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL; + } + } + else + { + if (mSettings.setFromLLSD(mSettings.getExampleLLSD())) + { + LL_WARNS("AutoReplace") << "no settings found; loaded example." << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "no settings found and example invalid!" << LL_ENDL; + } + } } - return FALSE; } -BOOL LLAutoReplace::removeReplacementList(std::string listName) +void LLAutoReplace::saveToUserSettings(const LLSD& newSettings) { - if(mAutoReplaces.has(listName)) - { - mAutoReplaces.erase(listName); - return TRUE; - } - return FALSE; + std::string filename=getUserSettingsFileName(); + llofstream file; + file.open(filename.c_str()); + LLSDSerialize::toPrettyXML(newSettings, file); + file.close(); + LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL; } -BOOL LLAutoReplace::setListEnabled(std::string listName, BOOL enabled) +// ================================================================ +// LLAutoReplaceSettings +// ================================================================ + +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_NAME = "name"; ///< key for looking up list names +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_REPLACEMENTS = "replacements"; ///< key for looking up replacement map + +LLAutoReplaceSettings::LLAutoReplaceSettings() { - if(mAutoReplaces.has(listName)) +} + +LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settings) +{ + // copy all values through fundamental type intermediates for thread safety + mLists = LLSD::emptyArray(); + + for ( LLSD::array_const_iterator list = settings.mLists.beginArray(), listEnd = settings.mLists.endArray(); + list != listEnd; + list++ + ) { - mAutoReplaces[listName]["enabled"]=enabled; - return TRUE; + LLSD listMap = LLSD::emptyMap(); + std::string listName = (*list)[AUTOREPLACE_LIST_NAME]; + listMap[AUTOREPLACE_LIST_NAME] = listName; + listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + + for ( LLSD::map_const_iterator + entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), + entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); + entry != entriesEnd; + entry++ + ) + { + std::string keyword = entry->first; + std::string replacement = entry->second.asString(); + listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement)); + } + + mLists.append(listMap); } - - return FALSE; } -BOOL LLAutoReplace::setListPriority(std::string listName, int priority) +void LLAutoReplaceSettings::set(const LLAutoReplaceSettings& newSettings) { - if(mAutoReplaces.has(listName)) + mLists = newSettings.mLists; +} + +bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD) +{ + bool settingsValid = true; + + if ( settingsFromLLSD.isArray() ) { - mAutoReplaces[listName]["priority"]=priority; - return TRUE; + for ( LLSD::array_const_iterator + list = settingsFromLLSD.beginArray(), + listEnd = settingsFromLLSD.endArray(); + settingsValid && list != listEnd; + list++ + ) + { + settingsValid = listIsValid(*list); + } } - return FALSE; + else + { + settingsValid = false; + LL_WARNS("AutoReplace") << "settings are not an array" << LL_ENDL; + } + + if ( settingsValid ) + { + mLists = settingsFromLLSD; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings discarded; using hard coded example" << LL_ENDL; + } + + return settingsValid; } -LLSD LLAutoReplace::getAutoReplaces() +bool LLAutoReplaceSettings::listNameMatches( const LLSD& list, const std::string name ) { - return mAutoReplaces; + return list.isMap() + && list.has(AUTOREPLACE_LIST_NAME) + && list[AUTOREPLACE_LIST_NAME].asString() == name; } -void LLAutoReplace::loadFromDisk() +const LLSD* LLAutoReplaceSettings::getListEntries(std::string listName) { - std::string filename=getFileName(); - if (filename.empty()) + const LLSD* returnedEntries = NULL; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + returnedEntries == NULL && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + returnedEntries = &thisList[AUTOREPLACE_LIST_REPLACEMENTS]; + } + } + return returnedEntries; +} + +std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::string listName) +{ + std::string replacement; + bool foundList = false; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + ! foundList && list != endList; + list++ + ) { - llinfos << "no valid user directory." << llendl; + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + foundList = true; // whether there is a replacement or not, we're done + if ( thisList.isMap() + && thisList.has(AUTOREPLACE_LIST_REPLACEMENTS) + && thisList[AUTOREPLACE_LIST_REPLACEMENTS].has(keyword) + ) + { + replacement = thisList[AUTOREPLACE_LIST_REPLACEMENTS][keyword].asString(); + LL_DEBUGS("AutoReplace")<<"'"< '"<fileExists(filename)) + if (replacement.empty()) { - std::string defaultName = getDefaultFileName(); - llinfos << " user settings file doesnt exist, going to try and read default one from "<fileExists(defaultName)) +LLSD LLAutoReplaceSettings::getListNames() +{ + LLSD toReturn = LLSD::emptyArray(); + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + list != endList && (*list).isDefined(); // deleting entries leaves undefined items in the iterator + list++ + ) + { + const LLSD& thisList = *list; + if ( thisList.isMap() ) { - LLSD blankllsd; - llifstream file; - file.open(defaultName.c_str()); - if (file.is_open()) + if ( thisList.has(AUTOREPLACE_LIST_NAME) ) { - LLSDSerialize::fromXMLDocument(blankllsd, file); + std::string name = thisList[AUTOREPLACE_LIST_NAME].asString(); + toReturn.append(LLSD(name)); + } + else + { + LL_ERRS("AutoReplace") << " ! MISSING "<second.isString() ) + { + listValid = false; + LL_WARNS("AutoReplace") + << "non-string replacement value found in list '" + << list[AUTOREPLACE_LIST_NAME].asString() << "'" + << LL_ENDL; + } } - file.close(); - } + } + + return listValid; } -void LLAutoReplace::saveToDisk(LLSD newSettings) +const LLSD* LLAutoReplaceSettings::exportList(std::string listName) { - mAutoReplaces=newSettings; - std::string filename=getFileName(); - llofstream file; - file.open(filename.c_str()); - LLSDSerialize::toPrettyXML(mAutoReplaces, file); - file.close(); + const LLSD* exportedList = NULL; + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + exportedList == NULL && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + const LLSD& namedList = (*list); + exportedList = &namedList; + } + } + return exportedList; } -void LLAutoReplace::runTest() +bool LLAutoReplaceSettings::listNameIsUnique(const LLSD& newList) { - std::string startS("He just abandonned all his abilties"); - std::string endS = replaceWords(startS); - llinfos << "!!! Test of autoreplace; start with "< perform_autoreplace(gSavedSettings, "AutoReplace"); - if(!(perform_autoreplace))return currentWord; - //loop through priorities - for(int currentPriority = 10;currentPriority>=0;currentPriority--) + bool found = false; + for( S32 index = 0; !found && mLists[index].isDefined(); index++ ) { - LLSD::map_const_iterator loc_it = mAutoReplaces.beginMap(); - LLSD::map_const_iterator loc_end = mAutoReplaces.endMap(); - for (; loc_it != loc_end; ++loc_it) + if( listNameMatches(mLists.get(index), listName) ) { - const std::string& location = (*loc_it).first; - //llinfos << "location is "< " << replacement.c_str() << llendl; - return replacement; - } - } + LL_DEBUGS("AutoReplace")<<"list '"< perform_autoreplace(gSavedSettings, "AutoReplace"); - if(!(perform_autoreplace)) + LL_DEBUGS("AutoReplace")<(" ")); - for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) - { - std::string currentWord(*token_iter); - LLSD::map_const_iterator loc_it = mAutoReplaces.beginMap(); - LLSD::map_const_iterator loc_end = mAutoReplaces.endMap(); - for (; loc_it != loc_end; ++loc_it) + if ( listNameMatches( targetList, listName) ) { - const std::string& location = (*loc_it).first; - const LLSD& loc_map = (*loc_it).second; - if((loc_map["data"].has(currentWord))&&(loc_map["enabled"].asBoolean())) + LL_DEBUGS("AutoReplace")<<"found at index "< 0) + { + // copy the target to before the element preceding it + mLists.insert(search_index-1,targetList); + // delete the original, now duplicate, copy + mLists.erase(search_index+1); + } + else { - std::string replacement = loc_map["data"][currentWord]; - lldebugs << "found a word in list " << location.c_str() << " and it will replace " << currentWord.c_str() << " => " << replacement.c_str() << llendl; - int wordStart = words.find(currentWord); - words.replace(wordStart,currentWord.length(),replacement); - return replaceWords(words);//lol recursion! + LL_WARNS("AutoReplace") << "attempted to move top list up" << LL_ENDL; } - } + } } - return words; + return found; } -BOOL LLAutoReplace::addEntryToList(std::string wrong, std::string right, std::string listName) +/// Move the named list down in the priority order +bool LLAutoReplaceSettings::decreaseListPriority(std::string listName) { - // *HACK: Make sure the "Custom" list exists, because the design of this - // system prevents us from updating it by changing the original file... - if(mAutoReplaces.has(listName)) + LL_DEBUGS("AutoReplace")< autoreplace_enabled(gSavedSettings, "AutoReplace"); + if ( autoreplace_enabled ) { - if(mAutoReplaces[listName]["data"].has(wrong)) + //loop through lists in order + bool found = false; + for( LLSD::array_const_iterator list = mLists.beginArray(), endLists = mLists.endArray(); + ! found && list != endLists; + list++ + ) { - mAutoReplaces[listName]["data"].erase(wrong); - return TRUE; + const LLSD& checkList = *list; + const LLSD& replacements = checkList[AUTOREPLACE_LIST_REPLACEMENTS]; + + if ( replacements.has(currentWord) ) + { + found = true; + LL_DEBUGS("AutoReplace") + << "found in list '" << checkList[AUTOREPLACE_LIST_NAME].asString() << "' : '" + << currentWord << "' => '" << replacements[currentWord].asString() << "'" + << LL_ENDL; + returnedWord = replacements[currentWord].asString(); + } } } - return FALSE; + return returnedWord; } -LLSD LLAutoReplace::getExampleLLSD() +bool LLAutoReplaceSettings::addEntryToList(std::string keyword, std::string replacement, std::string listName) { - LLSD toReturn; - - LLSD listone; - LLSD listtwo; - - LLSD itemOne; - itemOne["wrong"]="wrong1"; - itemOne["right"]="right1"; - listone[0]=itemOne; - - LLSD itemTwo; - itemTwo["wrong"]="wrong2"; - itemTwo["right"]="right2"; - listone[1]=itemTwo; - - toReturn["listOne"]=listone; + bool added = false; + if ( ! keyword.empty() && ! replacement.empty() ) + { + bool isOneWord = true; + for (S32 character = 0; isOneWord && character < keyword.size(); character++ ) + { + if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) + { + LL_WARNS("AutoReplace") << "keyword '" << keyword << "' not a single word" << LL_ENDL; + isOneWord = false; + } + } - itemOne["wrong"]="secondwrong1"; - itemOne["right"]="secondright1"; - listone[0]=itemOne; + if ( isOneWord ) + { + bool listFound = false; + for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray(); + ! listFound && list != endLists; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + listFound = true; + (*list)[AUTOREPLACE_LIST_REPLACEMENTS][keyword]=replacement; + } + } + if (listFound) + { + added = true; + } + else + { + LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL; + } + } + } - itemTwo["wrong"]="secondwrong2"; - itemTwo["right"]="secondright2"; - listone[1]=itemTwo; + return added; +} - toReturn["listTwo"]=listone; +bool LLAutoReplaceSettings::removeEntryFromList(std::string keyword, std::string listName) +{ + bool found = false; + for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray(); + ! found && list != endLists; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + found = true; + (*list)[AUTOREPLACE_LIST_REPLACEMENTS].erase(keyword); + } + } + if (!found) + { + LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL; + } + return found; +} - return toReturn; +LLSD LLAutoReplaceSettings::getExampleLLSD() +{ + LL_DEBUGS("AutoReplace")< Date: Fri, 25 May 2012 19:24:38 -0400 Subject: fix problems due to LLSD-30, and implement persistent settings --- indra/newview/llautoreplace.cpp | 142 ++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 49 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index 0432bf735a..32cd7d2ae3 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -32,7 +32,7 @@ LLAutoReplace* LLAutoReplace::sInstance; -const char* LLAutoReplace::SETTINGS_FILE_NAME = "settings_autoreplace.xml"; +const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml"; LLAutoReplace::LLAutoReplace() { @@ -144,6 +144,8 @@ LLAutoReplaceSettings LLAutoReplace::getSettings() void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings) { mSettings.set(newSettings); + /// Make the newSettings active and write them to user storage + saveToUserSettings(); } void LLAutoReplace::loadFromSettings() @@ -175,10 +177,9 @@ void LLAutoReplace::loadFromSettings() else // no user settings found, try application settings { std::string defaultName = getAppSettingsFileName(); - LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found;\n" - << " trying '" << defaultName.c_str() << "'" - << LL_ENDL; + LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found"<< LL_ENDL; + bool gotSettings = false; if(gDirUtilp->fileExists(defaultName)) { LLSD appDefault; @@ -192,15 +193,16 @@ void LLAutoReplace::loadFromSettings() if ( mSettings.setFromLLSD(appDefault) ) { - LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL; - saveToUserSettings(appDefault); + LL_INFOS("AutoReplace") << "settings loaded from '" << defaultName.c_str() << "'" << LL_ENDL; + gotSettings = true; } else { - LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL; + LL_WARNS("AutoReplace") << "invalid settings found in '" << defaultName.c_str() << "'" << LL_ENDL; } } - else + + if ( ! gotSettings ) { if (mSettings.setFromLLSD(mSettings.getExampleLLSD())) { @@ -214,12 +216,12 @@ void LLAutoReplace::loadFromSettings() } } -void LLAutoReplace::saveToUserSettings(const LLSD& newSettings) +void LLAutoReplace::saveToUserSettings() { std::string filename=getUserSettingsFileName(); llofstream file; file.open(filename.c_str()); - LLSDSerialize::toPrettyXML(newSettings, file); + LLSDSerialize::toPrettyXML(mSettings.getAsLLSD(), file); file.close(); LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL; } @@ -245,24 +247,27 @@ LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settin list++ ) { - LLSD listMap = LLSD::emptyMap(); - std::string listName = (*list)[AUTOREPLACE_LIST_NAME]; - listMap[AUTOREPLACE_LIST_NAME] = listName; - listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); - - for ( LLSD::map_const_iterator - entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), - entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); - entry != entriesEnd; - entry++ - ) + if ( (*list).isMap() ) // can fail due to LLSD-30: ignore it { - std::string keyword = entry->first; - std::string replacement = entry->second.asString(); - listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement)); - } + LLSD listMap = LLSD::emptyMap(); + std::string listName = (*list)[AUTOREPLACE_LIST_NAME]; + listMap[AUTOREPLACE_LIST_NAME] = listName; + listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + + for ( LLSD::map_const_iterator + entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), + entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); + entry != entriesEnd; + entry++ + ) + { + std::string keyword = entry->first; + std::string replacement = entry->second.asString(); + listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement)); + } - mLists.append(listMap); + mLists.append(listMap); + } } } @@ -284,7 +289,10 @@ bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD) list++ ) { - settingsValid = listIsValid(*list); + if ( (*list).isDefined() ) // can be undef due to LLSD-30: ignore it + { + settingsValid = listIsValid(*list); + } } } else @@ -365,9 +373,11 @@ std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::stri LLSD LLAutoReplaceSettings::getListNames() { + LL_DEBUGS("AutoReplace")<<"====="< 0) + if ( listNameMatches( targetList, listName) ) { - // copy the target to before the element preceding it - mLists.insert(search_index-1,targetList); - // delete the original, now duplicate, copy - mLists.erase(search_index+1); + LL_DEBUGS("AutoReplace")<<"found at "<= 0) + { + LL_DEBUGS("AutoReplace") << "erase "< Date: Sat, 26 May 2012 06:44:59 -0400 Subject: storm-1738: clarify word recognition code --- indra/newview/llautoreplace.cpp | 77 +++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 37 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index 32cd7d2ae3..a4a08daf27 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -48,53 +48,56 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace"); if(perform_autoreplace) { - S32 wordStart = 0; S32 wordEnd = cursorPos-1; - - if(wordEnd < 1) - { - return; - } - LLWString text = inputText.getWString(); - if(text.size()<1) - { - return; - } - if(LLWStringUtil::isPartOfWord(text[wordEnd])) - { - return;//we only check on word breaks - } + bool atSpace = (text[wordEnd] == ' '); + bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd])); - wordEnd--; - if ( LLWStringUtil::isPartOfWord(text[wordEnd]) ) + if (atSpace || haveWord) { - while ((wordEnd > 0) && (' ' != text[wordEnd-1])) + if (atSpace) { + // find out if this space immediately follows a word wordEnd--; + haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd])); } - - wordStart=wordEnd; - - while ((wordEnd < (S32)text.length()) && (' ' != text[wordEnd])) - { - wordEnd++; - } - - std::string strLastWord = std::string(text.begin(), text.end()); - std::string lastTypedWord = strLastWord.substr(wordStart, wordEnd-wordStart); - std::string replacedWord( mSettings.replaceWord(lastTypedWord) ); - - if(replacedWord != lastTypedWord) + if (haveWord) { - LLWString strNew = utf8str_to_wstring(replacedWord); - LLWString strOld = utf8str_to_wstring(lastTypedWord); - int nDiff = strNew.size() - strOld.size(); + std::string word; + S32 wordStart = wordEnd; + for ( S32 backOne = wordStart - 1; + backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]); + backOne-- + ) + { + wordStart--; // walk wordStart back to the beginning of the word + } + LL_DEBUGS("AutoReplace")<<"wordStart: "< '"< Date: Sat, 26 May 2012 07:32:50 -0400 Subject: storm-1738: fix dumb pre-checkin change --- indra/newview/llautoreplace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index a4a08daf27..5a3689cee6 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -84,7 +84,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) if (atSpace) { // replace the last word in the input - LLWString strNew = utf8str_to_wstring(replWord); + LLWString strNew = utf8str_to_wstring(replacementWord); LLWString strOld = utf8str_to_wstring(lastWord); int size_change = strNew.size() - strOld.size(); @@ -95,7 +95,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) else { // @TODO display replacement as tooltip? - LL_DEBUGS("AutoReplace")<<"tooltip: '"< '"< '"< Date: Wed, 30 May 2012 13:54:15 -0400 Subject: possible fix for storm-1866 (crash when first key in chat is space) --- indra/newview/llautoreplace.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index 5a3689cee6..641e354605 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -56,7 +56,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) if (atSpace || haveWord) { - if (atSpace) + if (atSpace && wordEnd > 0) { // find out if this space immediately follows a word wordEnd--; @@ -92,11 +92,6 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) inputText = wstring_to_utf8str(text); cursorPos+=size_change; } - else - { - // @TODO display replacement as tooltip? - LL_DEBUGS("AutoReplace")<<"tooltip: '"< '"< Date: Mon, 11 Jun 2012 08:21:39 -0400 Subject: fix error notices to be more prominent for invalid list names and keywords --- indra/newview/llautoreplace.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'indra/newview/llautoreplace.cpp') diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index 641e354605..0f1ce2bcd0 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -64,6 +64,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) } if (haveWord) { + // wordEnd points to the end of a word, now find the start of the word std::string word; S32 wordStart = wordEnd; for ( S32 backOne = wordStart - 1; @@ -650,6 +651,7 @@ std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord) static LLCachedControl autoreplace_enabled(gSavedSettings, "AutoReplace"); if ( autoreplace_enabled ) { + LL_DEBUGS("AutoReplace")<<"checking '"< '" << replacements[currentWord].asString() << "'" + << " found in list '" << checkList[AUTOREPLACE_LIST_NAME].asString() + << " => '" << replacements[currentWord].asString() << "'" << LL_ENDL; returnedWord = replacements[currentWord].asString(); } @@ -674,7 +676,7 @@ std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord) return returnedWord; } -bool LLAutoReplaceSettings::addEntryToList(std::string keyword, std::string replacement, std::string listName) +bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName) { bool added = false; @@ -685,7 +687,7 @@ bool LLAutoReplaceSettings::addEntryToList(std::string keyword, std::string repl { if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) { - LL_WARNS("AutoReplace") << "keyword '" << keyword << "' not a single word" << LL_ENDL; + LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "<