diff options
25 files changed, 317 insertions, 52 deletions
| @@ -420,3 +420,5 @@ b23419a2748483c98f3b84b630468a21c88feba5 DRTVWR-292  0a5d409161ef2a89b28c9a741051dd2dedc707d6 DRTVWR-297  852b69ef0b5fe6b13b69cc2217282cc64de6afab 3.4.5-beta5  a49c715243a36a8a380504d14cb7416b3039c956 3.4.5-release +279ef1dfc9b749a6cc499cf190fec0c090b6d682 DRTVWR-288 +9b19edaf1d8ddf435f60fbbb444dd25db8f63953 3.5.0-beta1 diff --git a/doc/contributions.txt b/doc/contributions.txt index e86ef11a72..10c935f9bb 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -748,6 +748,7 @@ Marine Kelley  MartinRJ Fayray      STORM-1844      STORM-1845 +    STORM-1934  Matthew Anthony  Matthew Dowd  	VWR-1344 diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 6a5ff314e4..1554e9e665 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,8 +28,8 @@  #define LL_LLVERSIONVIEWER_H  const S32 LL_VERSION_MAJOR = 3; -const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 6; +const S32 LL_VERSION_MINOR = 5; +const S32 LL_VERSION_PATCH = 0;  const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7cee9f5b46..4bb819a7f6 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1911,6 +1911,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)  	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));  	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));  	registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url)); +	registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));  	registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));  	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));  	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url)); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index fd9b3d9a6d..fd872eca4b 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -157,3 +157,17 @@ void LLUrlAction::showProfile(std::string url)  		}  	}  } + +void LLUrlAction::sendIM(std::string url) +{ +	LLURI uri(url); +	LLSD path_array = uri.pathArray(); +	if (path_array.size() == 4) +	{ +		std::string id_str = path_array.get(2).asString(); +		if (LLUUID::validate(id_str)) +		{ +			executeSLURL("secondlife:///app/agent/" + id_str + "/im"); +		} +	} +} diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index c34960b826..f5f2ceba72 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -76,6 +76,7 @@ public:  	/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile  	static void showProfile(std::string url); +	static void sendIM(std::string url);  	/// specify the callbacks to enable this class's functionality  	typedef boost::function<void (const std::string&)> url_callback_t; 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..4be169e267 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -31,6 +31,8 @@  #include "llnotificationsutil.h"  #include "lltrans.h" +#include "boost/lexical_cast.hpp" +  const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec  struct ConversationParams @@ -378,6 +380,41 @@ void LLConversationLog::cache()  	}  } +bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory) +{ + +	std::string backupFileName; +	unsigned backupFileCount = 0; + +	//Does the file exist in the current path, if it does lets move it +	if(LLFile::isfile(originDirectory))  +	{ +		//The target directory contains that file already, so lets store it +		if(LLFile::isfile(targetDirectory)) +		{ +			backupFileName = targetDirectory + ".backup"; + +			//If needed store backup file as .backup1 etc. +			while(LLFile::isfile(backupFileName)) +			{ +				++backupFileCount; +				backupFileName = targetDirectory + ".backup" + boost::lexical_cast<std::string>(backupFileCount); +			} + +			//Rename the file to its backup name so it is not overwritten +			LLFile::rename(targetDirectory, backupFileName); +		} + +		//Move the file from the current path to target 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/llconversationview.cpp b/indra/newview/llconversationview.cpp index 882ef64715..74b348cd81 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -567,6 +567,7 @@ BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )      		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");      		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); +			im_container->setSelectedSession(session_id);  			im_container->flashConversationItemWidget(session_id,false);  			im_container->selectFloater(session_floater);  			im_container->collapseMessagesPane(false); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 59c2f15dd9..4b0d3b361d 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -577,6 +577,12 @@ F32 LLDrawable::updateXform(BOOL undamped)  			mVObjp->dirtySpatialGroup();  		}  	} +	else if (!isRoot() && +			((dist_vec_squared(old_pos, target_pos) > 0.f) +			|| (1.f - dot(old_rot, target_rot)) > 0.f)) +	{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247 +			gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); +	}  	else if (!getVOVolume() && !isAvatar())  	{  		movePartition(); @@ -643,18 +649,9 @@ BOOL LLDrawable::updateMove()  		return FALSE;  	} -	BOOL done; +	makeActive(); -	if (isState(MOVE_UNDAMPED)) -	{ -		done = updateMoveUndamped(); -	} -	else -	{ -		makeActive(); -		done = updateMoveDamped(); -	} -	return done; +	return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped();  }  BOOL LLDrawable::updateMoveUndamped() diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 46ec1d510d..a0c386717b 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -758,11 +758,21 @@ void LLFloaterIMContainer::assignResizeLimits()  	// between the panels are merged into one      S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);      S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH; -	S32 conv_pane_current_width = is_msg_pane_expanded -			? mConversationsPane->getRect().getWidth() -			: (is_conv_pane_expanded? mConversationsPane->getExpandedMinDim() : mConversationsPane->getMinDim()); +	S32 conv_pane_target_width = is_conv_pane_expanded? +			(is_msg_pane_expanded? +					mConversationsPane->getRect().getWidth() +					: mConversationsPane->getExpandedMinDim()) +			: mConversationsPane->getMinDim();  	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0; -	S32 new_min_width = conv_pane_current_width + msg_pane_min_width + summary_width_of_visible_borders; +	S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders; + +    if (is_conv_pane_expanded) +    { +    	// Save the conversations pane width. +	    gSavedPerAccountSettings.setS32( +	            "ConversationsListPaneWidth", +                mConversationsPane->getRect().getWidth()); +    }  	setResizeLimits(new_min_width, getMinHeight());  } @@ -1947,10 +1957,10 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)  	// Most of the time the user will never see this state.  	setMinimized(FALSE); -	S32 conv_pane_width = mConversationsPane->getRect().getWidth(); - -	// Save the conversations pane width before collapsing it. -	gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width); +	// Save the conversations pane width. +	gSavedPerAccountSettings.setS32( +			"ConversationsListPaneWidth", +			mConversationsPane->getRect().getWidth());  	LLFloater::closeFloater(app_quitting);  } diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 02f54e76db..dfaf4bbdd6 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -353,6 +353,13 @@ BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask )  		sendChat(CHAT_TYPE_SHOUT);  		handled = TRUE;  	} +	else if (KEY_RETURN == key && mask == MASK_SHIFT) +	{ +		// whisper +		sendChat(CHAT_TYPE_WHISPER); +		handled = TRUE; +	} +  	if((mask == MASK_ALT) && isTornOff())  	{ diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h index 2992c12436..4ad37eb0c7 100644 --- a/indra/newview/llfloaterimnearbychat.h +++ b/indra/newview/llfloaterimnearbychat.h @@ -69,6 +69,7 @@ public:  	LLChatEntry* getChatBox() { return mInputEditor; }  	std::string getCurrentChat(); +	S32 getMessageArchiveLength() {return mMessageArchive.size();}  	virtual BOOL handleKeyHere( KEY key, MASK mask ); diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index 381b3cf721..cb330bca0f 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -133,6 +133,7 @@ public:  	static floater_showed_signal_t sIMFloaterShowedSignal;  	bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; } +	S32 getLastChatMessageIndex() {return mLastMessageIndex;}  private:  	/*virtual*/ void refresh(); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 47744b6ba0..d3fcfbbc56 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -725,6 +725,27 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/*  	}  } +// static +void LLFloaterIMSessionTab::reloadEmptyFloaters() +{ +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); +		iter != inst_list.end(); ++iter) +	{ +		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter); +		if (floater && floater->getLastChatMessageIndex() == -1) +		{ +			floater->reloadMessages(true); +		} +	} + +	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); +	if (nearby_chat && nearby_chat->getMessageArchiveLength() == 0) +	{ +		nearby_chat->reloadMessages(true); +	} +} +  void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)  {  	LLButton* voiceButton = getChild<LLButton>("voice_call_btn"); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index b52bdfd8cd..d55b021df7 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -54,6 +54,7 @@ public:  	// reload all message with new settings of visual modes  	static void processChatHistoryStyleUpdate(bool clean_messages = false); +	static void reloadEmptyFloaters();  	/**  	 * Returns true if chat is displayed in multi tabbed floater diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 688d453789..3f8c23ba83 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -798,13 +798,28 @@ void LLFloaterPreference::onBtnOK()  		//Conversation transcript and log path changed so reload conversations based on new location  		if(mPriorInstantMessageLogPath.length())  		{ -			std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); -			updateLogLocation(dir_name); +			if(moveTranscriptsAndLog()) +			{ +				//When floaters are empty but have a chat history files, reload chat history into them +				LLFloaterIMSessionTab::reloadEmptyFloaters(); +			} +			//Couldn't move files so restore the old path and show a notification +			else +			{ +				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  	{ @@ -1441,9 +1456,9 @@ 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 ) ) @@ -1457,22 +1472,76 @@ void LLFloaterPreference::onClickLogPath()  	//Path changed  	if(proposed_name != dir_name)  	{ -		gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name); +	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);  		mPriorInstantMessageLogPath = proposed_name; - -		// enable/disable 'Delete transcripts button -		updateDeleteTranscriptsButton(); -	} +	 +	// 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 31c1e2d9e5..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(); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d69bd89f13..8f3f5145a9 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -273,7 +273,7 @@ void on_new_message(const LLSD& msg)  		}      } -    else if("openconversations" == action && !session_floater_is_open) +    else if("openconversations" == action)      {          //User is not focused on conversation containing the message          if(session_floater_not_focused) @@ -291,7 +291,8 @@ void on_new_message(const LLSD& msg)              //useMostItrusiveIMNotification will be called to notify user a message exists              if(session_id.notNull()                   && participant_id.notNull() -                && gAgent.isDoNotDisturb()) +                && gAgent.isDoNotDisturb() +				&& !session_floater_is_open)              {                  LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));  			} diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 09f816a4e6..448100c5d6 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -502,6 +502,81 @@ 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; +	std::string backupFileName; +	unsigned backupFileCount; + +	BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove) +	{ +		backupFileCount = 0; +		newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos); + +		//The target directory contains that file already, so lets store it +		if(LLFile::isfile(newFullPath)) +		{ +			backupFileName = newFullPath + ".backup"; + +			//If needed store backup file as .backup1 etc. +			while(LLFile::isfile(backupFileName)) +			{ +				++backupFileCount; +				backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount); +			} + +			//Rename the file to its backup name so it is not overwritten +			LLFile::rename(newFullPath, backupFileName); +		} + +		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; + +				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 b981d9ce04..784786a565 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();  	static bool isTranscriptExist(const LLUUID& avatar_id); diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index 73f0fa7979..88ae441bd3 100644 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -3,6 +3,13 @@   layout="topleft"   name="Url Popup">      <menu_item_call +     label="Send IM" +     layout="topleft" +     name="show_agent"> +        <menu_item_call.on_click +         function="Url.SendIM" />         +    </menu_item_call> +    <menu_item_call       label="Show Resident Profile"       layout="topleft"       name="show_agent"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3ae9b206a4..88c02fc84e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9708,14 +9708,6 @@ No room to sit here, try another spot.    <notification     icon="alertmodal.tga" -   name="AutopilotCanceled" -   type="notify"> -   <tag>fail</tag> -Autopilot canceled -  </notification> - -  <notification -   icon="alertmodal.tga"     name="ClaimObjectFailedNoPermission"     type="notify">     <tag>fail</tag> @@ -10028,4 +10020,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> | 
