summaryrefslogtreecommitdiff
path: root/indra/newview/llscriptfloater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llscriptfloater.cpp')
-rw-r--r--indra/newview/llscriptfloater.cpp144
1 files changed, 139 insertions, 5 deletions
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 1d021ec28f..da912ef3d4 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()
+ : mDialogLimitationsSlot()
+{
+}
+
void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
{
if(notification_id.isNull())
@@ -354,6 +361,19 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
return;
}
+ if (!mDialogLimitationsSlot.connected())
+ {
+ LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl("ScriptDialogLimitations");
+ if (cntrl_ptr.notNull())
+ {
+ mDialogLimitationsSlot = cntrl_ptr->getCommitSignal()->connect(boost::bind(&clearScriptNotifications));
+ }
+ else
+ {
+ LL_WARNS() << "Unable to set signal on setting 'ScriptDialogLimitations'" << LL_ENDL;
+ }
+ }
+
// get scripted Object's ID
LLUUID object_id = notification_id_to_object_id(notification_id);
@@ -365,16 +385,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 +473,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 +669,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 +719,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)