From 02f0f87f95c7f47a93d20de9478bf0b2d5c6e4e6 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 14 Jun 2012 21:21:42 -0400 Subject: STORM-1880: copy imported dictionary files rather than moving them --- indra/newview/llfloaterspellchecksettings.cpp | 124 +++++++++++++++------ indra/newview/llfloaterspellchecksettings.h | 1 + .../newview/skins/default/xui/en/notifications.xml | 11 ++ 3 files changed, 105 insertions(+), 31 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp index 5116ec50a6..758ac23b4c 100644 --- a/indra/newview/llfloaterspellchecksettings.cpp +++ b/indra/newview/llfloaterspellchecksettings.cpp @@ -35,6 +35,7 @@ #include "llspellcheck.h" #include "lltrans.h" #include "llviewercontrol.h" +#include "llnotificationsutil.h" #include @@ -291,47 +292,108 @@ void LLFloaterSpellCheckerImport::onBtnOK() return; } - LLSD custom_dict_info; - custom_dict_info["is_primary"] = (bool)gDirUtilp->fileExists(dict_aff); - custom_dict_info["name"] = mDictionaryBasename; - custom_dict_info["language"] = dict_language; - - LLSD custom_dict_map; - llifstream custom_file_in(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml"); - if (custom_file_in.is_open()) + bool imported = false; + std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic"; + if ( copyFile( dict_dic, settings_dic ) ) { - LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file_in); - custom_file_in.close(); - } - - LLSD::array_iterator it = custom_dict_map.beginArray(); - for (; it != custom_dict_map.endArray(); ++it) - { - LLSD& dict_info = *it; - if (dict_info["name"].asString() == mDictionaryBasename) + if (gDirUtilp->fileExists(dict_aff)) + { + std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff"; + if (copyFile( dict_aff, settings_aff )) + { + imported = true; + } + else + { + LLSD args = LLSD::emptyMap(); + args["FROM_NAME"] = dict_aff; + args["TO_NAME"] = settings_aff; + LLNotificationsUtil::add("SpellingDictImportFailed", args); + } + } + else { - dict_info = custom_dict_info; - break; + imported = true; } } - if (custom_dict_map.endArray() == it) + else { - custom_dict_map.append(custom_dict_info); + LLSD args = LLSD::emptyMap(); + args["FROM_NAME"] = dict_dic; + args["TO_NAME"] = settings_dic; + LLNotificationsUtil::add("SpellingDictImportFailed", args); } - llofstream custom_file_out(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml", std::ios::trunc); - if (custom_file_out.is_open()) + if ( imported ) { - LLSDSerialize::toPrettyXML(custom_dict_map, custom_file_out); - custom_file_out.close(); - } + LLSD custom_dict_info; + custom_dict_info["is_primary"] = (bool)gDirUtilp->fileExists(dict_aff); + custom_dict_info["name"] = mDictionaryBasename; + custom_dict_info["language"] = dict_language; + + LLSD custom_dict_map; + llifstream custom_file_in(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml"); + if (custom_file_in.is_open()) + { + LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file_in); + custom_file_in.close(); + } + + LLSD::array_iterator it = custom_dict_map.beginArray(); + for (; it != custom_dict_map.endArray(); ++it) + { + LLSD& dict_info = *it; + if (dict_info["name"].asString() == mDictionaryBasename) + { + dict_info = custom_dict_info; + break; + } + } + if (custom_dict_map.endArray() == it) + { + custom_dict_map.append(custom_dict_info); + } - LLFile::rename(dict_dic, LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic"); - if (gDirUtilp->fileExists(dict_aff)) - { - LLFile::rename(dict_aff, LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff"); + llofstream custom_file_out(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml", std::ios::trunc); + if (custom_file_out.is_open()) + { + LLSDSerialize::toPrettyXML(custom_dict_map, custom_file_out); + custom_file_out.close(); + } + + LLSpellChecker::refreshDictionaryMap(); } - LLSpellChecker::refreshDictionaryMap(); closeFloater(false); } + +bool LLFloaterSpellCheckerImport::copyFile(const std::string from, const std::string to) +{ + bool copied = false; + LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */ + if (in) + { + LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */ + if (out) + { + char buf[16384]; /* Flawfinder: ignore */ + size_t readbytes; + bool write_ok = true; + while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ + { + if (fwrite(buf, 1, readbytes, out) != readbytes) + { + LL_WARNS("SpellCheck") << "Short write" << LL_ENDL; + write_ok = false; + } + } + if ( write_ok ) + { + copied = true; + } + fclose(out); + } + } + fclose(in); + return copied; +} diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h index 4bc68e2a88..8c4ac22bc6 100644 --- a/indra/newview/llfloaterspellchecksettings.h +++ b/indra/newview/llfloaterspellchecksettings.h @@ -58,6 +58,7 @@ protected: void onBtnBrowse(); void onBtnCancel(); void onBtnOK(); + bool copyFile(const std::string from, const std::string to); std::string mDictionaryDir; std::string mDictionaryBasename; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index bc69e973ed..c04e33fe8e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2396,6 +2396,17 @@ Would you be my friend? fail + + Unable to copy + [FROM_NAME] + to + [TO_NAME] + fail + +