From 20059c5de19010932ce76f6e881b61a73b48ccca Mon Sep 17 00:00:00 2001 From: cinder <cinder@cinderblocks.biz> Date: Sun, 4 Dec 2022 20:29:09 -0600 Subject: [PATCH] =?UTF-8?q?Add=20Legacy=20Profiles=20That=20Do=20Not=20Suc?= =?UTF-8?q?k=E2=84=A2=20Unplumbed=20at=20the=20moment=20while=20the=20tras?= =?UTF-8?q?h=20gets=20taken=20out.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- indra/newview/CMakeLists.txt | 6 + indra/newview/llfloaterprofilelegacy.cpp | 69 + indra/newview/llfloaterprofilelegacy.h | 52 + indra/newview/llpanelavatarlegacy.cpp | 109 ++ indra/newview/llpanelavatarlegacy.h | 105 ++ indra/newview/llpanelprofilelegacy.cpp | 1467 +++++++++++++++++ indra/newview/llpanelprofilelegacy.h | 233 +++ indra/newview/llviewerfloaterreg.cpp | 2 + indra/newview/skins/default/colors.xml | 6 +- .../default/xui/en/floater_profile_legacy.xml | 27 + .../default/xui/en/menu_profile_legacy.xml | 106 ++ .../xui/en/panel_profile_legacy_firstlife.xml | 43 + .../panel_profile_legacy_group_list_item.xml | 81 + .../xui/en/panel_profile_legacy_groups.xml | 36 + .../xui/en/panel_profile_legacy_interests.xml | 254 +++ .../xui/en/panel_profile_legacy_notes.xml | 36 + .../xui/en/panel_profile_legacy_picks.xml | 150 ++ .../en/panel_profile_legacy_secondlife.xml | 274 +++ .../xui/en/panel_profile_legacy_sidetray.xml | 323 ++++ 19 files changed, 3378 insertions(+), 1 deletion(-) create mode 100644 indra/newview/llfloaterprofilelegacy.cpp create mode 100644 indra/newview/llfloaterprofilelegacy.h create mode 100644 indra/newview/llpanelavatarlegacy.cpp create mode 100644 indra/newview/llpanelavatarlegacy.h create mode 100644 indra/newview/llpanelprofilelegacy.cpp create mode 100644 indra/newview/llpanelprofilelegacy.h create mode 100644 indra/newview/skins/default/xui/en/floater_profile_legacy.xml create mode 100644 indra/newview/skins/default/xui/en/menu_profile_legacy.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9f8ff84c863..822d0560764 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -341,6 +341,7 @@ set(viewer_SOURCE_FILES llfloaterpay.cpp llfloaterperms.cpp llfloaterprofile.cpp + llfloaterprofilelegacy.cpp llfloaterpreference.cpp llfloaterpreferenceviewadvanced.cpp llfloaterpreviewtrash.cpp @@ -487,6 +488,7 @@ set(viewer_SOURCE_FILES lloutputmonitorctrl.cpp llpanelappearancetab.cpp llpanelavatar.cpp + llpanelavatarlegacy.cpp llpanelavatartag.cpp llpanelblockedlist.cpp llpanelclassified.cpp @@ -544,6 +546,7 @@ set(viewer_SOURCE_FILES llpanelpresetspulldown.cpp llpanelprimmediacontrols.cpp llpanelprofile.cpp + llpanelprofilelegacy.cpp llpanelprofileclassifieds.cpp llpanelprofilepicks.cpp llpanelsearchbase.cpp @@ -1045,6 +1048,7 @@ set(viewer_HEADER_FILES llfloaterpay.h llfloaterperms.h llfloaterprofile.h + llfloaterprofilelegacy.h llfloaterpreference.h llfloaterpreferenceviewadvanced.h llfloaterpreviewtrash.h @@ -1180,6 +1184,7 @@ set(viewer_HEADER_FILES lloutputmonitorctrl.h llpanelappearancetab.h llpanelavatar.h + llpanelavatarlegacy.h llpanelavatartag.h llpanelblockedlist.h llpanelclassified.h @@ -1238,6 +1243,7 @@ set(viewer_HEADER_FILES llpanelpresetspulldown.h llpanelprimmediacontrols.h llpanelprofile.h + llpanelprofilelegacy.h llpanelprofileclassifieds.h llpanelprofilepicks.h llpanelsearchbase.h diff --git a/indra/newview/llfloaterprofilelegacy.cpp b/indra/newview/llfloaterprofilelegacy.cpp new file mode 100644 index 00000000000..056336c8175 --- /dev/null +++ b/indra/newview/llfloaterprofilelegacy.cpp @@ -0,0 +1,69 @@ +/* + * @file llfloaterprofilelegacy.h + * @brief Floater that holds panel don't bitch about it, Dog; Merging is easy. + * + * Copyright (c) 2017-2022, Cinder Roxley <cinder@sdf.org> + * + * 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 "llfloaterprofilelegacy.h" + +#include "llavatarname.h" +#include "llavatarnamecache.h" + +LLFloaterProfileLegacy::LLFloaterProfileLegacy(LLSD const& key) +: LLFloater(key) +{ + +} + +LLFloaterProfileLegacy::~LLFloaterProfileLegacy() +{ + if (mAvatarNameCacheConnection.connected()) + mAvatarNameCacheConnection.disconnect(); +} + +BOOL LLFloaterProfileLegacy::postBuild() +{ + return TRUE; +} + +void LLFloaterProfileLegacy::onOpen(const LLSD& key) +{ + if (!key.has("avatar_id")) return; + const LLUUID av_id = key["avatar_id"].asUUID(); + + mAvatarNameCacheConnection = LLAvatarNameCache::get(av_id, + boost::bind(&LLFloaterProfileLegacy::onAvatarNameCache, this, _1, _2)); + + getChild<LLPanel>("panel_profile_legacy_sidetray")->onOpen(key); +} + +void LLFloaterProfileLegacy::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + setTitle(av_name.getCompleteName()); + mAvatarNameCacheConnection.disconnect(); +} diff --git a/indra/newview/llfloaterprofilelegacy.h b/indra/newview/llfloaterprofilelegacy.h new file mode 100644 index 00000000000..c2b7dcaad62 --- /dev/null +++ b/indra/newview/llfloaterprofilelegacy.h @@ -0,0 +1,52 @@ +/* +* @file llfloaterlegacyprofile.h +* @brief Floater that holds panel +* +* Copyright (c) 2017-2022, Cinder Roxley <cinder@sdf.org> +* +* 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 LL_FLOATERLEGACYPROFILE_H +#define LL_FLOATERLEGACYPROFILE_H + +#include "llfloater.h" + +class LLAvatarName; + +class LLFloaterProfileLegacy final : public LLFloater +{ +public: + LLFloaterProfileLegacy(LLSD const& key); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + +private: + ~LLFloaterProfileLegacy() override; + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + + boost::signals2::connection mAvatarNameCacheConnection; +}; + +#endif // LL_FLOATERLEGACYPROFILE_H diff --git a/indra/newview/llpanelavatarlegacy.cpp b/indra/newview/llpanelavatarlegacy.cpp new file mode 100644 index 00000000000..aca6fc82167 --- /dev/null +++ b/indra/newview/llpanelavatarlegacy.cpp @@ -0,0 +1,109 @@ +/** + * @file llpanelavatarlegacy.cpp + * @brief LLPanelAvatar and related class implementations + * + * $LicenseInfo:firstyear=2004&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 "llpanelavatarlegacy.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llcallingcard.h" + +#include "llscrollcontainer.h" +#include "llavatariconctrl.h" +#include "lltextbox.h" + +LLPanelProfileLegacyTab::LLPanelProfileLegacyTab() +: LLPanel() +, mAvatarId(LLUUID::null) +{ +} + +LLPanelProfileLegacyTab::~LLPanelProfileLegacyTab() +{ + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + } +} + +void LLPanelProfileLegacyTab::setAvatarId(const LLUUID& id) +{ + if(id.notNull()) + { + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this); + } + mAvatarId = id; + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this); + } +} + +void LLPanelProfileLegacyTab::onOpen(const LLSD& key) +{ + // Don't reset panel if we are opening it for same avatar. + if(getAvatarId() != key.asUUID()) + { + resetControls(); + resetData(); + + scrollToTop(); + } + + // Update data even if we are viewing same avatar profile as some data might been changed. + setAvatarId(key.asUUID()); + updateData(); + updateButtons(); +} + +void LLPanelProfileLegacyTab::scrollToTop() const +{ + LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll"); + if (scrollContainer) + scrollContainer->goToTop(); +} + +void LLPanelProfileLegacyTab::onMapButtonClick() +{ + LLAvatarActions::showOnMap(getAvatarId()); +} + +void LLPanelProfileLegacyTab::updateButtons() +{ + bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); + + if(LLAvatarActions::isFriend(getAvatarId())) + { + getChildView("teleport")->setEnabled(is_buddy_online); + } + else + { + getChildView("teleport")->setEnabled(true); + } + + bool enable_map_btn = (is_buddy_online && LLAvatarActions::isAgentMappable(getAvatarId())) || gAgent.isGodlike(); + getChildView("show_on_map_btn")->setEnabled(enable_map_btn); +} diff --git a/indra/newview/llpanelavatarlegacy.h b/indra/newview/llpanelavatarlegacy.h new file mode 100644 index 00000000000..63e396ffaf5 --- /dev/null +++ b/indra/newview/llpanelavatarlegacy.h @@ -0,0 +1,105 @@ +/** + * @file llpanelavatarlegacy.h + * @brief LLPanelAvatar and related class definitions + * + * $LicenseInfo:firstyear=2004&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$ + */ + +#ifndef LL_LLPANELAVATARLEGACY_H +#define LL_LLPANELAVATARLEGACY_H + +#include "llpanel.h" +#include "llavatarpropertiesprocessor.h" + +class LLComboBox; +class LLLineEditor; + +/** +* Base class for any Profile View. +*/ +class LLPanelProfileLegacyTab + : public LLPanel + , public LLAvatarPropertiesObserver +{ +public: + + /** + * Sets avatar ID, sets panel as observer of avatar related info replies from server. + */ + virtual void setAvatarId(const LLUUID& id); + + /** + * Returns avatar ID. + */ + virtual const LLUUID& getAvatarId() { return mAvatarId; } + + /** + * Sends update data request to server. + */ + virtual void updateData() = 0; + + /** + * Clears panel data if viewing avatar info for first time and sends update data request. + */ + void onOpen(const LLSD& key) override; + + /** + * Profile tabs should close any opened panels here. + * + * Called from LLPanelProfile::onOpen() before opening new profile. + * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel + * before new profile is displayed, otherwise new profile will + * be hidden behind picture info panel. + */ + virtual void onClosePanel() {} + + /** + * Resets controls visibility, state, etc. + */ + virtual void resetControls(){}; + + /** + * Clears all data received from server. + */ + virtual void resetData(){}; + + ~LLPanelProfileLegacyTab() override; + +protected: + + LLPanelProfileLegacyTab(); + + /** + * Scrolls panel to top when viewing avatar info for first time. + */ + void scrollToTop() const; + + virtual void onMapButtonClick(); + + virtual void updateButtons(); + +private: + + LLUUID mAvatarId; +}; + +#endif // LL_LLPANELAVATARLEGACY_H diff --git a/indra/newview/llpanelprofilelegacy.cpp b/indra/newview/llpanelprofilelegacy.cpp new file mode 100644 index 00000000000..58744a8b7ae --- /dev/null +++ b/indra/newview/llpanelprofilelegacy.cpp @@ -0,0 +1,1467 @@ +/* + * @file llpanelprofilelegacy.cpp + * @brief Legacy protocol avatar profile panel + * + * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org> + * + * 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 "llpanelprofilelegacy.h" + +// libraries +#include "llaccordionctrl.h" +#include "llaccordionctrltab.h" +#include "llavatarnamecache.h" +#include "llcheckboxctrl.h" +#include "llflatlistview.h" +#include "llfloaterreg.h" +#include "lllineeditor.h" +#include "llloadingindicator.h" +#include "llnotificationsutil.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lltoggleablemenu.h" +#include "lltrans.h" + +// newview +#include "llagent.h" +#include "llagentdata.h" +#include "llagentpicksinfo.h" +#include "llavataractions.h" +#include "llcallingcard.h" // for LLAvatarTracker +#include "lldateutil.h" +#include "lldroptarget.h" +#include "llfloaterreporter.h" +#include "llfloaterworldmap.h" +#include "llgroupactions.h" +#include "llpanelclassified.h" +#include "llpanelpick.h" +#if WIP_PROFILES +#include "llpanelpicks.h" +#include "llpickitem.h" +#endif +#include "llmutelist.h" +#include "llsidetraypanelcontainer.h" +#include "llslurl.h" +#include "llviewerdisplayname.h" +#include "llviewermenu.h" // gMenuHolder + +// These are order-senstitive so don't fk with 'em! +static const std::array<std::string, 8> sWantCheckboxes{{"wanna_build", "wanna_explore", "wanna_yiff", "wanna_work", "wanna_group", "wanna_buy", "wanna_sell", "wanna_hire"}}; +static const std::array<std::string, 6> sSkillsCheckboxes{{"can_texture", "can_architect", "can_model", "can_event", "can_script", "can_characters"}}; + +static LLPanelInjector<LLPanelProfileLegacy> t_panel_lprofile("panel_profile_legacy_sidetray"); +static LLPanelInjector<LLPanelProfileLegacy::LLPanelProfileGroups> t_panel_group("panel_profile_legacy_groups"); +#if WIP_PROFILES +static LLPanelInjector<LLPanelProfileLegacy::LLPanelProfilePicks> t_panel_picks("panel_profile_legacy_picks"); +#endif + +LLPanelProfileLegacy::LLPanelProfileLegacy() +: LLPanelProfileLegacyTab() +#if WIP_PROFILES +, mPanelPicks(nullptr) +#endif +, mPanelGroups(nullptr) +{ + mChildStack.setParent(this); + mCommitCallbackRegistrar.add("Profile.CommitInterest", boost::bind(&LLPanelProfileLegacy::onCommitInterest, this)); + mCommitCallbackRegistrar.add("Profile.CommitProperties", boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + mCommitCallbackRegistrar.add("Profile.CommitRights", boost::bind(&LLPanelProfileLegacy::onCommitRights, this)); + mCommitCallbackRegistrar.add("Profile.CommitModifyObjectRights", boost::bind(&LLPanelProfileLegacy::onCommitModifyObjectsRights, this, _1)); + mCommitCallbackRegistrar.add("Profile.CopyData", boost::bind(&LLPanelProfileLegacy::copyData, this, _2)); + mCommitCallbackRegistrar.add("Profile.Action", boost::bind(&LLPanelProfileLegacy::onCommitAction, this, _2)); + mEnableCallbackRegistrar.add("Profile.Enable", boost::bind(&LLPanelProfileLegacy::isActionEnabled, this, _2)); +} + +LLPanelProfileLegacy::~LLPanelProfileLegacy() +{ + if (LLAvatarPropertiesProcessor::instanceExists() && LLPanelProfileLegacyTab::getAvatarId().notNull()) + LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLPanelProfileLegacyTab::getAvatarId(), this); + if (mAvatarNameCacheConnection.connected()) + mAvatarNameCacheConnection.disconnect(); + if (mNameChangedConnection.connected()) + mNameChangedConnection.disconnect(); +} + +// virtual +BOOL LLPanelProfileLegacy::postBuild() +{ + mPanelGroups = static_cast<LLPanelProfileGroups*>(getChild<LLUICtrl>("groups_tab_panel")); +#if WIP_PROFILES + mPanelPicks = static_cast<LLPanelProfilePicks*>(getChild<LLUICtrl>("picks_tab_panel")); + mPanelPicks->setProfilePanel(this); +#endif + + if (dynamic_cast<LLSideTrayPanelContainer*>(getParent()) != nullptr) + getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onBackBtnClick, this)); + else if (dynamic_cast<LLFloater*>(getParent()) != nullptr) + getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::closeParentFloater, this)); + else + getChild<LLUICtrl>("back")->setEnabled(FALSE); + getChild<LLTextEditor>("sl_about")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextEditor>("fl_about")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextureCtrl>("sl_profile_pic")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextureCtrl>("fl_profile_pic")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextEditor>("notes")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitNotes, this, _1)); + getChild<LLTextEditor>("avatar_name")->setDoubleClickCallback(boost::bind(&LLPanelProfileLegacy::onDoubleClickName, this)); + return TRUE; +} + +// virtual +void LLPanelProfileLegacy::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + // Temporarily add saved children back and reshape them. + mChildStack.preParentReshape(); + LLPanel::reshape(width, height, called_from_parent); + mChildStack.postParentReshape(); +} + +// virtual +void LLPanelProfileLegacy::onOpen(const LLSD& key) +{ + if (!key.has("avatar_id")) return; + const LLUUID av_id = key["avatar_id"].asUUID(); + + if (key.has("action")) + { + // *TODO: Actions, if any + return; + } + + if (mNameChangedConnection.connected()) + { + mNameChangedConnection.disconnect(); + } + + setAvatarId(av_id); + + mPanelGroups->onOpen(LLSD(av_id)); +#if WIP_PROFILES + mPanelPicks->onOpen(LLSD(av_id)); +#endif + // Oh joy! + bool is_self = (getAvatarId() == gAgentID); + getChild<LLView>("sl_profile_pic")->setEnabled(is_self); + getChild<LLView>("fl_profile_pic")->setEnabled(is_self); + getChild<LLView>("sl_about")->setEnabled(is_self); + getChild<LLView>("fl_about")->setEnabled(is_self); + getChild<LLView>("www")->setVisible(!is_self); + getChild<LLView>("www_edit")->setVisible(is_self); + getChild<LLView>("allow_publish")->setVisible(is_self); + childSetEnabled("wanna_something", is_self); + childSetEnabled("can_something", is_self); + childSetEnabled("languages", is_self); + for (const std::string& checkbox: sWantCheckboxes) + childSetEnabled(checkbox, is_self); + for (const std::string& checkbox: sSkillsCheckboxes) + childSetEnabled(checkbox, is_self); + childSetEnabled("drop_target", !is_self); + getChild<LLLayoutPanel>("avatar_in_search", is_self); + getChild<LLDropTarget>("drop_target")->setAgentID(av_id); + + updateData(); + resetControls(); + + getChild<LLAccordionCtrl>("avatar_accordion")->expandDefaultTab(); +} + +void LLPanelProfileLegacy::resetControls() +{ + LLButton* button = getChild<LLButton>("btn_chat"); + button->setEnabled(getAvatarId() != gAgentID); + button = getChild<LLButton>("btn_friend"); + button->setEnabled(getAvatarId() != gAgentID); + button->setLabel(getString((LLAvatarTracker::instance().getBuddyInfo(getAvatarId()) == nullptr) + ? "add_friend" : "remove_friend")); + button = getChild<LLButton>("btn_block"); + button->setEnabled(getAvatarId() != gAgentID); + button->setLabel(LLTrans::getString(LLMuteList::getInstance()->isMuted(getAvatarId()) + ? "UnmuteAvatar" + : "MuteAvatar")); +} + +void LLPanelProfileLegacy::updateData() +{ + setProgress(true); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(getAvatarId()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarNotesRequest(getAvatarId()); + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), + boost::bind(&LLPanelProfileLegacy::onAvatarNameCache, this, _1, _2)); + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + bool is_other = (relation && getAvatarId() != gAgentID); + getChild<LLLayoutPanel>("avatar_perm")->setVisible(is_other); + if (is_other) + { + S32 rights = relation->getRightsGrantedTo(); + getChild<LLCheckBoxCtrl>("allow_show_online")->setValue(rights & LLRelationship::GRANT_ONLINE_STATUS ? TRUE : FALSE); + getChild<LLCheckBoxCtrl>("allow_mapping")->setValue(rights & LLRelationship::GRANT_MAP_LOCATION ? TRUE : FALSE); + getChild<LLCheckBoxCtrl>("allow_object_perms")->setValue(rights & LLRelationship::GRANT_MODIFY_OBJECTS ? TRUE : FALSE); + } +} + +void LLPanelProfileLegacy::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + getChild<LLTextEditor>("avatar_name")->setText(av_name.getCompleteName()); +} + +void LLPanelProfileLegacy::processProperties(void* data, EAvatarProcessorType type) +{ + if (!data) return; + switch(type) + { + case APT_PROPERTIES: + { + const LLAvatarData* pData = static_cast<const LLAvatarData*>(data); + if (!pData || pData->avatar_id != getAvatarId()) return; + getChild<LLTextureCtrl>("sl_profile_pic")->setValue(pData->image_id); + getChild<LLTextureCtrl>("fl_profile_pic")->setValue(pData->fl_image_id); + if (pData->partner_id.notNull()) + { + getChild<LLTextBase>("partner_info")->setText(LLSLURL("agent", pData->partner_id, "inspect").getSLURLString()); + getChild<LLTextBase>("partner_label")->setVisible(TRUE); + getChild<LLTextBase>("partner_info")->setVisible(TRUE); + } + else + { + getChild<LLTextBase>("partner_label")->setVisible(FALSE); + getChild<LLTextBase>("partner_info")->setVisible(FALSE); + } + getChild<LLTextEditor>("sl_about")->setText(pData->about_text); + getChild<LLTextEditor>("fl_about")->setText(pData->fl_about_text); + getChild<LLTextBase>("www")->setText(pData->profile_url); + getChild<LLLineEditor>("www_edit")->setText(pData->profile_url); + + LLStringUtil::format_map_t args; + std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); + LLStringUtil::format(birth_date, LLSD().with("datetime", static_cast<S32>(pData->born_on.secondsSinceEpoch()))); + args["[AGE]"] = LLDateUtil::ageFromDate(pData->born_on, LLDate::now()); + args["[REZDAY]"] = birth_date; + args["[ACCOUNT_TYPE]"] = LLAvatarPropertiesProcessor::accountType(pData); + args["[PAYMENT_INFO]"] = LLAvatarPropertiesProcessor::paymentInfo(pData); + args["[AGE_VERIFIED]"] = pData->flags & AVATAR_AGEVERIFIED ? getString("age_verified") : LLStringUtil::null; + LLSD formatted_info(getString("account_info_fmt", args)); + getChild<LLTextBase>("account_info")->setValue(formatted_info); + formatted_info = LLSD(getString("rezday_fmt", args)); + getChild<LLTextBase>("rezday")->setValue(formatted_info); + getChild<LLView>("cake")->setVisible(pData->born_on.toHTTPDateString(LLStringExplicit("%d %b")) == + LLDate::now().toHTTPDateString(LLStringExplicit("%d %b"))); + getChild<LLCheckBoxCtrl>("allow_publish")->setValue(static_cast<bool>(pData->flags & AVATAR_ALLOW_PUBLISH)); + getChild<LLUICtrl>("online")->setVisible(static_cast<BOOL>(pData->flags & AVATAR_ONLINE || + pData->avatar_id == gAgentID)); + break; + } + case APT_NOTES: + { + const LLAvatarNotes* pData = static_cast<const LLAvatarNotes*>(data); + if (!pData || pData->target_id != getAvatarId()) return; + getChild<LLTextEditor>("notes")->setValue(pData->notes); + break; + } + case APT_INTERESTS: + { + const LLAvatarInterests* pData = static_cast<const LLAvatarInterests*>(data); + if (!pData || pData->avatar_id != getAvatarId()) return; + + for (U32 i = 0; i < sWantCheckboxes.size(); ++i) + { + getChild<LLCheckBoxCtrl>(sWantCheckboxes.at(i))->setValue(pData->want_to_mask & (1<<i) ? TRUE : FALSE); + } + + for (U32 i = 0; i < sSkillsCheckboxes.size(); ++i) + { + getChild<LLCheckBoxCtrl>(sSkillsCheckboxes.at(i))->setValue(pData->skills_mask & (1<<i) ? TRUE : FALSE); + } + getChild<LLLineEditor>("wanna_something")->setText(pData->want_to_text); + getChild<LLLineEditor>("can_something")->setText(pData->skills_text); + getChild<LLLineEditor>("languages")->setText(pData->languages_text); + break; + } + case APT_GROUPS: + { + LLAvatarGroups* pData = static_cast<LLAvatarGroups*>(data); + if(!pData || getAvatarId() != pData->avatar_id) return; + + showAccordion("avatar_groups_tab", !pData->group_list.empty()); + break; + } + // These are handled by their respective panels + case APT_PICKS: + case APT_CLASSIFIEDS: + case APT_PICK_INFO: + case APT_CLASSIFIED_INFO: + // No idea what this message is... + case APT_TEXTURES: + default: + break; + } + setProgress(false); +} + +void LLPanelProfileLegacy::setProgress(bool started) +{ + LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator"); + indicator->setVisible(started); + if (started) + indicator->start(); + else + indicator->stop(); +} + +void LLPanelProfileLegacy::showAccordion(const std::string& name, bool show) +{ + LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name); + tab->setVisible(show); + getChild<LLAccordionCtrl>("avatar_accordion")->arrange(); +} + +void LLPanelProfileLegacy::onCommitAction(const LLSD& userdata) +{ + const std::string action = userdata.asString(); + if (action == "friend") + { + if (LLAvatarTracker::instance().getBuddyInfo(getAvatarId()) == nullptr) + LLAvatarActions::requestFriendshipDialog(getAvatarId()); + else + LLAvatarActions::removeFriendDialog(getAvatarId()); + resetControls(); + } + else if (action == "block") + { + LLAvatarActions::toggleBlock(getAvatarId()); + resetControls(); + } + else if (action == "chat") + LLAvatarActions::startIM(getAvatarId()); + else if (action == "call") + LLAvatarActions::startCall(getAvatarId()); + else if (action == "share") + LLAvatarActions::share(getAvatarId()); + else if (action == "teleport") + LLAvatarActions::offerTeleport(getAvatarId()); + else if (action == "req_teleport") + LLAvatarActions::teleportRequest(getAvatarId()); + else if (action == "map") + LLAvatarActions::showOnMap(getAvatarId()); + else if (action == "pay") + LLAvatarActions::pay(getAvatarId()); + else if (action == "report_abuse") + LLFloaterReporter::showFromObject(getAvatarId()); + else + LL_WARNS("LegacyProfiles") << "Unhandled action: " << action << LL_ENDL; +} + +void LLPanelProfileLegacy::copyData(const LLSD& userdata) +{ +#if WIP_PROFILES + const std::string& param = userdata.asString(); + if (param == "copy_name") + LLAvatarActions::copyData(getAvatarId(), LLAvatarActions::E_DATA_NAME); + else if (param == "copy_slurl") + LLAvatarActions::copyData(getAvatarId(), LLAvatarActions::E_DATA_SLURL); + else if (param == "copy_key") + LLAvatarActions::copyData(getAvatarId(), LLAvatarActions::E_DATA_UUID); + else + LL_WARNS("LegacyProfiles") << "Unhandled action: " << param << LL_ENDL; +#endif +} + +bool LLPanelProfileLegacy::isActionEnabled(const LLSD& userdata) +{ + bool action_enabled = false; + const std::string check = userdata.asString(); + if (check == "can_has_telefono") + action_enabled = (LLAvatarActions::canCall() && getAvatarId() != gAgentID); + else if (check == "can_has_teleport") + action_enabled = (LLAvatarActions::canOfferTeleport(getAvatarId()) && getAvatarId() != gAgentID); + else if (check == "can_has_map") + { + action_enabled = (LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) + && LLAvatarActions::isAgentMappable(getAvatarId())) + || gAgent.isGodlike(); + } + else if (check == "can_has_pay") + action_enabled = (getAvatarId() != gAgentID); + else if (check == "can_share") + action_enabled = (getAvatarId() != gAgentID); + else if (check == "can_drama") + action_enabled = (getAvatarId() != gAgentID); + else + LL_INFOS("LegacyProfiles") << "Unhandled check " << check << LL_ENDL; + return action_enabled; +} + +void LLPanelProfileLegacy::onCommitAvatarProperties() +{ + if (getAvatarId() != gAgentID) return; + LLAvatarData data = LLAvatarData(); + + data.avatar_id = gAgentID; + data.image_id = getChild<LLTextureCtrl>("sl_profile_pic")->getImageAssetID(); + data.fl_image_id = getChild<LLTextureCtrl>("fl_profile_pic")->getImageAssetID(); + data.about_text = getChild<LLTextEditor>("sl_about")->getText(); + data.fl_about_text = getChild<LLTextEditor>("fl_about")->getText(); + data.profile_url = getChild<LLLineEditor>("www_edit")->getText(); + data.allow_publish = getChild<LLCheckBoxCtrl>("allow_publish")->getValue().asBoolean(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&data); +} + +void LLPanelProfileLegacy::onCommitInterest() +{ + if (getAvatarId() != gAgentID) return; + LLAvatarInterests data = LLAvatarInterests(); + + data.want_to_mask = 0x0; + data.skills_mask = 0x0; + data.want_to_text = getChild<LLLineEditor>("wanna_something")->getText(); + data.skills_text = getChild<LLLineEditor>("can_something")->getText(); + data.languages_text = getChild<LLLineEditor>("languages")->getText(); + for (U32 i = 0; i < sWantCheckboxes.size(); ++i) + { + if(getChild<LLCheckBoxCtrl>(sWantCheckboxes.at(i))->getValue().asBoolean()) + data.want_to_mask |= 1<<i; + } + for (U32 i = 0; i < sSkillsCheckboxes.size(); ++i) + { + if(getChild<LLCheckBoxCtrl>(sSkillsCheckboxes.at(i))->getValue().asBoolean()) + data.skills_mask |= 1<<i; + } + + LLAvatarPropertiesProcessor::getInstance()->sendInterestsUpdate(&data); +} + +void LLPanelProfileLegacy::onCommitNotes(LLUICtrl* ctrl) +{ + const std::string& notes = ctrl->getValue().asString(); + LLAvatarPropertiesProcessor::getInstance()->sendNotes(getAvatarId(), notes); +} + +void LLPanelProfileLegacy::onDoubleClickName() +{ + if (getAvatarId() == gAgentID) + { + LLFloaterReg::showInstance("display_name"); + mNameChangedConnection = LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLPanelProfileLegacy::onNameChanged, this)); + } +} + +void LLPanelProfileLegacy::onNameChanged() +{ + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), + boost::bind(&LLPanelProfileLegacy::onAvatarNameCache, this, _1, _2)); +} + +void LLPanelProfileLegacy::onBackBtnClick() +{ + LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); + if(parent) + { + parent->openPreviousPanel(); + } +} + +void LLPanelProfileLegacy::onCommitModifyObjectsRights(LLUICtrl* ctrl) +{ + if (ctrl->getValue().asBoolean()) // We want to confirm that the user really wants to grant object rights + { + LLNotificationsUtil::add("ConfirmGrantModifyRights", + LLSD().with("AGENT", LLSLURL("agent", getAvatarId(), "inspect").getSLURLString()), + LLSD(), + boost::bind(&LLPanelProfileLegacy::handleConfirmModifyRightsCallback, this, _1, _2)); + } + else // No confirmation needed on removing rights + { + onCommitRights(); + } +} + +bool LLPanelProfileLegacy::handleConfirmModifyRightsCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + onCommitRights(); + return true; + } + // Make sure to flip the checkbox back off + findChild<LLCheckBoxCtrl>("allow_object_perms")->setValue(false); + return false; +} + +void LLPanelProfileLegacy::closeParentFloater() +{ + LLFloater* floater = dynamic_cast<LLFloater*>(getParent()); + if (floater) floater->closeFloater(); +} + +void LLPanelProfileLegacy::onCommitRights() +{ + if (!LLAvatarActions::isFriend(getAvatarId())) return; + S32 flags = 0; + if (getChild<LLCheckBoxCtrl>("allow_show_online")->getValue().asBoolean()) + flags |= LLRelationship::GRANT_ONLINE_STATUS; + if (getChild<LLCheckBoxCtrl>("allow_mapping")->getValue().asBoolean()) + flags |= LLRelationship::GRANT_MAP_LOCATION; + if (getChild<LLCheckBoxCtrl>("allow_object_perms")->getValue().asBoolean()) + flags |= LLRelationship::GRANT_MODIFY_OBJECTS; + + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), flags); +} + +void LLPanelProfileLegacy::openPanel(LLPanel* panel, const LLSD& params) +{ + // Hide currently visible panel. + mChildStack.push(); + + // Add the panel or bring it to front. + if (panel->getParent() != this) + { + addChild(panel); + } + else + { + sendChildToFront(panel); + } + + panel->setVisible(TRUE); + panel->setFocus(TRUE); // prevent losing focus by the floater + panel->onOpen(params); + + LLRect new_rect = getRect(); + panel->reshape(new_rect.getWidth(), new_rect.getHeight()); + new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight()); + panel->setRect(new_rect); +} + +void LLPanelProfileLegacy::closePanel(LLPanel* panel) +{ + panel->setVisible(FALSE); + + if (panel->getParent() == this) + { + removeChild(panel); + + // Make the underlying panel visible. + mChildStack.pop(); + + // Prevent losing focus by the floater + const child_list_t* child_list = getChildList(); + if (!child_list->empty()) + { + child_list->front()->setFocus(TRUE); + } + else + { + LL_WARNS() << "No underlying panel to focus." << LL_ENDL; + } + } +} + +// LLPanelProfilePicks // +#if WIP_PROFILES +LLPanelProfileLegacy::LLPanelProfilePicks::LLPanelProfilePicks() +: LLPanelProfileLegacyTab() +, mProfilePanel(nullptr) +, mClassifiedsList(nullptr) +, mPicksList(nullptr) +, mPanelPickEdit(nullptr) +, mPanelPickInfo(nullptr) +, mPanelClassifiedInfo(nullptr) +, mPopupMenuHandle() +, mPlusMenuHandle() +{ +} + +LLPanelProfileLegacy::LLPanelProfilePicks::~LLPanelProfilePicks() +{ + auto popup_menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + auto plus_menu = mPlusMenuHandle.get(); + if (popup_menu) + { + popup_menu->die(); + mPopupMenuHandle.markDead(); + } + + if (plus_menu) + { + plus_menu->die(); + mPlusMenuHandle.markDead(); + } +} + +BOOL LLPanelProfileLegacy::LLPanelProfilePicks::postBuild() +{ + mPicksList = getChild<LLFlatListView>("picks_list"); + mClassifiedsList = getChild<LLFlatListView>("classifieds_list"); + childSetAction("add_btn", boost::bind(&LLPanelProfilePicks::onClickPlusBtn, this)); + childSetAction("teleport_btn", boost::bind(&LLPanelProfilePicks::onClickTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePicks::onClickShowOnMap, this)); + childSetAction("info_btn", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + + // setup menu + CommitCallbackRegistry::ScopedRegistrar registar; + registar.add("Pick.Info", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + registar.add("Pick.Edit", boost::bind(&LLPanelProfilePicks::onPanelEdit, this)); + registar.add("Pick.Teleport", boost::bind(&LLPanelProfilePicks::onClickTeleport, this)); + registar.add("Pick.Map", boost::bind(&LLPanelProfilePicks::onClickShowOnMap, this)); + registar.add("Pick.Delete", boost::bind(&LLPanelProfilePicks::onClickDelete, this)); + //EnableCallbackRegistry::ScopedRegistrar enable_registar; + //enable_registar.add("Pick.Enable", boost::bind(&LLPanelProfilePicks::onEnableMenuItem, this, _2)); + + auto popup_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, child_registry_t::instance()); + if (popup_menu) + mPopupMenuHandle = popup_menu->getHandle(); + + CommitCallbackRegistry::ScopedRegistrar plus_registar; + plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelProfilePicks::onPlusMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelProfilePicks::isActionEnabled, this, _2)); + auto plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, child_registry_t::instance()); + if (plus_menu) + mPlusMenuHandle = plus_menu->getHandle(); + + updateButtons(); + return TRUE; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onOpen(const LLSD& key) +{ + const LLUUID id(key.asUUID()); + BOOL self = (gAgent.getID() == id); + + setAvatarId(id); + updateData(); + + getChild<LLView>("add_btn_lp")->setVisible(self); + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) + { + menu->setItemVisible("pick_delete", self); + menu->setItemVisible("pick_edit", self); + menu->setItemVisible("pick_separator", self); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::updateData() +{ + mPicksList->clear(); + mClassifiedsList->clear(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PICKS == type) + { + mPicksList->clear(); + LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); + if (!avatar_picks || getAvatarId() != avatar_picks->target_id) return; + for (const LLAvatarPicks::pick_data_t& pick: avatar_picks->picks_list) + { + const LLUUID pick_id = pick.first; + const std::string pick_name = pick.second; + + LLPickItem* picture = LLPickItem::create(); + picture->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + picture->setPickName(pick_name); + picture->setPickId(pick_id); + picture->setCreatorId(getAvatarId()); + + LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture); + picture->update(); + + LLSD pick_value = LLSD(); + pick_value.insert(PICK_ID, pick_id); + pick_value.insert(PICK_NAME, pick_name); + pick_value.insert(PICK_CREATOR_ID, getAvatarId()); + + mPicksList->addItem(picture, pick_value); + picture->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this)); + picture->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4)); + } + showAccordion("tab_picks", mPicksList->size()); + } + else if (APT_CLASSIFIEDS == type) + { + mClassifiedsList->clear(); + LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data); + if (!c_info || getAvatarId() != c_info->target_id) return; + for (const LLAvatarClassifieds::classified_data& c_data: c_info->classifieds_list) + { + LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id); + c_item->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + c_item->setClassifiedName(c_data.name); + + LLSD pick_value = LLSD(); + pick_value.insert(CLASSIFIED_ID, c_data.classified_id); + pick_value.insert(CLASSIFIED_NAME, c_data.name); + + if (!findClassifiedById(c_data.classified_id)) + { + mClassifiedsList->addItem(c_item, pick_value); + } + c_item->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this)); + c_item->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4)); + } + showAccordion("tab_classifieds", mClassifiedsList->size()); + } + updateButtons(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::showAccordion(const std::string& name, bool show) +{ + getChild<LLAccordionCtrlTab>(name)->setVisible(show); + LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion"); + acc->arrange(); +} + +LLClassifiedItem *LLPanelProfileLegacy::LLPanelProfilePicks::findClassifiedById(const LLUUID& classified_id) const +{ + // HACK - find item by classified id. Should be a better way. + std::vector<LLPanel*> items; + mClassifiedsList->getItems(items); + LLClassifiedItem* c_item = nullptr; + for(LLPanel* it: items) + { + LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(it); + if (test_item && test_item->getClassifiedId() == classified_id) + { + c_item = test_item; + break; + } + } + return c_item; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::updateButtons() +{ + bool has_selected = (mPicksList->numSelected() > 0|| + mClassifiedsList->numSelected() > 0); + + getChildView("info_btn")->setEnabled(has_selected); + getChildView("teleport_btn")->setEnabled(has_selected); + getChildView("show_on_map_btn")->setEnabled(has_selected); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickInfo() +{ + if(mClassifiedsList->numSelected() > 0) + openClassifiedInfo(); + else if(mPicksList->numSelected() > 0) + openPickInfo(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickPlusBtn() +{ + auto menu = mPlusMenuHandle.get(); + if (menu) + { + LLRect rect(getChildView("add_btn")->getRect()); + menu->setButtonRect(rect, this); + LLMenuGL::showPopup(this, menu, rect.mLeft, rect.mTop); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickTeleport() +{ + LLPickItem* pick_item = static_cast<LLPickItem*>(mPicksList->getSelectedItem()); + LLClassifiedItem* c_item = getSelectedClassifiedItem(); + + LLVector3d pos; + if (pick_item) + { + pos = pick_item->getPosGlobal(); + } + else if (c_item) + { + pos = c_item->getPosGlobal(); + LLPanelClassifiedInfo::sendClickMessage("teleport", false, + c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); + } + + if (!pos.isExactlyZero()) + { + gAgent.teleportViaLocation(pos); + LLFloaterWorldMap::getInstance()->trackLocation(pos); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickShowOnMap() +{ + LLPickItem* pick_item = static_cast<LLPickItem*>(mPicksList->getSelectedItem()); + LLClassifiedItem* c_item = getSelectedClassifiedItem(); + + LLVector3d pos; + if (pick_item) + { + pos = pick_item->getPosGlobal(); + } + else if (c_item) + { + LLPanelClassifiedInfo::sendClickMessage("map", false, + c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); + pos = c_item->getPosGlobal(); + } + + LLFloaterWorldMap::getInstance()->trackLocation(pos); + LLFloaterReg::showInstance("world_map", "center"); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickDelete() +{ + LLSD value = mPicksList->getSelectedValue(); + if (value.isDefined()) + { + LLSD args; + args["PICK"] = value[PICK_NAME]; + LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2)); + return; + } + value = mClassifiedsList->getSelectedValue(); + if (value.isDefined()) + { + LLSD args; + args["NAME"] = value[CLASSIFIED_NAME]; + LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelProfilePicks::callbackDeleteClassified, this, _1, _2)); + return; + } +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLSD pick_value = mPicksList->getSelectedValue(); + + if (0 == option) + { + LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]); + mPicksList->removeItemByValue(pick_value); + } + updateButtons(); + return false; +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLSD value = mClassifiedsList->getSelectedValue(); + + if (0 == option) + { + LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]); + mClassifiedsList->removeItemByValue(value); + } + updateButtons(); + return false; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::openPickInfo() +{ + LLSD selected_value = mPicksList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem()); + + if (!mPanelPickInfo) + { + mPanelPickInfo = LLPanelPickInfo::create(); + mPanelPickInfo->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickInfo)); + mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelProfilePicks::onPanelPickEdit, this)); + mPanelPickInfo->setVisible(FALSE); + } + + LLSD params; + params["pick_id"] = pick->getPickId(); + params["avatar_id"] = pick->getCreatorId(); + params["snapshot_id"] = pick->getSnapshotId(); + params["pick_name"] = pick->getPickName(); + params["pick_desc"] = pick->getPickDesc(); + + getProfilePanel()->openPanel(mPanelPickInfo, params); +} + +// virtual +void LLPanelProfileLegacy::LLPanelProfilePicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask) +{ + updateButtons(); + + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) + { + menu->buildDrawLabels(); + ((LLContextMenu*)menu)->show(x, y); + LLMenuGL::showPopup(item, menu, x, y); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::openClassifiedInfo() +{ + LLSD selected_value = mClassifiedsList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLClassifiedItem* c_item = getSelectedClassifiedItem(); + + if (!mPanelClassifiedInfo) + { + mPanelClassifiedInfo = LLPanelClassifiedInfo::create(); + mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, mPanelClassifiedInfo)); + mPanelClassifiedInfo->setVisible(FALSE); + } + + LLSD params; + params["classified_id"] = c_item->getClassifiedId(); + params["classified_creator_id"] = c_item->getAvatarId(); + params["classified_snapshot_id"] = c_item->getSnapshotId(); + params["classified_name"] = c_item->getClassifiedName(); + params["classified_desc"] = c_item->getDescription(); + params["from_search"] = false; + + getProfilePanel()->openPanel(mPanelClassifiedInfo, params); +} + +LLClassifiedItem* LLPanelProfileLegacy::LLPanelProfilePicks::getSelectedClassifiedItem() const +{ + LLPanel* selected_item = mClassifiedsList->getSelectedItem(); + if (!selected_item) return nullptr; + + return dynamic_cast<LLClassifiedItem*>(selected_item); +} + +LLPickItem* LLPanelProfileLegacy::LLPanelProfilePicks::getSelectedPickItem() const +{ + LLPanel* selected_item = mPicksList->getSelectedItem(); + if (!selected_item) return nullptr; + + return dynamic_cast<LLPickItem*>(selected_item); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel) +{ + if (!panel->canClose()) + { + return; + } + + if (panel->isNew()) + { + mEditClassifiedPanels[panel->getClassifiedId()] = panel; + + LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId()); + c_item->fillIn(panel); + + LLSD c_value; + c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId()); + c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName()); + mClassifiedsList->addItem(c_item, c_value, ADD_TOP); + + //c_item->setDoubleClickCallback(boost::bind(&LLPanelProfilePicks::onDoubleClickClassifiedItem, this, _1)); + c_item->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4)); + c_item->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this)); + c_item->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + + // order does matter, showAccordion will invoke arrange for accordions. + //mClassifiedsAccTab->changeOpenClose(false); + //showAccordion("tab_classifieds", true); + } + else if (panel->isNewWithErrors()) + { + LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); + llassert(c_item); + if (c_item) + { + c_item->fillIn(panel); + } + } + else + { + onPanelClassifiedClose(panel); + return; + } + + onPanelPickClose(panel); + updateButtons(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel) +{ + if(panel->getInfoLoaded() && !panel->isDirty()) + { + std::vector<LLSD> values; + mClassifiedsList->getValues(values); + for (auto& value : values) + { + LLUUID c_id = value[CLASSIFIED_ID].asUUID(); + if(panel->getClassifiedId() == c_id) + { + LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getItemByValue(value)); + llassert(c_item); + if (c_item) + { + c_item->setClassifiedName(panel->getClassifiedName()); + c_item->setDescription(panel->getDescription()); + c_item->setSnapshotId(panel->getSnapshotId()); + } + } + } + } + + onPanelPickClose(panel); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onDoubleClickClassifiedItem(LLUICtrl* item) +{ + LLSD value = mClassifiedsList->getSelectedValue(); + if (value.isUndefined()) return; + + LLSD args; + args["CLASSIFIED"] = value[CLASSIFIED_NAME]; + LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), + boost::bind(&LLPanelProfilePicks::callbackTeleport, this, _1, _2)); +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackTeleport(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (0 == option) + { + onClickTeleport(); + } + return false; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickClose(LLPanel* panel) +{ + getProfilePanel()->closePanel(panel); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickSave(LLPanel* panel) +{ + getProfilePanel()->closePanel(panel); + updateButtons(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickEditSave(LLPanelPickEdit* panel) +{ + panel->sendUpdate(); + getProfilePanel()->closePanel(panel); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelEdit() +{ + if (getSelectedPickItem()) + { + onPanelPickEdit(); + } + else if (getSelectedClassifiedItem()) + { + onPanelClassifiedEdit(); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedEdit() +{ + LLSD selected_value = mClassifiedsList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); + llassert(c_item); + if (!c_item) return; + editClassified(c_item->getClassifiedId()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::editClassified(const LLUUID& classified_id) +{ + LLClassifiedItem* c_item = findClassifiedById(classified_id); + if (!c_item) + { + LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL; + return; + } + + LLSD params; + params["classified_id"] = c_item->getClassifiedId(); + params["classified_creator_id"] = c_item->getAvatarId(); + params["snapshot_id"] = c_item->getSnapshotId(); + params["name"] = c_item->getClassifiedName(); + params["desc"] = c_item->getDescription(); + params["category"] = (S32)c_item->getCategory(); + params["content_type"] = (S32)c_item->getContentType(); + params["auto_renew"] = c_item->getAutoRenew(); + params["price_for_listing"] = c_item->getPriceForListing(); + params["location_text"] = c_item->getLocationText(); + + LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()]; + if (!panel) + { + createClassifiedEditPanel(&panel); + mEditClassifiedPanels[c_item->getClassifiedId()] = panel; + } + getProfilePanel()->openPanel(panel, params); + panel->setPosGlobal(c_item->getPosGlobal()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickEdit() +{ + LLSD selected_value = mPicksList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem()); + + LLSD params; + params["pick_id"] = pick->getPickId(); + params["avatar_id"] = pick->getCreatorId(); + params["snapshot_id"] = pick->getSnapshotId(); + params["pick_name"] = pick->getPickName(); + params["pick_desc"] = pick->getPickDesc(); + + mPanelPickEdit = LLPanelPickEdit::create(); + mPanelPickEdit->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelPickEditSave, this, mPanelPickEdit)); + getProfilePanel()->openPanel(mPanelPickEdit, params); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPlusMenuItemClicked(const LLSD& param) +{ + std::string value = param.asString(); + + if ("new_pick" == value) + { + createNewPick(); + } + else if ("new_classified" == value) + { + createNewClassified(); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createNewPick() +{ + createPickEditPanel(); + + getProfilePanel()->openPanel(mPanelPickEdit, LLSD()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createNewClassified() +{ + LLPanelClassifiedEdit* panel = nullptr; + createClassifiedEditPanel(&panel); + + getProfilePanel()->openPanel(panel, LLSD()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createPickEditPanel() +{ + mPanelPickEdit = LLPanelPickEdit::create(); + mPanelPickEdit->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelPickSave, this, mPanelPickEdit)); + mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setVisible(FALSE); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel) +{ + + if (panel) + { + LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create(); + new_panel->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, new_panel)); + new_panel->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedSave, this, new_panel)); + new_panel->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, new_panel)); + new_panel->setVisible(FALSE); + *panel = new_panel; + } +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::isActionEnabled(const LLSD& userdata) const +{ + return (!(userdata.asString() == LLStringExplicit("new_pick") && LLAgentPicksInfo::getInstance()->isPickLimitReached())); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::setProfilePanel(LLPanelProfileLegacy* profile_panel) +{ + mProfilePanel = profile_panel; +} + +inline LLPanelProfileLegacy* LLPanelProfileLegacy::LLPanelProfilePicks::getProfilePanel() const +{ + llassert_always(mProfilePanel != nullptr); + return mProfilePanel; +} +#endif + +// LLPanelProfileGroups // + +LLPanelProfileLegacy::LLPanelProfileGroups::LLPanelProfileGroups() +: LLPanelProfileLegacyTab() +, mGroupsText(nullptr) +, mGroupsList(nullptr) +{ + +} + +BOOL LLPanelProfileLegacy::LLPanelProfileGroups::postBuild() +{ + mGroupsList = getChild<LLFlatListView>("groups_detail_list"); + mGroupsText = getChild<LLTextBase>("groups_panel_text"); + return TRUE; +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::onOpen(const LLSD& key) +{ + const LLUUID id(key.asUUID()); + setAvatarId(id); + + updateData(); +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::updateData() +{ + mGroupsText->setVisible(TRUE); + mGroupsList->clear(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarGroupsRequest(getAvatarId()); +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_GROUPS != type) return; + LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); + if(!avatar_groups || getAvatarId() != avatar_groups->avatar_id) return; + + for (auto const& gdata: avatar_groups->group_list) + { + LLProfileGroupItem* item = LLProfileGroupItem::create(); + item->childSetAction("info_chevron", boost::bind(&LLPanelProfileGroups::showGroup, this, gdata.group_id)); + item->init(gdata); + + LLSD item_value = LLSD(); + item_value.insert("group_id", gdata.group_id); + item_value.insert("group_name", gdata.group_name); + item_value.insert("group_icon", gdata.group_insignia_id); + item_value.insert("group_desc", LLStringUtil::null); + + if (!mGroupsList->valueExists(item_value)) + { + mGroupsList->addItem(item, item_value); + } + } +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::showGroup(const LLUUID& id) +{ + LLGroupActions::show(id); +} + +// LLProfileGroupItem // + +LLProfileGroupItem::LLProfileGroupItem() +: LLPanel() +, mInsignia(LLUUID::null) +, mGroupName(LLStringUtil::null) +, mCharter(LLStringUtil::null) +{ + buildFromFile("panel_profile_legacy_group_list_item.xml"); +} + +LLProfileGroupItem::~LLProfileGroupItem() +{ + LLGroupMgr::getInstance()->removeObserver(this); +} + +//static +LLProfileGroupItem* LLProfileGroupItem::create() +{ + return new LLProfileGroupItem(); +} + +void LLProfileGroupItem::init(const LLAvatarGroups::LLGroupData& data) +{ + setId(data.group_id); + setGroupName(data.group_name); + setInsignia(data.group_insignia_id); + LLGroupMgr::getInstance()->addObserver(this); + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(data.group_id); + + LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture"); + picture->setImageAssetID(data.group_insignia_id); +} + +BOOL LLProfileGroupItem::postBuild() +{ + setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true)); + setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false)); + return TRUE; +} + +void LLProfileGroupItem::setValue(const LLSD& value) +{ + if (!value.isMap()) return;; + if (!value.has("selected")) return; + getChildView("selected_icon")->setVisible( value["selected"]); +} + +void LLProfileGroupItem::setId(const LLUUID& id) +{ + mID = id; +} + +void LLProfileGroupItem::setInsignia(const LLUUID& id) +{ + mInsignia = id; + getChild<LLTextureCtrl>("picture")->setImageAssetID(id); +} + +void LLProfileGroupItem::setGroupName(const std::string& name) +{ + mGroupName = name; + getChild<LLUICtrl>("name")->setValue(name); +} + +void LLProfileGroupItem::setCharter(const std::string& charter) +{ + mCharter = charter; + getChild<LLUICtrl>("description")->setValue(charter); +} + +void LLProfileGroupItem::changed(LLGroupChange gc) +{ + if (gc != GC_PROPERTIES) return; + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID); + if (group_data) + { + setCharter(group_data->mCharter); + } + LLGroupMgr::getInstance()->removeObserver(this); +} + +// ChildStack // + +LLPanelProfileLegacy::ChildStack::ChildStack() +: mParent(nullptr) +{ +} + +LLPanelProfileLegacy::ChildStack::~ChildStack() +{ + while (!mStack.empty()) + { + view_list_t& top = mStack.back(); + for (auto viewp : top) + { + if (viewp) + { + viewp->die(); + } + } + mStack.pop_back(); + } +} + +void LLPanelProfileLegacy::ChildStack::setParent(LLPanel* parent) +{ + llassert_always(parent != nullptr); + mParent = parent; +} + +/// Save current parent's child views and remove them from the child list. +bool LLPanelProfileLegacy::ChildStack::push() +{ + view_list_t vlist = *mParent->getChildList(); + + for (auto viewp : vlist) + { + mParent->removeChild(viewp); + } + + mStack.push_back(vlist); + dump(); + return true; +} + +/// Restore saved children (adding them back to the child list). +bool LLPanelProfileLegacy::ChildStack::pop() +{ + if (mStack.empty()) + { + LL_WARNS() << "Empty stack" << LL_ENDL; + llassert(mStack.size() == 0); + return false; + } + + view_list_t& top = mStack.back(); + for (auto viewp : top) + { + mParent->addChild(viewp); + } + + mStack.pop_back(); + dump(); + return true; +} + +/// Temporarily add all saved children back. +void LLPanelProfileLegacy::ChildStack::preParentReshape() +{ + mSavedStack = mStack; + while(!mStack.empty()) + { + pop(); + } +} + +/// Add the temporarily saved children back. +void LLPanelProfileLegacy::ChildStack::postParentReshape() +{ + mStack = mSavedStack; + mSavedStack = stack_t(); + + for (const auto& vlist : mStack) + { + for (auto viewp : vlist) + { + LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL; + mParent->removeChild(viewp); + } + } +} + +void LLPanelProfileLegacy::ChildStack::dump() +{ + unsigned lvl = 0; + LL_DEBUGS() << "child stack dump:" << LL_ENDL; + for (const auto& vlist : mStack) + { + ++lvl; + std::ostringstream dbg_line; + dbg_line << "lvl #" << lvl << ":"; + for (const auto& list_it : vlist) + { + dbg_line << " " << list_it->getName(); + } + LL_DEBUGS() << dbg_line.str() << LL_ENDL; + } +} diff --git a/indra/newview/llpanelprofilelegacy.h b/indra/newview/llpanelprofilelegacy.h new file mode 100644 index 00000000000..1c451842c06 --- /dev/null +++ b/indra/newview/llpanelprofilelegacy.h @@ -0,0 +1,233 @@ +/* + * @file llpanelprofilelegacy.h + * @brief Legacy protocol avatar profile panel + * + * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org> + * + * 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 LL_PANELPROFILELEGACY_H +#define LL_PANELPROFILELEGACY_H + +#include "llgroupmgr.h" +#include "llpanelavatarlegacy.h" +#if WIP_PROFILES +#include "llclassifieditem.h" +#endif + +class LLAvatarName; +class LLFlatListView; +class LLPanel; +class LLPanelPickEdit; +class LLPanelPickInfo; +class LLPanelProfileLegacyTab; +class LLPanelClassifiedInfo; +class LLPanelClassifiedEdit; +class LLPickItem; +class LLTextBase; +class LLToggleableMenu; + +class LLPanelProfileLegacy final : public LLPanelProfileLegacyTab +{ +public: + LLPanelProfileLegacy(); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + +protected: + void openPanel(LLPanel* panel, const LLSD& params); + void closePanel(LLPanel* panel); + +private: + ~LLPanelProfileLegacy() override; + void updateData() override; + void processProperties(void* data, EAvatarProcessorType type) override; + void resetControls() override; + void setProgress(bool started); + void showAccordion(const std::string& name, bool show); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void onCommitAvatarProperties(); + void onCommitInterest(); + void onCommitNotes(LLUICtrl* ctrl); + void onDoubleClickName(); + void onCommitRights(); + void onBackBtnClick(); + void onCommitModifyObjectsRights(LLUICtrl* ctrl); + void onCommitAction(const LLSD& userdata); + void copyData(const LLSD& userdata); + void onNameChanged(); + bool isActionEnabled(const LLSD& userdata); + bool handleConfirmModifyRightsCallback(const LLSD& notification, const LLSD& response); + void closeParentFloater(); + + boost::signals2::connection mAvatarNameCacheConnection; + boost::signals2::connection mNameChangedConnection; + + class ChildStack + { + public: + ChildStack(); + ~ChildStack(); + void setParent(LLPanel* parent); + + bool push(); + bool pop(); + void preParentReshape(); + void postParentReshape(); + + private: + void dump(); + + typedef LLView::child_list_t view_list_t; + typedef std::list<view_list_t> stack_t; + + stack_t mStack; + stack_t mSavedStack; + LLPanel* mParent; + }; + ChildStack mChildStack; + +public: +#if WIP_PROFILES + class LLPanelProfilePicks final : public LLPanelProfileLegacyTab + { + friend class LLPanelProfileLegacy; + public: + LLPanelProfilePicks(); + ~LLPanelProfilePicks() override; + BOOL postBuild() override; + + protected: + void onOpen(const LLSD& key) override; + + private: + void updateData() override; + void processProperties(void* data, EAvatarProcessorType type) override; + void resetControls() override {}; + void showAccordion(const std::string& name, bool show); + void setProfilePanel(LLPanelProfileLegacy* profile_panel); + LLPanelProfileLegacy* getProfilePanel() const; + void onPanelPickClose(LLPanel* panel); + void onPanelPickSave(LLPanel* panel); + void onPanelPickEditSave(LLPanelPickEdit* panel); + void onPanelEdit(); + void onPanelClassifiedEdit(); + void onPanelPickEdit(); + void onPlusMenuItemClicked(const LLSD& param); + void createNewPick(); + void createNewClassified(); + void editClassified(const LLUUID& classified_id); + void updateButtons() override; + void onClickPlusBtn(); + void onClickInfo(); + void onClickTeleport(); + void onClickShowOnMap(); + void onClickDelete(); + void openPickInfo(); + void openClassifiedInfo(); + void onPanelClassifiedSave(LLPanelClassifiedEdit* panel); + void onPanelClassifiedClose(LLPanelClassifiedInfo* panel); + void onDoubleClickClassifiedItem(LLUICtrl* item); + LLClassifiedItem* findClassifiedById(const LLUUID& classified_id) const; + LLClassifiedItem* getSelectedClassifiedItem() const; + LLPickItem* getSelectedPickItem() const; + + void createPickEditPanel(); + void createClassifiedEditPanel(LLPanelClassifiedEdit** panel); + + bool isActionEnabled(const LLSD& userdata) const; + bool callbackDeletePick(const LLSD& notification, const LLSD& response); + bool callbackDeleteClassified(const LLSD& notification, const LLSD& response); + bool callbackTeleport(const LLSD& notification, const LLSD& response); + virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask); + + LLPanelProfileLegacy* mProfilePanel; + LLFlatListView* mClassifiedsList; + LLFlatListView* mPicksList; + LLPanelPickEdit* mPanelPickEdit; + LLPanelPickInfo* mPanelPickInfo; + LLPanelClassifiedInfo* mPanelClassifiedInfo; + LLHandle<LLView> mPopupMenuHandle; + LLHandle<LLToggleableMenu> mPlusMenuHandle; + + // This map is needed for newly created classifieds. The purpose of panel is to + // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback. + panel_classified_edit_map_t mEditClassifiedPanels; + }; +#endif + + class LLPanelProfileGroups final : public LLPanelProfileLegacyTab + { + friend class LLPanelProfileLegacy; + public: + LLPanelProfileGroups(); + BOOL postBuild() override; + + protected: + void onOpen(const LLSD& key) override; + + private: + void updateData() override; + void processProperties(void* data, EAvatarProcessorType type) override; + void resetControls() override {}; + void showGroup(const LLUUID& id); + + LLTextBase* mGroupsText; + LLFlatListView* mGroupsList; + }; + +private: +#if WIP_PROFILES + LLPanelProfilePicks* mPanelPicks; +#endif + LLPanelProfileGroups* mPanelGroups; +}; + +class LLProfileGroupItem final : public LLPanel, public LLGroupMgrObserver +{ +public: + LLProfileGroupItem(); + ~LLProfileGroupItem() override; + static LLProfileGroupItem* create(); + void init(const LLAvatarGroups::LLGroupData& data); + BOOL postBuild() override; + + void setValue(const LLSD& value) override; + void setId(const LLUUID& id); + void setInsignia(const LLUUID& id); + void setGroupName(const std::string& name); + void setCharter(const std::string& charter); + +protected: + void changed(LLGroupChange gc) override; + +private: + LLUUID mInsignia; + std::string mGroupName; + std::string mCharter; +}; + +#endif //LL_PANELPROFILELEGACY_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index bdb25056ad7..224bda5e31e 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -131,6 +131,7 @@ #include "llfloaterpreferenceviewadvanced.h" #include "llfloaterpreviewtrash.h" #include "llfloaterprofile.h" +#include "llfloaterprofilelegacy.h" #include "llfloaterprogressview.h" #include "llfloaterproperties.h" #include "llfloaterregiondebugconsole.h" @@ -428,6 +429,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("asset_hex_editor", "floater_hex_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHexEditor>); LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>); LLFloaterReg::add("generic_text", "floater_generic_text.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGenericText>); + LLFloaterReg::add("legacy_profile", "floater_profile_legacy.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<LLFloaterProfileLegacy>); LLFloaterReg::add("lightbox", "floater_lightbox_settings.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<ALFloaterLightBox>); LLFloaterReg::add("message_builder", "floater_message_builder.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageBuilder>); LLFloaterReg::add("message_log", "floater_message_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageLog>); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 6fb44e3fa1e..e519ea5e851 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -901,7 +901,11 @@ name="PanelNotificationListItem" value="0.3 0.3 0.3 .3" /> - <!-- profiles --> + <color + name="ProfileOnlineIndicatorColor" + reference="Green" /> + + <!-- dildo profiles --> <color name="StatusUserOnline" reference="White" /> diff --git a/indra/newview/skins/default/xui/en/floater_profile_legacy.xml b/indra/newview/skins/default/xui/en/floater_profile_legacy.xml new file mode 100644 index 00000000000..2a896d10796 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile_legacy.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + can_close="true" + can_resize="true" + height="580" + min_height="350" + min_width="260" + layout="topleft" + name="floater_profile_legacy" + save_rect="true" + title="PROFILE" + width="370"> + <panel + class="panel_profile_legacy_sidetray" + name="panel_profile_legacy_sidetray" + filename="panel_profile_legacy_sidetray.xml" + label="Profile" + font="SansSerifBold" + follows="all" + layout="topleft" + min_height="350" + left="1" + right="-1" + top="0" + bottom="-8"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_profile_legacy.xml b/indra/newview/skins/default/xui/en/menu_profile_legacy.xml new file mode 100644 index 00000000000..eb7f625cd7f --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_legacy.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_profile_legacy" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <!--<menu_item_call + label="Open Webprofile..." + name="webprofile"> + <menu_item_call.on_click + function="Profile.Action" + parameter="webprofile"/> + </menu_item_call> + <menu_item_separator/>--> + <menu_item_call + label="Share..." + name="share"> + <menu_item_call.on_click + function="Profile.Action" + parameter="share"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_share" /> + </menu_item_call> + <menu_item_call + label="Call Avatar..." + name="call"> + <menu_item_call.on_click + function="Profile.Action" + parameter="call"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_telefono" /> + </menu_item_call> + <menu_item_call + label="Offer teleport..." + name="teleport"> + <menu_item_call.on_click + function="Profile.Action" + parameter="teleport"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_teleport" /> + </menu_item_call> + <menu_item_call + label="Request teleport..." + name="request_teleport"> + <menu_item_call.on_click + function="Profile.Action" + parameter="req_teleport"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_teleport" /> + </menu_item_call> + <menu_item_call + label="Show on map..." + name="map"> + <menu_item_call.on_click + function="Profile.Action" + parameter="map"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_map" /> + </menu_item_call> + <menu_item_call + label="Pay..." + name="pay"> + <menu_item_call.on_click + function="Profile.Action" + parameter="pay"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_pay" /> + </menu_item_call> + <menu_item_call + label="Report Abuse..." + name="report_abuse"> + <menu_item_call.on_click + function="Profile.Action" + parameter="report_abuse"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_drama" /> + </menu_item_call> + <menu_item_separator /> + <menu_item_call + label="Copy Name" + name="Copy Name"> + <menu_item_call.on_click + function="Profile.CopyData" + parameter="copy_name" /> + </menu_item_call> + <menu_item_call + label="Copy SLURL" + name="Copy SLURL"> + <menu_item_call.on_click + function="Profile.CopyData" + parameter="copy_slurl" /> + </menu_item_call> + <menu_item_call + label="Copy Key" + name="Copy Key"> + <menu_item_call.on_click + function="Profile.CopyData" + parameter="copy_key" /> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml new file mode 100644 index 00000000000..88654c8540e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + label="First Life" + height="360" + width="304" + name="avatar_firstlife_tab"> + <panel + name="avatar_info_top" + follows="top|left|right" + top="0" + left="0" + height="129" + width="304" + layout="topleft"> + <texture_picker + default_image_name="Generic_Person_Large" + fallback_image="Generic_Person_Large" + follows="left|top" + height="143" + label="" + layout="topleft" + left="5" + name="fl_profile_pic" + no_commit_on_selection="true" + tool_tip="Click to choose a picture" + top="6" + width="120" /> + </panel> + <text_editor + type="string" + follows="all" + left="3" + height="200" + layout="topleft" + max_length="253" + name="fl_about" + top="134" + right="-4" + bg_readonly_color="DkGray2" + text_readonly_color="White" + commit_on_focus_lost="true" + word_wrap="true" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml new file mode 100644 index 00000000000..ed0b4a8825e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="top|left|right" + height="85" + layout="topleft" + left="0" + name="panel_group_item" + top="0" + width="313"> + <icon + follows="all" + height="85" + image_name="ListItem_Over" + right="-2" + mouse_opaque="false" + name="hovered_icon" + top="1" + scale_image="true" + visible="false" + width="308"/> + <icon + follows="all" + height="85" + image_name="ListItem_Select" + right="-2" + mouse_opaque="false" + name="selected_icon" + top="1" + scale_image="true" + visible="false" + width="308"/> + <texture_picker + allow_no_texture="true" + fallback_image="Generic_Group_Large" + enabled="false" + follows="left|top" + height="80" + layout="topleft" + left="10" + mouse_opaque="false" + name="picture" + tab_stop="false" + top="10" + top_pad="10" + width="90" /> + <text + follows="top|left|right" + font="SansSerifSmall" + height="15" + layout="topleft" + left="110" + name="name" + text_color="white" + top="9" + use_ellipses="true" + width="193" + word_wrap="false" /> + <expandable_text + follows="top|left|right" + font="SansSerifSmall" + height="55" + layout="topleft" + left="103" + name="description" + textbox.max_length="1024" + textbox.show_context_menu="false" + textbox.word_wrap="true" + top_pad="0" + width="178" /> + <button + follows="right" + height="20" + image_overlay="ForwardArrow_Off" + layout="topleft" + left_pad="5" + right="-8" + name="info_chevron" + top_delta="24" + width="20" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml new file mode 100644 index 00000000000..105d7ac1d65 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + follows="all" + height="360" + label="Groups" + layout="topleft" + left="0" + name="panel_profile_groups" + top_pad="0" + width="304"> + <text + type="string" + follows="all" + height="35" + layout="topleft" + left="6" + right="-6" + name="groups_panel_text" + wrap="true" + top="10"> + No Groups + </text> + <flat_list_view + color="DkGray2" + follows="all" + layout="topleft" + left="0" + right="-1" + name="groups_detail_list" + opaque="true" + top="0" + height="360" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml new file mode 100644 index 00000000000..a99e004b599 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml @@ -0,0 +1,254 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + label="Interests" + height="360" + width="304" + name="avatar_interests_tab"> + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="i_want_label" + top="2"> + I want to: + </text> + <check_box + height="16" + initial_value="false" + label="Build" + layout="topleft" + top_pad="4" + left="25" + name="wanna_build" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Explore" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_explore" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Meet" + layout="topleft" + top_pad="4" + left="25" + name="wanna_yiff" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Be Hired" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_work" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Group" + layout="topleft" + top_pad="4" + left="25" + name="wanna_group" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Buy" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_buy" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Sell" + layout="topleft" + top_pad="4" + left="25" + name="wanna_sell" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Hire" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_hire" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <line_editor + top_pad="4" + follows="left|top|right" + height="20" + left="25" + text_pad_left="5" + name="wanna_something" + right="-40"> + <line_editor.commit_callback + function="Profile.CommitInterest" /> + </line_editor> + + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="skills_label" + top_pad="8"> + Skills: + </text> + <check_box + height="16" + initial_value="false" + label="Textures" + layout="topleft" + top_pad="4" + left="25" + name="can_texture" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Architecture" + layout="topleft" + top_delta="0" + left_pad="4" + name="can_architect" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Modeling" + layout="topleft" + top_pad="4" + left="25" + name="can_model" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Event Planning" + layout="topleft" + top_delta="0" + left_pad="4" + name="can_event" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Scripting" + layout="topleft" + top_pad="4" + left="25" + name="can_script" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Custom Characters" + layout="topleft" + top_delta="0" + left_pad="4" + name="can_characters" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <line_editor + top_pad="4" + follows="left|top|right" + height="20" + left="25" + text_pad_left="5" + name="can_something" + right="-40"> + <line_editor.commit_callback + function="Profile.CommitInterest" /> + </line_editor> + <text + top_pad="8" + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="language_label" > + Languages: + </text> + <line_editor + top_pad="4" + follows="left|top|right" + height="20" + left="25" + text_pad_left="5" + name="languages" + right="-40"> + <line_editor.commit_callback + function="Profile.CommitInterest" /> + </line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml new file mode 100644 index 00000000000..55b80437ec0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + label="Notes" + height="360" + width="304" + name="avatar_notes_tab"> + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="notes_label" + top="2"> + Private notes: + </text> + <text_editor + type="string" + follows="all" + left="3" + height="320" + layout="topleft" + max_length="1022" + name="notes" + top_pad="4" + right="-4" + bg_readonly_color="DkGray2" + text_readonly_color="White" + commit_on_focus_lost="true" + word_wrap="true" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml new file mode 100644 index 00000000000..a0a501fd750 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + follows="all" + height="360" + label="Picks" + layout="topleft" + left="0" + name="panel_profile_picks" + top="0" + width="304"> + <text + type="string" + follows="all" + height="35" + layout="topleft" + left="6" + right="-6" + name="picks_panel_text" + wrap="true" + top="10"> + No Picks + </text> + <accordion + fit_parent="true" + follows="all" + height="332" + layout="topleft" + left="0" + right="-1" + name="accordion" + top="0" + single_expansion="true"> + <accordion_tab + layout="topleft" + height="101" + min_height="150" + name="tab_picks" + title="Picks" + visible="true"> + <flat_list_view + color="DkGray2" + follows="all" + layout="topleft" + left="0" + name="picks_list" + opaque="true" + top="0" + width="313" /> + </accordion_tab> + <accordion_tab + layout="topleft" + height="101" + name="tab_classifieds" + title="Classifieds" + visible="true"> + <flat_list_view + color="DkGray2" + follows="all" + layout="topleft" + left="0" + name="classifieds_list" + opaque="true" + top="0" + width="313" /> + </accordion_tab> + </accordion> + <panel + bg_opaque_color="DkGray" + background_visible="true" + background_opaque="true" + follows="bottom|left|right" + layout="topleft" + left="0" + height="30" + name="buttons_cucks" + top_pad="0" + width="304"> + <layout_stack + follows="bottom|left|right" + height="28" + layout="topleft" + left="2" + name="buttons_cucks_ls" + orientation="horizontal" + top="0" + width="304"> + <layout_panel + follows="bottom|left|right" + height="28" + layout="topleft" + left="0" + name="info_btn_lp" + auto_resize="true" + top="0" + width="95"> + <button + enabled="false" + follows="top|left|right" + height="23" + label="Info" + layout="topleft" + name="info_btn" + tab_stop="false" + tool_tip="Show pick information" + width="95" /> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="28" + layout="bottomleft" + left_pad="2" + name="teleport_btn_lp" + auto_resize="true" + width="117"> + <button + enabled="false" + follows="top|left|right" + height="23" + label="Teleport" + layout="topleft" + name="teleport_btn" + tab_stop="false" + tool_tip="Teleport to the corresponding area" + width="117" /> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="28" + layout="bottomleft" + name="show_on_map_btn_lp" + auto_resize="true" + left_pad="2" + width="90"> + <button + enabled="false" + follows="top|left|right" + height="23" + label="Map" + layout="topleft" + name="show_on_map_btn" + tab_stop="false" + tool_tip="Show the corresponding area on the World Map" + width="88" /> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml new file mode 100644 index 00000000000..fab76f3cfc6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml @@ -0,0 +1,274 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="all" + label="Second Life" + height="360" + width="304" + class="panel_avatar_secondlife" + name="avatar_secondlife_tab"> + <layout_stack + follows="all" + animate="false" + top="0" + height="360" + left="0" + width="304" + layout="topleft" + orientation="vertical" + show_drag_handle="false"> + <layout_panel + name="avatar_info_top" + follows="top|left|right" + top="0" + left="0" + height="125" + right="-1" + auto_resize="false" + layout="topleft"> + <texture_picker + default_image_name="Generic_Person_Large" + fallback_image="Generic_Person_Large" + follows="left|top" + height="143" + label="" + layout="topleft" + left="5" + name="sl_profile_pic" + no_commit_on_selection="true" + tool_tip="Click to choose a picture" + top="0" + width="120" /> + <text + font="SansSerifSmall" + text_color="White_50" + width="87" + follows="top|left" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left_pad="4" + name="rezday_label" + top_delta="0"> + Born: + </text> + <icon + height="16" + width="16" + visible="false" + image_name="Cake" + tool_tip="Happy rezday" + mouse_opaque="true" + name="cake" + left_pad="2" /> + <text + font="SansSerifSmall" + text_color="ProfileOnlineIndicatorColor" + width="57" + follows="right|top" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + right="-1" + name="online" + top_delta="0" > + Online + </text> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left_delta="-117" + name="rezday" + top_pad="0" > + (Unknown) + </text> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="48" + length="1" + left_delta="0" + name="account_info" + top_pad="2" /> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left_delta="0" + name="partner_label" + top_pad="2"> + Partner: + </text> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left_delta="0" + name="partner_info" + top_pad="2"> + secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect + </text> + </layout_panel> + <layout_panel + name="avatar_desc" + follows="top|left|right" + top_pad="1" + left="0" + height="125" + width="304" + auto_resize="true" + layout="topleft"> + <text_editor + type="string" + follows="all" + left="3" + layout="topleft" + max_length="512" + name="sl_about" + top="0" + bottom="-20" + right="-4" + bg_readonly_color="DkGray2" + text_readonly_color="White" + commit_on_focus_lost="true" + word_wrap="true" /> + <text + font="SansSerifSmall" + text_color="White_50" + follows="bottom|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + right="-4" + name="www" + top_pad="2" /> + <line_editor + top_delta="-2" + follows="left|bottom|right" + layout="topleft" + height="20" + max_length_chars="254" + left="2" + right="-4" + text_pad_left="5" + tool_tip="Website link" + name="www_edit"> + <line_editor.commit_callback + function="Profile.CommitProperties" /> + </line_editor> + </layout_panel> + <layout_panel + visible="true" + name="avatar_perm" + follows="top|left|right" + top_pad="1" + left="0" + height="74" + width="304" + auto_resize="false" + layout="topleft"> + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="permissions_label" + top_pad="2"> + Allow this avatar to: + </text> + <check_box + height="16" + initial_value="false" + label="See when I am online" + layout="topleft" + top_pad="4" + left="5" + name="allow_show_online" + width="150"> + <check_box.commit_callback + function="Profile.CommitRights" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Find me on the world map" + layout="topleft" + top_pad="2" + name="allow_mapping" + width="150"> + <check_box.commit_callback + function="Profile.CommitRights" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Edit, delete, or take my objects" + layout="topleft" + top_pad="2" + name="allow_object_perms" + width="150"> + <check_box.commit_callback + function="Profile.CommitModifyObjectRights" /> + </check_box> + </layout_panel> + <layout_panel + visible="false" + name="avatar_in_search" + follows="top|left|right" + top_pad="1" + left="0" + height="18" + width="304" + auto_resize="false" + layout="topleft"> + <check_box + height="16" + initial_value="true" + label="Show in search" + layout="topleft" + top_pad="0" + left="5" + name="allow_publish" + width="150"> + <check_box.commit_callback + function="Profile.CommitProperties" /> + </check_box> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml new file mode 100644 index 00000000000..223a1357d94 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml @@ -0,0 +1,323 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_opaque="true" + background_visible="true" + follows="all" + height="570" + label="Profile" + layout="topleft" + min_height="350" + left="0" + top="20" + name="Avatar Profile" + width="313"> + <panel.string + name="account_info_fmt"> +[ACCOUNT_TYPE] +[PAYMENT_INFO] +[AGE_VERIFIED] + </panel.string> + <panel.string + name="age_verified"> +Age Verified + </panel.string> + <panel.string + name="rezday_fmt"> +[REZDAY] ([AGE]) + </panel.string> + <panel.string + name="add_friend"> +Add Friend + </panel.string> + <panel.string + name="remove_friend"> +Remove Friend + </panel.string> + <panel + name="avatar_info_top" + follows="top|left|right" + top="0" + left="0" + height="29" + width="313" + layout="topleft"> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back" + left="7" + tab_stop="false" + top="2" + width="30" + use_draw_context_alpha="false" /> + <text_editor + allow_scroll="false" + bg_visible="false" + read_only="true" + layout="topleft" + name="avatar_name" + v_pad="0" + value="(Loading...)" + font="SansSerifHugeBold" + h_pad="0" + height="26" + left_pad="8" + text_color="LtGray" + top="1" + use_ellipses="true" + width="268" + follows="top|left|right" + word_wrap="false" + mouse_opaque="false"/> + <loading_indicator + height="25" + follows="top|right" + layout="topleft" + left_pad="-32" + name="progress_indicator" + top_delta="1" + width="25" /> + </panel> + <layout_stack + name="layout" + orientation="vertical" + follows="all" + left="6" + top_pad="0" + height="506" + width="302" + border_size="0"> + <layout_panel + bg_alpha_color="DkGray2" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + name="avatar_accordions" + follows="all" + layout="topleft" + auto_resize="true" + user_resize="true" + height="513" + width="313"> + <accordion + left="0" + top="0" + single_expansion="true" + fit_parent="true" + follows="all" + layout="topleft" + name="avatar_accordion" + height="513" + width="313"> + <accordion_tab + expanded="true" + layout="topleft" + name="avatar_secondlife_tab" + title="Second Life" + fit_panel="true"> + <panel + border="false" + filename="panel_profile_legacy_secondlife.xml" + layout="topleft" + left="0" + follows="all" + name="secondlife_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_groups_tab" + title="Groups" + fit_panel="true"> + <panel + border="false" + class="panel_profile_legacy_groups" + filename="panel_profile_legacy_groups.xml" + follows="all" + layout="topleft" + left="0" + name="groups_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_interest_tab" + title="Interests" + fit_panel="false"> + <panel + border="false" + filename="panel_profile_legacy_interests.xml" + follows="left|top|right" + layout="topleft" + left="0" + name="interests_tab_panel" + top="0" /> + </accordion_tab> + <!--<accordion_tab + expanded="false" + layout="topleft" + name="avatar_picks_tab" + title="Picks" + fit_panel="true"> + <panel + border="false" + class="panel_profile_legacy_picks" + filename="panel_profile_legacy_picks.xml" + follows="all" + layout="topleft" + left="0" + name="picks_tab_panel" + top="0" /> + </accordion_tab>--> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_firstlife_tab" + title="First Life" + fit_panel="true"> + <panel + border="false" + filename="panel_profile_legacy_firstlife.xml" + follows="left|top|right" + layout="topleft" + left="0" + name="firstlife_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_notes_tab" + title="Notes" + fit_panel="true"> + <panel + border="false" + filename="panel_profile_legacy_notes.xml" + follows="all" + layout="topleft" + left="0" + name="notes_tab_panel" + top="0" /> + </accordion_tab> + </accordion> + </layout_panel> + </layout_stack> + + <layout_stack + follows="bottom|left|right" + height="25" + layout="topleft" + name="button_row_ls" + left="6" + orientation="horizontal" + top_pad="5" + width="299"> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left="0" + name="btn_chat_lp" + auto_resize="true" + width="91"> + <button + follows="bottom|left|right" + left="1" + height="23" + name="btn_chat" + label="Chat" + layout="topleft" + tool_tip="Send an instant message" + top="0" + width="90"> + <button.commit_callback + function="Profile.Action" + parameter="chat" /> + </button> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="btn_friend_lp" + auto_resize="true" + width="91"> + <button + follows="bottom|left|right" + left="1" + height="23" + name="btn_friend" + label="Add Friend" + layout="topleft" + top="0" + width="90"> + <button.commit_callback + function="Profile.Action" + parameter="friend" /> + </button> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="btn_block_lp" + auto_resize="true" + width="91"> + <button + follows="bottom|left|right" + left="1" + height="23" + name="btn_block" + label="Block" + layout="topleft" + tool_tip="Block this avatar" + top="0" + width="90"> + <button.commit_callback + function="Profile.Action" + parameter="block" /> + </button> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="btn_menu_lp" + auto_resize="false" + width="30"> + <menu_button + follows="bottom|left|right" + height="23" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_filename="menu_profile_legacy.xml" + menu_position="bottomleft" + tool_tip="Actions on this avatar" + layout="topleft" + left="1" + top="0" + name="btn_menu" + width="30" /> + </layout_panel> + </layout_stack> + <drop_target + top="0" + bottom="-1" + left="0" + right="-1" + layout="topleft" + follows="all" + name="drop_target" + mouse_opaque="false" /> +</panel> -- GitLab