/** * @file llautocorrect.cpp * @brief Auto Correct Manager * @copyright Copyright (c) 2011 LordGregGreg Back * * 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 */ #include "llviewerprecompiledheaders.h" #include "llautocorrect.h" #include "llsdserialize.h" #include "llboost.h" #include "llcontrol.h" #include "llviewercontrol.h" #include "llnotificationsutil.h" AutoCorrect* AutoCorrect::sInstance; AutoCorrect::AutoCorrect() { sInstance = this; sInstance->loadFromDisk(); } AutoCorrect::~AutoCorrect() { sInstance = NULL; } AutoCorrect* AutoCorrect::getInstance() { if(sInstance)return sInstance; else { sInstance = new AutoCorrect(); return sInstance; } } void AutoCorrect::save() { saveToDisk(mAutoCorrects); } std::string AutoCorrect::getFileName() { std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); if (!path.empty()) { path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings_autocorrect.xml"); } return path; } std::string AutoCorrect::getDefaultFileName() { std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); if (!path.empty()) { path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_autocorrect.xml"); } return path; } LLSD AutoCorrect::exportList(std::string listName) { LLSD toReturn; if(mAutoCorrects.has(listName)) { toReturn["listName"]=listName; toReturn["data"]=mAutoCorrects[listName]["data"]; toReturn["author"]=mAutoCorrects[listName]["author"]; toReturn["wordStyle"]=mAutoCorrects[listName]["wordStyle"]; toReturn["priority"]=mAutoCorrects[listName]["priority"]; } return toReturn; } BOOL AutoCorrect::addCorrectionList(LLSD newList) { if(newList.has("listName")) { std::string name = newList["listName"]; //if(!mAutoCorrects.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(mAutoCorrects, file); } file.close(); } } void AutoCorrect::saveToDisk(LLSD newSettings) { mAutoCorrects=newSettings; std::string filename=getFileName(); llofstream file; file.open(filename.c_str()); LLSDSerialize::toPrettyXML(mAutoCorrects, file); file.close(); } void AutoCorrect::runTest() { std::string startS("He just abandonned all his abilties"); std::string endS = replaceWords(startS); llinfos << "!!! Test of autoreplace; start with "< doAnything(gSavedSettings, "EnableAutoCorrect"); if(!(doAnything))return currentWord; //loop through priorities for(int currentPriority = 10;currentPriority>=0;currentPriority--) { LLSD::map_const_iterator loc_it = mAutoCorrects.beginMap(); LLSD::map_const_iterator loc_end = mAutoCorrects.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 AutoCorrect::replaceWords(std::string words) { static LLCachedControl doAnything(gSavedSettings, "EnableAutoCorrect"); if(!(doAnything))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 = mAutoCorrects.beginMap(); LLSD::map_const_iterator loc_end = mAutoCorrects.endMap(); for ( ; loc_it != loc_end; ++loc_it) { const std::string& location = (*loc_it).first; //llinfos << "location is "< " << replacement.c_str() << llendl; int wordStart = words.find(currentWord); words.replace(wordStart,currentWord.length(),replacement); return replaceWords(words);//lol recursion! } } } return words; } BOOL AutoCorrect::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(mAutoCorrects.has(listName)) { mAutoCorrects[listName]["data"][wrong]=right; return TRUE; } else if(listName == "Custom") { mAutoCorrects[listName]["announce"] = 0; mAutoCorrects[listName]["author"] = "You"; mAutoCorrects[listName]["data"][wrong] = right; mAutoCorrects[listName]["enabled"] = 1; mAutoCorrects[listName]["priority"] = 10; mAutoCorrects[listName]["wordStyle"] = 1; return TRUE; } return FALSE; } BOOL AutoCorrect::removeEntryFromList(std::string wrong, std::string listName) { if(mAutoCorrects.has(listName)) { if(mAutoCorrects[listName]["data"].has(wrong)) { mAutoCorrects[listName]["data"].erase(wrong); return TRUE; } } return FALSE; } LLSD AutoCorrect::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; }