diff options
-rw-r--r-- | indra/llvfs/lldir.cpp | 5 | ||||
-rw-r--r-- | indra/llvfs/lldir.h | 1 | ||||
-rw-r--r-- | indra/newview/llconversationlog.cpp | 21 | ||||
-rw-r--r-- | indra/newview/llconversationlog.h | 13 | ||||
-rwxr-xr-x | indra/newview/llfloaterpreference.cpp | 86 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.h | 4 | ||||
-rw-r--r-- | indra/newview/lllogchat.cpp | 60 | ||||
-rw-r--r-- | indra/newview/lllogchat.h | 4 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 11 |
9 files changed, 186 insertions, 19 deletions
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index f7bc19574a..6899e9a44a 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -347,6 +347,11 @@ const std::string &LLDir::getLLPluginDir() const return mLLPluginDir; } +const std::string &LLDir::getUserName() const +{ + return mUserName; +} + static std::string ELLPathToString(ELLPath location) { typedef std::map<ELLPath, const char*> ELLPathMap; diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 95cab65149..cc10ed5bbd 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -104,6 +104,7 @@ class LLDir const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell + const std::string &getUserName() const; // Expanded filename std::string getExpandedFilename(ELLPath location, const std::string &filename) const; diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index fc3bc8551c..88671a789f 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -376,6 +376,27 @@ void LLConversationLog::cache() } } +bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory) +{ + //Does the file exist in the current path + if(LLFile::isfile(originDirectory)) + { + //Does same file exist in the destination path, if so try to remove it + if(LLFile::isfile(targetDirectory)) + { + LLFile::remove(targetDirectory); + } + + //Move the file from the current path to destination path + if(LLFile::rename(originDirectory, targetDirectory) != 0) + { + return false; + } + } + + return true; +} + std::string LLConversationLog::getFileName() { std::string filename = "conversation"; diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index fd38556131..58e698de25 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -137,6 +137,7 @@ public: * public method which is called on viewer exit to save conversation log */ void cache(); + bool moveLog(const std::string &originDirectory, const std::string &targetDirectory); void onClearLog(); void onClearLogResponse(const LLSD& notification, const LLSD& response); @@ -144,6 +145,12 @@ public: bool getIsLoggingEnabled() { return mLoggingEnabled; } bool isLogEmpty() { return mConversations.empty(); } + /** + * constructs file name in which conversations log will be saved + * file name is conversation.log + */ + std::string getFileName(); + private: LLConversationLog(); @@ -164,12 +171,6 @@ private: void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask); - /** - * constructs file name in which conversations log will be saved - * file name is conversation.log - */ - std::string getFileName(); - bool saveToFile(const std::string& filename); bool loadFromFile(const std::string& filename); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index e5444583d6..b9239b544f 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -796,15 +796,25 @@ void LLFloaterPreference::onBtnOK() closeFloater(false); //Conversation transcript and log path changed so reload conversations based on new location - if(mInstantMessageLogPathChanged) + if(mPriorInstantMessageLogPath.length()) { - std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); - updateLogLocation(dir_name); - mInstantMessageLogPathChanged = false; + //Couldn't move files so restore the old path and show a notification + if(!moveTranscriptsAndLog()) + { + gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath); + LLNotificationsUtil::add("PreferenceChatPathChanged"); + } + mPriorInstantMessageLogPath.clear(); } LLUIColorTable::instance().saveUserSettings(); gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); + + //Only save once logged in and loaded per account settings + if(mGotPersonalInfo) + { + gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); + } } else { @@ -1442,7 +1452,7 @@ void LLFloaterPreference::setAllIgnored() void LLFloaterPreference::onClickLogPath() { std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); - mInstantMessageLogPathChanged = false; + mPriorInstantMessageLogPath.clear(); LLDirPicker& picker = LLDirPicker::instance(); //Launches a directory picker and waits for feedback @@ -1458,21 +1468,75 @@ void LLFloaterPreference::onClickLogPath() if(proposed_name != dir_name) { gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name); - mInstantMessageLogPathChanged = true; + mPriorInstantMessageLogPath = proposed_name; // enable/disable 'Delete transcripts button updateDeleteTranscriptsButton(); } } -void LLFloaterPreference::updateLogLocation(const std::string& dir_name) +bool LLFloaterPreference::moveTranscriptsAndLog() { - gDirUtilp->setChatLogsDir(dir_name); + std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath")); + std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName()); + + bool madeDirectory = false; + + //Does the directory really exist, if not then make it + if(!LLFile::isdir(chatLogPath)) + { + //mkdir success is defined as zero + if(LLFile::mkdir(chatLogPath) != 0) + { + return false; + } + madeDirectory = true; + } + + std::string originalConversationLogDir = LLConversationLog::instance().getFileName(); + std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log"); + //Try to move the conversation log + if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir)) + { + //Couldn't move the log and created a new directory so remove the new directory + if(madeDirectory) + { + LLFile::rmdir(chatLogPath); + } + return false; + } + + //Attempt to move transcripts + std::vector<std::string> listOfTranscripts; + std::vector<std::string> listOfFilesMoved; + + LLLogChat::getListOfTranscriptFiles(listOfTranscripts); + + if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(), + instantMessageLogPath, + listOfTranscripts, + listOfFilesMoved)) + { + //Couldn't move all the transcripts so restore those that moved back to their old location + LLLogChat::moveTranscripts(instantMessageLogPath, + gDirUtilp->getChatLogsDir(), + listOfFilesMoved); + + //Move the conversation log back + LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir); + + if(madeDirectory) + { + LLFile::rmdir(chatLogPath); + } + + return false; + } + + gDirUtilp->setChatLogsDir(instantMessageLogPath); gDirUtilp->updatePerAccountChatLogsDir(); - LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); - // refresh IM floaters with new logs from files from new selected directory - LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true); + return true; } void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email) diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index c72346c3b6..22e80a21cb 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -143,7 +143,7 @@ public: void resetAllIgnored(); void setAllIgnored(); void onClickLogPath(); - void updateLogLocation(const std::string& dir_name); + bool moveTranscriptsAndLog(); void enableHistory(); void setPersonalInfo(const std::string& visibility, bool im_via_email); void refreshEnabledState(); @@ -186,8 +186,8 @@ private: bool mGotPersonalInfo; bool mOriginalIMViaEmail; bool mLanguageChanged; - bool mInstantMessageLogPathChanged; bool mAvatarDataInitialized; + std::string mPriorInstantMessageLogPath; bool mOriginalHideOnlineStatus; std::string mDirectoryVisibility; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 17b72c5023..b60e2aa44e 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -501,6 +501,66 @@ boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_s } //static +bool LLLogChat::moveTranscripts(const std::string originDirectory, + const std::string targetDirectory, + std::vector<std::string>& listOfFilesToMove, + std::vector<std::string>& listOfFilesMoved) +{ + std::string newFullPath; + bool movedAllTranscripts = true; + + BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove) + { + newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos); + + S32 retry_count = 0; + while (retry_count < 5) + { + //success is zero + if (LLFile::rename(fullpath, newFullPath) != 0) + { + retry_count++; + S32 result = errno; + LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: " + << result << " attempt " << retry_count << LL_ENDL; + + if(retry_count >= 5) + { + LL_WARNS("LLLogChat::moveTranscripts") << "Failed to rename " << fullpath << LL_ENDL; + return false; + } + + //If the file already exists in the new location, remove it then try again + if(LLFile::isfile(newFullPath)) + { + LLFile::remove(newFullPath); + LL_WARNS("LLLogChat::moveTranscripts") << "File already exists " << fullpath << LL_ENDL; + } + + ms_sleep(100); + } + else + { + listOfFilesMoved.push_back(newFullPath); + + if (retry_count) + { + LL_WARNS("LLLogChat::moveTranscripts") << "Successfully renamed " << fullpath << LL_ENDL; + } + break; + } + } + } + + if(listOfFilesMoved.size() != listOfFilesToMove.size()) + { + movedAllTranscripts = false; + } + + return movedAllTranscripts; +} + +//static void LLLogChat::deleteTranscripts() { std::vector<std::string> list_of_transcriptions; diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 5fbb4ade96..b9aede0b29 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -56,6 +56,10 @@ public: typedef boost::signals2::signal<void ()> save_history_signal_t; static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb); + static bool moveTranscripts(const std::string currentDirectory, + const std::string newDirectory, + std::vector<std::string>& listOfFilesToMove, + std::vector<std::string>& listOfFilesMoved = std::vector<std::string>()); static void deleteTranscripts(); private: diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3ae9b206a4..234c6d7c0f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -10028,4 +10028,15 @@ Cannot create large prims that intersect other players. Please re-try when othe yestext="OK"/> </notification> + <notification + icon="alert.tga" + name="PreferenceChatPathChanged" + type="alert"> + Unable to move files. Restored previous path. + <usetemplate + ignoretext="Unable to move files. Restored previous path." + name="okignore" + yestext="OK"/> + </notification> + </notifications> |