diff options
Diffstat (limited to 'indra/newview/llscriptfloater.cpp')
-rw-r--r-- | indra/newview/llscriptfloater.cpp | 131 |
1 files changed, 126 insertions, 5 deletions
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) |