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 | 104 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.h | 3 | ||||
-rw-r--r-- | indra/newview/lllogchat.cpp | 69 | ||||
-rw-r--r-- | indra/newview/lllogchat.h | 8 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 11 |
9 files changed, 215 insertions, 20 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 b777edba77..4953bcbd02 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -378,6 +378,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 3d8d0e15ec..b9239b544f 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -646,9 +646,6 @@ void LLFloaterPreference::cancel() LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get(); pPathfindingConsole->onRegionBoundaryCross(); } - - std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); - updateLogLocation(dir_name); } void LLFloaterPreference::onOpen(const LLSD& key) @@ -798,8 +795,26 @@ void LLFloaterPreference::onBtnOK() apply(); closeFloater(false); + //Conversation transcript and log path changed so reload conversations based on new location + if(mPriorInstantMessageLogPath.length()) + { + //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 { @@ -1436,29 +1451,92 @@ void LLFloaterPreference::setAllIgnored() void LLFloaterPreference::onClickLogPath() { - std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); + std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); + mPriorInstantMessageLogPath.clear(); LLDirPicker& picker = LLDirPicker::instance(); + //Launches a directory picker and waits for feedback if (!picker.getDir(&proposed_name ) ) { return; //Canceled! } + //Gets the path from the directory picker std::string dir_name = picker.getDirName(); - gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name); - - // enable/disable 'Delete transcripts button - updateDeleteTranscriptsButton(); + + //Path changed + if(proposed_name != dir_name) + { + gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name); + 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 dbd87f74a1..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(); @@ -187,6 +187,7 @@ private: bool mOriginalIMViaEmail; bool mLanguageChanged; bool mAvatarDataInitialized; + std::string mPriorInstantMessageLogPath; bool mOriginalHideOnlineStatus; std::string mDirectoryVisibility; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 17b72c5023..95b0e6b9d6 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -501,6 +501,75 @@ 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 +bool LLLogChat::moveTranscripts(const std::string currentDirectory, + const std::string newDirectory, + std::vector<std::string>& listOfFilesToMove) +{ + std::vector<std::string> listOfFilesMoved; + return moveTranscripts(currentDirectory, newDirectory, listOfFilesToMove, listOfFilesMoved); +} + +//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..244f1c8790 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -56,6 +56,14 @@ 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); + static bool moveTranscripts(const std::string currentDirectory, + const std::string newDirectory, + std::vector<std::string>& listOfFilesToMove); + 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> |