diff options
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llscriptfloater.cpp | 131 | ||||
| -rw-r--r-- | indra/newview/llscriptfloater.h | 17 | 
3 files changed, 153 insertions, 6 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 097a9ac7b9..db2d48bd12 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10734,6 +10734,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>ScriptDialogLimitations</key> +    <map> +      <key>Comment</key> +      <string>Limits amount of dialogs per script (0 - per object, 1 - per channel, 2 - per channel for attachments, 3 - per channel for HUDs, 4 -unconstrained for HUDs)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>U32</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>SecondLifeEnterprise</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index 1d021ec28f..b2c450aa0c 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -40,6 +40,7 @@  #include "lltoastnotifypanel.h"  #include "lltoastscripttextbox.h"  #include "lltrans.h" +#include "llviewerobjectlist.h"  #include "llviewerwindow.h"  #include "llfloaterimsession.h" @@ -61,6 +62,7 @@ LLUUID notification_id_to_object_id(const LLUUID& notification_id)  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +  LLScriptFloater::LLScriptFloater(const LLSD& key)  : LLDockableFloater(NULL, true, key)  , mScriptForm(NULL) @@ -346,6 +348,11 @@ void LLScriptFloater::hideToastsIfNeeded()  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLScriptFloaterManager::LLScriptFloaterManager() +{ +	gSavedSettings.getControl("ScriptDialogLimitations")->getCommitSignal()->connect(boost::bind(&clearScriptNotifications)); +} +  void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)  {  	if(notification_id.isNull()) @@ -365,16 +372,86 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)  	// LLDialog can spawn only one instance, LLLoadURL and LLGiveInventory can spawn unlimited number of instances  	if(OBJ_SCRIPT == obj_type)  	{ -		// If an Object spawns more-than-one floater, only the newest one is shown.  -		// The previous is automatically closed. -		script_notification_map_t::const_iterator it = findUsingObjectId(object_id); +		static LLCachedControl<U32> script_dialog_limitations(gSavedSettings, "ScriptDialogLimitations", 0); +		script_notification_map_t::const_iterator it = mNotifications.end(); +		switch (script_dialog_limitations) +		{ +			case SCRIPT_PER_CHANNEL: +			{ +				// If an Object spawns more-than-one floater per channel, only the newest one is shown. +				// The previous is automatically closed. +				LLNotificationPtr notification = LLNotifications::instance().find(notification_id); +				if (notification) +				{ +					it = findUsingObjectIdAndChannel(object_id, notification->getPayload()["chat_channel"].asInteger()); +				} +				break; +			} +			case SCRIPT_ATTACHMENT_PER_CHANNEL: +			{ +				LLViewerObject* objectp = gObjectList.findObject(object_id); +				if (objectp && objectp->getAttachmentItemID().notNull()) //in user inventory +				{ +					LLNotificationPtr notification = LLNotifications::instance().find(notification_id); +					if (notification) +					{ +						it = findUsingObjectIdAndChannel(object_id, notification->getPayload()["chat_channel"].asInteger()); +					} +				} +				else +				{ +					it = findUsingObjectId(object_id); +				} +				break; +			} +			case SCRIPT_HUD_PER_CHANNEL: +			{ +				LLViewerObject* objectp = gObjectList.findObject(object_id); +				if (objectp && objectp->isHUDAttachment()) +				{ +					LLNotificationPtr notification = LLNotifications::instance().find(notification_id); +					if (notification) +					{ +						it = findUsingObjectIdAndChannel(object_id, notification->getPayload()["chat_channel"].asInteger()); +					} +				} +				else +				{ +					it = findUsingObjectId(object_id); +				} +				break; +			} +			case SCRIPT_HUD_UNCONSTRAINED: +			{ +				LLViewerObject* objectp = gObjectList.findObject(object_id); +				if (objectp && objectp->isHUDAttachment()) +				{ +					// don't remove existing floaters +					break; +				} +				else +				{ +					it = findUsingObjectId(object_id); +				} +				break; +			} +			case SCRIPT_PER_OBJECT: +			default: +			{ +				// If an Object spawns more-than-one floater, only the newest one is shown. +				// The previous is automatically closed. +				it = findUsingObjectId(object_id); +				break; +			} +		} +  		if(it != mNotifications.end())  		{  			LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();  			if (NULL != chiclet_panelp)  			{  				LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first); -				if(NULL != chicletp) +				if (NULL != chicletp)  				{  					// Pass the new_message icon state further.  					set_new_message = chicletp->getShowNewMessagesIcon(); @@ -383,7 +460,7 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)  			}  			LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first); -			if(floater) +			if (floater)  			{  				// Generate chiclet with a "new message" indicator if a docked window was opened but not in focus. See EXT-3142.  				set_new_message |= !floater->hasFocus(); @@ -579,6 +656,23 @@ LLScriptFloaterManager::script_notification_map_t::const_iterator LLScriptFloate  	return mNotifications.end();  } +LLScriptFloaterManager::script_notification_map_t::const_iterator LLScriptFloaterManager::findUsingObjectIdAndChannel(const LLUUID& object_id, S32 im_channel) +{ +	script_notification_map_t::const_iterator it = mNotifications.begin(); +	for (; mNotifications.end() != it; ++it) +	{ +		if (object_id == it->second) +		{ +			LLNotificationPtr notification = LLNotifications::instance().find(it->first); +			if (notification && (im_channel == notification->getPayload()["chat_channel"].asInteger())) +			{ +				return it; +			} +		} +	} +	return mNotifications.end(); +} +  void LLScriptFloaterManager::saveFloaterPosition(const LLUUID& object_id, const FloaterPositionInfo& fpi)  {  	if(object_id.notNull()) @@ -612,6 +706,33 @@ void LLScriptFloaterManager::setFloaterVisible(const LLUUID& notification_id, bo  	}  } +//static +void LLScriptFloaterManager::clearScriptNotifications() +{ +	LLScriptFloaterManager* inst = LLScriptFloaterManager::getInstance(); +	static const object_type_map TYPE_MAP = initObjectTypeMap(); + +	script_notification_map_t::const_iterator ntf_it = inst->mNotifications.begin(); +	while (inst->mNotifications.end() != ntf_it) +	{ +		LLUUID notification_id = ntf_it->first; +		ntf_it++; // onRemoveNotification() erases notification +		LLNotificationPtr notification = LLNotifications::instance().find(notification_id); +		if (notification) +		{ +			object_type_map::const_iterator map_it = TYPE_MAP.find(notification->getName()); +			if (map_it != TYPE_MAP.end() && map_it->second == OBJ_SCRIPT) +			{ +				if (notification != NULL && !notification->isCancelled()) +				{ +					LLNotificationsUtil::cancel(notification); +				} +				inst->onRemoveNotification(notification_id); +			} +		} +	} +} +  //////////////////////////////////////////////////////////////////  bool LLScriptFloater::isScriptTextbox(LLNotificationPtr notification) diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h index c0b84abdcb..0192a8893e 100644 --- a/indra/newview/llscriptfloater.h +++ b/indra/newview/llscriptfloater.h @@ -41,7 +41,7 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>  	// *TODO  	// LLScriptFloaterManager and LLScriptFloater will need some refactoring after we   	// know how script notifications should look like. -	LLSINGLETON_EMPTY_CTOR(LLScriptFloaterManager); +	LLSINGLETON(LLScriptFloaterManager);  public:  	typedef enum e_object_type @@ -53,6 +53,15 @@ public:  		OBJ_UNKNOWN  	}EObjectType; +	typedef enum e_limitation_type +	{ +		SCRIPT_PER_OBJECT = 0, +		SCRIPT_PER_CHANNEL = 1, +		SCRIPT_ATTACHMENT_PER_CHANNEL, +		SCRIPT_HUD_PER_CHANNEL, +		SCRIPT_HUD_UNCONSTRAINED +	}ELimitationType; +  	/**  	 * Handles new notifications.  	 * Saves notification and object ids, removes old notification if needed, creates script chiclet @@ -104,6 +113,11 @@ public:  protected: +	/** +	 * Removes all script-dialog notifications +	 */ +	static void clearScriptNotifications(); +  	typedef std::map<std::string, EObjectType> object_type_map;  	static object_type_map initObjectTypeMap(); @@ -112,6 +126,7 @@ protected:  	typedef std::map<LLUUID, LLUUID> script_notification_map_t;  	script_notification_map_t::const_iterator findUsingObjectId(const LLUUID& object_id); +	script_notification_map_t::const_iterator findUsingObjectIdAndChannel(const LLUUID& object_id, S32 im_channel);  private: | 
