From fdcd99ae34cfd07845d939bee496155ec49b8ffb Mon Sep 17 00:00:00 2001 From: Cinders Date: Tue, 19 Nov 2013 17:01:37 -0700 Subject: [PATCH] Initial drop of new Contact Sets UI, fixes FIRE-10402, FIRE-11346 (and FIRE-5390 if using the new UI) TODO: signal refresh to avatar list when an avatar is added from right click menu, confirm removal of avatar from set, possible other bugs, possible removal or lggcontactsetsfloater --- indra/newview/CMakeLists.txt | 6 + indra/newview/fscontactsfloater.cpp | 5 + indra/newview/fscontactsfloater.h | 1 + indra/newview/fsfloateraddtocontactset.cpp | 93 ++++++ indra/newview/fsfloateraddtocontactset.h | 55 ++++ .../fsfloatercontactsetconfiguration.cpp | 86 ++++++ .../fsfloatercontactsetconfiguration.h | 58 ++++ indra/newview/fspanelcontactsets.cpp | 288 ++++++++++++++++++ indra/newview/fspanelcontactsets.h | 74 +++++ indra/newview/fsparticipantlist.cpp | 1 + indra/newview/fsradarmenu.cpp | 1 + indra/newview/lggcontactsets.h | 11 +- indra/newview/llavataractions.cpp | 8 + indra/newview/llavataractions.h | 5 + indra/newview/llpanelpeoplemenus.cpp | 1 + indra/newview/llviewerfloaterreg.cpp | 4 + indra/newview/llviewermenu.cpp | 27 +- .../default/xui/en/floater_fs_contact_add.xml | 54 ++++ .../floater_fs_contact_set_configuration.xml | 159 ++++++++++ .../default/xui/en/floater_fs_contacts.xml | 10 +- .../default/xui/en/menu_attachment_other.xml | 7 + .../default/xui/en/menu_avatar_other.xml | 9 +- .../skins/default/xui/en/menu_fs_radar.xml | 7 + .../default/xui/en/menu_participant_list.xml | 7 + .../default/xui/en/menu_people_nearby.xml | 7 + .../skins/default/xui/en/notifications.xml | 74 +++++ .../default/xui/en/panel_fs_contacts_sets.xml | 118 +++++++ 27 files changed, 1158 insertions(+), 18 deletions(-) create mode 100644 indra/newview/fsfloateraddtocontactset.cpp create mode 100644 indra/newview/fsfloateraddtocontactset.h create mode 100644 indra/newview/fsfloatercontactsetconfiguration.cpp create mode 100644 indra/newview/fsfloatercontactsetconfiguration.h create mode 100644 indra/newview/fspanelcontactsets.cpp create mode 100644 indra/newview/fspanelcontactsets.h create mode 100644 indra/newview/skins/default/xui/en/floater_fs_contact_add.xml create mode 100644 indra/newview/skins/default/xui/en/floater_fs_contact_set_configuration.xml create mode 100644 indra/newview/skins/default/xui/en/panel_fs_contacts_sets.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 674b00e690..34a451e288 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -133,7 +133,9 @@ set(viewer_SOURCE_FILES fscontactsfloater.cpp fsdata.cpp fsexportperms.cpp + fsfloateraddtocontactset.cpp fsfloaterblocklist.cpp + fsfloatercontactsetconfiguration.cpp fsfloaterexport.cpp fsfloatergroup.cpp fsfloatergrouptitles.cpp @@ -162,6 +164,7 @@ set(viewer_SOURCE_FILES fsnearbychathub.cpp fsnearbychatvoicemonitor.cpp fspanelclassified.cpp + fspanelcontactsets.cpp fspanelimcontrolpanel.cpp fspanelprefs.cpp fspanelprofile.cpp @@ -828,7 +831,9 @@ set(viewer_HEADER_FILES fscontactsfloater.h fsdata.h fsexportperms.h + fsfloateraddtocontactset.h fsfloaterblocklist.h + fsfloatercontactsetconfiguration.h fsfloaterexport.h fsfloatergroup.h fsfloatergrouptitles.h @@ -857,6 +862,7 @@ set(viewer_HEADER_FILES fsnearbychatcontrol.h fsnearbychathub.h fsnearbychatvoicemonitor.h + fspanelcontactsets.h fspanelclassified.h fspanelimcontrolpanel.h fspanelprefs.h diff --git a/indra/newview/fscontactsfloater.cpp b/indra/newview/fscontactsfloater.cpp index 11516b374e..04a02837ba 100644 --- a/indra/newview/fscontactsfloater.cpp +++ b/indra/newview/fscontactsfloater.cpp @@ -443,6 +443,11 @@ std::string FSFloaterContacts::getActiveTabName() const return mTabContainer->getCurrentPanel()->getName(); } +LLPanel* FSFloaterContacts::getPanelByName(const std::string& panel_name) +{ + return mTabContainer->getPanelByName(panel_name); +} + LLUUID FSFloaterContacts::getCurrentItemID() const { std::string cur_tab = getActiveTabName(); diff --git a/indra/newview/fscontactsfloater.h b/indra/newview/fscontactsfloater.h index ac439ac567..7d859bd588 100644 --- a/indra/newview/fscontactsfloater.h +++ b/indra/newview/fscontactsfloater.h @@ -62,6 +62,7 @@ public: static FSFloaterContacts* findInstance(); void openTab(const std::string& name); + LLPanel* getPanelByName(const std::string& panel_name); void sortFriendList(); diff --git a/indra/newview/fsfloateraddtocontactset.cpp b/indra/newview/fsfloateraddtocontactset.cpp new file mode 100644 index 0000000000..8137d9fbdb --- /dev/null +++ b/indra/newview/fsfloateraddtocontactset.cpp @@ -0,0 +1,93 @@ +/* + * @file fsfloateraddtocontactset.cpp + * @brief Add an avatar to a contact set + * + * (C) 2013 Cinder Roxley @ Second Life + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "llviewerprecompiledheaders.h" +#include "fsfloateraddtocontactset.h" + +#include "llnotificationsutil.h" +#include "llslurl.h" +#include + +FSFloaterAddToContactSet::FSFloaterAddToContactSet(const LLSD& target) +: LLFloater(target) +, mContactSetsCombo(NULL) +{ + mAgentID = target.asUUID(); +} + +BOOL FSFloaterAddToContactSet::postBuild() +{ + childSetTextArg("textfield", "[NAME]", LLSLURL("agent", mAgentID, "inspect").getSLURLString()); + + mContactSetsCombo = getChild("contact_sets"); + populateContactSets(); + + childSetAction("add_btn", boost::bind(&FSFloaterAddToContactSet::onClickAdd, this)); + childSetAction("cancel_btn", boost::bind(&FSFloaterAddToContactSet::onClickCancel, this)); + + return TRUE; +} + +void FSFloaterAddToContactSet::onClickAdd() +{ + const std::string set = mContactSetsCombo->getSimple(); + if (LGGContactSets::getInstance()->isNonFriend(mAgentID)) + LGGContactSets::getInstance()->addNonFriendToList(mAgentID); + LGGContactSets::getInstance()->addFriendToGroup(mAgentID, set); + LLSD args; + args["NAME"] = LLSLURL("agent", mAgentID, "inspect").getSLURLString(); + args["SET"] = set; + LLNotificationsUtil::add("AddToContactSetSuccess", args); + closeFloater(); +} + +void FSFloaterAddToContactSet::onClickCancel() +{ + closeFloater(); +} + +void FSFloaterAddToContactSet::populateContactSets() +{ + if (!mContactSetsCombo) return; + + mContactSetsCombo->clear(); + std::vector contact_sets = LGGContactSets::getInstance()->getAllGroups(); + if (contact_sets.empty()) + { + mContactSetsCombo->add(getString("no_sets"), LLSD(NULL)); + getChild("add_btn")->setEnabled(FALSE); + } + else + { + BOOST_FOREACH(const std::string& set_name, contact_sets) + { + mContactSetsCombo->add(set_name); + } + } +} diff --git a/indra/newview/fsfloateraddtocontactset.h b/indra/newview/fsfloateraddtocontactset.h new file mode 100644 index 0000000000..dd3b455cd1 --- /dev/null +++ b/indra/newview/fsfloateraddtocontactset.h @@ -0,0 +1,55 @@ +/* + * @file fsfloateraddtocontactset.h + * @brief Add an avatar to a contact set + * + * (C) 2013 Cinder Roxley @ Second Life + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef FS_FLOATERADDTOCONTACTSET_H +#define FS_FLOATERADDTOCONTACTSET_H + +#include "llfloater.h" +#include "llcombobox.h" + +#include "lggcontactsets.h" + +class FSFloaterAddToContactSet : public LLFloater +{ +public: + FSFloaterAddToContactSet(const LLSD& target); + BOOL postBuild(); + +private: + ~FSFloaterAddToContactSet(){}; + void onClickAdd(); + void onClickCancel(); + void populateContactSets(); + + LLUUID mAgentID; + + LLComboBox* mContactSetsCombo; +}; + +#endif // FS_FLOATERADDTOCONTACTSET_H diff --git a/indra/newview/fsfloatercontactsetconfiguration.cpp b/indra/newview/fsfloatercontactsetconfiguration.cpp new file mode 100644 index 0000000000..6ad32b172e --- /dev/null +++ b/indra/newview/fsfloatercontactsetconfiguration.cpp @@ -0,0 +1,86 @@ +/* + * @file fsfloatercontactsetconfiguration.cpp + * @brief Contact set configuration floater + * + * (C) 2013 Cinder Roxley @ Second Life + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "llviewerprecompiledheaders.h" +#include "fsfloatercontactsetconfiguration.h" +#include "lggcontactsets.h" + +FSFloaterContactSetConfiguration::FSFloaterContactSetConfiguration(const LLSD& target_set) +: LLFloater(target_set) +{ + mContactSet = target_set.asString(); +} + +BOOL FSFloaterContactSetConfiguration::postBuild() +{ + LLStringUtil::format_map_t map; + map["NAME"] = mContactSet; + setTitle(getString("title", map)); + + mSetSwatch = getChild("set_swatch"); + if (mSetSwatch) + { + mSetSwatch->setCommitCallback(boost::bind(&FSFloaterContactSetConfiguration::onCommitSetColor, this)); + } + + mGlobalSwatch = getChild("global_swatch"); + if (mGlobalSwatch) + { + mGlobalSwatch->setCommitCallback(boost::bind(&FSFloaterContactSetConfiguration::onCommitDefaultColor, this)); + } + + mNotificationCheckBox = getChild("show_set_notifications"); + if (mNotificationCheckBox) + { + mNotificationCheckBox->setCommitCallback(boost::bind(&FSFloaterContactSetConfiguration::onCommitSetNotifications, this)); + } + return TRUE; +} + +void FSFloaterContactSetConfiguration::onOpen(const LLSD& target_set) +{ + mSetSwatch->set(LGGContactSets::getInstance()->getGroupColor(mContactSet), TRUE); + mGlobalSwatch->set(LGGContactSets::getInstance()->getDefaultColor(), TRUE); + mNotificationCheckBox->set(LGGContactSets::getInstance()->getNotifyForGroup(mContactSet)); +} + +void FSFloaterContactSetConfiguration::onCommitSetColor() +{ + LGGContactSets::getInstance()->setGroupColor(mContactSet, mSetSwatch->get()); +} + +void FSFloaterContactSetConfiguration::onCommitSetNotifications() +{ + LGGContactSets::getInstance()->setNotifyForGroup(mContactSet, mNotificationCheckBox->getValue().asBoolean()); +} + +void FSFloaterContactSetConfiguration::onCommitDefaultColor() +{ + LGGContactSets::getInstance()->setDefaultColor(mGlobalSwatch->get()); +} diff --git a/indra/newview/fsfloatercontactsetconfiguration.h b/indra/newview/fsfloatercontactsetconfiguration.h new file mode 100644 index 0000000000..d24400c28a --- /dev/null +++ b/indra/newview/fsfloatercontactsetconfiguration.h @@ -0,0 +1,58 @@ +/* + * @file fsfloatercontactsetconfiguration.h + * @brief Contact set configuration floater definitions + * + * (C) 2013 Cinder Roxley @ Second Life + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef FS_FLOATERCONTACTSETCONFIGURATION_H +#define FS_FLOATERCONTACTSETCONFIGURATION_H + +#include "llfloater.h" +#include "llcheckboxctrl.h" +#include "llcolorswatch.h" + +class FSFloaterContactSetConfiguration : public LLFloater +{ +public: + FSFloaterContactSetConfiguration(const LLSD& target_set); + BOOL postBuild(); + void onOpen(const LLSD& target_set); + +private: + ~FSFloaterContactSetConfiguration(){}; + void onCommitSetColor(); + void onCommitSetNotifications(); + void onCommitDefaultColor(); + + // Wish there was something better to use for this... + std::string mContactSet; + + LLCheckBoxCtrl* mNotificationCheckBox; + LLColorSwatchCtrl* mSetSwatch; + LLColorSwatchCtrl* mGlobalSwatch; +}; + +#endif //FS_FLOATERCONTACTSETCONFIGURATION_H diff --git a/indra/newview/fspanelcontactsets.cpp b/indra/newview/fspanelcontactsets.cpp new file mode 100644 index 0000000000..89084668df --- /dev/null +++ b/indra/newview/fspanelcontactsets.cpp @@ -0,0 +1,288 @@ +/* + * @file fspanelcontactsets.cpp + * @brief Contact sets UI + * + * (C) 2013 Cinder Roxley @ Second Life + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "llviewerprecompiledheaders.h" + +#include "llnotificationsutil.h" + +#include "fspanelcontactsets.h" +#include "fscontactsfloater.h" +#include "lggcontactsets.h" +#include "llavataractions.h" +#include "llcallingcard.h" +#include "llfloateravatarpicker.h" +#include "llfloaterreg.h" +#include "llslurl.h" +#include "lltrans.h" + +#include + +static LLRegisterPanelClassWrapper t_panel_contact_sets("contact_sets_panel"); + +FSPanelContactSets::FSPanelContactSets() : LLPanel() +, mContactSetCombo(NULL) +, mAvatarList(NULL) +, mAvatarSelections(NULL) +{ +} + +BOOL FSPanelContactSets::postBuild() +{ + childSetAction("add_set_btn", boost::bind(&FSPanelContactSets::onClickAddSet, this)); + childSetAction("remove_set_btn", boost::bind(&FSPanelContactSets::onClickRemoveSet, this)); + childSetAction("config_btn", boost::bind(&FSPanelContactSets::onClickConfigureSet, this)); + childSetAction("add_btn", boost::bind(&FSPanelContactSets::onClickAddAvatar, this)); + childSetAction("remove_btn", boost::bind(&FSPanelContactSets::onClickRemoveAvatar, this)); + childSetAction("profile_btn", boost::bind(&FSPanelContactSets::onClickOpenProfile, this)); + childSetAction("start_im_btn", boost::bind(&FSPanelContactSets::onClickStartIM, this)); + childSetAction("offer_teleport_btn", boost::bind(&FSPanelContactSets::onClickOfferTeleport, this)); + + mContactSetCombo = getChild("combo_sets"); + if (mContactSetCombo) + { + mContactSetCombo->setCommitCallback(boost::bind(&FSPanelContactSets::onSelectContactSet, this)); + refreshContactSets(); + } + + mAvatarList = getChild("contact_list"); + if (mAvatarList) + { + mAvatarList->setCommitCallback(boost::bind(&FSPanelContactSets::onSelectAvatar, this)); + mAvatarList->setNoItemsCommentText(getString("empty_list")); + generateAvatarList(mContactSetCombo->getSimple()); + } + + return TRUE; +} + +void FSPanelContactSets::onSelectAvatar() +{ + mAvatarSelections.clear(); + mAvatarList->getSelectedUUIDs(mAvatarSelections); + resetControls(); +} + +void FSPanelContactSets::generateAvatarList(const std::string& contact_set) +{ + if (!mAvatarList) return; + + uuid_vec_t& avatars = mAvatarList->getIDs(); + avatars.clear(); + if (contact_set == getString("no_sets")) + { + + } + //else if (contact_set == "Friends") + //{ + // LLAvatarTracker::buddy_map_t buddies; + // LLAvatarTracker::instance().copyBuddyList(buddies); + // LLAvatarTracker::buddy_map_t::const_iterator buddy = buddies.begin(); + // for (; buddy != buddies.end(); ++buddy) + // { + // avatars.push_back(buddy->first); + // } + //} + else + { + LGGContactSets::ContactSetGroup* group = LGGContactSets::getInstance()->getGroup(contact_set); // UGLY! + BOOST_FOREACH(const LLUUID id, group->mFriends) + { + avatars.push_back(id); + } + } + mAvatarList->setDirty(); + resetControls(); +} + +void FSPanelContactSets::resetControls() +{ + bool has_sets = (!LGGContactSets::getInstance()->getAllGroups().empty()); + bool has_selection = mAvatarSelections.size(); + childSetEnabled("remove_set_btn", has_sets); + childSetEnabled("config_btn", has_sets); + childSetEnabled("add_btn", has_sets); + childSetEnabled("remove_btn", (has_sets && has_selection)); + childSetEnabled("profile_btn", has_selection); + childSetEnabled("start_im_btn", has_selection); + childSetEnabled("offer_teleport_btn", has_selection); // Should probably check if they're online... +} + +void FSPanelContactSets::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")); + } + // This only gets enabled for testing. + //mContactSetCombo->add(LLTrans::getString("InvFolder Friends"), LLSD("Friends"), ADD_TOP); + resetControls(); +} + +void FSPanelContactSets::onSelectContactSet() +{ + generateAvatarList(mContactSetCombo->getSimple()); + resetControls(); +} + +void FSPanelContactSets::onClickAddAvatar() +{ + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloater* avatar_picker = LLFloaterAvatarPicker::show(boost::bind(&FSPanelContactSets::handlePickerCallback, this, _1, mContactSetCombo->getSimple()), + TRUE, TRUE, TRUE, root_floater->getName()); + if (root_floater && avatar_picker) + root_floater->addDependentFloater(avatar_picker); +} + +void FSPanelContactSets::handlePickerCallback(const uuid_vec_t& ids, const std::string& set) +{ + if (ids.empty() || !mContactSetCombo) return; + + BOOST_FOREACH(const LLUUID& id, ids) + { + if (LGGContactSets::getInstance()->isNonFriend(id)) + LGGContactSets::getInstance()->addNonFriendToList(id); + LGGContactSets::getInstance()->addFriendToGroup(id, set); + } + // Only refresh the list if it's currently open. + if (set == mContactSetCombo->getSimple()) + generateAvatarList(set); +} + +void FSPanelContactSets::onClickRemoveAvatar() +{ + if (!(mAvatarList && mContactSetCombo)) return; + + std::string set = mContactSetCombo->getSimple(); + BOOST_FOREACH(const LLUUID& id, mAvatarSelections) + { + LGGContactSets::getInstance()->removeFriendFromGroup(id, set); + if (LGGContactSets::getInstance()->isNonFriend(id)) + LGGContactSets::getInstance()->removeNonFriendFromList(id); + } + if (set == mContactSetCombo->getSimple()) + generateAvatarList(set); +} + +void FSPanelContactSets::onClickAddSet() +{ + LLNotificationsUtil::add("AddNewContactSet", LLSD(), LLSD(), &handleAddContactSetCallback); +} + +void FSPanelContactSets::onClickRemoveSet() +{ + LLSD payload, args; + std::string set = mContactSetCombo->getSimple(); + args["SET_NAME"] = set; + payload["contact_set"] = set; + LLNotificationsUtil::add("RemoveContactSet", args, payload, &handleRemoveContactSetCallback); +} + +void FSPanelContactSets::onClickConfigureSet() +{ + 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); +} + +void FSPanelContactSets::onClickOpenProfile() +{ + BOOST_FOREACH(const LLUUID& id, mAvatarSelections) + { + LLAvatarActions::showProfile(id); + } +} + +void FSPanelContactSets::onClickStartIM() +{ + if ( mAvatarSelections.size() == 1 ) + { + LLAvatarActions::startIM(mAvatarSelections[0]); + } + else if ( mAvatarSelections.size() > 1 ) + { + LLAvatarActions::startConference(mAvatarSelections); + } +} + +void FSPanelContactSets::onClickOfferTeleport() +{ + LLAvatarActions::offerTeleport(mAvatarSelections); +} + +//////////////////// +// Static methods // +//////////////////// + +// static +bool FSPanelContactSets::handleAddContactSetCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + std::string set_name = response["message"].asString(); + LGGContactSets::getInstance()->addGroup(set_name); + FSPanelContactSets* panel = dynamic_cast(FSFloaterContacts::findInstance()->getPanelByName("contact_sets_panel")); + if (panel) + { + panel->refreshContactSets(); + panel->mContactSetCombo->setSimple(set_name); + panel->generateAvatarList(set_name); + } + } + return false; +} + +// static +bool FSPanelContactSets::handleRemoveContactSetCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + LGGContactSets::getInstance()->deleteGroup(notification["payload"]["contact_set"].asString()); + FSPanelContactSets* panel = dynamic_cast(FSFloaterContacts::findInstance()->getPanelByName("contact_sets_panel")); + if (panel) + { + panel->refreshContactSets(); + panel->generateAvatarList(panel->mContactSetCombo->getSimple()); + } + } + return false; +} diff --git a/indra/newview/fspanelcontactsets.h b/indra/newview/fspanelcontactsets.h new file mode 100644 index 0000000000..807f14b3eb --- /dev/null +++ b/indra/newview/fspanelcontactsets.h @@ -0,0 +1,74 @@ +/* + * @file fspanelcontactsets.h + * @brief Contact sets UI defintions + * + * (C) 2013 Cinder Roxley @ Second Life + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef FS_PANELCONTACTSETS_H +#define FS_PANELCONTACTSETS_H + +#include "llavatarlist.h" +#include "llcombobox.h" +#include "llpanel.h" + +#include + +class FSPanelContactSets : public LLPanel +{ +public: + FSPanelContactSets(); + BOOL postBuild(); + +private: + ~FSPanelContactSets(){}; + + void onSelectAvatar(); + void generateAvatarList(const std::string& contact_set); + void onClickAddAvatar(); + void handlePickerCallback(const uuid_vec_t& ids, const std::string& set); + void onClickRemoveAvatar(); + void onClickOpenProfile(); + void onClickStartIM(); + void onClickOfferTeleport(); + void onSelectContactSet(); + void onClickAddSet(); + void onClickRemoveSet(); + void onClickConfigureSet(); + void refreshContactSets(); + void removeAvatarFromSet(); + void resetControls(); + + static bool handleAddContactSetCallback(const LLSD& notification, const LLSD& response); + static bool handleRemoveContactSetCallback(const LLSD& notification, const LLSD& response); + static bool handleRemoveAvatarFromSetCallback(const LLSD& notification, const LLSD& response); + + uuid_vec_t mAvatarSelections; + + LLComboBox* mContactSetCombo; + LLAvatarList* mAvatarList; +}; + +#endif // FS_PANELCONTACTSETS_H diff --git a/indra/newview/fsparticipantlist.cpp b/indra/newview/fsparticipantlist.cpp index f65c1560f6..36c6db9965 100644 --- a/indra/newview/fsparticipantlist.cpp +++ b/indra/newview/fsparticipantlist.cpp @@ -694,6 +694,7 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front())); registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs.front())); registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front())); + registrar.add("Avatar.AddToContactSet", boost::bind(&LLAvatarActions::addToContactSet, mUUIDs.front())); registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2)); diff --git a/indra/newview/fsradarmenu.cpp b/indra/newview/fsradarmenu.cpp index e56ede42c4..4b3bc69d45 100644 --- a/indra/newview/fsradarmenu.cpp +++ b/indra/newview/fsradarmenu.cpp @@ -82,6 +82,7 @@ LLContextMenu* FSRadarMenu::createMenu() registrar.add("Avatar.EstateBan", boost::bind(&LLAvatarActions::estateBan, id)); registrar.add("Avatar.Derender", boost::bind(&LLAvatarActions::derender, id, false)); registrar.add("Avatar.DerenderPermanent", boost::bind(&LLAvatarActions::derender, id, true)); + registrar.add("Avatar.AddToContactSet", boost::bind(&LLAvatarActions::addToContactSet, id)); registrar.add("Nearby.People.TeleportToAvatar", boost::bind(&FSRadarMenu::teleportToAvatar, this)); registrar.add("Nearby.People.TrackAvatar", boost::bind(&FSRadarMenu::onTrackAvatarMenuItemClick, this)); diff --git a/indra/newview/lggcontactsets.h b/indra/newview/lggcontactsets.h index 7701831bac..f64b42d24f 100644 --- a/indra/newview/lggcontactsets.h +++ b/indra/newview/lggcontactsets.h @@ -94,10 +94,8 @@ public: bool isInternalGroupName(const std::string& groupName); bool hasGroups() { return !mGroups.empty(); } - -private: + typedef boost::unordered_set uuid_set_t; - typedef boost::unordered_map uuid_map_t; class ContactSetGroup { @@ -112,7 +110,10 @@ private: bool mNotify; LLColor4 mColor; }; - + ContactSetGroup* getGroup(const std::string& groupName); + +private: + typedef boost::unordered_map uuid_map_t; LGGContactSets(); ~LGGContactSets(); @@ -136,8 +137,6 @@ private: typedef std::map group_map_t; group_map_t mGroups; - ContactSetGroup* getGroup(const std::string& groupName); - void importFromLLSD(const LLSD& data); LLSD exportToLLSD(); void saveToDisk(); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index d6bb8a6394..6c6512ed7d 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -1234,6 +1234,14 @@ void LLAvatarActions::viewChatHistoryExternally(const LLUUID& id) } // +// [FS:CR] Add to contact set +//static +void LLAvatarActions::addToContactSet(const LLUUID& agent_id) +{ + LLFloaterReg::showInstance("fs_add_contact", agent_id, TRUE); +} +// [/FS:CR] Add to contact set + //== private methods ======================================================================================== // static diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 5a61fa039f..10de5bbf95 100755 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -197,6 +197,11 @@ public: * Open csr page for avatar */ static void csr(const LLUUID& id, std::string name); + + /** + * [FS:CR] Add avatar to contact set + */ + static void addToContactSet(const LLUUID& agent_id); /** * Checks whether we can offer a teleport to the avatar, only offline friends diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index 2ded940082..0006b191e6 100755 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -85,6 +85,7 @@ LLContextMenu* PeopleContextMenu::createMenu() registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id)); // Firestorm additions registrar.add("Avatar.GroupInvite", boost::bind(&LLAvatarActions::inviteToGroup, id)); + registrar.add("Avatar.AddToContactSet", boost::bind(&LLAvatarActions::addToContactSet, id)); // [FS:CR] enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2)); enable_registrar.add("Avatar.CheckItem", boost::bind(&PeopleContextMenu::checkContextMenuItem, this, _2)); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 2283e64597..bb480c0f61 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -153,6 +153,8 @@ #include "floatermedialists.h" #include "fsareasearch.h" #include "fscontactsfloater.h" +#include "fsfloateraddtocontactset.h" +#include "fsfloatercontactsetconfiguration.h" #include "fsfloaterexport.h" #include "fsfloaterblocklist.h" #include "fsfloatergroup.h" @@ -395,6 +397,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("floater_profile", "floater_profile_view.xml",&LLFloaterReg::build); LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_add_contact", "floater_fs_contact_add.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_contact_set_config", "floater_fs_contact_set_configuration.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_group", "floater_fs_group.xml",&LLFloaterReg::build); LLFloaterReg::add("fs_group_titles", "floater_fs_group_titles.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_export", "floater_fs_export.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index cb0ad03137..2db4e75605 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1344,7 +1344,7 @@ class LLAdvancedDumpScriptedCamera : public view_listener_t { handle_dump_followcam(NULL); return true; -} + } }; @@ -1596,7 +1596,7 @@ class LLAdvancedLoadUIFromXML : public view_listener_t { handle_load_from_xml(NULL); return true; -} + } }; @@ -1612,7 +1612,7 @@ class LLAdvancedSaveUIToXML : public view_listener_t { handle_save_to_xml(NULL); return true; -} + } }; @@ -1622,7 +1622,7 @@ class LLAdvancedSendTestIms : public view_listener_t { LLIMModel::instance().testMessages(); return true; -} + } }; @@ -1767,7 +1767,7 @@ class LLAdvancedToggleCharacterGeometry : public view_listener_t { handle_god_request_avatar_geometry(NULL); return true; -} + } }; @@ -9094,6 +9094,21 @@ class FSDumpSimulatorFeaturesToChat : public view_listener_t }; // Dump SimulatorFeatures to chat +// Add to contact set +class FSAddToContactSet : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + if (avatarp) + { + LLFloaterReg::showInstance("fs_add_contact", LLSD(avatarp->getID()), TRUE); + } + return true; + } +}; +// Add to contact set + // Opensim menu item visibility control class LLGridCheck : public view_listener_t { @@ -10909,6 +10924,8 @@ void initialize_menus() view_listener_t::addMenu(new FSStreamListImportXML(), "Streamlist.xml_import"); // Dump SimulatorFeatures to chat view_listener_t::addMenu(new FSDumpSimulatorFeaturesToChat(), "Develop.DumpSimFeaturesToChat"); + // Add to contact set + view_listener_t::addMenu(new FSAddToContactSet(), "Avatar.AddToContactSet"); // export view_listener_t::addMenu(new FSObjectExport(), "Object.Export"); diff --git a/indra/newview/skins/default/xui/en/floater_fs_contact_add.xml b/indra/newview/skins/default/xui/en/floater_fs_contact_add.xml new file mode 100644 index 0000000000..8c6e7cc14c --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_fs_contact_add.xml @@ -0,0 +1,54 @@ + + + +No contact sets available. + + + Please select which contact set to add [NAME] to: + + +