summaryrefslogtreecommitdiff
path: root/indra/newview/llautoreplace.cpp
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2012-05-23 21:30:13 -0400
committerOz Linden <oz@lindenlab.com>2012-05-23 21:30:13 -0400
commit04ab2cf43b5341900737f0d480bce0b8205add8e (patch)
treed413bed4ad998b779a4b631902d967e2678630bb /indra/newview/llautoreplace.cpp
parent0d11c70e8e68ea2c33cdf01b56b6f2f81ed46f1e (diff)
storm-1738: restructure code, preferences storage, preferences ui; ui not completely tested
Diffstat (limited to 'indra/newview/llautoreplace.cpp')
-rw-r--r--indra/newview/llautoreplace.cpp711
1 files changed, 512 insertions, 199 deletions
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 "<<newPart["priority"].asInteger() <<llendl;
- mAutoReplaces[name]=newPart;
+ LLSD userSettings;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(userSettings, file);
+ }
+ file.close();
+ if ( mSettings.setFromLLSD(userSettings) )
+ {
+ LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL;
+ }
+ }
+ 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;
+
+ if(gDirUtilp->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")<<"'"<<keyword<<"' -> '"<<replacement<<"'"<<LL_ENDL;
+ }
+ }
+ if (!foundList)
+ {
+ LL_WARNS("AutoReplace")<<"failed to find list '"<<listName<<"'"<<LL_ENDL;
+ }
}
- if(!gDirUtilp->fileExists(filename))
+ if (replacement.empty())
{
- std::string defaultName = getDefaultFileName();
- llinfos << " user settings file doesnt exist, going to try and read default one from "<<defaultName.c_str()<< llendl;
+ LL_WARNS("AutoReplace")<<"failed to find '"<<keyword<<"'"<<LL_ENDL;
+ }
+ return replacement;
+}
- if(gDirUtilp->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 "<<AUTOREPLACE_LIST_NAME<< LL_ENDL;
}
- file.close();
- saveToDisk(blankllsd);
}
else
{
- saveToDisk(getExampleLLSD());
+ LL_ERRS("AutoReplace") << " ! not a map: "<<LLSD::typeString(thisList.type())<< LL_ENDL;
}
}
+ return toReturn;
+}
+
+bool LLAutoReplaceSettings::listIsValid(const LLSD& list)
+{
+ bool listValid = true;
+ if ( ! list.isMap() )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace") << "list is not a map" << LL_ENDL;
+ }
+ else if ( ! list.has(AUTOREPLACE_LIST_NAME)
+ || ! list[AUTOREPLACE_LIST_NAME].isString()
+ || list[AUTOREPLACE_LIST_NAME].asString().empty()
+ )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace")
+ << "list found without " << AUTOREPLACE_LIST_NAME
+ << " (or it is empty)"
+ << LL_ENDL;
+ }
+ else if ( ! list.has(AUTOREPLACE_LIST_REPLACEMENTS) || ! list[AUTOREPLACE_LIST_REPLACEMENTS].isMap() )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace") << "list '" << list[AUTOREPLACE_LIST_NAME].asString() << "' without " << AUTOREPLACE_LIST_REPLACEMENTS << LL_ENDL;
+ }
else
{
- llifstream file;
- file.open(filename.c_str());
- if (file.is_open())
+ for ( LLSD::map_const_iterator
+ entry = list[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(),
+ entriesEnd = list[AUTOREPLACE_LIST_REPLACEMENTS].endMap();
+ listValid && entry != entriesEnd;
+ entry++
+ )
{
- LLSDSerialize::fromXML(mAutoReplaces, file);
+ if ( ! entry->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 "<<startS.c_str() << " end with " << endS.c_str()<<llendl;
+ bool nameIsUnique = true;
+ // this must always be called with a valid list, so it is safe to assume it has a name
+ std::string newListName = newList[AUTOREPLACE_LIST_NAME].asString();
+ for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray();
+ nameIsUnique && list != listEnd;
+ list++
+ )
+ {
+ if ( listNameMatches(*list, newListName) )
+ {
+ LL_WARNS("AutoReplace")<<"duplicate list name '"<<newListName<<"'"<<LL_ENDL;
+ nameIsUnique = false;
+ }
+ }
+ return nameIsUnique;
+}
+/* static */
+void LLAutoReplaceSettings::createEmptyList(LLSD& emptyList)
+{
+ emptyList = LLSD::emptyMap();
+ emptyList[AUTOREPLACE_LIST_NAME] = "Empty";
+ emptyList[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+}
+/* static */
+void LLAutoReplaceSettings::setListName(LLSD& list, const std::string& newName)
+{
+ list[AUTOREPLACE_LIST_NAME] = newName;
}
-BOOL LLAutoReplace::saveListToDisk(std::string listName, std::string fileName)
+/* static */
+std::string LLAutoReplaceSettings::getListName(LLSD& list)
{
- if(mAutoReplaces.has(listName))
+ std::string name;
+ if ( list.isMap() && list.has(AUTOREPLACE_LIST_NAME) && list[AUTOREPLACE_LIST_NAME].isString() )
{
- llofstream file;
- file.open(fileName.c_str());
- LLSDSerialize::toPrettyXML(exportList(listName), file);
- file.close();
- return TRUE;
+ name = list[AUTOREPLACE_LIST_NAME].asString();
}
- return FALSE;
+ return name;
}
-LLSD LLAutoReplace::getAutoReplaceEntries(std::string listName)
+LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::addList(const LLSD& newList)
{
- LLSD toReturn;
- if(mAutoReplaces.has(listName))
+ AddListResult result;
+ if ( listIsValid( newList ) )
{
- toReturn=mAutoReplaces[listName];
+ if ( listNameIsUnique( newList ) )
+ {
+ mLists.append(newList);
+ result = AddListOk;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempt to add duplicate name" << LL_ENDL;
+ result = AddListDuplicateName;
+ }
}
- return toReturn;
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempt to add invalid list" << LL_ENDL;
+ result = AddListInvalidList;
+ }
+ return result;
}
-std::string LLAutoReplace::replaceWord(std::string currentWord)
+bool LLAutoReplaceSettings::removeReplacementList(std::string listName)
{
- static LLCachedControl<bool> 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 "<<location.c_str() << " word is "<<currentWord.c_str()<<llendl;
- const LLSD& loc_map = (*loc_it).second;
- if(loc_map["priority"].asInteger()==currentPriority)
- {
- if((loc_map["data"].has(currentWord))&&(loc_map["enabled"].asBoolean()))
- {
- 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;
- return replacement;
- }
- }
+ LL_DEBUGS("AutoReplace")<<"list '"<<listName<<"'"<<LL_ENDL;
+ mLists.erase(index);
+ found = true;
}
}
- return currentWord;
+ return found;
}
-std::string LLAutoReplace::replaceWords(std::string words)
+/// Move the named list up in the priority order
+bool LLAutoReplaceSettings::increaseListPriority(std::string listName)
{
- static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
- if(!(perform_autoreplace))
+ LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL;
+ bool found = false;
+ S32 search_index;
+ LLSD targetList;
+ for ( search_index = 0, targetList = mLists[0];
+ !found && targetList.isDefined();
+ search_index += 1, targetList = mLists[search_index]
+ )
{
- return words;
- }
-
- boost_tokenizer tokens(words, boost::char_separator<char>(" "));
- 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 "<<search_index<<LL_ENDL;
+ found = true;
+ if (search_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")<<listName<<LL_ENDL;
+ S32 found_index = -1;
+ S32 search_index;
+ for ( search_index = 0;
+ found_index == -1 && mLists[search_index].isDefined();
+ search_index++
+ )
{
- mAutoReplaces[listName]["data"][wrong]=right;
- return TRUE;
+ if ( listNameMatches( mLists[search_index], listName) )
+ {
+ LL_DEBUGS("AutoReplace")<<"found at index "<<search_index<<LL_ENDL;
+ found_index = search_index;
+ }
}
- else if(listName == "Custom")
+ if (found_index != -1)
{
- mAutoReplaces[listName]["data"][wrong] = right;
- mAutoReplaces[listName]["enabled"] = 1;
- mAutoReplaces[listName]["priority"] = 10;
- return TRUE;
+ // move this list after the found_index from after it to before it
+ if (mLists[found_index+1].isDefined())
+ {
+ // copy item to after the element that follows it
+ mLists.insert(found_index+2, mLists[found_index]);
+ // erase the original, now duplicate, copy
+ mLists.erase(found_index);
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempted to move bottom list down" << LL_ENDL;
+ }
}
-
- return FALSE;
+ return (found_index != -1);
}
-BOOL LLAutoReplace::removeEntryFromList(std::string wrong, std::string listName)
+
+std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord)
{
- if(mAutoReplaces.has(listName))
+ std::string returnedWord = currentWord; // in case no replacement is found
+ static LLCachedControl<bool> 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")<<LL_ENDL;
+ LLSD example = LLSD::emptyArray();
+
+ example[0] = LLSD::emptyMap();
+ example[0][AUTOREPLACE_LIST_NAME] = "Example List 1";
+ example[0][AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+ example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword1"] = "replacement string 1";
+ example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword2"] = "replacement string 2";
+
+ example[1] = LLSD::emptyMap();
+ example[1][AUTOREPLACE_LIST_NAME] = "Example List 2";
+ example[1][AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+ example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake1"] = "correction 1";
+ example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake2"] = "correction 2";
+
+ return example;
}
+LLAutoReplaceSettings::~LLAutoReplaceSettings()
+{
+}