STORM-1880: copy imported dictionary files rather than moving them

master
Oz Linden 2012-06-14 21:21:42 -04:00
parent c8f21753fa
commit 02f0f87f95
3 changed files with 105 additions and 31 deletions

View File

@ -35,6 +35,7 @@
#include "llspellcheck.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llnotificationsutil.h"
#include <boost/algorithm/string.hpp>
@ -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))
{
dict_info = custom_dict_info;
break;
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
{
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;
LLFile::rename(dict_dic, LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic");
if (gDirUtilp->fileExists(dict_aff))
{
LLFile::rename(dict_aff, LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff");
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);
}
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;
}

View File

@ -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;

View File

@ -2396,6 +2396,17 @@ Would you be my friend?
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="SpellingDictImportFailed"
type="alertmodal">
Unable to copy
[FROM_NAME]
to
[TO_NAME]
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
label="Save Outfit"