diff options
Diffstat (limited to 'indra/newview/llavataractions.cpp')
-rw-r--r-- | indra/newview/llavataractions.cpp | 277 |
1 files changed, 267 insertions, 10 deletions
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index e6666c7f83..2dafe295fe 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,14 +48,18 @@ #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" #include "llfloaterpay.h" #include "llfloaterworldmap.h" +#include "llgiveinventory.h" #include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType +#include "llinventorypanel.h" #include "llimview.h" // for gIMMgr #include "llmutelist.h" +#include "llnotificationsutil.h" // for LLNotificationsUtil #include "llrecentpeople.h" #include "llsidetray.h" #include "lltrans.h" @@ -113,13 +119,13 @@ void LLAvatarActions::removeFriendDialog(const LLUUID& id) if (id.isNull()) return; - std::vector<LLUUID> ids; + uuid_vec_t ids; ids.push_back(id); removeFriendsDialog(ids); } // static -void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& ids) +void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids) { if(ids.size() == 0) return; @@ -144,7 +150,7 @@ void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& ids) } LLSD payload; - for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { payload["ids"].append(*it); } @@ -161,13 +167,21 @@ void LLAvatarActions::offerTeleport(const LLUUID& invitee) if (invitee.isNull()) return; + //waiting until Name Cache gets updated with corresponding avatar name + std::string just_to_request_name; + if (!gCacheName->getFullName(invitee, just_to_request_name)) + { + gCacheName->get(invitee, FALSE, boost::bind((void (*)(const LLUUID&)) &LLAvatarActions::offerTeleport, invitee)); + return; + } + LLDynamicArray<LLUUID> ids; ids.push_back(invitee); offerTeleport(ids); } // static -void LLAvatarActions::offerTeleport(const std::vector<LLUUID>& ids) +void LLAvatarActions::offerTeleport(const uuid_vec_t& ids) { if (ids.size() == 0) return; @@ -228,7 +242,7 @@ void LLAvatarActions::startCall(const LLUUID& id) } // static -void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids) +void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) { if (ids.size() == 0) { @@ -237,7 +251,7 @@ void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids) // convert vector into LLDynamicArray for addSession LLDynamicArray<LLUUID> id_array; - for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { id_array.push_back(*it); } @@ -274,15 +288,15 @@ bool LLAvatarActions::isCalling(const LLUUID &id) //static bool LLAvatarActions::canCall() { - return LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking(); + return LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); } // static -void LLAvatarActions::startConference(const std::vector<LLUUID>& ids) +void LLAvatarActions::startConference(const uuid_vec_t& ids) { // *HACK: Copy into dynamic array LLDynamicArray<LLUUID> id_array; - for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { id_array.push_back(*it); } @@ -417,6 +431,235 @@ void LLAvatarActions::share(const LLUUID& id) } } +namespace action_give_inventory +{ + typedef std::set<LLUUID> uuid_set_t; + + /** + * Checks My Inventory visibility. + */ + static bool is_give_inventory_acceptable() + { + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) return false; + + // check selection in the panel + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) return false; // nothing selected + + bool acceptable = false; + uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); + const uuid_set_t::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_residents_string(const std::vector<std::string>& avatar_names, std::string& residents_string) + { + llassert(avatar_names.size() > 0); + + const std::string& separator = LLTrans::getString("words_separator"); + for (std::vector<std::string>::const_iterator it = avatar_names.begin(); ; ) + { + residents_string.append(*it); + if (++it == avatar_names.end()) + { + break; + } + residents_string.append(separator); + } + } + + static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string) + { + llassert(inventory_selected_uuids.size() > 0); + + const std::string& separator = LLTrans::getString("words_separator"); + for (uuid_set_t::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<std::string> 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; + } + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) + { + return; + } + + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) + { + return; + } + + S32 count = LLShareInfo::instance().mAvatarNames.size(); + bool shared = false; + + // iterate through avatars + for(S32 i = 0; i < count; ++i) + { + const std::string& avatar_name = LLShareInfo::instance().mAvatarNames[i]; + const LLUUID& avatar_uuid = LLShareInfo::instance().mAvatarUuids[i]; + + // Start up IM before give the item + const LLUUID session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, avatar_uuid); + + uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); + const uuid_set_t::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) + { + LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id); + shared = true; + 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 + { + LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); + shared = true; + } + } + 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; + LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload, + &LLGiveInventory::handleCopyProtectedItem); + break; + } + } + if (shared) + { + LLFloaterReg::hideInstance("avatar_picker"); + 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 std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids) + { + llassert(avatar_names.size() == avatar_uuids.size()); + + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) + { + return; + } + + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) + { + return; + } + + std::string residents; + build_residents_string(avatar_names, residents); + + std::string items; + build_items_string(inventory_selected_uuids, items); + + LLSD substitutions; + substitutions["RESIDENTS"] = residents; + substitutions["ITEMS"] = items; + LLShareInfo::instance().mAvatarNames = avatar_names; + LLShareInfo::instance().mAvatarUuids = avatar_uuids; + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, LLSD(), &give_inventory_cb); + } +} + +//static +void LLAvatarActions::shareWithAvatars() +{ + using namespace action_give_inventory; + + LLFloaterAvatarPicker* picker = + LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE); + picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); + picker->openFriendsTab(); + LLNotificationsUtil::add("ShareNotification"); +} + // static void LLAvatarActions::toggleBlock(const LLUUID& id) { @@ -434,6 +677,20 @@ void LLAvatarActions::toggleBlock(const LLUUID& id) LLMuteList::getInstance()->add(mute); } } +// static +bool LLAvatarActions::canOfferTeleport(const LLUUID& id) +{ + // First use LLAvatarTracker::isBuddy() + // If LLAvatarTracker::instance().isBuddyOnline function only is used + // then for avatars that are online and not a friend it will return false. + // But we should give an ability to offer a teleport for such avatars. + if(LLAvatarTracker::instance().isBuddy(id)) + { + return LLAvatarTracker::instance().isBuddyOnline(id); + } + + return true; +} void LLAvatarActions::inviteToGroup(const LLUUID& id) { @@ -499,7 +756,7 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response, // static void LLAvatarActions::callback_invite_to_group(LLUUID group_id, LLUUID id) { - std::vector<LLUUID> agent_ids; + uuid_vec_t agent_ids; agent_ids.push_back(id); LLFloaterGroupInvite::showForGroup(group_id, &agent_ids); |