summaryrefslogtreecommitdiff
path: root/indra/newview/llviewermessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewermessage.cpp')
-rw-r--r--indra/newview/llviewermessage.cpp263
1 files changed, 213 insertions, 50 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 9b39cbfdf1..ef3ee32f11 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -41,6 +41,7 @@
#include "lleventtimer.h"
#include "llfloaterreg.h"
#include "llfollowcamparams.h"
+#include "llinventorydefines.h"
#include "llregionhandle.h"
#include "llsdserialize.h"
#include "llteleportflags.h"
@@ -70,7 +71,6 @@
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llpanelgrouplandmoney.h"
-#include "llpanelplaces.h"
#include "llrecentpeople.h"
#include "llscriptfloater.h"
#include "llselectmgr.h"
@@ -691,6 +691,52 @@ 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_item(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);
@@ -713,6 +759,108 @@ 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 LLInventoryMoveFromWorldObserver
+{
+public:
+ LLViewerInventoryMoveFromWorldObserver()
+ : LLInventoryMoveFromWorldObserver()
+ , 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();
+ mActivePanel->getRootFolder()->getSelectionList(mSelectedItems);
+ 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);
+ 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
@@ -723,6 +871,33 @@ 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();
}
@@ -751,6 +926,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 LLInventoryFetchComboObserver
@@ -915,9 +1097,12 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)
}
else if("group_offer" == from_name)
{
- // do not open inventory when we open group notice attachment because
- // we already opened landmark info panel
// "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"] = item_id;
+ LLSideTray::getInstance()->showPanel("panel_places", args);
continue;
}
@@ -928,28 +1113,6 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)
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)
- {
- // 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())
- {
- LLSD args;
- args["type"] = "landmark";
- args["id"] = item_id;
- LLSideTray::getInstance()->showPanel("panel_places", args);
- }
- }
}
}
break;
@@ -1206,7 +1369,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
uuid_vec_t items;
items.push_back(mObjectID);
LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
- open_agent_offer->fetchItems(items);
+ open_agent_offer->fetch(items);
if(catp || (itemp && itemp->isComplete()))
{
open_agent_offer->done();
@@ -1573,9 +1736,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");
@@ -1604,7 +1767,7 @@ void inventory_offer_handler(LLOfferInfo* info)
uuid_vec_t items;
items.push_back(info->mObjectID);
LLInventoryFetchObserver* fetch_item = new LLInventoryFetchObserver();
- fetch_item->fetchItems(items);
+ fetch_item->fetch(items);
if(fetch_item->isEverythingComplete())
{
fetch_item->done();
@@ -2123,7 +2286,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
uuid_vec_t items;
items.push_back(info->mObjectID);
LLInventoryFetchObserver* fetch_item = new LLInventoryFetchObserver();
- fetch_item->fetchItems(items);
+ fetch_item->fetch(items);
delete fetch_item;
// Same as closing window
@@ -2244,7 +2407,10 @@ 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;
@@ -2327,7 +2493,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
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;
LLSD payload;
payload["from_id"] = from_id;
@@ -2393,7 +2559,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
@@ -2854,8 +3020,8 @@ public:
LLInventoryModel::cat_array_t land_cats;
LLInventoryModel::item_array_t land_items;
- uuid_vec_t::iterator it = mCompleteFolders.begin();
- uuid_vec_t::iterator end = mCompleteFolders.end();
+ uuid_vec_t::iterator it = mComplete.begin();
+ uuid_vec_t::iterator end = mComplete.end();
for(; it != end; ++it)
{
gInventory.collectDescendentsIf(
@@ -2926,7 +3092,7 @@ BOOL LLPostTeleportNotifiers::tick()
if(!folders.empty())
{
LLFetchInWelcomeArea* fetcher = new LLFetchInWelcomeArea;
- fetcher->fetchDescendents(folders);
+ fetcher->fetch(folders);
if(fetcher->isEverythingComplete())
{
fetcher->done();
@@ -3152,9 +3318,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);
@@ -4550,11 +4714,12 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
if(boost::regex_match(desc, matches, expr))
{
// Name of full localizable notification string
- // there are three types of this string- with name of receiver and reason of payment,
- // without name and without reason (but not simultaneously)
+ // 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).
// 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
@@ -4575,7 +4740,7 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
std::string reason = std::string(matches[3]);
if (reason.empty())
{
- line = "you_paid_ldollars_no_reason";
+ line = name.empty() ? "you_paid_ldollars_no_info" : "you_paid_ldollars_no_reason";
}
else
{
@@ -5227,7 +5392,7 @@ void process_derez_container(LLMessageSystem *msg, void**)
}
void container_inventory_arrived(LLViewerObject* object,
- InventoryObjectList* inventory,
+ LLInventoryObject::object_list_t* inventory,
S32 serial_num,
void* data)
{
@@ -5247,8 +5412,8 @@ void container_inventory_arrived(LLViewerObject* object,
LLFolderType::FT_NONE,
LLTrans::getString("AcquiredItems"));
- InventoryObjectList::const_iterator it = inventory->begin();
- InventoryObjectList::const_iterator end = inventory->end();
+ LLInventoryObject::object_list_t::const_iterator it = inventory->begin();
+ LLInventoryObject::object_list_t::const_iterator end = inventory->end();
for ( ; it != end; ++it)
{
if ((*it)->getType() != LLAssetType::AT_CATEGORY)
@@ -5284,7 +5449,7 @@ void container_inventory_arrived(LLViewerObject* object,
{
// we're going to get one fake root category as well as the
// one actual object
- InventoryObjectList::iterator it = inventory->begin();
+ LLInventoryObject::object_list_t::iterator it = inventory->begin();
if ((*it)->getType() == LLAssetType::AT_CATEGORY)
{
@@ -5547,9 +5712,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)
@@ -5992,7 +6155,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);