diff --git a/indra/newview/fspanelcontactsets.cpp b/indra/newview/fspanelcontactsets.cpp index 31561cb7fe..9760053bc6 100644 --- a/indra/newview/fspanelcontactsets.cpp +++ b/indra/newview/fspanelcontactsets.cpp @@ -38,6 +38,7 @@ #include "llcallingcard.h" #include "llfloateravatarpicker.h" #include "llfloaterreg.h" +#include "llpanelpeoplemenus.h" #include "llslurl.h" #include "lltrans.h" @@ -81,6 +82,7 @@ BOOL FSPanelContactSets::postBuild() { mAvatarList->setCommitCallback(boost::bind(&FSPanelContactSets::onSelectAvatar, this)); mAvatarList->setNoItemsCommentText(getString("empty_list")); + mAvatarList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); generateAvatarList(mContactSetCombo->getSimple()); } diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index da12598814..b677a689a3 100755 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -78,17 +78,22 @@ // Firestorm includes #include "fspanelradar.h" +#include "lggcontactsets.h" +#include "llcombobox.h" #include "lllayoutstack.h" #include "rlvhandler.h" -#define FRIEND_LIST_UPDATE_TIMEOUT 0.5 -#define NEARBY_LIST_UPDATE_INTERVAL 1 +#include + +const F32 FRIEND_LIST_UPDATE_TIMEOUT = 0.5f; +const F32 NEARBY_LIST_UPDATE_INTERVAL = 1.f; static const std::string NEARBY_TAB_NAME = "nearby_panel"; static const std::string FRIENDS_TAB_NAME = "friends_panel"; static const std::string GROUP_TAB_NAME = "groups_panel"; static const std::string RECENT_TAB_NAME = "recent_panel"; static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars +static const std::string CONTACT_SETS_TAB_NAME = "contact_sets_panel"; // [FS:CR] Contact sets static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; @@ -521,6 +526,9 @@ LLPanelPeople::LLPanelPeople() mNearbyList(NULL), mRecentList(NULL), mGroupList(NULL), + // [FS:CR] Contact sets + mContactSetList(NULL), + mContactSetCombo(NULL), // Firestorm radar //mMiniMap(NULL) mMiniMap(NULL), @@ -553,6 +561,12 @@ LLPanelPeople::LLPanelPeople() //mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2)); mEnableCallbackRegistrar.add("People.Group.Plus.Validate", boost::bind(&LLPanelPeople::onGroupPlusButtonValidate, this)); + + // [FS:CR] Contact sets + mCommitCallbackRegistrar.add("ContactSet.Action", boost::bind(&LLPanelPeople::onContactSetsMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("ContactSet.Enable", boost::bind(&LLPanelPeople::onContactSetsEnable, this, _2)); + mContactSetChangedConnection = LGGContactSets::getInstance()->setContactSetChangeCallback(boost::bind(&LLPanelPeople::updateContactSets, this, _1)); + // [/FS:CR] } LLPanelPeople::~LLPanelPeople() @@ -567,6 +581,11 @@ LLPanelPeople::~LLPanelPeople() { LLVoiceClient::getInstance()->removeObserver(this); } + + // [FS:CR] Contact sets + if (mContactSetChangedConnection.connected()) + mContactSetChangedConnection.disconnect(); + // [/FS:CR] } void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list) @@ -718,6 +737,25 @@ BOOL LLPanelPeople::postBuild() { llwarns << "People->Groups list menu not found" << llendl; } + + // [FS:CR] Contact sets + mContactSetCombo = getChild("combo_sets"); + if (mContactSetCombo) + { + mContactSetCombo->setCommitCallback(boost::bind(&LLPanelPeople::generateCurrentContactList, this)); + refreshContactSets(); + } + + mContactSetList = getChild("contact_list"); + if (mContactSetList) + { + mContactSetList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this)); + mContactSetList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); + mContactSetList->setNoItemsCommentText(getString("empty_list")); + mContactSetList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); + generateCurrentContactList(); + } + // [/FS:CR] // Friend list accordion replacement //LLAccordionCtrlTab* accordion_tab = getChild("tab_all"); @@ -1020,15 +1058,19 @@ LLUUID LLPanelPeople::getCurrentItemID() const return mRadarPanel->getCurrentItemID(); // - if (cur_tab == RECENT_TAB_NAME) + else if (cur_tab == RECENT_TAB_NAME) return mRecentList->getSelectedUUID(); - if (cur_tab == GROUP_TAB_NAME) + else if (cur_tab == GROUP_TAB_NAME) return mGroupList->getSelectedUUID(); - if (cur_tab == BLOCKED_TAB_NAME) + else if (cur_tab == BLOCKED_TAB_NAME) return LLUUID::null; // FIXME? - + + // [FS:CR] Contact sets + else if (cur_tab == CONTACT_SETS_TAB_NAME) + return mContactSetList->getSelectedUUID(); + // [/FS:CR] Contact sets llassert(0 && "unknown tab selected"); return LLUUID::null; } @@ -1054,6 +1096,10 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const mGroupList->getSelectedUUIDs(selected_uuids); else if (cur_tab == BLOCKED_TAB_NAME) selected_uuids.clear(); // FIXME? + // [FS:CR] Contact sets + else if (cur_tab == CONTACT_SETS_TAB_NAME) + mContactSetList->getSelectedUUIDs(selected_uuids); + // [/FS:CR] Contact sets else llassert(0 && "unknown tab selected"); @@ -1241,9 +1287,8 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list) mAllFriendList->resetSelection(true); else if (list == mAllFriendList) mOnlineFriendList->resetSelection(true); -// possible side effect of sidebar work; should be no harm in ignoring this -KC -// else -// llassert(0 && "commit on unknown friends list"); + else + llassert(0 && "commit on unknown friends list"); } updateButtons(); @@ -1375,7 +1420,6 @@ void LLPanelPeople::onGroupMinusButtonClicked() void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata) { std::string chosen_item = userdata.asString(); - if (chosen_item == "join_group") LLGroupActions::search(); else if (chosen_item == "new_group") @@ -1505,7 +1549,7 @@ void LLPanelPeople::onMoreButtonClicked() // *TODO: not implemented yet } -void LLPanelPeople::onOpen(const LLSD& key) +void LLPanelPeople::onOpen(const LLSD& key) { std::string tab_name = key["people_panel_tab_name"]; if (!tab_name.empty()) @@ -1674,4 +1718,175 @@ void LLPanelPeople::onGlobalVisToggleButtonClicked() } // Firestorm radar +// [FS:CR] Contact sets +void LLPanelPeople::updateContactSets(LGGContactSets::EContactSetUpdate type) +{ + switch (type) + { + case LGGContactSets::UPDATED_LISTS: + refreshContactSets(); + case LGGContactSets::UPDATED_MEMBERS: + generateCurrentContactList(); + break; + } +} + +void LLPanelPeople::refreshContactSets() +{ + if (!mContactSetCombo) return; + + mContactSetCombo->clearRows(); + std::vector contact_sets = LGGContactSets::getInstance()->getAllGroups(); + if (!contact_sets.empty()) + { + BOOST_FOREACH(const std::string& set_name, contact_sets) + { + mContactSetCombo->add(set_name); + } + } + else + { + mContactSetCombo->add(getString("no_sets"), LLSD("No Set")); + } +} + +void LLPanelPeople::generateContactList(const std::string& contact_set) +{ + if (!mContactSetList) return; + + uuid_vec_t& avatars = mContactSetList->getIDs(); + avatars.clear(); + if (contact_set == getString("no_sets")) + { + + } + else + { + LGGContactSets::ContactSetGroup* group = LGGContactSets::getInstance()->getGroup(contact_set); + BOOST_FOREACH(const LLUUID id, group->mFriends) + { + avatars.push_back(id); + } + } + mContactSetList->setDirty(); +} + +void LLPanelPeople::generateCurrentContactList() +{ + generateContactList(mContactSetCombo->getSimple()); +} + +bool LLPanelPeople::onContactSetsEnable(const LLSD& userdata) +{ + std::string item = userdata.asString(); + if (item == "has_set") + return (!LGGContactSets::getInstance()->getAllGroups().empty()); + else if (item == "has_selection") + { + uuid_vec_t selected_uuids; + getCurrentItemIDs(selected_uuids); + return (!selected_uuids.empty()); + } + return false; +} + +void LLPanelPeople::onContactSetsMenuItemClicked(const LLSD& userdata) +{ + std::string chosen_item = userdata.asString(); + if (chosen_item == "add_set") + { + LLNotificationsUtil::add("AddNewContactSet", LLSD(), LLSD(), &LGGContactSets::handleAddContactSetCallback); + } + else if (chosen_item == "remove_set") + { + LLSD payload, args; + std::string set = mContactSetCombo->getSimple(); + args["SET_NAME"] = set; + payload["contact_set"] = set; + LLNotificationsUtil::add("RemoveContactSet", args, payload, &LGGContactSets::handleRemoveContactSetCallback); + } + else if (chosen_item == "add_contact") + { + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloater* avatar_picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::handlePickerCallback, this, _1, mContactSetCombo->getSimple()), + TRUE, TRUE, TRUE, root_floater->getName()); + if (root_floater && avatar_picker) + root_floater->addDependentFloater(avatar_picker); + } + else if (chosen_item == "remove_contact") + { + if (!mContactSetCombo) return; + + uuid_vec_t selected_uuids; + getCurrentItemIDs(selected_uuids); + if (selected_uuids.empty()) return; + + LLSD payload, args; + std::string set = mContactSetCombo->getSimple(); + S32 selected_size = selected_uuids.size(); + args["SET_NAME"] = set; + args["TARGET"] = (selected_size > 1 ? llformat("%d", selected_size) : LLSLURL("agent", selected_uuids.front(), "about").getSLURLString()); + payload["contact_set"] = set; + BOOST_FOREACH(const LLUUID& id, selected_uuids) + { + payload["ids"].append(id); + } + LLNotificationsUtil::add((selected_size > 1 ? "RemoveContactsFromSet" : "RemoveContactFromSet"), args, payload, &LGGContactSets::handleRemoveAvatarFromSetCallback); + } + else if (chosen_item == "set_config") + { + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloater* config_floater = LLFloaterReg::showInstance("fs_contact_set_config", LLSD(mContactSetCombo->getSimple())); + if (root_floater && config_floater) + root_floater->addDependentFloater(config_floater); + } + else if (chosen_item == "profile") + { + uuid_vec_t selected_uuids; + getCurrentItemIDs(selected_uuids); + if (selected_uuids.empty()) return; + + BOOST_FOREACH(const LLUUID& id, selected_uuids) + { + LLAvatarActions::showProfile(id); + } + } + else if (chosen_item == "im") + { + uuid_vec_t selected_uuids; + getCurrentItemIDs(selected_uuids); + if (selected_uuids.empty()) return; + + if (selected_uuids.size() == 1) + { + LLAvatarActions::startIM(selected_uuids[0]); + } + else if (selected_uuids.size() > 1) + { + LLAvatarActions::startConference(selected_uuids); + } + } + else if (chosen_item == "teleport") + { + uuid_vec_t selected_uuids; + getCurrentItemIDs(selected_uuids); + if (selected_uuids.empty()) return; + + LLAvatarActions::offerTeleport(selected_uuids); + } +} + +void LLPanelPeople::handlePickerCallback(const uuid_vec_t& ids, const std::string& set) +{ + if (ids.empty() || !mContactSetCombo) return; + + BOOST_FOREACH(const LLUUID& id, ids) + { + if (!LLAvatarTracker::instance().isBuddy(id)) + LGGContactSets::getInstance()->addNonFriendToList(id); + LGGContactSets::getInstance()->addFriendToGroup(id, set); + } +} +// [/FS:CR] + // EOF diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index bd72b0d418..518a35b221 100755 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -35,6 +35,10 @@ #include "llfloater.h" +// [FS:CR] Contact sets +#include "lggcontactsets.h" +#include + class LLAvatarList; class LLAvatarName; class LLFilterEditor; @@ -148,6 +152,7 @@ private: LLAvatarList* mAllFriendList; LLAvatarList* mSuggestedFriends; LLAvatarList* mNearbyList; + LLAvatarList* mContactSetList; // [FS:CR] Contact sets // Firestorm radar FSPanelRadar* mRadarPanel; // Firestorm radar @@ -166,6 +171,19 @@ private: Updater* mFacebookListUpdater; Updater* mButtonsUpdater; LLHandle< LLFloater > mPicker; + + // [FS:CR] Contact sets + bool onContactSetsEnable(const LLSD& userdata); + void onContactSetsMenuItemClicked(const LLSD& userdata); + void handlePickerCallback(const uuid_vec_t& ids, const std::string& set); + void refreshContactSets(); + void generateContactList(const std::string& contact_set); + void generateCurrentContactList(); + + void updateContactSets(LGGContactSets::EContactSetUpdate type); + boost::signals2::connection mContactSetChangedConnection; + LLComboBox* mContactSetCombo; + // [/FS:CR] }; #endif //LL_LLPANELPEOPLE_H diff --git a/indra/newview/skins/default/xui/en/menu_people_contact_sets_add.xml b/indra/newview/skins/default/xui/en/menu_people_contact_sets_add.xml new file mode 100755 index 0000000000..9782a2b4d9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_contact_sets_add.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_people_contact_sets_gear.xml b/indra/newview/skins/default/xui/en/menu_people_contact_sets_gear.xml new file mode 100755 index 0000000000..e7002030e0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_contact_sets_gear.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_people_contact_sets_remove.xml b/indra/newview/skins/default/xui/en/menu_people_contact_sets_remove.xml new file mode 100755 index 0000000000..8db1c11667 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_contact_sets_remove.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 5a506085dc..7b95dbfc23 100755 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -57,6 +57,14 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M + + This contact set is empty. + + + No contact sets available. + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_people_contact_sets.xml b/indra/newview/skins/default/xui/en/panel_people_contact_sets.xml new file mode 100755 index 0000000000..7837c011d0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_people_contact_sets.xml @@ -0,0 +1,92 @@ + + + + + + + + + +