Issue 1151: Add share to LLAvatarActions
Syncs LLGiveInventory and LLFloaterAvatarPicker with upstream. Syncsyncsync~ Translators: menu_inventory.xml menu_radar.xml and menu_avs_list.xml: Share notifications.xml: ShareNotification, ShareItemsConfirmation, ShareFolderConfirmation, ItemsShared strings.xml: share_alert
This commit is contained in:
@@ -906,7 +906,6 @@ AIHTTPTimeoutPolicy const* AIHTTPTimeoutPolicy::getTimeoutPolicyByName(std::stri
|
||||
|
||||
// Policy name Policy
|
||||
P(assetReportHandler);
|
||||
P(avatarPickerResponder);
|
||||
P(authHandler);
|
||||
P(avatarNameResponder);
|
||||
P2(baseCapabilitiesComplete, transfer_18s_connect_5s);
|
||||
|
||||
@@ -444,6 +444,7 @@ set(viewer_SOURCE_FILES
|
||||
llscrollingpanelparam.cpp
|
||||
llscrollingpanelparambase.cpp
|
||||
llselectmgr.cpp
|
||||
llshareavatarhandler.cpp
|
||||
llsky.cpp
|
||||
llslurl.cpp
|
||||
llspatialpartition.cpp
|
||||
|
||||
@@ -5084,6 +5084,39 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ContextConeInAlpha</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Cone In Alpha</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>ContextConeOutAlpha</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Cone Out Alpha</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>ContextConeFadeTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Cone Fade Time</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>.08</real>
|
||||
</map>
|
||||
<key>CookiesEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -37,20 +37,26 @@
|
||||
#include "llagent.h"
|
||||
#include "llcallingcard.h" // for LLAvatarTracker
|
||||
#include "llfloateravatarinfo.h"
|
||||
#include "llfloateravatarpicker.h" // for LLFloaterAvatarPicker
|
||||
#include "llfloaterchatterbox.h"
|
||||
#include "llfloatergroupbulkban.h"
|
||||
#include "llfloatergroupinvite.h"
|
||||
#include "llfloatergroups.h"
|
||||
#include "llfloaterwebprofile.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llgiveinventory.h"
|
||||
#include "llgivemoney.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llimview.h" // for gIMMgr
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llmutelist.h"
|
||||
#include "llpanelprofile.h"
|
||||
#include "lltrans.h"
|
||||
#include "llvoiceclient.h"
|
||||
#include "llweb.h"
|
||||
#include "llslurl.h" // IDEVO
|
||||
#include "llpanelmaininventory.h"
|
||||
#include "llavatarname.h"
|
||||
#include "llagentui.h"
|
||||
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0)
|
||||
@@ -569,7 +575,262 @@ void LLAvatarActions::csr(const LLUUID& id)
|
||||
LLWeb::loadURL(url);
|
||||
}
|
||||
|
||||
// Singu TODO: Share inventory code block should live here
|
||||
//static
|
||||
void LLAvatarActions::share(const LLUUID& id)
|
||||
{
|
||||
/*
|
||||
LLSD key;
|
||||
LLFloaterSidePanelContainer::showPanel("inventory", key);
|
||||
LLFloaterReg::showInstance("im_container");
|
||||
*/
|
||||
LLInventoryView::getActiveInventory()->setVisible(true);
|
||||
|
||||
LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
|
||||
|
||||
if (!gIMMgr->hasSession(session_id))
|
||||
{
|
||||
startIM(id);
|
||||
}
|
||||
|
||||
if (gIMMgr->hasSession(session_id))
|
||||
{
|
||||
// we should always get here, but check to verify anyways
|
||||
LLIMMgr::getInstance()->addMessage(session_id, LLUUID::null, SYSTEM_FROM, LLTrans::getString("share_alert"));
|
||||
LLFloaterChatterBox::showInstance(session_id);
|
||||
}
|
||||
}
|
||||
|
||||
namespace action_give_inventory
|
||||
{
|
||||
/**
|
||||
* Returns a pointer to 'Add More' inventory panel of Edit Outfit SP.
|
||||
*
|
||||
static LLInventoryPanel* get_outfit_editor_inventory_panel()
|
||||
{
|
||||
LLPanelOutfitEdit* panel_outfit_edit = dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
|
||||
if (NULL == panel_outfit_edit) return NULL;
|
||||
|
||||
LLInventoryPanel* inventory_panel = panel_outfit_edit->findChild<LLInventoryPanel>("folder_view");
|
||||
return inventory_panel;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @return active inventory panel, or NULL if there's no such panel
|
||||
*/
|
||||
static LLInventoryPanel* get_active_inventory_panel()
|
||||
{
|
||||
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
|
||||
/*if (!active_panel)
|
||||
{
|
||||
active_panel = get_outfit_editor_inventory_panel();
|
||||
}*/
|
||||
|
||||
return active_panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks My Inventory visibility.
|
||||
*/
|
||||
|
||||
static bool is_give_inventory_acceptable()
|
||||
{
|
||||
// check selection in the panel
|
||||
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
|
||||
if (inventory_selected_uuids.empty()) return false; // nothing selected
|
||||
|
||||
bool acceptable = false;
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
// any category can be offered.
|
||||
if (inv_cat)
|
||||
{
|
||||
acceptable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
|
||||
// check if inventory item can be given
|
||||
if (LLGiveInventory::isInventoryGiveAcceptable(inv_item))
|
||||
{
|
||||
acceptable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// there are neither item nor category in inventory
|
||||
acceptable = false;
|
||||
break;
|
||||
}
|
||||
return acceptable;
|
||||
}
|
||||
|
||||
static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)
|
||||
{
|
||||
llassert(inventory_selected_uuids.size() > 0);
|
||||
|
||||
const std::string& separator = LLTrans::getString("words_separator");
|
||||
for (std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); ; )
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
if (NULL != inv_cat)
|
||||
{
|
||||
items_string = inv_cat->getName();
|
||||
break;
|
||||
}
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
|
||||
if (NULL != inv_item)
|
||||
{
|
||||
items_string.append(inv_item->getName());
|
||||
}
|
||||
if(++it == inventory_selected_uuids.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
items_string.append(separator);
|
||||
}
|
||||
}
|
||||
|
||||
struct LLShareInfo : public LLSingleton<LLShareInfo>
|
||||
{
|
||||
std::vector<LLAvatarName> mAvatarNames;
|
||||
uuid_vec_t mAvatarUuids;
|
||||
};
|
||||
|
||||
static void give_inventory_cb(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
// if Cancel pressed
|
||||
if (option == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
|
||||
if (inventory_selected_uuids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
S32 count = LLShareInfo::instance().mAvatarNames.size();
|
||||
bool shared = count && !inventory_selected_uuids.empty();
|
||||
|
||||
// iterate through avatars
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
const LLUUID& avatar_uuid = LLShareInfo::instance().mAvatarUuids[i];
|
||||
|
||||
// We souldn't open IM session, just calculate session ID for logging purpose. See EXT-6710
|
||||
const LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, avatar_uuid);
|
||||
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
|
||||
|
||||
const std::string& separator = LLTrans::getString("words_separator");
|
||||
std::string noncopy_item_names;
|
||||
LLSD noncopy_items = LLSD::emptyArray();
|
||||
// iterate through selected inventory objects
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
if (inv_cat)
|
||||
{
|
||||
if (!LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id, "ItemsShared"))
|
||||
{
|
||||
shared = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
|
||||
if (!inv_item->getPermissions().allowCopyBy(gAgentID))
|
||||
{
|
||||
if (!noncopy_item_names.empty())
|
||||
{
|
||||
noncopy_item_names.append(separator);
|
||||
}
|
||||
noncopy_item_names.append(inv_item->getName());
|
||||
noncopy_items.append(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id))
|
||||
{
|
||||
shared = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (noncopy_items.beginArray() != noncopy_items.endArray())
|
||||
{
|
||||
LLSD substitutions;
|
||||
substitutions["ITEMS"] = noncopy_item_names;
|
||||
LLSD payload;
|
||||
payload["agent_id"] = avatar_uuid;
|
||||
payload["items"] = noncopy_items;
|
||||
payload["success_notification"] = "ItemsShared";
|
||||
LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload,
|
||||
&LLGiveInventory::handleCopyProtectedItem);
|
||||
shared = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shared)
|
||||
{
|
||||
if (LLFloaterAvatarPicker::instanceExists()) LLFloaterAvatarPicker::instance().close();
|
||||
LLNotificationsUtil::add("ItemsShared");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs "give inventory" operations for provided avatars.
|
||||
*
|
||||
* Sends one requests to give all selected inventory items for each passed avatar.
|
||||
* Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other.
|
||||
*
|
||||
* @param avatar_names - avatar names request to be sent.
|
||||
* @param avatar_uuids - avatar names request to be sent.
|
||||
*/
|
||||
static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names)
|
||||
{
|
||||
llassert(avatar_names.size() == avatar_uuids.size());
|
||||
|
||||
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
|
||||
if (inventory_selected_uuids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string residents;
|
||||
LLAvatarActions::buildResidentsString(avatar_names, residents);
|
||||
|
||||
std::string items;
|
||||
build_items_string(inventory_selected_uuids, items);
|
||||
|
||||
int folders_count = 0;
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
|
||||
//traverse through selected inventory items and count folders among them
|
||||
for ( ; it != inventory_selected_uuids.end() && folders_count <=1 ; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
if (NULL != inv_cat)
|
||||
{
|
||||
folders_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// EXP-1599
|
||||
// In case of sharing multiple folders, make the confirmation
|
||||
// dialog contain a warning that only one folder can be shared at a time.
|
||||
std::string notification = (folders_count > 1) ? "ShareFolderConfirmation" : "ShareItemsConfirmation";
|
||||
LLSD substitutions;
|
||||
substitutions["RESIDENTS"] = residents;
|
||||
substitutions["ITEMS"] = items;
|
||||
LLShareInfo::instance().mAvatarNames = avatar_names;
|
||||
LLShareInfo::instance().mAvatarUuids = avatar_uuids;
|
||||
LLNotificationsUtil::add(notification, substitutions, LLSD(), &give_inventory_cb);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string)
|
||||
@@ -611,7 +872,118 @@ void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::
|
||||
}
|
||||
}
|
||||
|
||||
// Singu TODO: Share inventory code block should live here, too
|
||||
//static
|
||||
std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
|
||||
{
|
||||
LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
|
||||
return active_panel ? active_panel->getRootFolder()->getSelectionList() : std::set<LLUUID>();
|
||||
/*std::set<LLFolderViewItem*> inventory_selected;
|
||||
|
||||
LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
|
||||
if (active_panel)
|
||||
{
|
||||
inventory_selected= active_panel->getRootFolder()->getSelectionList();
|
||||
}
|
||||
|
||||
if (inventory_selected.empty())
|
||||
{
|
||||
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
|
||||
if (sidepanel_inventory)
|
||||
{
|
||||
inventory_selected= sidepanel_inventory->getInboxSelectionList();
|
||||
}
|
||||
}
|
||||
|
||||
std::set<LLUUID> inventory_selected_uuids;
|
||||
for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
inventory_selected_uuids.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
|
||||
}
|
||||
return inventory_selected_uuids;*/
|
||||
}
|
||||
|
||||
//static
|
||||
void LLAvatarActions::shareWithAvatars(LLView * panel)
|
||||
{
|
||||
using namespace action_give_inventory;
|
||||
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(panel);
|
||||
LLFloaterAvatarPicker* picker =
|
||||
LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName());
|
||||
if (!picker)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
|
||||
picker->openFriendsTab();
|
||||
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(picker);
|
||||
}
|
||||
LLNotificationsUtil::add("ShareNotification");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NULL*/)
|
||||
{
|
||||
using namespace action_give_inventory;
|
||||
|
||||
if (!inv_panel)
|
||||
{
|
||||
LLInventoryPanel* active_panel = get_active_inventory_panel();
|
||||
if (!active_panel) return false;
|
||||
inv_panel = active_panel;
|
||||
}
|
||||
|
||||
// check selection in the panel
|
||||
LLFolderView* root_folder = inv_panel->getRootFolder();
|
||||
if (!root_folder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const std::set<LLUUID> inventory_selected = root_folder->getSelectionList();
|
||||
if (inventory_selected.empty()) return false; // nothing selected
|
||||
|
||||
bool can_share = true;
|
||||
const LLUUID& trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); // <alchemy/>
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected.begin();
|
||||
const std::set<LLUUID>::const_iterator it_end = inventory_selected.end();
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
const LLUUID id(*it);
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(id);
|
||||
// any category can be offered.
|
||||
if (inv_cat && !gInventory.isObjectDescendentOf(inv_cat->getUUID(), trash_id)) // <alchemy/>
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if inventory item can be given
|
||||
else if (!inv_cat && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) // Singu Note: These three ifs comprise the item half of LLInvFVBridge::canShare, which LL calls here.
|
||||
if (LLViewerInventoryItem* item = gInventory.getItem(id))
|
||||
if (LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item) && LLGiveInventory::isInventoryGiveAcceptable(item))
|
||||
/*
|
||||
LLFolderViewItem* item = *it;
|
||||
if (!item) return false;
|
||||
LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getViewModelItem());
|
||||
if (bridge && bridge->canShare())
|
||||
*/
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// there are neither item nor category in inventory
|
||||
can_share = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return can_share;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::toggleBlock(const LLUUID& id)
|
||||
@@ -898,6 +1270,21 @@ bool LLAvatarActions::canBlock(const LLUUID& id)
|
||||
return !is_self && !is_linden;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLAvatarActions::isAgentMappable(const LLUUID& agent_id)
|
||||
{
|
||||
const LLRelationship* buddy_info = NULL;
|
||||
bool is_friend = LLAvatarActions::isFriend(agent_id);
|
||||
|
||||
if (is_friend)
|
||||
buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
|
||||
|
||||
return (buddy_info &&
|
||||
buddy_info->isOnline() &&
|
||||
buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
|
||||
);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::copyUUIDs(const uuid_vec_t& ids)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#define LL_LLAVATARACTIONS_H
|
||||
|
||||
class LLAvatarName;
|
||||
class LLInventoryPanel;
|
||||
class LLFloater;
|
||||
class LLView;
|
||||
|
||||
/**
|
||||
* Friend-related actions (add, remove, offer teleport, etc)
|
||||
@@ -108,6 +110,16 @@ public:
|
||||
static void teleportRequest(const LLUUID& id);
|
||||
static void teleport_request_callback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/**
|
||||
* Share items with the avatar.
|
||||
*/
|
||||
static void share(const LLUUID& id);
|
||||
|
||||
/**
|
||||
* Share items with the picked avatars.
|
||||
*/
|
||||
static void shareWithAvatars(LLView * panel);
|
||||
|
||||
/**
|
||||
* Block/unblock the avatar.
|
||||
*/
|
||||
@@ -190,6 +202,20 @@ public:
|
||||
*/
|
||||
static bool canOfferTeleport(const uuid_vec_t& ids);
|
||||
|
||||
/**
|
||||
* Checks whether all items selected in the given inventory panel can be shared
|
||||
*
|
||||
* @param inv_panel Inventory panel to get selection from. If NULL, the active inventory panel is used.
|
||||
*
|
||||
* @return false if the selected items cannot be shared or the active inventory panel cannot be obtained
|
||||
*/
|
||||
static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL);
|
||||
|
||||
/**
|
||||
* Checks whether agent is mappable
|
||||
*/
|
||||
static bool isAgentMappable(const LLUUID& agent_id);
|
||||
|
||||
/**
|
||||
* Builds a string of residents' display names separated by "words_separator" string.
|
||||
*
|
||||
@@ -206,6 +232,8 @@ public:
|
||||
*/
|
||||
static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string);
|
||||
|
||||
static std::set<LLUUID> getInventorySelectedUUIDs();
|
||||
|
||||
/**
|
||||
* Copy the selected avatar's UUID to clipboard
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "llscrolllistitem.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lldraghandle.h"
|
||||
#include "message.h"
|
||||
|
||||
|
||||
@@ -58,17 +59,21 @@ static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
|
||||
|
||||
LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
|
||||
BOOL allow_multiple,
|
||||
BOOL closeOnSelect)
|
||||
BOOL closeOnSelect,
|
||||
BOOL skip_agent,
|
||||
const std::string& name,
|
||||
LLView * frustumOrigin)
|
||||
{
|
||||
// *TODO: Use a key to allow this not to be an effective singleton
|
||||
|
||||
LLFloaterAvatarPicker* floater = getInstance();
|
||||
LLFloaterAvatarPicker* floater =
|
||||
getInstance();
|
||||
floater->open();
|
||||
|
||||
floater->mSelectionCallback = callback;
|
||||
floater->setAllowMultiple(allow_multiple);
|
||||
floater->mNearMeListComplete = FALSE;
|
||||
floater->mCloseOnSelect = closeOnSelect;
|
||||
floater->mExcludeAgentFromSearchResults = skip_agent;
|
||||
|
||||
if (!closeOnSelect)
|
||||
{
|
||||
@@ -79,6 +84,11 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
|
||||
floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
|
||||
}
|
||||
|
||||
if(frustumOrigin)
|
||||
{
|
||||
floater->mFrustumOrigin = frustumOrigin->getHandle();
|
||||
}
|
||||
|
||||
return floater;
|
||||
}
|
||||
|
||||
@@ -87,10 +97,18 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker()
|
||||
: LLFloater(),
|
||||
mNumResultsReturned(0),
|
||||
mNearMeListComplete(FALSE),
|
||||
mCloseOnSelect(FALSE)
|
||||
mCloseOnSelect(FALSE),
|
||||
mContextConeOpacity (0.f),
|
||||
mContextConeInAlpha(0.f),
|
||||
mContextConeOutAlpha(0.f),
|
||||
mContextConeFadeTime(0.f)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml", NULL);
|
||||
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
|
||||
}
|
||||
|
||||
BOOL LLFloaterAvatarPicker::postBuild()
|
||||
@@ -188,11 +206,10 @@ static void addAvatarUUID(const LLUUID av_id, uuid_vec_t& avatar_ids, std::vecto
|
||||
|
||||
static void getSelectedAvatarData(const LLUICtrl* from, uuid_vec_t& avatar_ids, std::vector<LLAvatarName>& avatar_names)
|
||||
{
|
||||
const LLScrollListCtrl* list = dynamic_cast<const LLScrollListCtrl*>(from);
|
||||
if(list)
|
||||
if(const LLScrollListCtrl* list = dynamic_cast<const LLScrollListCtrl*>(from))
|
||||
{
|
||||
std::vector<LLScrollListItem*> items = list->getAllSelected();
|
||||
for (std::vector<LLScrollListItem*>::iterator iter = items.begin(); iter != items.end(); ++iter)
|
||||
const std::vector<LLScrollListItem*> items = list->getAllSelected();
|
||||
for (std::vector<LLScrollListItem*>::const_iterator iter = items.begin(); iter != items.end(); ++iter)
|
||||
{
|
||||
addAvatarUUID((*iter)->getUUID(), avatar_ids, avatar_names);
|
||||
}
|
||||
@@ -366,8 +383,67 @@ void LLFloaterAvatarPicker::populateFriend()
|
||||
friends_scroller->sortByColumnIndex(0, TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterAvatarPicker::drawFrustum()
|
||||
{
|
||||
if (mFrustumOrigin.get())
|
||||
{
|
||||
LLView * frustumOrigin = mFrustumOrigin.get();
|
||||
LLRect origin_rect;
|
||||
frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
|
||||
// draw context cone connecting color picker with color swatch in parent floater
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterAvatarPicker::draw()
|
||||
{
|
||||
drawFrustum();
|
||||
|
||||
// sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars).
|
||||
// lets check this via mOkButtonValidateSignal callback periodically.
|
||||
static LLFrameTimer timer;
|
||||
@@ -411,19 +487,20 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
extern AIHTTPTimeoutPolicy avatarPickerResponder_timeout;
|
||||
class LLAvatarPickerResponder : public LLHTTPClient::ResponderWithCompleted
|
||||
{
|
||||
LOG_CLASS(LLAvatarPickerResponder);
|
||||
public:
|
||||
LLUUID mQueryID;
|
||||
|
||||
LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { }
|
||||
|
||||
/*virtual*/ void httpCompleted(void)
|
||||
protected:
|
||||
/*virtual*/ void httpCompleted()
|
||||
{
|
||||
//std::ostringstream ss;
|
||||
//LLSDSerialize::toPrettyXML(mContent, ss);
|
||||
//llinfos << ss.str() << llendl;
|
||||
//LLSDSerialize::toPrettyXML(content, ss);
|
||||
//LL_INFOS() << ss.str() << LL_ENDL;
|
||||
|
||||
// in case of invalid characters, the avatar picker returns a 400
|
||||
// just set it to process so it displays 'not found'
|
||||
@@ -436,12 +513,11 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "avatar picker failed " << mStatus << " reason " << mReason << llendl;
|
||||
llwarns << "avatar picker failed " << dumpResponse() << LL_ENDL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return avatarPickerResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "LLAvatarPickerResponder"; }
|
||||
};
|
||||
|
||||
@@ -460,9 +536,7 @@ void LLFloaterAvatarPicker::find()
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
url = region->getCapability("AvatarPickerSearch");
|
||||
// Prefer use of capabilities to search on both SLID and display name
|
||||
// but allow display name search to be manually turned off for test
|
||||
if (!url.empty()
|
||||
&& LLAvatarNameCache::useDisplayNames())
|
||||
if (!url.empty())
|
||||
{
|
||||
// capability urls don't end in '/', but we need one to parse
|
||||
// query parameters correctly
|
||||
@@ -471,6 +545,7 @@ void LLFloaterAvatarPicker::find()
|
||||
url += "/";
|
||||
}
|
||||
url += "?page_size=100&names=";
|
||||
std::replace(text.begin(), text.end(), '.', ' ');
|
||||
url += LLURI::escape(text);
|
||||
llinfos << "avatar picker " << url << llendl;
|
||||
LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID));
|
||||
@@ -595,8 +670,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
|
||||
// Not for us
|
||||
if (agent_id != gAgent.getID()) return;
|
||||
|
||||
if(!instanceExists())
|
||||
return;
|
||||
if (!instanceExists()) return;
|
||||
LLFloaterAvatarPicker* floater = getInstance();
|
||||
|
||||
// floater is closed or these are not results from our last request
|
||||
@@ -620,35 +694,38 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
|
||||
msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i);
|
||||
msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i);
|
||||
msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, last_name, i);
|
||||
|
||||
std::string avatar_name;
|
||||
if (avatar_id.isNull())
|
||||
{
|
||||
LLStringUtil::format_map_t map;
|
||||
map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
|
||||
avatar_name = floater->getString("not_found", map);
|
||||
search_results->setEnabled(FALSE);
|
||||
floater->getChildView("ok_btn")->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar_name = LLCacheName::buildFullName(first_name, last_name);
|
||||
search_results->setEnabled(TRUE);
|
||||
found_one = TRUE;
|
||||
|
||||
LLAvatarName av_name;
|
||||
av_name.mLegacyFirstName = first_name;
|
||||
av_name.mLegacyLastName = last_name;
|
||||
av_name.mDisplayName = avatar_name;
|
||||
const LLUUID& agent_id = avatar_id;
|
||||
sAvatarNameMap[agent_id] = av_name;
|
||||
if (avatar_id != agent_id || !floater->isExcludeAgentFromSearchResults()) // exclude agent from search results?
|
||||
{
|
||||
std::string avatar_name;
|
||||
if (avatar_id.isNull())
|
||||
{
|
||||
LLStringUtil::format_map_t map;
|
||||
map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
|
||||
avatar_name = floater->getString("not_found", map);
|
||||
search_results->setEnabled(FALSE);
|
||||
floater->getChildView("ok_btn")->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar_name = LLCacheName::buildFullName(first_name, last_name);
|
||||
search_results->setEnabled(TRUE);
|
||||
found_one = TRUE;
|
||||
|
||||
LLAvatarName av_name;
|
||||
av_name.mLegacyFirstName = first_name;
|
||||
av_name.mLegacyLastName = last_name;
|
||||
av_name.mDisplayName = avatar_name;
|
||||
const LLUUID& agent_id = avatar_id;
|
||||
sAvatarNameMap[agent_id] = av_name;
|
||||
|
||||
}
|
||||
LLSD element;
|
||||
element["id"] = avatar_id; // value
|
||||
element["columns"][0]["column"] = "name";
|
||||
element["columns"][0]["value"] = avatar_name;
|
||||
search_results->addElement(element);
|
||||
}
|
||||
LLSD element;
|
||||
element["id"] = avatar_id; // value
|
||||
element["columns"][0]["column"] = "name";
|
||||
element["columns"][0]["value"] = avatar_name;
|
||||
search_results->addElement(element);
|
||||
}
|
||||
|
||||
if (found_one)
|
||||
@@ -690,18 +767,21 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD&
|
||||
for ( ; it != agents.endArray(); ++it)
|
||||
{
|
||||
const LLSD& row = *it;
|
||||
item["id"] = row["id"];
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "name";
|
||||
columns[0]["value"] = row["display_name"];
|
||||
columns[1]["column"] = "username";
|
||||
columns[1]["value"] = row["username"];
|
||||
search_results->addElement(item);
|
||||
if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
|
||||
{
|
||||
item["id"] = row["id"];
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "name";
|
||||
columns[0]["value"] = row["display_name"];
|
||||
columns[1]["column"] = "username";
|
||||
columns[1]["value"] = row["username"];
|
||||
search_results->addElement(item);
|
||||
|
||||
// add the avatar name to our list
|
||||
LLAvatarName avatar_name;
|
||||
avatar_name.fromLLSD(row);
|
||||
sAvatarNameMap[row["id"].asUUID()] = avatar_name;
|
||||
// add the avatar name to our list
|
||||
LLAvatarName avatar_name;
|
||||
avatar_name.fromLLSD(row);
|
||||
sAvatarNameMap[row["id"].asUUID()] = avatar_name;
|
||||
}
|
||||
}
|
||||
|
||||
getChildView("ok_btn")->setEnabled(true);
|
||||
@@ -713,10 +793,10 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD&
|
||||
|
||||
void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller)
|
||||
{
|
||||
if(caller->getName() == "Edit")
|
||||
if (caller->getName() == "Edit")
|
||||
getChildView("Find")->setEnabled(caller->getText().size() >= 3);
|
||||
else
|
||||
childSetEnabled("Select", caller->getValue().asUUID().notNull());
|
||||
getChildView("Select")->setEnabled(caller->getValue().asUUID().notNull());
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
||||
@@ -45,11 +45,15 @@ public:
|
||||
// Call this to select an avatar.
|
||||
static LLFloaterAvatarPicker* show(select_callback_t callback,
|
||||
BOOL allow_multiple = FALSE,
|
||||
BOOL closeOnSelect = FALSE);
|
||||
BOOL closeOnSelect = FALSE,
|
||||
BOOL skip_agent = FALSE,
|
||||
const std::string& name = "",
|
||||
LLView * frustumOrigin = NULL);
|
||||
|
||||
// do not call these directly
|
||||
LLFloaterAvatarPicker();
|
||||
virtual ~LLFloaterAvatarPicker();
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
||||
void setOkBtnEnableCb(validate_callback_t cb);
|
||||
@@ -63,6 +67,7 @@ public:
|
||||
std::string& tooltip_msg);
|
||||
|
||||
void openFriendsTab();
|
||||
BOOL isExcludeAgentFromSearchResults() { return mExcludeAgentFromSearchResults; }
|
||||
|
||||
private:
|
||||
void editKeystroke(class LLLineEditor* caller);
|
||||
@@ -84,6 +89,7 @@ private:
|
||||
void setAllowMultiple(BOOL allow_multiple);
|
||||
LLScrollListCtrl* getActiveList();
|
||||
|
||||
void drawFrustum();
|
||||
virtual void draw();
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
|
||||
@@ -91,6 +97,12 @@ private:
|
||||
int mNumResultsReturned;
|
||||
BOOL mNearMeListComplete;
|
||||
BOOL mCloseOnSelect;
|
||||
BOOL mExcludeAgentFromSearchResults;
|
||||
LLHandle <LLView> mFrustumOrigin;
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
|
||||
validate_signal_t mOkButtonValidateSignal;
|
||||
select_callback_t mSelectionCallback;
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
virtual void pasteLinkFromClipboard() = 0;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
|
||||
virtual BOOL isUpToDate() const = 0;
|
||||
virtual BOOL hasChildren() const = 0;
|
||||
virtual bool hasChildren() const = 0;
|
||||
virtual LLInventoryType::EType getInventoryType() const = 0;
|
||||
virtual void performAction(LLInventoryModel* model, std::string action) = 0;
|
||||
virtual LLWearableType::EType getWearableType() const = 0;
|
||||
|
||||
@@ -231,23 +231,25 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
|
||||
bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
|
||||
const LLInventoryCategory* cat,
|
||||
const LLUUID& im_session_id)
|
||||
const LLUUID& im_session_id,
|
||||
const std::string& notification_name)
|
||||
|
||||
{
|
||||
if (!cat)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
llinfos << "LLGiveInventory::giveInventoryCategory() - "
|
||||
<< cat->getUUID() << llendl;
|
||||
|
||||
if (!isAgentAvatarValid())
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool give_successful = true;
|
||||
// Test out how many items are being given.
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
@@ -270,24 +272,24 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
|
||||
if(!complete)
|
||||
{
|
||||
LLNotificationsUtil::add("IncompleteInventory");
|
||||
return;
|
||||
give_successful = false;
|
||||
}
|
||||
count = items.count() + cats.count();
|
||||
if(count > MAX_ITEMS)
|
||||
{
|
||||
LLNotificationsUtil::add("TooManyItems");
|
||||
return;
|
||||
give_successful = false;
|
||||
}
|
||||
else if(count == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("NoItems");
|
||||
return;
|
||||
give_successful = false;
|
||||
}
|
||||
else
|
||||
else if (give_successful)
|
||||
{
|
||||
if(0 == giveable.countNoCopy())
|
||||
{
|
||||
LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
|
||||
give_successful = LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -296,9 +298,16 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
|
||||
LLSD payload;
|
||||
payload["agent_id"] = to_agent;
|
||||
payload["folder_id"] = cat->getUUID();
|
||||
if (!notification_name.empty())
|
||||
{
|
||||
payload["success_notification"] = notification_name;
|
||||
}
|
||||
LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
|
||||
give_successful = false;
|
||||
}
|
||||
}
|
||||
|
||||
return give_successful;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -377,6 +386,10 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
|
||||
give_successful = false;
|
||||
}
|
||||
}
|
||||
if (give_successful && notification["payload"]["success_notification"].isDefined())
|
||||
{
|
||||
LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
|
||||
}
|
||||
break;
|
||||
|
||||
default: // no, cancel, whatever, who cares, not yes.
|
||||
@@ -445,13 +458,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
LLInventoryCategory* cat = NULL;
|
||||
bool give_successful = true;
|
||||
switch(option)
|
||||
{
|
||||
case 0: // "Yes"
|
||||
cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
|
||||
if(cat)
|
||||
{
|
||||
LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
|
||||
give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
|
||||
cat);
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
@@ -467,29 +481,36 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
|
||||
gInventory.deleteObject(items.get(i)->getUUID());
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
|
||||
if (give_successful && notification["payload"]["success_notification"].isDefined())
|
||||
{
|
||||
LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("CannotGiveCategory");
|
||||
give_successful = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default: // no, cancel, whatever, who cares, not yes.
|
||||
LLNotificationsUtil::add("TransactionCancelled");
|
||||
give_successful = false;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
return give_successful;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
const LLInventoryCategory* cat,
|
||||
const LLUUID& im_session_id)
|
||||
|
||||
{
|
||||
if(!cat)
|
||||
if (!cat)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
|
||||
<< cat->getUUID() << llendl;
|
||||
@@ -504,6 +525,7 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
giveable);
|
||||
|
||||
bool give_successful = true;
|
||||
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
|
||||
// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
|
||||
// 66. I've cut it down a bit from there to give some pad.
|
||||
@@ -511,12 +533,12 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
if(count > MAX_ITEMS)
|
||||
{
|
||||
LLNotificationsUtil::add("TooManyItems");
|
||||
return;
|
||||
give_successful = false;
|
||||
}
|
||||
else if(count == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("NoItems");
|
||||
return;
|
||||
give_successful = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -589,6 +611,8 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
|
||||
logInventoryOffer(to_agent, im_session_id);
|
||||
}
|
||||
|
||||
return give_successful;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
@@ -62,9 +62,11 @@ public:
|
||||
/**
|
||||
* Gives passed inventory category to specified avatar in specified session.
|
||||
*/
|
||||
static void doGiveInventoryCategory(const LLUUID& to_agent,
|
||||
static bool doGiveInventoryCategory(const LLUUID& to_agent,
|
||||
const LLInventoryCategory* item,
|
||||
const LLUUID &session_id = LLUUID::null);
|
||||
const LLUUID &session_id = LLUUID::null,
|
||||
const std::string& notification = std::string());
|
||||
|
||||
// give inventory item functionality
|
||||
static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
|
||||
|
||||
@@ -84,7 +86,7 @@ private:
|
||||
|
||||
// give inventory category functionality
|
||||
static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
|
||||
static void commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
static bool commitGiveInventoryCategory(const LLUUID& to_agent,
|
||||
const LLInventoryCategory* cat,
|
||||
const LLUUID &im_session_id = LLUUID::null);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llfloaterperms.h"
|
||||
#include "llfoldervieweventlistener.h"
|
||||
#include "llimview.h"
|
||||
@@ -627,6 +628,7 @@ void init_object_inventory_panel_actions(LLPanelObjectInventory *panel)
|
||||
|
||||
void init_inventory_actions(LLInventoryView *floater)
|
||||
{
|
||||
(new LLDoToSelectedFloater())->registerListener(floater, "Inventory.DoToSelected");
|
||||
(new LLDoToSelectedFloater())->registerListener(floater, "Inventory.DoToSelected");
|
||||
(new LLCloseAllFoldersFloater())->registerListener(floater, "Inventory.CloseAllFolders");
|
||||
(new LLEmptyTrashFloater())->registerListener(floater, "Inventory.EmptyTrash");
|
||||
@@ -640,6 +642,15 @@ void init_inventory_actions(LLInventoryView *floater)
|
||||
(new LLSetSearchType())->registerListener(floater, "Inventory.SetSearchType");
|
||||
}
|
||||
|
||||
class LLShare : public inventory_panel_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
LLAvatarActions::shareWithAvatars(mPtr);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void init_inventory_panel_actions(LLInventoryPanel *panel)
|
||||
{
|
||||
(new LLDoToSelected())->registerListener(panel, "Inventory.DoToSelected");
|
||||
@@ -649,4 +660,5 @@ void init_inventory_panel_actions(LLInventoryPanel *panel)
|
||||
(new LLEmptyLostAndFound())->registerListener(panel, "Inventory.EmptyLostAndFound");
|
||||
(new LLDoCreate())->registerListener(panel, "Inventory.DoCreate");
|
||||
(new LLBeginIMSession())->registerListener(panel, "Inventory.BeginIMSession");
|
||||
(new LLShare())->registerListener(panel, "Inventory.Share");
|
||||
}
|
||||
|
||||
@@ -804,6 +804,12 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Share"));
|
||||
if (!canShare())
|
||||
{
|
||||
disabled_items.push_back(std::string("Share"));
|
||||
}
|
||||
|
||||
addOpenRightClickMenuOption(items);
|
||||
items.push_back(std::string("Properties"));
|
||||
|
||||
@@ -1235,6 +1241,33 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
|
||||
}
|
||||
}
|
||||
|
||||
bool LLInvFVBridge::canShare() const
|
||||
{
|
||||
bool can_share = false;
|
||||
|
||||
if (!isItemInTrash() && isAgentInventory())
|
||||
{
|
||||
const LLInventoryModel* model = getInventoryModel();
|
||||
if (model)
|
||||
{
|
||||
const LLViewerInventoryItem *item = model->getItem(mUUID);
|
||||
if (item)
|
||||
{
|
||||
if (LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item))
|
||||
{
|
||||
can_share = LLGiveInventory::isInventoryGiveAcceptable(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Categories can be given.
|
||||
can_share = (model->getCategory(mUUID) != NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return can_share;
|
||||
}
|
||||
|
||||
bool LLInvFVBridge::canListOnMarketplace() const
|
||||
{
|
||||
@@ -2613,8 +2646,17 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
|
||||
LLInventoryModel::item_array_t* item_array;
|
||||
gInventory.getDirectDescendentsOf(*current_folder, cat_array, item_array);
|
||||
|
||||
S32 item_count = item_array->count();
|
||||
S32 cat_count = cat_array->count();
|
||||
S32 item_count(0);
|
||||
if (item_array)
|
||||
{
|
||||
item_count = item_array->count();
|
||||
}
|
||||
|
||||
S32 cat_count(0);
|
||||
if (cat_array)
|
||||
{
|
||||
cat_count = cat_array->count();
|
||||
}
|
||||
|
||||
// Move to next if current folder empty
|
||||
if ((item_count == 0) && (cat_count == 0))
|
||||
@@ -3387,6 +3429,15 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
|
||||
{
|
||||
mDisabledItems.push_back(std::string("Delete System Folder"));
|
||||
}
|
||||
|
||||
if (!isOutboxFolder() && !isItemInTrash()) // <alchemy/>
|
||||
{
|
||||
mItems.push_back(std::string("Share"));
|
||||
if (!canShare())
|
||||
{
|
||||
mDisabledItems.push_back(std::string("Share"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
|
||||
@@ -3528,7 +3579,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
menu.arrangeAndClear();
|
||||
}
|
||||
|
||||
BOOL LLFolderBridge::hasChildren() const
|
||||
bool LLFolderBridge::hasChildren() const
|
||||
{
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
if(!model) return FALSE;
|
||||
@@ -4321,6 +4372,12 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Share"));
|
||||
if (!canShare())
|
||||
{
|
||||
disabled_items.push_back(std::string("Share"));
|
||||
}
|
||||
|
||||
addOpenRightClickMenuOption(items);
|
||||
items.push_back(std::string("Properties"));
|
||||
|
||||
@@ -4412,6 +4469,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"));
|
||||
|
||||
@@ -4465,6 +4527,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"));
|
||||
|
||||
@@ -4734,6 +4801,11 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Share"));
|
||||
if (!canShare())
|
||||
{
|
||||
disabled_items.push_back(std::string("Share"));
|
||||
}
|
||||
/* Singu Note: Multiple profiles get opened in a multifloater
|
||||
if ((flags & FIRST_SELECTED_ITEM) == 0)
|
||||
{
|
||||
@@ -5039,6 +5111,11 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Share"));
|
||||
if (!canShare())
|
||||
{
|
||||
disabled_items.push_back(std::string("Share"));
|
||||
}
|
||||
|
||||
addOpenRightClickMenuOption(items);
|
||||
items.push_back(std::string("Properties"));
|
||||
@@ -5094,6 +5171,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"));
|
||||
|
||||
@@ -5411,6 +5493,12 @@ void LLObjectBridge::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("Properties"));
|
||||
|
||||
getClipboardEntries(true, items, disabled_items, flags);
|
||||
@@ -5819,6 +5907,12 @@ 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"));
|
||||
}
|
||||
|
||||
if (can_open)
|
||||
{
|
||||
addOpenRightClickMenuOption(items);
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
U32 flags = 0x00);
|
||||
virtual ~LLInvFVBridge() {}
|
||||
|
||||
bool canShare() const;
|
||||
bool canListOnMarketplace() const;
|
||||
bool canListOnMarketplaceNow() const;
|
||||
|
||||
@@ -121,6 +122,8 @@ public:
|
||||
void* cargo_data) { return FALSE; }
|
||||
virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
|
||||
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
|
||||
virtual LLInventoryObject* getInventoryObject() const;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Convenience functions for adding various common menu options.
|
||||
@@ -137,16 +140,15 @@ protected:
|
||||
protected:
|
||||
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
|
||||
|
||||
LLInventoryObject* getInventoryObject() const;
|
||||
LLInventoryModel* getInventoryModel() const;
|
||||
|
||||
BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
|
||||
BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?
|
||||
|
||||
BOOL isAgentInventory() const; // false if lost or in the inventory library
|
||||
BOOL isCOFFolder() const; // true if COF or descendent of
|
||||
BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
|
||||
BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
|
||||
BOOL isCOFFolder() const; // true if COF or descendant of
|
||||
BOOL isInboxFolder() const; // true if COF or descendant of marketplace inbox
|
||||
BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox
|
||||
BOOL isOutboxFolderDirectParent() const;
|
||||
const LLUUID getOutboxFolder() const;
|
||||
|
||||
@@ -165,7 +167,7 @@ protected:
|
||||
LLFolderView* mRoot;
|
||||
const LLUUID mUUID; // item id
|
||||
LLInventoryType::EType mInvType;
|
||||
BOOL mIsLink;
|
||||
bool mIsLink;
|
||||
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
|
||||
};
|
||||
|
||||
@@ -213,7 +215,7 @@ public:
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual BOOL removeItem();
|
||||
virtual BOOL isItemCopyable() const;
|
||||
virtual BOOL hasChildren() const { return FALSE; }
|
||||
virtual bool hasChildren() const { return FALSE; }
|
||||
virtual BOOL isUpToDate() const { return TRUE; }
|
||||
|
||||
static void showFloaterImagePreview(LLInventoryItem* item, AIFilePicker* filepicker);
|
||||
@@ -235,8 +237,8 @@ class LLFolderBridge : public LLInvFVBridge
|
||||
public:
|
||||
LLFolderBridge(LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, root, uuid),
|
||||
const LLUUID& uuid)
|
||||
: LLInvFVBridge(inventory, root, uuid),
|
||||
mCallingCards(FALSE),
|
||||
mWearables(FALSE)
|
||||
{}
|
||||
@@ -265,7 +267,7 @@ public:
|
||||
virtual void pasteFromClipboard(bool only_copies = false);
|
||||
virtual void pasteLinkFromClipboard();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual BOOL hasChildren() const;
|
||||
virtual bool hasChildren() const;
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
@@ -326,8 +328,9 @@ public:
|
||||
static void staticFolderOptionsMenu();
|
||||
|
||||
private:
|
||||
BOOL mCallingCards;
|
||||
BOOL mWearables;
|
||||
|
||||
bool mCallingCards;
|
||||
bool mWearables;
|
||||
menuentry_vec_t mItems;
|
||||
menuentry_vec_t mDisabledItems;
|
||||
LLRootHandle<LLFolderBridge> mHandle;
|
||||
@@ -405,7 +408,6 @@ protected:
|
||||
LLCallingCardObserver* mObserver;
|
||||
};
|
||||
|
||||
|
||||
class LLNotecardBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
@@ -436,7 +438,6 @@ public:
|
||||
static void playGesture(const LLUUID& item_id);
|
||||
};
|
||||
|
||||
|
||||
class LLAnimationBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
@@ -450,7 +451,6 @@ public:
|
||||
virtual void openItem();
|
||||
};
|
||||
|
||||
|
||||
class LLObjectBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
@@ -515,8 +515,6 @@ public:
|
||||
void editOnAvatar();
|
||||
|
||||
static BOOL canRemoveFromAvatar( void* userdata );
|
||||
//static void onRemoveFromAvatar( void* userdata );
|
||||
//static void onRemoveFromAvatarArrived( LLViewerWearable* wearable, void* userdata );
|
||||
//static void removeAllClothesFromAvatar();
|
||||
void removeFromAvatar();
|
||||
protected:
|
||||
@@ -629,7 +627,8 @@ public:
|
||||
class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
|
||||
{
|
||||
public:
|
||||
LLRecentInventoryBridgeBuilder(): LLInventoryFVBridgeBuilder() {}
|
||||
LLRecentInventoryBridgeBuilder() {}
|
||||
|
||||
// Overrides FolderBridge for Recent Inventory Panel.
|
||||
// It use base functionality for bridges other than FolderBridge.
|
||||
virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual BOOL isUpToDate() const { return TRUE; }
|
||||
virtual BOOL hasChildren() const { return FALSE; }
|
||||
virtual bool hasChildren() const { return FALSE; }
|
||||
virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
|
||||
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
|
||||
|
||||
@@ -872,7 +872,7 @@ public:
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual BOOL hasChildren() const;
|
||||
virtual bool hasChildren() const;
|
||||
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
@@ -922,7 +922,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
hide_context_entries(menu, items, disabled_items);
|
||||
}
|
||||
|
||||
BOOL LLTaskCategoryBridge::hasChildren() const
|
||||
bool LLTaskCategoryBridge::hasChildren() const
|
||||
{
|
||||
// return TRUE if we have or do know know if we have children.
|
||||
// *FIX: For now, return FALSE - we will know for sure soon enough.
|
||||
|
||||
67
indra/newview/llshareavatarhandler.cpp
Normal file
67
indra/newview/llshareavatarhandler.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file llshareavatarhandler.cpp
|
||||
* @brief slapp to handle sharing with an avatar
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llcommandhandler.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llui.h"
|
||||
|
||||
class LLShareWithAvatarHandler : public LLCommandHandler
|
||||
{
|
||||
public:
|
||||
// requires trusted browser to trigger
|
||||
LLShareWithAvatarHandler() : LLCommandHandler("sharewithavatar", UNTRUSTED_THROTTLE)
|
||||
{
|
||||
}
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
|
||||
{
|
||||
/*if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAvatarShare"))
|
||||
{
|
||||
LLNotificationsUtil::add("NoAvatarShare", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
|
||||
return true;
|
||||
}*/
|
||||
|
||||
//Make sure we have some parameters
|
||||
if (params.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get the ID
|
||||
LLUUID id;
|
||||
if (!id.set( params[0], FALSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//instigate share with this avatar
|
||||
LLAvatarActions::share(id);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
LLShareWithAvatarHandler gShareWithAvatar;
|
||||
@@ -2930,6 +2930,7 @@ class LLObjectImportUpload : public view_listener_t
|
||||
//---------------------------------------------------------------------------
|
||||
// Parcel freeze, eject, etc.
|
||||
//---------------------------------------------------------------------------
|
||||
void send_freeze(const LLUUID& avatar_id, bool freeze);
|
||||
bool callback_freeze(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
|
||||
@@ -2937,27 +2938,7 @@ bool callback_freeze(const LLSD& notification, const LLSD& response)
|
||||
|
||||
if (0 == option || 1 == option)
|
||||
{
|
||||
U32 flags = KICK_FLAGS_FREEZE;
|
||||
if (1 == option)
|
||||
{
|
||||
// unfreeze
|
||||
flags |= KICK_FLAGS_UNFREEZE;
|
||||
}
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
LLVOAvatar* avatarp = gObjectList.findAvatar(avatar_id);
|
||||
|
||||
if (avatarp && avatarp->getRegion())
|
||||
{
|
||||
msg->newMessage("FreezeUser");
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("Data");
|
||||
msg->addUUID("TargetID", avatar_id );
|
||||
msg->addU32("Flags", flags );
|
||||
msg->sendReliable( avatarp->getRegion()->getHost() );
|
||||
}
|
||||
send_freeze(avatar_id, !option);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -9105,6 +9086,15 @@ class ListRequestTeleport : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
class ListShare : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
LLAvatarActions::share(get_focused_list_id_selected());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ListShowProfile : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
@@ -9559,6 +9549,7 @@ void initialize_menus()
|
||||
addMenu(new ListRemoveFriend(), "List.RemoveFriend");
|
||||
addMenu(new ListRequestFriendship(), "List.RequestFriendship");
|
||||
addMenu(new ListRequestTeleport(), "List.RequestTeleport");
|
||||
addMenu(new ListShare(), "List.Share");
|
||||
addMenu(new ListShowProfile(), "List.ShowProfile");
|
||||
addMenu(new ListShowWebProfile(), "List.ShowWebProfile");
|
||||
addMenu(new ListStartAdhocCall(), "List.StartAdhocCall");
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
<on_click function="List.RequestTeleport"/>
|
||||
<on_visible function="List.EnableSingleSelected"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Share" name="Share">
|
||||
<on_click function="List.Share"/>
|
||||
<on_visible function="List.EnableSingleSelected"/>
|
||||
</menu_item_call>
|
||||
<menu_item_separator/>
|
||||
<menu_item_call label="Mute/Unmute" name="Mute/Unmute">
|
||||
<on_click function="List.ToggleMute"/>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<menu bottom="100" color="MenuDefaultBgColor" drop_shadow="true" height="101" left="100"
|
||||
mouse_opaque="false" name="Popup" opaque="true" width="128">
|
||||
<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 bottom_delta="-18" height="18" label="Buy" left="0" mouse_opaque="true"
|
||||
name="Task Buy" width="128">
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="task_buy" />
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
<on_click function="List.RequestTeleport"/>
|
||||
<on_visible function="List.EnableSingleSelected"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Share" name="Share">
|
||||
<on_click function="List.Share"/>
|
||||
<on_visible function="List.EnableSingleSelected"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Track/Untrack" name="Track/Untrack">
|
||||
<on_click function="Radar.Track"/>
|
||||
<on_enable function="List.EnableSingleSelected"/>
|
||||
|
||||
@@ -2142,15 +2142,6 @@ Multiple parcels selected.
|
||||
Try selecting a single parcel.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="DeedToGroupFail"
|
||||
type="notifytip">
|
||||
Deed to group failed.
|
||||
<tag>group</tag>
|
||||
<tag>fail</tag>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ParcelCanPlayMedia"
|
||||
@@ -7738,6 +7729,13 @@ Server Error: Media update or get failed.
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="ShareNotification"
|
||||
type="notifytip">
|
||||
Select residents to share with.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
name="MeshUploadError"
|
||||
icon="alert.tga"
|
||||
@@ -7761,6 +7759,61 @@ See the log file for details.
|
||||
Could not get region capability '[CAPABILITY]'.
|
||||
</notification>
|
||||
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="ShareItemsConfirmation"
|
||||
type="alertmodal">
|
||||
Are you sure you want to share the following items:
|
||||
|
||||
[ITEMS]
|
||||
|
||||
With the following Residents:
|
||||
|
||||
[RESIDENTS]
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
name="okcancelbuttons"
|
||||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="ShareFolderConfirmation"
|
||||
type="alertmodal">
|
||||
Only one folder at a time can be shared.
|
||||
|
||||
Are you sure you want to share the following items:
|
||||
|
||||
[ITEMS]
|
||||
|
||||
With the following Residents:
|
||||
|
||||
[RESIDENTS]
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
name="okcancelbuttons"
|
||||
notext="Cancel"
|
||||
yestext="Ok"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="ItemsShared"
|
||||
type="notifytip">
|
||||
Items successfully shared.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="DeedToGroupFail"
|
||||
type="notifytip">
|
||||
Deed to group failed.
|
||||
<tag>group</tag>
|
||||
<tag>fail</tag>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="AvatarRezNotification"
|
||||
|
||||
@@ -4185,6 +4185,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
|
||||
<string name="inventory_item_offered_rlv">
|
||||
Inventory item offered to [NAME]
|
||||
</string>
|
||||
<string name="share_alert">
|
||||
Drag items from inventory here
|
||||
</string>
|
||||
|
||||
|
||||
<string name="only_user_message">
|
||||
|
||||
Reference in New Issue
Block a user