summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Mutavchi <emutavchi@productengine.com>2010-04-12 17:02:16 +0300
committerEugene Mutavchi <emutavchi@productengine.com>2010-04-12 17:02:16 +0300
commit27b457f2ce860f7fc36d15e8792bfa89bca5b93f (patch)
tree896a24879395fbaec9e1cf12dd3a05ef5ccbb21b
parent7e76f26407c6760464b5928b7c6cb8c800a5883f (diff)
Implemented major task EXT-6710(Feature request: Allow drag and drop from Inventory panel to Resident Picker)
- added handling the drag add drop inventory items to resident picker - added "Share" verb button to the inventory panel which opens resident picker - added "Share" menu item to the individual inventory context menu which acts as verb button Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/215/ --HG-- branch : product-engine
-rw-r--r--indra/newview/llavataractions.cpp14
-rw-r--r--indra/newview/llavataractions.h5
-rw-r--r--indra/newview/llfloateravatarpicker.cpp64
-rw-r--r--indra/newview/llfloateravatarpicker.h8
-rw-r--r--indra/newview/llinventorybridge.cpp86
-rw-r--r--indra/newview/llinventorybridge.h2
-rw-r--r--indra/newview/llinventorypanel.cpp2
-rw-r--r--indra/newview/llpanelmaininventory.cpp2
-rw-r--r--indra/newview/llpanelobjectinventory.cpp2
-rw-r--r--indra/newview/llsidepanelinventory.cpp26
-rw-r--r--indra/newview/llsidepanelinventory.h1
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml7
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml24
14 files changed, 241 insertions, 10 deletions
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index c85c72837c..764d54a987 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -35,6 +35,8 @@
#include "llavataractions.h"
+#include "boost/lambda/lambda.hpp" // for lambda::constant
+
#include "llsd.h"
#include "lldarray.h"
#include "llnotifications.h"
@@ -46,6 +48,7 @@
#include "llappviewer.h" // for gLastVersionChannel
#include "llcachename.h"
#include "llcallingcard.h" // for LLAvatarTracker
+#include "llfloateravatarpicker.h" // for LLFloaterAvatarPicker
#include "llfloatergroupinvite.h"
#include "llfloatergroups.h"
#include "llfloaterreg.h"
@@ -54,6 +57,7 @@
#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
#include "llimview.h" // for gIMMgr
#include "llmutelist.h"
+#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llrecentpeople.h"
#include "llsidetray.h"
#include "lltrans.h"
@@ -425,6 +429,16 @@ void LLAvatarActions::share(const LLUUID& id)
}
}
+//static
+void LLAvatarActions::shareWithAvatars()
+{
+ LLFloaterAvatarPicker* picker =
+ LLFloaterAvatarPicker::show(NULL, FALSE, TRUE);
+ picker->setOkBtnEnableCb(boost::lambda::constant(false));
+
+ LLNotificationsUtil::add("ShareNotification");
+}
+
// static
void LLAvatarActions::toggleBlock(const LLUUID& id)
{
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 9d8b4b4e23..d106a83eea 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -114,6 +114,11 @@ public:
static void share(const LLUUID& id);
/**
+ * Share items with the picked avatars.
+ */
+ static void shareWithAvatars();
+
+ /**
* Block/unblock the avatar.
*/
static void toggleBlock(const LLUUID& id);
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 2cb0cdf368..01a699506e 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -38,6 +38,8 @@
#include "llcallingcard.h"
#include "llfocusmgr.h"
#include "llfloaterreg.h"
+#include "llimview.h" // for gIMMgr
+#include "lltooldraganddrop.h" // for LLToolDragAndDrop
#include "llviewercontrol.h"
#include "llworld.h"
@@ -370,6 +372,68 @@ void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)
getChild<LLScrollListCtrl>("Friends")->setAllowMultipleSelection(allow_multiple);
}
+LLScrollListCtrl* LLFloaterAvatarPicker::getActiveList()
+{
+ std::string acvtive_panel_name;
+ LLScrollListCtrl* list = NULL;
+ LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs");
+ if(active_panel)
+ {
+ acvtive_panel_name = active_panel->getName();
+ }
+ if(acvtive_panel_name == "SearchPanel")
+ {
+ list = getChild<LLScrollListCtrl>("SearchResults");
+ }
+ else if(acvtive_panel_name == "NearMePanel")
+ {
+ list = getChild<LLScrollListCtrl>("NearMe");
+ }
+ else if (acvtive_panel_name == "FriendsPanel")
+ {
+ list = getChild<LLScrollListCtrl>("Friends");
+ }
+ return list;
+}
+
+BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type,
+ void *cargo_data, EAcceptance *accept,
+ std::string& tooltip_msg)
+{
+ LLScrollListCtrl* list = getActiveList();
+ if(list)
+ {
+ LLRect rc_list;
+ LLRect rc_point(x,y,x,y);
+ if (localRectToOtherView(rc_point, &rc_list, list))
+ {
+ // Keep selected only one item
+ list->deselectAllItems(TRUE);
+ list->selectItemAt(rc_list.mLeft, rc_list.mBottom, mask);
+ LLScrollListItem* selection = list->getFirstSelected();
+ if (selection)
+ {
+ LLUUID session_id = LLUUID::null;
+ LLUUID dest_agent_id = selection->getUUID();
+ std::string avatar_name = selection->getColumn(0)->getValue().asString();
+ if (dest_agent_id.notNull() && dest_agent_id != gAgentID)
+ {
+ if (drop)
+ {
+ // Start up IM before give the item
+ session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id);
+ }
+ return LLToolDragAndDrop::handleGiveDragAndDrop(dest_agent_id, session_id, drop,
+ cargo_type, cargo_data, accept);
+ }
+ }
+ }
+ }
+ *accept = ACCEPT_NO;
+ return TRUE;
+}
+
// static
void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)
{
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 860f3930ef..e69b814f9f 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -37,6 +37,8 @@
#include <vector>
+class LLScrollListCtrl;
+
class LLFloaterAvatarPicker : public LLFloater
{
public:
@@ -59,6 +61,11 @@ public:
static void processAvatarPickerReply(class LLMessageSystem* msg, void**);
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type,
+ void *cargo_data, EAcceptance *accept,
+ std::string& tooltip_msg);
+
private:
void editKeystroke(class LLLineEditor* caller, void* user_data);
@@ -77,6 +84,7 @@ private:
void find();
void setAllowMultiple(BOOL allow_multiple);
+ LLScrollListCtrl* getActiveList();
virtual void draw();
virtual BOOL handleKeyHere(KEY key, MASK mask);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 943a851c13..76c0d69dda 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -672,6 +672,11 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
items.push_back(std::string("Open"));
items.push_back(std::string("Properties"));
@@ -1031,6 +1036,38 @@ bool LLInvFVBridge::isInOutfitsSidePanel() const
return outfit_panel->isTabPanel(my_panel);
}
+bool LLInvFVBridge::canShare()
+{
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return false;
+ }
+
+ LLViewerInventoryItem *item = model->getItem(mUUID);
+ if (item)
+ {
+ bool allowed = false;
+ allowed = LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item);
+ if (allowed &&
+ !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ allowed = false;
+ }
+ if (allowed &&
+ !item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ allowed = false;
+ }
+ return allowed;
+ }
+
+ LLViewerInventoryCategory* cat = model->getCategory(mUUID);
+
+ // All categories can be given.
+ return cat != NULL;
+}
+
// +=================================================+
// | InventoryFVBridgeBuilder |
// +=================================================+
@@ -2748,7 +2785,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
mDisabledItems.push_back(std::string("Delete System Folder"));
}
-
+
+ mItems.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ mDisabledItems.push_back(std::string("Share"));
+ }
+
hide_context_entries(menu, mItems, mDisabledItems);
}
@@ -3266,6 +3309,12 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
+
items.push_back(std::string("Open"));
items.push_back(std::string("Properties"));
@@ -3354,6 +3403,11 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
items.push_back(std::string("Sound Open"));
items.push_back(std::string("Properties"));
@@ -3400,6 +3454,11 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
items.push_back(std::string("Landmark Open"));
items.push_back(std::string("Properties"));
@@ -3617,6 +3676,11 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
items.push_back(std::string("Open"));
items.push_back(std::string("Properties"));
@@ -3887,6 +3951,11 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
bool is_sidepanel = isInOutfitsSidePanel();
if (!is_sidepanel)
@@ -3945,6 +4014,11 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
items.push_back(std::string("Animation Open"));
items.push_back(std::string("Properties"));
@@ -4221,6 +4295,11 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
bool is_sidepanel = isInOutfitsSidePanel();
if (!is_sidepanel)
@@ -4610,6 +4689,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
can_open = FALSE;
}
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
bool is_sidepanel = isInOutfitsSidePanel();
if (can_open && !is_sidepanel)
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index e7b3785a48..f378d219f6 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -125,6 +125,8 @@ public:
// Allow context menus to be customized for side panel.
bool isInOutfitsSidePanel() const;
+ bool canShare();
+
//--------------------------------------------------------------------
// Convenience functions for adding various common menu options.
//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 92f795462b..6ed7723aff 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -38,6 +38,7 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
+#include "llavataractions.h"
#include "llfloaterinventory.h"
#include "llfloaterreg.h"
#include "llimfloater.h"
@@ -99,6 +100,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));
mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
+ mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
if (mStartFolderString != "")
{
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 8be4c8402c..0ba373c51b 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -34,6 +34,7 @@
#include "llpanelmaininventory.h"
#include "llagent.h"
+#include "llavataractions.h"
#include "lldndbutton.h"
#include "lleconomy.h"
#include "llfilepicker.h"
@@ -116,6 +117,7 @@ LLPanelMainInventory::LLPanelMainInventory()
mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
// Controls
// *TODO: Just use persistant settings for each of these
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index df74c5dd47..3a82cf6f8b 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -46,6 +46,7 @@
#include "roles_constants.h"
#include "llagent.h"
+#include "llavataractions.h"
#include "llcallbacklist.h"
#include "llfloaterbuycurrency.h"
#include "llfloaterreg.h"
@@ -1528,6 +1529,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
+ mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
}
// Destroys the object
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 18e56a9c01..fa543f1371 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -33,6 +33,7 @@
#include "llsidepanelinventory.h"
#include "llagent.h"
+#include "llavataractions.h"
#include "llbutton.h"
#include "llinventorybridge.h"
#include "llinventorypanel.h"
@@ -151,6 +152,7 @@ void LLSidepanelInventory::onInfoButtonClicked()
void LLSidepanelInventory::onShareButtonClicked()
{
+ LLAvatarActions::shareWithAvatars();
}
void LLSidepanelInventory::performActionOnSelection(const std::string &action)
@@ -252,7 +254,9 @@ void LLSidepanelInventory::updateVerbs()
mPlayBtn->setEnabled(FALSE);
mTeleportBtn->setVisible(FALSE);
mTeleportBtn->setEnabled(FALSE);
-
+
+ mShareBtn->setEnabled(canShare());
+
const LLInventoryItem *item = getSelectedItem();
if (!item)
return;
@@ -260,7 +264,6 @@ void LLSidepanelInventory::updateVerbs()
bool is_single_selection = getSelectedCount() == 1;
mInfoBtn->setEnabled(is_single_selection);
- mShareBtn->setEnabled(is_single_selection);
switch(item->getInventoryType())
{
@@ -285,6 +288,25 @@ void LLSidepanelInventory::updateVerbs()
}
}
+bool LLSidepanelInventory::canShare()
+{
+ LLPanelMainInventory* panel_main_inventory =
+ mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
+
+ LLFolderView* root_folder =
+ panel_main_inventory->getActivePanel()->getRootFolder();
+
+ LLFolderViewItem* current_item = root_folder->hasVisibleChildren()
+ ? root_folder->getCurSelectedItem()
+ : NULL;
+
+ LLInvFVBridge* bridge = current_item
+ ? dynamic_cast <LLInvFVBridge*> (current_item->getListener())
+ : NULL;
+
+ return bridge ? bridge->canShare() : false;
+}
+
LLInventoryItem *LLSidepanelInventory::getSelectedItem()
{
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index ee11fb6b54..95eab3571c 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -60,6 +60,7 @@ protected:
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
// "wear", "teleport", etc.
void performActionOnSelection(const std::string &action);
+ bool canShare();
void showItemInfoPanel();
void showTaskInfoPanel();
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 2874151df5..5e1f6b58e8 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -5,6 +5,14 @@
name="Popup"
visible="false">
<menu_item_call
+ label="Share"
+ layout="topleft"
+ name="Share"
+ visible="true">
+ <menu_item_call.on_click
+ function="Inventory.Share" />
+ </menu_item_call>
+ <menu_item_call
label="Buy"
layout="topleft"
name="Task Buy">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 7f0e8891d7..9ee4e13f3c 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5961,6 +5961,13 @@ Selected button can not be shown right now.
The button will be shown when there is enough space for it.
</notification>
+ <notification
+ icon="notifytip.tga"
+ name="ShareNotification"
+ type="notifytip">
+Drag items from inventory onto a person in the resident picker
+ </notification>
+
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index a233d42568..812d94c55f 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -46,17 +46,27 @@
left="0"
name="info_btn"
top="0"
- width="153" />
+ width="102" />
+ <button
+ enabled="true"
+ follows="bottom|left"
+ height="23"
+ label="Share"
+ layout="topleft"
+ left="105"
+ name="share_btn"
+ top="0"
+ width="102" />
<button
enabled="false"
follows="bottom|left"
height="23"
label="Wear"
layout="topleft"
- left="156"
+ left="210"
name="wear_btn"
top="0"
- width="152" />
+ width="102" />
<button
enabled="false"
follows="bottom|left"
@@ -64,19 +74,19 @@
label="Play"
layout="topleft"
name="play_btn"
- left="156"
+ left="210"
top="0"
- width="152" />
+ width="102" />
<button
enabled="false"
follows="bottom|left"
height="23"
label="Teleport"
layout="topleft"
- left="156"
+ left="210"
name="teleport_btn"
top="0"
- width="152" />
+ width="102" />
</panel>
</panel>