diff options
Diffstat (limited to 'indra/newview/llviewermessage.cpp')
-rw-r--r-- | indra/newview/llviewermessage.cpp | 795 |
1 files changed, 219 insertions, 576 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 2a6b272741..c542459cdb 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2,31 +2,36 @@ * @file llviewermessage.cpp * @brief Dumping ground for viewer-side message system callbacks. * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llviewermessage.h" -#include "boost/lexical_cast.hpp" #include "llanimationstates.h" #include "llaudioengine.h" @@ -49,7 +54,8 @@ #include "llagent.h" #include "llagentcamera.h" #include "llcallingcard.h" -#include "llbuycurrencyhtml.h" +//#include "llfirstuse.h" +#include "llfloaterbuycurrency.h" #include "llfloaterbuyland.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" @@ -65,6 +71,7 @@ #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpanelgrouplandmoney.h" +#include "llpanelplaces.h" #include "llrecentpeople.h" #include "llscriptfloater.h" #include "llselectmgr.h" @@ -103,13 +110,12 @@ #include <boost/algorithm/string/split.hpp> // #include <boost/regex.hpp> -#include "llnotificationmanager.h" // - -#if LL_MSVC -// disable boost::lexical_cast warning -#pragma warning (disable:4702) +#if LL_WINDOWS // For Windows specific error handler +#include "llwindebug.h" // For the invalid message handler #endif +#include "llnotificationmanager.h" // + // // Constants // @@ -272,7 +278,7 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_ { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", amount); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("giving", args), amount ); + LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("giving", args), amount); } } @@ -686,52 +692,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response) return false; } - -static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel) -{ - if (NULL == inventory_panel) return; - - for (std::vector<LLUUID>::const_iterator item_iter = items.begin(); - item_iter != items.end(); - ++item_iter) - { - const LLUUID& item_id = (*item_iter); - if(!highlight_offered_object(item_id)) - { - continue; - } - - LLInventoryItem* item = gInventory.getItem(item_id); - llassert(item); - if (!item) { - continue; - } - - LL_DEBUGS("Inventory_Move") << "Highlighting inventory item: " << item->getName() << ", " << item_id << LL_ENDL; - LLFolderView* fv = inventory_panel->getRootFolder(); - if (fv) - { - LLFolderViewItem* fv_item = fv->getItemByID(item_id); - if (fv_item) - { - LLFolderViewItem* fv_folder = fv_item->getParentFolder(); - if (fv_folder) - { - // Parent folders can be different in case of 2 consecutive drag and drop - // operations when the second one is started before the first one completes. - LL_DEBUGS("Inventory_Move") << "Open folder: " << fv_folder->getName() << LL_ENDL; - fv_folder->setOpen(TRUE); - if (fv_folder->isSelected()) - { - fv->changeSelection(fv_folder, FALSE); - } - } - fv->changeSelection(fv_item, TRUE); - } - } - } -} - static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response); static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response); static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response); @@ -740,25 +700,10 @@ static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_ //----------------------------------------------------------------------------- // Instant Message //----------------------------------------------------------------------------- -class LLOpenAgentOffer : public LLInventoryFetchItemsObserver +class LLOpenAgentOffer : public LLInventoryFetchObserver { public: - LLOpenAgentOffer(const LLUUID& object_id, - const std::string& from_name) : - LLInventoryFetchItemsObserver(object_id), - mFromName(from_name) {} - /*virtual*/ void startFetch() - { - for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it) - { - LLViewerInventoryCategory* cat = gInventory.getCategory(*it); - if (cat) - { - mComplete.push_back((*it)); - } - } - LLInventoryFetchItemsObserver::startFetch(); - } + LLOpenAgentOffer(const std::string& from_name) : mFromName(from_name) {} /*virtual*/ void done() { open_inventory_offer(mComplete, mFromName); @@ -769,110 +714,6 @@ private: std::string mFromName; }; -/** - * Class to observe adding of new items moved from the world to user's inventory to select them in inventory. - * - * We can't create it each time items are moved because "drop" event is sent separately for each - * element even while multi-dragging. We have to have the only instance of the observer. See EXT-4347. - */ -class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetObserver -{ -public: - LLViewerInventoryMoveFromWorldObserver() - : LLInventoryAddItemByAssetObserver() - , mActivePanel(NULL) - { - - } - - void setMoveIntoFolderID(const LLUUID& into_folder_uuid) {mMoveIntoFolderID = into_folder_uuid; } - -private: - /*virtual */void onAssetAdded(const LLUUID& asset_id) - { - // Store active Inventory panel. - mActivePanel = LLInventoryPanel::getActiveInventoryPanel(); - - // Store selected items (without destination folder) - mSelectedItems.clear(); - if (mActivePanel) - { - mSelectedItems = mActivePanel->getRootFolder()->getSelectionList(); - } - mSelectedItems.erase(mMoveIntoFolderID); - } - - /** - * Selects added inventory items watched by their Asset UUIDs if selection was not changed since - * all items were started to watch (dropped into a folder). - */ - void done() - { - // if selection is not changed since watch started lets hightlight new items. - if (mActivePanel && !isSelectionChanged()) - { - LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL; - mActivePanel->clearSelection(); - highlight_inventory_items_in_panel(mAddedItems, mActivePanel); - } - } - - /** - * Returns true if selected inventory items were changed since moved inventory items were started to watch. - */ - bool isSelectionChanged() - { - const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel(); - - if (NULL == mActivePanel || current_active_panel != mActivePanel) - { - return true; - } - - // get selected items (without destination folder) - selected_items_t selected_items = mActivePanel->getRootFolder()->getSelectionList(); - selected_items.erase(mMoveIntoFolderID); - - // compare stored & current sets of selected items - selected_items_t different_items; - std::set_symmetric_difference(mSelectedItems.begin(), mSelectedItems.end(), - selected_items.begin(), selected_items.end(), std::inserter(different_items, different_items.begin())); - - LL_DEBUGS("Inventory_Move") << "Selected firstly: " << mSelectedItems.size() - << ", now: " << selected_items.size() << ", difference: " << different_items.size() << LL_ENDL; - - return different_items.size() > 0; - } - - LLInventoryPanel *mActivePanel; - typedef std::set<LLUUID> selected_items_t; - selected_items_t mSelectedItems; - - /** - * UUID of FolderViewFolder into which watched items are moved. - * - * Destination FolderViewFolder becomes selected while mouse hovering (when dragged items are dropped). - * - * If mouse is moved out it set unselected and number of selected items is changed - * even if selected items in Inventory stay the same. - * So, it is used to update stored selection list. - * - * @see onAssetAdded() - * @see isSelectionChanged() - */ - LLUUID mMoveIntoFolderID; -}; - -LLViewerInventoryMoveFromWorldObserver* gInventoryMoveObserver = NULL; - -void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid) -{ - start_new_inventory_observer(); - - gInventoryMoveObserver->setMoveIntoFolderID(into_folder_uuid); - gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID()); -} - //unlike the FetchObserver for AgentOffer, we only make one //instance of the AddedObserver for TaskOffers //and it never dies. We do this because we don't know the UUID of @@ -883,33 +724,6 @@ class LLOpenTaskOffer : public LLInventoryAddedObserver protected: /*virtual*/ void done() { - for (uuid_vec_t::iterator it = mAdded.begin(); it != mAdded.end();) - { - const LLUUID& item_uuid = *it; - bool was_moved = false; - LLInventoryObject* added_object = gInventory.getObject(item_uuid); - if (added_object) - { - // cast to item to get Asset UUID - LLInventoryItem* added_item = dynamic_cast<LLInventoryItem*>(added_object); - if (added_item) - { - const LLUUID& asset_uuid = added_item->getAssetUUID(); - if (gInventoryMoveObserver->isAssetWatched(asset_uuid)) - { - LL_DEBUGS("Inventory_Move") << "Found asset UUID: " << asset_uuid << LL_ENDL; - was_moved = true; - } - } - } - - if (was_moved) - { - it = mAdded.erase(it); - } - else ++it; - } - open_inventory_offer(mAdded, ""); mAdded.clear(); } @@ -938,21 +752,13 @@ void start_new_inventory_observer() gNewInventoryObserver = new LLOpenTaskOffer; gInventory.addObserver(gNewInventoryObserver); } - - if (!gInventoryMoveObserver) //inventory move from the world observer - { - // Observer is deleted by gInventory - gInventoryMoveObserver = new LLViewerInventoryMoveFromWorldObserver; - gInventory.addObserver(gInventoryMoveObserver); - } } -class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver +class LLDiscardAgentOffer : public LLInventoryFetchComboObserver { LOG_CLASS(LLDiscardAgentOffer); public: LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) : - LLInventoryFetchItemsObserver(object_id), mFolderID(folder_id), mObjectID(object_id) {} virtual ~LLDiscardAgentOffer() {} @@ -1035,26 +841,21 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) { // Use the name of the last item giver, who is probably the person // spamming you. - - LLStringUtil::format_map_t arg; - std::string log_msg; - std::ostringstream time ; - time<<OFFER_THROTTLE_TIME; - - arg["APP_NAME"] = LLAppViewer::instance()->getSecondLifeTitle(); - arg["TIME"] = time.str(); - + std::ostringstream message; + message << LLAppViewer::instance()->getSecondLifeTitle(); if (!from_name.empty()) { - arg["FROM_NAME"] = from_name; - log_msg = LLTrans::getString("ItemsComingInTooFastFrom", arg); + message << ": Items coming in too fast from " << from_name; } else { - log_msg = LLTrans::getString("ItemsComingInTooFast", arg); + message << ": Items coming in too fast"; } + message << ", automatic preview disabled for " + << OFFER_THROTTLE_TIME << " seconds."; //this is kinda important, so actually put it on screen + std::string log_msg = message.str(); LLSD args; args["MESSAGE"] = log_msg; LLNotificationsUtil::add("SystemMessage", args); @@ -1071,135 +872,130 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) } } -void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name) +void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name) { - for (uuid_vec_t::const_iterator obj_iter = objects.begin(); - obj_iter != objects.end(); - ++obj_iter) + for (uuid_vec_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) { - const LLUUID& obj_id = (*obj_iter); - if(!highlight_offered_object(obj_id)) + const LLUUID& item_id = (*item_iter); + if(!highlight_offered_item(item_id)) { continue; } - const LLInventoryObject *obj = gInventory.getObject(obj_id); - if (!obj) - { - llwarns << "Cannot find object [ itemID:" << obj_id << " ] to open." << llendl; + LLInventoryItem* item = gInventory.getItem(item_id); + llassert(item); + if (!item) { continue; } - const LLAssetType::EType asset_type = obj->getActualType(); - - // Either an inventory item or a category. - const LLInventoryItem* item = dynamic_cast<const LLInventoryItem*>(obj); - if (item) - { - //////////////////////////////////////////////////////////////////////////////// - // Special handling for various types. - if (check_offer_throttle(from_name, false)) // If we are throttled, don't display + //////////////////////////////////////////////////////////////////////////////// + // Special handling for various types. + const LLAssetType::EType asset_type = item->getType(); + if (check_offer_throttle(from_name, false)) // If we are throttled, don't display + { + LL_DEBUGS("Messaging") << "Highlighting inventory item: " << item->getUUID() << LL_ENDL; + // If we opened this ourselves, focus it + const BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO; + switch(asset_type) { - LL_DEBUGS("Messaging") << "Highlighting inventory item: " << item->getUUID() << LL_ENDL; - // If we opened this ourselves, focus it - const BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO; - switch(asset_type) - { - case LLAssetType::AT_NOTECARD: + case LLAssetType::AT_NOTECARD: + { + LLFloaterReg::showInstance("preview_notecard", LLSD(item_id), take_focus); + break; + } + case LLAssetType::AT_LANDMARK: + { + LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID()); + if ("inventory_handler" == from_name) { - LLFloaterReg::showInstance("preview_notecard", LLSD(obj_id), take_focus); - break; + //we have to filter inventory_handler messages to avoid notification displaying + LLSideTray::getInstance()->showPanel("panel_places", + LLSD().with("type", "landmark").with("id", item->getUUID())); } - case LLAssetType::AT_LANDMARK: + else if("group_offer" == from_name) { - LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID()); - if ("inventory_handler" == from_name) - { - //we have to filter inventory_handler messages to avoid notification displaying - LLSideTray::getInstance()->showPanel("panel_places", - LLSD().with("type", "landmark").with("id", item->getUUID())); - } - else if("group_offer" == from_name) - { - // "group_offer" is passed by LLOpenTaskGroupOffer - // Notification about added landmark will be generated under the "from_name.empty()" called from LLOpenTaskOffer::done(). - LLSD args; - args["type"] = "landmark"; - args["id"] = obj_id; - LLSideTray::getInstance()->showPanel("panel_places", args); - - continue; - } - else if(from_name.empty()) + // do not open inventory when we open group notice attachment because + // we already opened landmark info panel + // "group_offer" is passed by LLOpenTaskGroupOffer + + continue; + } + else if(from_name.empty()) + { + // we receive a message from LLOpenTaskOffer, it mean that new landmark has been added. + LLSD args; + args["LANDMARK_NAME"] = item->getName(); + args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown"); + LLNotificationsUtil::add("LandmarkCreated", args); + // Created landmark is passed to Places panel to allow its editing. In fact panel should be already displayed. + // If the panel is closed we don't reopen it until created landmark is loaded. + //TODO*:: dserduk(7/12/09) remove LLPanelPlaces dependency from here + LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->getPanel("panel_places")); + if (places_panel) { - std::string folder_name; - if (parent_folder) + // Landmark creation handling is moved to LLPanelPlaces::showAddedLandmarkInfo() + // TODO* LLPanelPlaces dependency is going to be removed. See EXT-4347. + //if("create_landmark" == places_panel->getPlaceInfoType() && !places_panel->getItem()) + //{ + // places_panel->setItem(item); + //} + //else + // we are opening a group notice attachment + if("create_landmark" != places_panel->getPlaceInfoType()) { - // Localize folder name. - // *TODO: share this code? - folder_name = parent_folder->getName(); - if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType())) - { - LLTrans::findString(folder_name, "InvFolder " + folder_name); - } + LLSD args; + args["type"] = "landmark"; + args["id"] = item_id; + LLSideTray::getInstance()->showPanel("panel_places", args); } - else - { - folder_name = LLTrans::getString("Unknown"); - } - - // we receive a message from LLOpenTaskOffer, it mean that new landmark has been added. - LLSD args; - args["LANDMARK_NAME"] = item->getName(); - args["FOLDER_NAME"] = folder_name; - LLNotificationsUtil::add("LandmarkCreated", args); } } - break; - case LLAssetType::AT_TEXTURE: - { - LLFloaterReg::showInstance("preview_texture", LLSD(obj_id), take_focus); - break; - } - case LLAssetType::AT_ANIMATION: - LLFloaterReg::showInstance("preview_anim", LLSD(obj_id), take_focus); - break; - case LLAssetType::AT_SCRIPT: - LLFloaterReg::showInstance("preview_script", LLSD(obj_id), take_focus); - break; - case LLAssetType::AT_SOUND: - LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus); - break; - default: - break; } + break; + case LLAssetType::AT_TEXTURE: + { + LLFloaterReg::showInstance("preview_texture", LLSD(item_id), take_focus); + break; + } + case LLAssetType::AT_ANIMATION: + LLFloaterReg::showInstance("preview_anim", LLSD(item_id), take_focus); + break; + case LLAssetType::AT_SCRIPT: + LLFloaterReg::showInstance("preview_script", LLSD(item_id), take_focus); + break; + case LLAssetType::AT_SOUND: + LLFloaterReg::showInstance("preview_sound", LLSD(item_id), take_focus); + break; + default: + break; } } - + //////////////////////////////////////////////////////////////////////////////// - // Highlight item - const BOOL auto_open = - gSavedSettings.getBOOL("ShowInInventory") && // don't open if showininventory is false - !(asset_type == LLAssetType::AT_CALLINGCARD) && // don't open if it's a calling card - !(item && (item->getInventoryType() == LLInventoryType::IT_ATTACHMENT)) && // don't open if it's an item that's an attachment - !from_name.empty(); // don't open if it's not from anyone. + // Highlight item if it's not in the trash, lost+found, or COF + const BOOL auto_open = gSavedSettings.getBOOL("ShowInInventory") && + (asset_type != LLAssetType::AT_CALLINGCARD) && + (item->getInventoryType() != LLInventoryType::IT_ATTACHMENT) && + !from_name.empty(); LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open); if(active_panel) { - LL_DEBUGS("Messaging") << "Highlighting" << obj_id << LL_ENDL; + LL_DEBUGS("Messaging") << "Highlighting" << item_id << LL_ENDL; LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - active_panel->setSelection(obj_id, TAKE_FOCUS_NO); + active_panel->setSelection(item_id, TAKE_FOCUS_NO); gFocusMgr.setKeyboardFocus(focus_ctrl); } } } -bool highlight_offered_object(const LLUUID& obj_id) +bool highlight_offered_item(const LLUUID& item_id) { - const LLInventoryObject* obj = gInventory.getObject(obj_id); - if(!obj) + LLInventoryItem* item = gInventory.getItem(item_id); + if(!item) { - LL_WARNS("Messaging") << "Unable to show inventory item: " << obj_id << LL_ENDL; + LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL; return false; } @@ -1208,7 +1004,7 @@ bool highlight_offered_object(const LLUUID& obj_id) // notification (e.g. trash, cof, lost-and-found). if(!gAgent.getAFK()) { - const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(obj_id); + const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(item_id); if (parent) { const LLFolderType::EType parent_type = parent->getPreferredType(); @@ -1225,9 +1021,8 @@ bool highlight_offered_object(const LLUUID& obj_id) void inventory_offer_mute_callback(const LLUUID& blocked_id, const std::string& first_name, const std::string& last_name, - BOOL is_group, boost::shared_ptr<LLNotificationResponderInterface> offer_ptr) + BOOL is_group, LLOfferInfo* offer = NULL) { - LLOfferInfo* offer = dynamic_cast<LLOfferInfo*>(offer_ptr.get()); std::string from_name; LLMute::EType type; if (is_group) @@ -1262,6 +1057,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, bool matches(const LLNotificationPtr notification) const { if(notification->getName() == "ObjectGiveItem" + || notification->getName() == "ObjectGiveItemUnknownUser" || notification->getName() == "UserGiveItem") { return (notification->getPayload()["from_id"].asUUID() == blocked_id); @@ -1276,16 +1072,6 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id)); } -LLOfferInfo::LLOfferInfo() - : LLNotificationResponderInterface() - , mFromGroup(FALSE) - , mFromObject(FALSE) - , mIM(IM_NOTHING_SPECIAL) - , mType(LLAssetType::AT_NONE) - , mPersist(false) -{ -} - LLOfferInfo::LLOfferInfo(const LLSD& sd) { mIM = (EInstantMessage)sd["im_type"].asInteger(); @@ -1299,7 +1085,6 @@ LLOfferInfo::LLOfferInfo(const LLSD& sd) mFromName = sd["from_name"].asString(); mDesc = sd["description"].asString(); mHost = LLHost(sd["sender"].asString()); - mPersist = sd["persist"].asBoolean(); } LLOfferInfo::LLOfferInfo(const LLOfferInfo& info) @@ -1315,7 +1100,6 @@ LLOfferInfo::LLOfferInfo(const LLOfferInfo& info) mFromName = info.mFromName; mDesc = info.mDesc; mHost = info.mHost; - mPersist = info.mPersist; } LLSD LLOfferInfo::asLLSD() @@ -1332,15 +1116,9 @@ LLSD LLOfferInfo::asLLSD() sd["from_name"] = mFromName; sd["description"] = mDesc; sd["sender"] = mHost.getIPandPort(); - sd["persist"] = mPersist; return sd; } -void LLOfferInfo::fromLLSD(const LLSD& params) -{ - *this = params; -} - void LLOfferInfo::send_auto_receive_response(void) { LLMessageSystem* msg = gMessageSystem; @@ -1380,21 +1158,6 @@ void LLOfferInfo::send_auto_receive_response(void) } } -void LLOfferInfo::handleRespond(const LLSD& notification, const LLSD& response) -{ - initRespondFunctionMap(); - - const std::string name = notification["name"].asString(); - if(mRespondFunctions.find(name) == mRespondFunctions.end()) - { - llwarns << "Unexpected notification name : " << name << llendl; - llassert(!"Unexpected notification name"); - return; - } - - mRespondFunctions[name](notification, response); -} - bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response) { LLChat chat; @@ -1417,13 +1180,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // * we can't build two messages at once. if (2 == button) // Block { - LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); - - llassert(notification_ptr != NULL); - if (notification_ptr != NULL) - { - gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); - } + gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); } std::string from_string; // Used in the pop-up. @@ -1447,9 +1204,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // This is an offer from an agent. In this case, the back // end has already copied the items into your inventory, // so we can fetch it out of our inventory. - LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string); - open_agent_offer->startFetch(); - if(catp || (itemp && itemp->isFinished())) + uuid_vec_t items; + items.push_back(mObjectID); + LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string); + open_agent_offer->fetch(items); + if(catp || (itemp && itemp->isComplete())) { open_agent_offer->done(); } @@ -1506,9 +1265,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // Disabled logging to old chat floater to fix crash in group notices - EXT-4149 // LLFloaterChat::addChatHistory(chat); - LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID); - discard_agent_offer->startFetch(); - if (catp || (itemp && itemp->isFinished())) + uuid_vec_t folders; + uuid_vec_t items; + items.push_back(mObjectID); + LLDiscardAgentOffer* discard_agent_offer; + discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID); + discard_agent_offer->fetch(folders, items); + if(catp || (itemp && itemp->isComplete())) { discard_agent_offer->done(); } @@ -1537,10 +1300,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& gInventory.addObserver(opener); } - if(!mPersist) - { - delete this; - } + delete this; return false; } @@ -1557,13 +1317,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const // * we can't build two messages at once. if (2 == button) { - LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); - - llassert(notification_ptr != NULL); - if (notification_ptr != NULL) - { - gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); - } + gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); } LLMessageSystem* msg = gMessageSystem; @@ -1712,34 +1466,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const gInventory.addObserver(opener); } - if(!mPersist) - { - delete this; - } + delete this; return false; } -class LLPostponedOfferNotification: public LLPostponedNotification -{ -protected: - /* virtual */ - void modifyNotificationParams() - { - LLSD substitutions = mParams.substitutions; - substitutions["NAME"] = mName; - mParams.substitutions = substitutions; - } -}; - -void LLOfferInfo::initRespondFunctionMap() -{ - if(mRespondFunctions.empty()) - { - mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2); - mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2); - } -} - void inventory_offer_handler(LLOfferInfo* info) { //Until throttling is implmented, busy mode should reject inventory instead of silently @@ -1806,6 +1536,30 @@ void inventory_offer_handler(LLOfferInfo* info) return; } + // Name cache callbacks don't store userdata, so can't save + // off the LLOfferInfo. Argh. + BOOL name_found = FALSE; + if (info->mFromGroup) + { + std::string group_name; + if (gCacheName->getGroupName(info->mFromID, group_name)) + { + args["FIRST"] = group_name; + args["LAST"] = ""; + name_found = TRUE; + } + } + else + { + std::string first_name, last_name; + if (gCacheName->getName(info->mFromID, first_name, last_name)) + { + args["FIRST"] = first_name; + args["LAST"] = last_name; + name_found = TRUE; + } + } + // If mObjectID is null then generate the object_id based on msg to prevent // multiple creation of chiclets for same object. LLUUID object_id = info->mObjectID; @@ -1820,9 +1574,9 @@ void inventory_offer_handler(LLOfferInfo* info) payload["give_inventory_notification"] = FALSE; args["OBJECTFROMNAME"] = info->mFromName; args["NAME"] = info->mFromName; - args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString(); + args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about"); std::string verb = "select?name=" + LLURI::escape(msg); - args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString(); + args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str()); LLNotification::Params p("ObjectGiveItem"); @@ -1832,11 +1586,10 @@ void inventory_offer_handler(LLOfferInfo* info) // Inventory Slurls don't currently work for non agent transfers, so only display the object name. args["ITEM_SLURL"] = msg; // Note: sets inventory_task_offer_callback as the callback - p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info)); - info->mPersist = true; - p.name = "ObjectGiveItem"; + p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_task_offer_callback, info, _1, _2)); + p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser"; // Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory. - LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE); + LLNotifications::instance().add(p); } else // Agent -> Agent Inventory Offer { @@ -1845,14 +1598,15 @@ void inventory_offer_handler(LLOfferInfo* info) // *TODO fix memory leak // inventory_offer_callback() is not invoked if user received notification and // closes viewer(without responding the notification) - p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info)); - info->mPersist = true; + p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2)); p.name = "UserGiveItem"; // Prefetch the item into your local inventory. - LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID); - fetch_item->startFetch(); - if(fetch_item->isFinished()) + uuid_vec_t items; + items.push_back(info->mObjectID); + LLInventoryFetchObserver* fetch_item = new LLInventoryFetchObserver(); + fetch_item->fetch(items); + if(fetch_item->isEverythingComplete()) { fetch_item->done(); } @@ -1867,8 +1621,7 @@ void inventory_offer_handler(LLOfferInfo* info) // Inform user that there is a script floater via toast system { payload["give_inventory_notification"] = TRUE; - p.payload = payload; - LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false); + LLNotificationPtr notification = LLNotifications::instance().add(p.payload(payload)); } } } @@ -1945,76 +1698,6 @@ protected: } }; -static bool parse_lure_bucket(const std::string& bucket, - U64& region_handle, - LLVector3& pos, - LLVector3& look_at, - U8& region_access) -{ - // tokenize the bucket - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("|", "", boost::keep_empty_tokens); - tokenizer tokens(bucket, sep); - tokenizer::iterator iter = tokens.begin(); - - S32 gx,gy,rx,ry,rz,lx,ly,lz; - try - { - gx = boost::lexical_cast<S32>((*(iter)).c_str()); - gy = boost::lexical_cast<S32>((*(++iter)).c_str()); - rx = boost::lexical_cast<S32>((*(++iter)).c_str()); - ry = boost::lexical_cast<S32>((*(++iter)).c_str()); - rz = boost::lexical_cast<S32>((*(++iter)).c_str()); - lx = boost::lexical_cast<S32>((*(++iter)).c_str()); - ly = boost::lexical_cast<S32>((*(++iter)).c_str()); - lz = boost::lexical_cast<S32>((*(++iter)).c_str()); - } - catch( boost::bad_lexical_cast& ) - { - LL_WARNS("parse_lure_bucket") - << "Couldn't parse lure bucket." - << LL_ENDL; - return false; - } - // Grab region access - region_access = SIM_ACCESS_MIN; - if (++iter != tokens.end()) - { - std::string access_str((*iter).c_str()); - LLStringUtil::trim(access_str); - if ( access_str == "A" ) - { - region_access = SIM_ACCESS_ADULT; - } - else if ( access_str == "M" ) - { - region_access = SIM_ACCESS_MATURE; - } - else if ( access_str == "PG" ) - { - region_access = SIM_ACCESS_PG; - } - } - - pos.setVec((F32)rx, (F32)ry, (F32)rz); - look_at.setVec((F32)lx, (F32)ly, (F32)lz); - - region_handle = to_region_handle(gx, gy); - return true; -} - -class LLPostponedIMSystemTipNotification: public LLPostponedNotification -{ -protected: - /* virtual */ - void modifyNotificationParams() - { - LLSD payload = mParams.payload; - payload["SESSION_NAME"] = mName; - mParams.payload = payload; - } -}; - void process_improved_im(LLMessageSystem *msg, void **user_data) { if (gNoRender) @@ -2085,19 +1768,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLSD args; LLSD payload; - LLNotification::Params params; - switch(dialog) { case IM_CONSOLE_AND_CHAT_HISTORY: + // *TODO: Translate args["MESSAGE"] = message; - args["NAME"] = name; + payload["SESSION_NAME"] = name; payload["from_id"] = from_id; - - params.name = "IMSystemMessageTip"; - params.substitutions = args; - params.payload = payload; - LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false); + LLNotificationsUtil::add("IMSystemMessageTip",args, payload); break; case IM_NOTHING_SPECIAL: @@ -2119,7 +1797,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // initiated by the other party) then... std::string my_name; LLAgentUI::buildFullname(my_name); - std::string response = gSavedPerAccountSettings.getString("BusyModeResponse"); + std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2"); pack_instant_message( gMessageSystem, gAgent.getID(), @@ -2382,8 +2060,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLSD args; args["MESSAGE"] = message; - // we shouldn't pass callback functor since it is registered in LLFunctorRegistration - LLNotificationsUtil::add("JoinGroup", args, payload); + LLNotificationsUtil::add("JoinGroup", args, payload, join_group_response); } } break; @@ -2444,8 +2121,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) if (is_muted) { // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331) - LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID); - fetch_item->startFetch(); + uuid_vec_t items; + items.push_back(info->mObjectID); + LLInventoryFetchObserver* fetch_item = new LLInventoryFetchObserver(); + fetch_item->fetch(items); delete fetch_item; // Same as closing window @@ -2551,13 +2230,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mFromID = from_id ^ gAgent.getSessionID(); } - chat.mSourceType = CHAT_SOURCE_OBJECT; - if(SYSTEM_FROM == name) { // System's UUID is NULL (fixes EXT-4766) chat.mFromID = LLUUID::null; - chat.mSourceType = CHAT_SOURCE_SYSTEM; } LLSD query_string; @@ -2569,16 +2245,20 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) query_string["groupowned"] = "true"; } - chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString(); + std::ostringstream link; + link << "secondlife:///app/objectim/" << session_id << LLURI::mapToQueryString(query_string); + + chat.mURL = link.str(); chat.mText = message; + chat.mSourceType = CHAT_SOURCE_OBJECT; // Note: lie to Nearby Chat, pretending that this is NOT an IM, because // IMs from obejcts don't open IM sessions. LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); - if(SYSTEM_FROM != name && nearby_chat) + if(nearby_chat) { - chat.mOwnerID = from_id; LLSD args; + args["owner_id"] = from_id; args["slurl"] = location; args["type"] = LLNotificationsUI::NT_NEARBYCHAT; LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args); @@ -2608,7 +2288,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) params.substitutions = substitutions; params.payload = payload; - LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group); + LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, false); } break; case IM_FROM_TASK_AS_ALERT: @@ -2649,34 +2329,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - LLVector3 pos, look_at; - U64 region_handle; - U8 region_access = SIM_ACCESS_MIN; - std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); - std::string region_access_str = LLStringUtil::null; - std::string region_access_icn = LLStringUtil::null; - - if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access)) - { - region_access_str = LLViewerRegion::accessToString(region_access); - region_access_icn = LLViewerRegion::getAccessIcon(region_access); - } - LLSD args; // *TODO: Translate -> [FIRST] [LAST] (maybe) - args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString(); + args["NAME_SLURL"] = LLSLURL::buildCommand("agent", from_id, "about"); args["MESSAGE"] = message; - args["MATURITY_STR"] = region_access_str; - args["MATURITY_ICON"] = region_access_icn; LLSD payload; payload["from_id"] = from_id; payload["lure_id"] = session_id; payload["godlike"] = FALSE; - - LLNotification::Params params("TeleportOffered"); - params.substitutions = args; - params.payload = payload; - LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + LLNotificationsUtil::add("TeleportOffered", args, payload); } } break; @@ -2736,7 +2397,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString(); + args["NAME_SLURL"] = LLSLURL::buildCommand("agent", from_id, "about"); if(message.empty()) { //support for frienship offers from clients before July 2008 @@ -2745,10 +2406,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) else { args["[MESSAGE]"] = message; - LLNotification::Params params("OfferFriendship"); - params.substitutions = args; - params.payload = payload; - LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + LLNotificationsUtil::add("OfferFriendship", args, payload); } } } @@ -2792,7 +2450,7 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id) { std::string my_name; LLAgentUI::buildFullname(my_name); - std::string response = gSavedPerAccountSettings.getString("BusyModeResponse"); + std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2"); pack_instant_message( gMessageSystem, gAgent.getID(), @@ -3108,7 +2766,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // object inspect for an object that is chatting with you LLSD args; args["type"] = LLNotificationsUI::NT_NEARBYCHAT; - chat.mOwnerID = owner_id; + args["owner_id"] = owner_id; LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args); } @@ -3189,9 +2847,7 @@ void process_teleport_progress(LLMessageSystem* msg, void**) class LLFetchInWelcomeArea : public LLInventoryFetchDescendentsObserver { public: - LLFetchInWelcomeArea(const uuid_vec_t &ids) : - LLInventoryFetchDescendentsObserver(ids) - {} + LLFetchInWelcomeArea() {} virtual void done() { LLIsType is_landmark(LLAssetType::AT_LANDMARK); @@ -3273,9 +2929,9 @@ BOOL LLPostTeleportNotifiers::tick() folders.push_back(folder_id); if(!folders.empty()) { - LLFetchInWelcomeArea* fetcher = new LLFetchInWelcomeArea(folders); - fetcher->startFetch(); - if(fetcher->isFinished()) + LLFetchInWelcomeArea* fetcher = new LLFetchInWelcomeArea; + fetcher->fetch(folders); + if(fetcher->isEverythingComplete()) { fetcher->done(); } @@ -3500,9 +3156,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) { // Chat the "back" SLURL. (DEV-4907) - LLSLURL slurl; - gAgent.getTeleportSourceSLURL(slurl); - LLSD substitution = LLSD().with("[T_SLURL]", slurl.getSLURLString()); + LLSD substitution = LLSD().with("[T_SLURL]", gAgent.getTeleportSourceSLURL()); std::string completed_from = LLAgent::sTeleportProgressMessages["completed_from"]; LLStringUtil::format(completed_from, substitution); @@ -4530,9 +4184,6 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) } gAgentCamera.setForceMouselook(force_mouselook); - // Forcing turning off flying here to prevent flying after pressing "Stand" - // to stand up from an object. See EXT-1655. - gAgent.setFlying(FALSE); LLViewerObject* object = gObjectList.findObject(sitObjectID); if (object) @@ -4901,12 +4552,11 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) if(boost::regex_match(desc, matches, expr)) { // Name of full localizable notification string - // there are four types of this string- with name of receiver and reason of payment, - // without name and without reason (both may also be absent simultaneously). + // there are three types of this string- with name of receiver and reason of payment, + // without name and without reason (but not simultaneously) // example of string without name - You paid L$100 to create a group. // example of string without reason - You paid Smdby Linden L$100. // example of string with reason and name - You paid Smbdy Linden L$100 for a land access pass. - // example of string with no info - You paid L$50. std::string line = "you_paid_ldollars_no_name"; // arguments of string which will be in notification @@ -4927,7 +4577,7 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) std::string reason = std::string(matches[3]); if (reason.empty()) { - line = name.empty() ? "you_paid_ldollars_no_info" : "you_paid_ldollars_no_reason"; + line = "you_paid_ldollars_no_reason"; } else { @@ -4971,10 +4621,6 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD& gSavedSettings.setU32("PreferredMaturity", preferredMaturity); gAgent.sendMaturityPreferenceToServer(preferredMaturity); - // notify user that the maturity preference has been changed - LLSD args; - args["RATING"] = LLViewerRegion::accessToString(preferredMaturity); - LLNotificationsUtil::add("PreferredMaturityChanged", args); } return false; @@ -5116,7 +4762,7 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data) void process_alert_core(const std::string& message, BOOL modal) { - // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml + // HACK -- handle callbacks for specific alerts if ( message == "You died and have been teleported to your home location") { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT); @@ -5903,9 +5549,7 @@ void send_group_notice(const LLUUID& group_id, bool handle_lure_callback(const LLSD& notification, const LLSD& response) { std::string text = response["message"].asString(); - LLSLURL slurl; - LLAgentUI::buildSLURL(slurl); - text.append("\r\n").append(slurl.getSLURLString()); + text.append("\r\n").append(LLAgentUI::buildSLURL()); S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if(0 == option) @@ -6348,7 +5992,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**) LLFloaterBuyLand::updateEstateName(estate_name); std::string owner_name = - LLSLURL("agent", estate_owner_id, "inspect").getSLURLString(); + LLSLURL::buildCommand("agent", estate_owner_id, "inspect"); LLPanelEstateCovenant::updateEstateOwnerName(owner_name); LLPanelLandCovenant::updateEstateOwnerName(owner_name); LLFloaterBuyLand::updateEstateOwnerName(owner_name); @@ -6528,4 +6172,3 @@ void LLOfferInfo::forceResponse(InventoryOfferResponse response) params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2)); LLNotifications::instance().forceResponse(params, response); } - |