From b82d70cf2aa2b56a2c0bfdd941ee4f74e690e4df Mon Sep 17 00:00:00 2001 From: Kadah_Coba Date: Mon, 4 Mar 2019 00:18:45 -0800 Subject: Added viewer based profiles Split picks and classifieds in to separate panels Moved getProfileURL to LLAvatarActions Removed dead XUI panels Removed picks/classifieds floater --- indra/newview/llpanelprofile.cpp | 1494 ++++++++++++++++++++++++++++++++------ 1 file changed, 1264 insertions(+), 230 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 8afa35efa0..94169fd06f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpanelprofile.cpp * @brief Profile panel implementation * * $LicenseInfo:firstyear=2009&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$ */ @@ -27,31 +27,65 @@ #include "llviewerprecompiledheaders.h" #include "llpanelprofile.h" -#include "llagent.h" +// Common +#include "llavatarnamecache.h" +#include "llslurl.h" +#include "lldateutil.h" //ageFromDate + +// UI +#include "llavatariconctrl.h" +// #include "llclipboard.h" //gClipboard +#include "llcheckboxctrl.h" +#include "lllineeditor.h" +#include "llloadingindicator.h" +#include "llmenubutton.h" +#include "lltabcontainer.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lltoggleablemenu.h" +#include "llgrouplist.h" + +// Newview +#include "llagent.h" //gAgent +#include "llagentpicksinfo.h" #include "llavataractions.h" -#include "llfloaterreg.h" +#include "llavatarpropertiesprocessor.h" +#include "llcallingcard.h" #include "llcommandhandler.h" -#include "llnotificationsutil.h" -#include "llpanelpicks.h" -#include "lltabcontainer.h" -#include "llviewercontrol.h" -#include "llviewernetwork.h" +#include "llfloaterreg.h" +#include "llfirstuse.h" +#include "llgroupactions.h" #include "llmutelist.h" +#include "llnotificationsutil.h" #include "llpanelblockedlist.h" +#include "llpanelprofileclassifieds.h" +#include "llpanelprofilepicks.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llvoiceclient.h" #include "llweb.h" -static const std::string PANEL_PICKS = "panel_picks"; -std::string getProfileURL(const std::string& agent_name) -{ - std::string url = "[WEB_PROFILE_URL][AGENT_NAME]"; - LLSD subs; - subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL(); - subs["AGENT_NAME"] = agent_name; - url = LLWeb::expandURLSubstitutions(url, subs); - LLStringUtil::toLower(url); - return url; -} +static LLPanelInjector t_panel_profile_secondlife("panel_profile_secondlife"); +static LLPanelInjector t_panel_web("panel_profile_web"); +static LLPanelInjector t_panel_interests("panel_profile_interests"); +static LLPanelInjector t_panel_picks("panel_profile_picks"); +static LLPanelInjector t_panel_firstlife("panel_profile_firstlife"); +static LLPanelInjector t_panel_notes("panel_profile_notes"); +static LLPanelInjector t_panel_profile("panel_profile"); + +static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife"; +static const std::string PANEL_WEB = "panel_profile_web"; +static const std::string PANEL_INTERESTS = "panel_profile_interests"; +static const std::string PANEL_PICKS = "panel_profile_picks"; +static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds"; +static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife"; +static const std::string PANEL_NOTES = "panel_profile_notes"; + + +////////////////////////////////////////////////////////////////////////// +// LLProfileHandler class LLProfileHandler : public LLCommandHandler { @@ -73,6 +107,10 @@ public: }; LLProfileHandler gProfileHandler; + +////////////////////////////////////////////////////////////////////////// +// LLAgentHandler + class LLAgentHandler : public LLCommandHandler { public: @@ -184,273 +222,1269 @@ public: LLAgentHandler gAgentHandler; -//-- LLPanelProfile::ChildStack begins ---------------------------------------- -LLPanelProfile::ChildStack::ChildStack() -: mParent(NULL) + +////////////////////////////////////////////////////////////////////////// +// LLPanelProfileSecondLife + +LLPanelProfileSecondLife::LLPanelProfileSecondLife() + : LLPanelProfileTab() + , mStatusText(NULL) + , mAvatarNameCacheConnection() { } -LLPanelProfile::ChildStack::~ChildStack() +LLPanelProfileSecondLife::~LLPanelProfileSecondLife() { - while (mStack.size() != 0) - { - view_list_t& top = mStack.back(); - for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) - { - LLView* viewp = *it; - if (viewp) - { - viewp->die(); - } - } - mStack.pop_back(); - } + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); + } + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } -void LLPanelProfile::ChildStack::setParent(LLPanel* parent) +BOOL LLPanelProfileSecondLife::postBuild() { - llassert_always(parent != NULL); - mParent = parent; + mStatusText = getChild("status"); + mGroupList = getChild("group_list"); + mShowInSearchCheckbox = getChild("show_in_search_checkbox"); + mSecondLifePic = getChild("2nd_life_pic"); + mDescriptionEdit = getChild("sl_description_edit"); + mTeleportButton = getChild("teleport"); + mShowOnMapButton = getChild("show_on_map_btn"); + mBlockButton = getChild("block"); + mUnblockButton = getChild("unblock"); + mNameLabel = getChild("name_label"); + mDisplayNameButton = getChild("set_name"); + mAddFriendButton = getChild("add_friend"); + mGroupInviteButton = getChild("group_invite"); + mPayButton = getChild("pay"); + mIMButton = getChild("im"); + + mStatusText->setVisible(FALSE); + + mAddFriendButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onAddFriendButtonClick, this)); + mIMButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onIMButtonClick, this)); + mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onTeleportButtonClick, this)); + mShowOnMapButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onMapButtonClick, this)); + mPayButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::pay, this)); + mBlockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::toggleBlock,this)); + mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::toggleBlock,this)); + mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); + mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; + enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); + enable.add("Profile.EnableGod", [](LLUICtrl*, const LLSD&) { return gAgent.isGodlike(); }); + + mGroupList->setDoubleClickCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); + mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); + + LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); + + return TRUE; } -/// Save current parent's child views and remove them from the child list. -bool LLPanelProfile::ChildStack::push() +void LLPanelProfileSecondLife::onOpen(const LLSD& key) { - view_list_t vlist = *mParent->getChildList(); + LLPanelProfileTab::onOpen(key); - for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it) - { - LLView* viewp = *it; - mParent->removeChild(viewp); - } + resetData(); - mStack.push_back(vlist); - dump(); - return true; + LLUUID avatar_id = getAvatarId(); + LLAvatarPropertiesProcessor::getInstance()->addObserver(avatar_id, this); + + BOOL own_profile = getSelfProfile(); + + mGroupInviteButton->setVisible(!own_profile); + mShowOnMapButton->setVisible(!own_profile); + mPayButton->setVisible(!own_profile); + mTeleportButton->setVisible(!own_profile); + mIMButton->setVisible(!own_profile); + mAddFriendButton->setVisible(!own_profile); + mBlockButton->setVisible(!own_profile); + mUnblockButton->setVisible(!own_profile); + mGroupList->setShowNone(!own_profile); + + if (own_profile && !getEmbedded()) + { + // Group list control cannot toggle ForAgent loading + // Less than ideal, but viewing own profile via search is edge case + mGroupList->enableForAgent(false); + } + + if (own_profile && !getEmbedded() ) + { + mNameLabel->setVisible(FALSE); + mDisplayNameButton->setVisible(TRUE); + mDisplayNameButton->setEnabled(TRUE); + } + + mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded()); + + LLProfileDropTarget* drop_target = getChild("drop_target"); + drop_target->setVisible(!own_profile); + drop_target->setEnabled(!own_profile); + + if (!own_profile) + { + mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE); + drop_target->setAgentID(avatar_id); + updateOnlineStatus(); + } + + updateButtons(); + + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); } -/// Restore saved children (adding them back to the child list). -bool LLPanelProfile::ChildStack::pop() +void LLPanelProfileSecondLife::apply(LLAvatarData* data) { - if (mStack.size() == 0) - { - LL_WARNS() << "Empty stack" << LL_ENDL; - llassert(mStack.size() == 0); - return false; - } + if (getIsLoaded() && getSelfProfile()) + { + data->image_id = mSecondLifePic->getImageAssetID(); + data->about_text = mDescriptionEdit->getValue().asString(); + data->allow_publish = mShowInSearchCheckbox->getValue(); - view_list_t& top = mStack.back(); - for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) - { - LLView* viewp = *it; - mParent->addChild(viewp); - } + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(data); + } +} - mStack.pop_back(); - dump(); - return true; +void LLPanelProfileSecondLife::updateData() +{ + LLUUID avatar_id = getAvatarId(); + if (!getIsLoading() && avatar_id.notNull() && !(getSelfProfile() && !getEmbedded())) + { + setIsLoading(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarGroupsRequest(avatar_id); + } } -/// Temporarily add all saved children back. -void LLPanelProfile::ChildStack::preParentReshape() +void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorType type) { - mSavedStack = mStack; - while(mStack.size() > 0) - { - pop(); - } + + if (APT_PROPERTIES == type) + { + const LLAvatarData* avatar_data = static_cast(data); + if(avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProfileProperties(avatar_data); + updateButtons(); + } + } + else if (APT_GROUPS == type) + { + LLAvatarGroups* avatar_groups = static_cast(data); + if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) + { + processGroupProperties(avatar_groups); + } + } } -/// Add the temporarily saved children back. -void LLPanelProfile::ChildStack::postParentReshape() +void LLPanelProfileSecondLife::resetData() { - mStack = mSavedStack; - mSavedStack = stack_t(); + resetLoading(); + getChild("complete_name")->setValue(LLStringUtil::null); + getChild("register_date")->setValue(LLStringUtil::null); + getChild("acc_status_text")->setValue(LLStringUtil::null); + getChild("partner_text")->setValue(LLStringUtil::null); + mSecondLifePic->setValue(mSecondLifePic->getDefaultImageAssetID()); + mDescriptionEdit->setValue(LLStringUtil::null); + mStatusText->setVisible(FALSE); + mGroups.clear(); + mGroupList->setGroups(mGroups); +} - for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it) - { - const view_list_t& vlist = (*stack_it); - for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) - { - LLView* viewp = *list_it; - LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL; - mParent->removeChild(viewp); - } - } +void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) +{ + LLUUID avatar_id = getAvatarId(); + if (!LLAvatarActions::isFriend(avatar_id) && !getSelfProfile()) + { + // this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor. + // in LLPanelProfileSecondLife::processOnlineStatus() + + // subscribe observer to get online status. Request will be sent by LLPanelProfileSecondLife itself. + // do not subscribe for friend avatar because online status can be wrong overridden + // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. + processOnlineStatus(avatar_data->flags & AVATAR_ONLINE); + } + + fillCommonData(avatar_data); + + fillPartnerData(avatar_data); + + fillAccountStatus(avatar_data); } -void LLPanelProfile::ChildStack::dump() +void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups) { - unsigned lvl = 0; - LL_DEBUGS() << "child stack dump:" << LL_ENDL; - for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl) - { - std::ostringstream dbg_line; - dbg_line << "lvl #" << lvl << ":"; - const view_list_t& vlist = (*stack_it); - for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) - { - dbg_line << " " << (*list_it)->getName(); - } - LL_DEBUGS() << dbg_line.str() << LL_ENDL; - } + //KC: the group_list ctrl can handle all this for us on our own profile + if (getSelfProfile() && !getEmbedded()) + { + return; + } + + // *NOTE dzaporozhan + // Group properties may arrive in two callbacks, we need to save them across + // different calls. We can't do that in textbox as textbox may change the text. + + LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); + const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); + + for (; it_end != it; ++it) + { + LLAvatarGroups::LLGroupData group_data = *it; + mGroups[group_data.group_name] = group_data.group_id; + } + + mGroupList->setGroups(mGroups); } -//-- LLPanelProfile::ChildStack ends ------------------------------------------ +void LLPanelProfileSecondLife::openGroupProfile() +{ + LLUUID group_id = mGroupList->getSelectedUUID(); + LLGroupActions::show(group_id); +} -LLPanelProfile::LLPanelProfile() - : LLPanel() - , mAvatarId(LLUUID::null) +void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { - mChildStack.setParent(this); + mAvatarNameCacheConnection.disconnect(); + + getChild("complete_name")->setValue( av_name.getCompleteName() ); } -BOOL LLPanelProfile::postBuild() +void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) { - LLPanelPicks* panel_picks = findChild(PANEL_PICKS); - panel_picks->setProfilePanel(this); + //remove avatar id from cache to get fresh info + LLAvatarIconIDCache::getInstance()->remove(avatar_data->avatar_id); + + LLStringUtil::format_map_t args; + { + std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); + LLStringUtil::format(birth_date, LLSD().with("datetime", (S32) avatar_data->born_on.secondsSinceEpoch())); + args["[REG_DATE]"] = birth_date; + } - getTabContainer()[PANEL_PICKS] = panel_picks; + args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); + std::string register_date = getString("RegisterDateFormat", args); + getChild("register_date")->setValue(register_date ); + mDescriptionEdit->setValue(avatar_data->about_text); + mSecondLifePic->setValue(avatar_data->image_id); - return TRUE; + if (getSelfProfile()) + { + mShowInSearchCheckbox->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); + } } -// virtual -void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent) +void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) { - // Temporarily add saved children back and reshape them. - mChildStack.preParentReshape(); - LLPanel::reshape(width, height, called_from_parent); - mChildStack.postParentReshape(); + LLTextBox* partner_text = getChild("partner_text"); + if (avatar_data->partner_id.notNull()) + { + partner_text->setText(LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString()); + } + else + { + partner_text->setText(getString("no_partner_text")); + } } -void LLPanelProfile::onOpen(const LLSD& key) +void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data) { - getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId()); + LLStringUtil::format_map_t args; + args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data); + args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); - // support commands to open further pieces of UI - if (key.has("show_tab_panel")) - { - std::string panel = key["show_tab_panel"].asString(); - if (panel == "create_classified") - { - LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); - if (picks) - { - picks->createNewClassified(); - } - } - else if (panel == "classified_details") - { - LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); - if (picks) - { - LLSD params = key; - params.erase("show_tab_panel"); - params.erase("open_tab_name"); - picks->openClassifiedInfo(params); - } - } - else if (panel == "edit_classified") - { - LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); - if (picks) - { - LLSD params = key; - params.erase("show_tab_panel"); - params.erase("open_tab_name"); - picks->openClassifiedEdit(params); - } - } - else if (panel == "create_pick") - { - LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); - if (picks) - { - picks->createNewPick(); - } - } - else if (panel == "edit_pick") - { - LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); - if (picks) - { - LLSD params = key; - params.erase("show_tab_panel"); - params.erase("open_tab_name"); - picks->openPickEdit(params); - } - } - } + std::string caption_text = getString("CaptionTextAcctInfo", args); + getChild("acc_status_text")->setValue(caption_text); } -void LLPanelProfile::onTabSelected(const LLSD& param) +void LLPanelProfileSecondLife::onMapButtonClick() { - std::string tab_name = param.asString(); - if (NULL != getTabContainer()[tab_name]) - { - getTabContainer()[tab_name]->onOpen(getAvatarId()); - } + LLAvatarActions::showOnMap(getAvatarId()); } -void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params) +void LLPanelProfileSecondLife::pay() { - // Hide currently visible panel (STORM-690). - mChildStack.push(); + LLAvatarActions::pay(getAvatarId()); +} - // Add the panel or bring it to front. - if (panel->getParent() != this) - { - addChild(panel); - } - else - { - sendChildToFront(panel); - } +void LLPanelProfileSecondLife::toggleBlock() +{ + LLAvatarActions::toggleBlock(getAvatarId()); - panel->setVisible(TRUE); - panel->setFocus(TRUE); // prevent losing focus by the floater - panel->onOpen(params); + updateButtons(); +} - 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 LLPanelProfileSecondLife::onAddFriendButtonClick() +{ + LLAvatarActions::requestFriendshipDialog(getAvatarId()); } -void LLPanelProfile::closePanel(LLPanel* panel) +void LLPanelProfileSecondLife::onIMButtonClick() { - panel->setVisible(FALSE); + LLAvatarActions::startIM(getAvatarId()); +} - if (panel->getParent() == this) - { - removeChild(panel); +void LLPanelProfileSecondLife::onTeleportButtonClick() +{ + LLAvatarActions::offerTeleport(getAvatarId()); +} - // Make the underlying panel visible. - mChildStack.pop(); +void LLPanelProfileSecondLife::onGroupInvite() +{ + LLAvatarActions::inviteToGroup(getAvatarId()); +} - // Prevent losing focus by the floater - const child_list_t* child_list = getChildList(); - if (child_list->size() > 0) - { - child_list->front()->setFocus(TRUE); - } - else - { - LL_WARNS() << "No underlying panel to focus." << LL_ENDL; - } - } +// virtual, called by LLAvatarTracker +void LLPanelProfileSecondLife::changed(U32 mask) +{ + updateOnlineStatus(); + updateButtons(); } -S32 LLPanelProfile::notifyParent(const LLSD& info) +// virtual, called by LLVoiceClient +void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal) { - std::string action = info["action"]; - // lets update Picks list after Pick was saved - if("save_new_pick" == action) - { - onOpen(info); - return 1; - } + if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) + { + return; + } + + mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE); +} + +void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) +{ + if (avatar_id.notNull()) + { + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + + LLPanelProfileTab::setAvatarId(avatar_id); + + if (LLAvatarActions::isFriend(getAvatarId())) + { + LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); + } + } +} + +bool LLPanelProfileSecondLife::isGrantedToSeeOnlineStatus() +{ + // set text box visible to show online status for non-friends who has not set in Preferences + // "Only Friends & Groups can see when I am online" + if (!LLAvatarActions::isFriend(getAvatarId())) + { + return true; + } + + // *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status. + // When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer + // see comments for ChangeUserRights template message. EXT-453. + // If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880 + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); +} + +// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880 +void LLPanelProfileSecondLife::updateOnlineStatus() +{ + if (!LLAvatarActions::isFriend(getAvatarId())) return; + // For friend let check if he allowed me to see his status + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + bool online = relationship->isOnline(); + processOnlineStatus(online); +} - return LLPanel::notifyParent(info); +void LLPanelProfileSecondLife::processOnlineStatus(bool online) +{ + mStatusText->setVisible(isGrantedToSeeOnlineStatus()); + + std::string status = getString(online ? "status_online" : "status_offline"); + + mStatusText->setValue(status); + mStatusText->setColor(online ? + LLUIColorTable::instance().getColor("StatusUserOnline") : + LLUIColorTable::instance().getColor("StatusUserOffline")); } + +void LLPanelProfileSecondLife::updateButtons() +{ + LLPanelProfileTab::updateButtons(); + + if (getSelfProfile() && !getEmbedded()) + { + mShowInSearchCheckbox->setVisible(TRUE); + mShowInSearchCheckbox->setEnabled(TRUE); + mDescriptionEdit->setEnabled(TRUE); + mSecondLifePic->setEnabled(TRUE); + } + + if (!getSelfProfile()) + { + LLUUID av_id = getAvatarId(); + bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); + + if (LLAvatarActions::isFriend(av_id)) + { + mTeleportButton->setEnabled(is_buddy_online); + //Disable "Add Friend" button for friends. + mAddFriendButton->setEnabled(false); + } + else + { + mTeleportButton->setEnabled(true); + mAddFriendButton->setEnabled(true); + } + + bool enable_map_btn = (is_buddy_online && is_agent_mappable(av_id)) || gAgent.isGodlike(); + mShowOnMapButton->setEnabled(enable_map_btn); + + bool enable_block_btn = LLAvatarActions::canBlock(av_id) && !LLAvatarActions::isBlocked(av_id); + mBlockButton->setVisible(enable_block_btn); + + bool enable_unblock_btn = LLAvatarActions::isBlocked(av_id); + mUnblockButton->setVisible(enable_unblock_btn); + } +} + +void LLPanelProfileSecondLife::onClickSetName() +{ + LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); + + LLFirstUse::setDisplayName(false); +} + +void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + if (av_name.getDisplayName().empty()) + { + // something is wrong, tell user to try again later + LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); + return; + } + + LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update " + << LLDate(av_name.mNextUpdate) << LL_ENDL; + F64 now_secs = LLDate::now().secondsSinceEpoch(); + + if (now_secs < av_name.mNextUpdate) + { + // if the update time is more than a year in the future, it means updates have been blocked + // show a more general message + static const S32 YEAR = 60*60*24*365; + if (now_secs + YEAR < av_name.mNextUpdate) + { + LLNotificationsUtil::add("SetDisplayNameBlocked"); + return; + } + } + + LLFloaterReg::showInstance("display_name"); +} + +////////////////////////////////////////////////////////////////////////// +// LLPanelProfileWeb + +LLPanelProfileWeb::LLPanelProfileWeb() + : LLPanelProfileTab() + , mWebBrowser(NULL) + , mAvatarNameCacheConnection() +{ +} + +LLPanelProfileWeb::~LLPanelProfileWeb() +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } +} + +void LLPanelProfileWeb::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + resetData(); + + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2)); +} + +BOOL LLPanelProfileWeb::postBuild() +{ + mUrlEdit = getChild("url_edit"); + mLoadButton = getChild("load"); + mWebProfileButton = getChild("web_profile_popout_btn"); + + mLoadButton->setCommitCallback(boost::bind(&LLPanelProfileWeb::onCommitLoad, this, _1)); + mWebProfileButton->setCommitCallback(boost::bind(&LLPanelProfileWeb::onCommitWebProfile, this)); + + mWebBrowser = getChild("profile_html"); + mWebBrowser->addObserver(this); + mWebBrowser->setHomePageUrl("about:blank"); + + mUrlEdit->setEnabled(FALSE); + + return TRUE; +} + +void LLPanelProfileWeb::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + const LLAvatarData* avatar_data = static_cast(data); + if (avatar_data && getAvatarId() == avatar_data->avatar_id) + { + mURLHome = avatar_data->profile_url; + mUrlEdit->setValue(mURLHome); + mLoadButton->setEnabled(mURLHome.length() > 0); + updateButtons(); + } + } +} + +void LLPanelProfileWeb::resetData() +{ + mURLHome = LLStringUtil::null; + mUrlEdit->setValue(mURLHome); + mWebBrowser->navigateHome(); +} + +void LLPanelProfileWeb::apply(LLAvatarData* data) +{ + data->profile_url = mUrlEdit->getValue().asString(); +} + +void LLPanelProfileWeb::updateData() +{ + LLUUID avatar_id = getAvatarId(); + if (!getIsLoading() && avatar_id.notNull()) + { + setIsLoading(); + + if (!mURLWebProfile.empty()) + { + mWebBrowser->setVisible(TRUE); + mPerformanceTimer.start(); + mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML); + } + } +} + +void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + mAvatarNameCacheConnection.disconnect(); + + std::string username = av_name.getAccountName(); + if (username.empty()) + { + username = LLCacheName::buildUsername(av_name.getDisplayName()); + } + else + { + LLStringUtil::replaceChar(username, ' ', '.'); + } + + mURLWebProfile = getProfileURL(username); + if (mURLWebProfile.empty()) + { + return; + } + + //if the tab was opened before name was resolved, load the panel now + if (getIsLoading()) + { + updateData(); + } +} + +void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl) +{ + if (!mURLHome.empty()) + { + LLSD::String valstr = ctrl->getValue().asString(); + if (valstr.empty()) + { + mWebBrowser->setVisible(TRUE); + mPerformanceTimer.start(); + mWebBrowser->navigateTo( mURLHome, HTTP_CONTENT_TEXT_HTML ); + } + else if (valstr == "popout") + { + // open in viewer's browser, new window + LLWeb::loadURLInternal(mURLHome); + } + else if (valstr == "external") + { + // open in external browser + LLWeb::loadURLExternal(mURLHome); + } + } +} + +void LLPanelProfileWeb::onCommitWebProfile() +{ + // open the web profile floater + LLAvatarActions::showProfileWeb(getAvatarId()); +} + +void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + switch(event) + { + case MEDIA_EVENT_STATUS_TEXT_CHANGED: + childSetValue("status_text", LLSD( self->getStatusText() ) ); + break; + + case MEDIA_EVENT_LOCATION_CHANGED: + // don't set this or user will set there url to profile url + // when clicking ok on there own profile. + // childSetText("url_edit", self->getLocation() ); + break; + + case MEDIA_EVENT_NAVIGATE_BEGIN: + { + if (mFirstNavigate) + { + mFirstNavigate = false; + } + else + { + mPerformanceTimer.start(); + } + } + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + { + LLStringUtil::format_map_t args; + args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32()); + childSetValue("status_text", LLSD( getString("LoadTime", args)) ); + } + break; + + default: + // Having a default case makes the compiler happy. + break; + } +} + +void LLPanelProfileWeb::updateButtons() +{ + LLPanelProfileTab::updateButtons(); + + if (getSelfProfile() && !getEmbedded()) + { + mUrlEdit->setEnabled(TRUE); + } +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +static const S32 WANT_CHECKS = 8; +static const S32 SKILL_CHECKS = 6; + +LLPanelProfileInterests::LLPanelProfileInterests() + : LLPanelProfileTab() +{ +} + +LLPanelProfileInterests::~LLPanelProfileInterests() +{ +} + +void LLPanelProfileInterests::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + resetData(); +} + +BOOL LLPanelProfileInterests::postBuild() +{ + mWantToEditor = getChild("want_to_edit"); + mSkillsEditor = getChild("skills_edit"); + mLanguagesEditor = getChild("languages_edit"); + + for (S32 i = 0; i < WANT_CHECKS; ++i) + { + std::string check_name = llformat("chk%d", i); + mWantChecks[i] = getChild(check_name); + } + + for (S32 i = 0; i < SKILL_CHECKS; ++i) + { + std::string check_name = llformat("schk%d", i); + mSkillChecks[i] = getChild(check_name); + } + + return TRUE; +} + + +void LLPanelProfileInterests::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_INTERESTS_INFO == type) + { + const LLInterestsData* interests_data = static_cast(data); + if (interests_data && getAvatarId() == interests_data->avatar_id) + { + for (S32 i = 0; i < WANT_CHECKS; ++i) + { + if (interests_data->want_to_mask & (1<setValue(TRUE); + } + else + { + mWantChecks[i]->setValue(FALSE); + } + } + + for (S32 i = 0; i < SKILL_CHECKS; ++i) + { + if (interests_data->skills_mask & (1<setValue(TRUE); + } + else + { + mSkillChecks[i]->setValue(FALSE); + } + } + + mWantToEditor->setText(interests_data->want_to_text); + mSkillsEditor->setText(interests_data->skills_text); + mLanguagesEditor->setText(interests_data->languages_text); + + updateButtons(); + } + } +} + +void LLPanelProfileInterests::resetData() +{ + mWantToEditor->setValue(LLStringUtil::null); + mSkillsEditor->setValue(LLStringUtil::null); + mLanguagesEditor->setValue(LLStringUtil::null); + + for (S32 i = 0; i < WANT_CHECKS; ++i) + { + mWantChecks[i]->setValue(FALSE); + } + + for (S32 i = 0; i < SKILL_CHECKS; ++i) + { + mSkillChecks[i]->setValue(FALSE); + } +} + +void LLPanelProfileInterests::apply() +{ + if (getIsLoaded() && getSelfProfile()) + { + LLInterestsData interests_data = LLInterestsData(); + + interests_data.want_to_mask = 0; + for (S32 i = 0; i < WANT_CHECKS; ++i) + { + if (mWantChecks[i]->getValue().asBoolean()) + { + interests_data.want_to_mask |= (1 << i); + } + } + + interests_data.skills_mask = 0; + for (S32 i = 0; i < SKILL_CHECKS; ++i) + { + if (mSkillChecks[i]->getValue().asBoolean()) + { + interests_data.skills_mask |= (1 << i); + } + } + + interests_data.want_to_text = mWantToEditor->getText(); + interests_data.skills_text = mSkillsEditor->getText(); + interests_data.languages_text = mLanguagesEditor->getText(); + + LLAvatarPropertiesProcessor::getInstance()->sendInterestsInfoUpdate(&interests_data); + } + +} + +void LLPanelProfileInterests::updateButtons() +{ + LLPanelProfileTab::updateButtons(); + + if (getSelfProfile() && !getEmbedded()) + { + mWantToEditor->setEnabled(TRUE); + mSkillsEditor->setEnabled(TRUE); + mLanguagesEditor->setEnabled(TRUE); + + for (S32 i = 0; i < WANT_CHECKS; ++i) + { + mWantChecks[i]->setEnabled(TRUE); + } + + for (S32 i = 0; i < SKILL_CHECKS; ++i) + { + mSkillChecks[i]->setEnabled(TRUE); + } + } +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelProfileFirstLife::LLPanelProfileFirstLife() + : LLPanelProfileTab(), + mIsEditing(false) +{ +} + +LLPanelProfileFirstLife::~LLPanelProfileFirstLife() +{ +} + +BOOL LLPanelProfileFirstLife::postBuild() +{ + mDescriptionEdit = getChild("fl_description_edit"); + mPicture = getChild("real_world_pic"); + + mDescriptionEdit->setFocusReceivedCallback(boost::bind(&LLPanelProfileFirstLife::onDescriptionFocusReceived, this)); + + return TRUE; +} + +void LLPanelProfileFirstLife::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + resetData(); +} + + +void LLPanelProfileFirstLife::onDescriptionFocusReceived() +{ + if (!mIsEditing && getSelfProfile()) + { + mIsEditing = true; + mDescriptionEdit->setParseHTML(false); + mDescriptionEdit->setText(mCurrentDescription); + } +} + +void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + const LLAvatarData* avatar_data = static_cast(data); + if (avatar_data && getAvatarId() == avatar_data->avatar_id) + { + mCurrentDescription = avatar_data->fl_about_text; + mDescriptionEdit->setValue(mCurrentDescription); + mPicture->setValue(avatar_data->fl_image_id); + updateButtons(); + } + } +} + +void LLPanelProfileFirstLife::resetData() +{ + mDescriptionEdit->setValue(LLStringUtil::null); + mPicture->setValue(mPicture->getDefaultImageAssetID()); +} + +void LLPanelProfileFirstLife::apply(LLAvatarData* data) +{ + data->fl_image_id = mPicture->getImageAssetID(); + data->fl_about_text = mDescriptionEdit->getValue().asString(); +} + +void LLPanelProfileFirstLife::updateButtons() +{ + LLPanelProfileTab::updateButtons(); + + if (getSelfProfile() && !getEmbedded()) + { + mDescriptionEdit->setEnabled(TRUE); + mPicture->setEnabled(TRUE); + } +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelProfileNotes::LLPanelProfileNotes() +: LLPanelProfileTab() +{ + +} + +void LLPanelProfileNotes::updateData() +{ + LLUUID avatar_id = getAvatarId(); + if (!getIsLoading() && avatar_id.notNull()) + { + setIsLoading(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarNotesRequest(avatar_id); + } +} + +BOOL LLPanelProfileNotes::postBuild() +{ + mOnlineStatus = getChild("status_check"); + mMapRights = getChild("map_check"); + mEditObjectRights = getChild("objects_check"); + mNotesEditor = getChild("notes_edit"); + + mOnlineStatus->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); + mMapRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); + mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); + + mNotesEditor->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitNotes,this)); + mNotesEditor->setCommitOnFocusLost(TRUE); + + return TRUE; +} + +void LLPanelProfileNotes::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + resetData(); + + fillRightsData(); +} + +void LLPanelProfileNotes::apply() +{ + onCommitNotes(); +} + +void LLPanelProfileNotes::fillRightsData() +{ + mOnlineStatus->setValue(FALSE); + mMapRights->setValue(FALSE); + mEditObjectRights->setValue(FALSE); + + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + // If true - we are viewing friend's profile, enable check boxes and set values. + if(relation) + { + S32 rights = relation->getRightsGrantedTo(); + + mOnlineStatus->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); + mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + } + + enableCheckboxes(NULL != relation); +} + +void LLPanelProfileNotes::onCommitNotes() +{ + if (getIsLoaded()) + { + std::string notes = mNotesEditor->getValue().asString(); + LLAvatarPropertiesProcessor::getInstance()->sendNotes(getAvatarId(),notes); + } +} + +void LLPanelProfileNotes::rightsConfirmationCallback(const LLSD& notification, + const LLSD& response, S32 rights) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), rights); + } + else + { + mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); + } +} + +void LLPanelProfileNotes::confirmModifyRights(bool grant, S32 rights) +{ + LLSD args; + args["NAME"] = LLSLURL("agent", getAvatarId(), "completename").getSLURLString(); + + if (grant) + { + LLNotificationsUtil::add("GrantModifyRights", args, LLSD(), + boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, + _1, _2, rights)); + } + else + { + LLNotificationsUtil::add("RevokeModifyRights", args, LLSD(), + boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, + _1, _2, rights)); + } +} + +void LLPanelProfileNotes::onCommitRights() +{ + const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + + if (!buddy_relationship) + { + // Lets have a warning log message instead of having a crash. EXT-4947. + LL_WARNS("LegacyProfile") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; + return; + } + + S32 rights = 0; + + if (mOnlineStatus->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_ONLINE_STATUS; + } + if (mMapRights->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_MAP_LOCATION; + } + if (mEditObjectRights->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + } + + bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); + + // if modify objects checkbox clicked + if (buddy_relationship->isRightGrantedTo( + LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) + { + confirmModifyRights(allow_modify_objects, rights); + } + // only one checkbox can trigger commit, so store the rest of rights + else + { + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights( + getAvatarId(), rights); + } +} + +void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_NOTES == type) + { + LLAvatarNotes* avatar_notes = static_cast(data); + if (avatar_notes && getAvatarId() == avatar_notes->target_id) + { + mNotesEditor->setValue(avatar_notes->notes); + mNotesEditor->setEnabled(TRUE); + updateButtons(); + + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + } + } +} + +void LLPanelProfileNotes::resetData() +{ + resetLoading(); + mNotesEditor->setValue(LLStringUtil::null); + mOnlineStatus->setValue(FALSE); + mMapRights->setValue(FALSE); + mEditObjectRights->setValue(FALSE); +} + +void LLPanelProfileNotes::enableCheckboxes(bool enable) +{ + mOnlineStatus->setEnabled(enable); + mMapRights->setEnabled(enable); + mEditObjectRights->setEnabled(enable); +} + +LLPanelProfileNotes::~LLPanelProfileNotes() +{ + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } +} + +// virtual, called by LLAvatarTracker +void LLPanelProfileNotes::changed(U32 mask) +{ + // update rights to avoid have checkboxes enabled when friendship is terminated. EXT-4947. + fillRightsData(); +} + +void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) +{ + if (avatar_id.notNull()) + { + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + LLPanelProfileTab::setAvatarId(avatar_id); + LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); + } +} + + +////////////////////////////////////////////////////////////////////////// +// LLPanelProfile + +LLPanelProfile::LLPanelProfile() + : LLPanelProfileTab() +{ +} + +LLPanelProfile::~LLPanelProfile() +{ +} + +BOOL LLPanelProfile::postBuild() +{ + return TRUE; +} + +void LLPanelProfile::processProperties(void* data, EAvatarProcessorType type) +{ + //*TODO: figure out what this does + mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this)); + + // Load data on currently opened tab as well + onTabChange(); +} + +void LLPanelProfile::onTabChange() +{ + LLPanelProfileTab* active_panel = dynamic_cast(mTabContainer->getCurrentPanel()); + if (active_panel) + { + active_panel->updateData(); + } +} + +void LLPanelProfile::onOpen(const LLSD& key) +{ + LLUUID avatar_id = key["id"].asUUID(); + + // Don't reload the same profile + if (getAvatarId() == avatar_id) + { + return; + } + + LLPanelProfileTab::onOpen(avatar_id); + + mTabContainer = getChild("panel_profile_tabs"); + mPanelSecondlife = findChild(PANEL_SECONDLIFE); + mPanelWeb = findChild(PANEL_WEB); + mPanelInterests = findChild(PANEL_INTERESTS); + mPanelPicks = findChild(PANEL_PICKS); + mPanelClassifieds = findChild(PANEL_CLASSIFIEDS); + mPanelFirstlife = findChild(PANEL_FIRSTLIFE); + mPanelNotes = findChild(PANEL_NOTES); + + mPanelSecondlife->onOpen(avatar_id); + mPanelWeb->onOpen(avatar_id); + mPanelInterests->onOpen(avatar_id); + mPanelPicks->onOpen(avatar_id); + mPanelClassifieds->onOpen(avatar_id); + mPanelFirstlife->onOpen(avatar_id); + mPanelNotes->onOpen(avatar_id); + + mPanelSecondlife->setEmbedded(getEmbedded()); + mPanelWeb->setEmbedded(getEmbedded()); + mPanelInterests->setEmbedded(getEmbedded()); + mPanelPicks->setEmbedded(getEmbedded()); + mPanelClassifieds->setEmbedded(getEmbedded()); + mPanelFirstlife->setEmbedded(getEmbedded()); + mPanelNotes->setEmbedded(getEmbedded()); + + // Always request the base profile info + resetLoading(); + updateData(); + + // Only show commit buttons on own profile on floater version + if (getSelfProfile() && !getEmbedded()) + { + getChild("ok_btn")->setVisible(TRUE); + getChild("cancel_btn")->setVisible(TRUE); + } + + // KC - Not handling pick and classified opening thru onOpen + // because this would make unique profile floaters per slurl + // and result in multiple profile floaters for the same avatar +} + +void LLPanelProfile::updateData() +{ + LLUUID avatar_id = getAvatarId(); + if (!getIsLoading() && avatar_id.notNull()) + { + setIsLoading(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + } +} + +void LLPanelProfile::apply() +{ + if (getSelfProfile()) + { + //KC - AvatarData is spread over 3 different panels + // collect data from the last 2 and give to the first to save + LLAvatarData data = LLAvatarData(); + data.avatar_id = gAgentID; + mPanelFirstlife->apply(&data); + mPanelWeb->apply(&data); + mPanelSecondlife->apply(&data); + + mPanelInterests->apply(); + mPanelPicks->apply(); + mPanelNotes->apply(); + + //KC - Classifieds handles this itself + } +} + +void LLPanelProfile::showPick(const LLUUID& pick_id) +{ + if (pick_id.notNull()) + { + mPanelPicks->selectPick(pick_id); + } + mTabContainer->selectTabPanel(mPanelPicks); +} + +void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) +{ + if (classified_id.notNull()) + { + mPanelClassifieds->selectClassified(classified_id, edit); + } + mTabContainer->selectTabPanel(mPanelClassifieds); +} + + + -- cgit v1.2.3 From f0208fa72f2cc980ec9ca2b954a680b94392ffff Mon Sep 17 00:00:00 2001 From: Kadah_Coba Date: Mon, 4 Mar 2019 22:57:22 -0800 Subject: Removed redundant view_border elements --- indra/newview/llpanelprofile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 94169fd06f..fea76f9d04 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -488,7 +488,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) { - LLTextBox* partner_text = getChild("partner_text"); + LLTextEditor* partner_text = getChild("partner_text"); if (avatar_data->partner_id.notNull()) { partner_text->setText(LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString()); -- cgit v1.2.3 From eddd952cdeaaabf1b2ab91e9b62aec553621ff82 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 19 Mar 2019 20:26:22 +0200 Subject: SL-10730 [Legacy profiles] 'Cancel' does not discard changes at the Notes tab --- indra/newview/llpanelprofile.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index fea76f9d04..8fbd7fe726 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1166,7 +1166,6 @@ BOOL LLPanelProfileNotes::postBuild() mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); mNotesEditor->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitNotes,this)); - mNotesEditor->setCommitOnFocusLost(TRUE); return TRUE; } -- cgit v1.2.3 From e0b24ee960c7a7eebb9e7d6e4b5974973eb3da00 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Mon, 25 Mar 2019 15:38:26 +0200 Subject: SL-10798 FIXED [Legacy Profiles] 'Picks' toolbar button does nothing --- indra/newview/llpanelprofile.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 8fbd7fe726..3a772a8104 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1476,6 +1476,12 @@ void LLPanelProfile::showPick(const LLUUID& pick_id) mTabContainer->selectTabPanel(mPanelPicks); } +bool LLPanelProfile::isPickTabSelected() +{ + return (mTabContainer->getCurrentPanel() == mPanelPicks); +} + + void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) { if (classified_id.notNull()) -- cgit v1.2.3 From 458d318aebd7a7da8ea2c594b8df2f285f7efded Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 25 Mar 2019 17:19:11 +0200 Subject: SL-10804 [Legacy Profiles] Second Life tab block button size and focus --- indra/newview/llpanelprofile.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 3a772a8104..4933b0d25e 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -276,8 +276,8 @@ BOOL LLPanelProfileSecondLife::postBuild() mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onTeleportButtonClick, this)); mShowOnMapButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onMapButtonClick, this)); mPayButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::pay, this)); - mBlockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::toggleBlock,this)); - mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::toggleBlock,this)); + mBlockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); + mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); @@ -519,11 +519,20 @@ void LLPanelProfileSecondLife::pay() LLAvatarActions::pay(getAvatarId()); } -void LLPanelProfileSecondLife::toggleBlock() +void LLPanelProfileSecondLife::onClickToggleBlock() { - LLAvatarActions::toggleBlock(getAvatarId()); + bool blocked = LLAvatarActions::toggleBlock(getAvatarId()); updateButtons(); + // we are hiding one button and showing another, set focus + if (blocked) + { + mUnblockButton->setFocus(true); + } + else + { + mBlockButton->setFocus(true); + } } void LLPanelProfileSecondLife::onAddFriendButtonClick() -- cgit v1.2.3 From 5143456f51d32b90a94b6c01aebb74c3503a3e27 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 25 Mar 2019 18:09:23 +0200 Subject: SL-10799 [Legacy Profiles] added 3x4 image dimentions support --- indra/newview/llpanelprofile.cpp | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 4933b0d25e..b03fcabd92 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -257,6 +257,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mGroupList = getChild("group_list"); mShowInSearchCheckbox = getChild("show_in_search_checkbox"); mSecondLifePic = getChild("2nd_life_pic"); + mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); mTeleportButton = getChild("teleport"); mShowOnMapButton = getChild("show_on_map_btn"); @@ -397,7 +398,12 @@ void LLPanelProfileSecondLife::resetData() getChild("register_date")->setValue(LLStringUtil::null); getChild("acc_status_text")->setValue(LLStringUtil::null); getChild("partner_text")->setValue(LLStringUtil::null); + + // Set default image and 1:1 dimensions for it mSecondLifePic->setValue(mSecondLifePic->getDefaultImageAssetID()); + LLRect imageRect = mSecondLifePicLayout->getRect(); + mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); + mDescriptionEdit->setValue(LLStringUtil::null); mStatusText->setVisible(FALSE); mGroups.clear(); @@ -480,6 +486,23 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) mDescriptionEdit->setValue(avatar_data->about_text); mSecondLifePic->setValue(avatar_data->image_id); + //Don't bother about boost level, picker will set it + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); + if (imagep->getHeight()) + { + onImageLoaded(true, imagep); + } + else + { + imagep->setLoadedCallback(onImageLoaded, + MAX_DISCARD_LEVEL, + FALSE, + FALSE, + new LLHandle(getHandle()), + NULL, + FALSE); + } + if (getSelfProfile()) { mShowInSearchCheckbox->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); @@ -555,6 +578,48 @@ void LLPanelProfileSecondLife::onGroupInvite() LLAvatarActions::inviteToGroup(getAvatarId()); } +void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) +{ + LLRect imageRect = mSecondLifePicLayout->getRect(); + if (!success || imagep->getWidth() == imagep->getHeight()) + { + mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); + } + else + { + // assume 3:4, for sake of firestorm + mSecondLifePicLayout->reshape(imageRect.getHeight() * 4 / 3, imageRect.getHeight()); + } +} + +//static +void LLPanelProfileSecondLife::onImageLoaded(BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata) +{ + if (!userdata) return; + + LLHandle* handle = (LLHandle*)userdata; + + if (!handle->isDead()) + { + LLPanelProfileSecondLife* panel = static_cast(handle->get()); + if (panel) + { + panel->onImageLoaded(success, src_vi); + } + } + + if (final || !success) + { + delete handle; + } +} + // virtual, called by LLAvatarTracker void LLPanelProfileSecondLife::changed(U32 mask) { -- cgit v1.2.3 From 3c4cf92932fb8215f496e4100cfa3b6f3a4372b4 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 26 Mar 2019 16:13:44 +0200 Subject: SL-10799 [Legacy Profiles] Autoadjust texture during image selection --- indra/newview/llpanelprofile.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index b03fcabd92..d03d3f59b8 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -281,6 +281,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); + mSecondLifePic->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onCommitTexture, this)); LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); @@ -488,7 +489,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) //Don't bother about boost level, picker will set it LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); - if (imagep->getHeight()) + if (imagep->getFullHeight()) { onImageLoaded(true, imagep); } @@ -581,7 +582,7 @@ void LLPanelProfileSecondLife::onGroupInvite() void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) { LLRect imageRect = mSecondLifePicLayout->getRect(); - if (!success || imagep->getWidth() == imagep->getHeight()) + if (!success || imagep->getFullWidth() == imagep->getFullHeight()) { mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); } @@ -742,6 +743,25 @@ void LLPanelProfileSecondLife::onClickSetName() LLFirstUse::setDisplayName(false); } +void LLPanelProfileSecondLife::onCommitTexture() +{ + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(mSecondLifePic->getImageAssetID()); + if (imagep->getFullHeight()) + { + onImageLoaded(true, imagep); + } + else + { + imagep->setLoadedCallback(onImageLoaded, + MAX_DISCARD_LEVEL, + FALSE, + FALSE, + new LLHandle(getHandle()), + NULL, + FALSE); + } +} + void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name) { if (av_name.getDisplayName().empty()) -- cgit v1.2.3 From f74071b19fcac12b92a5f3611a068be30ae3fbd2 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 26 Mar 2019 18:12:19 +0200 Subject: SL-2878 Fixed eternal properties rerequests --- indra/newview/llpanelprofile.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index d03d3f59b8..e5fa8de6a0 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -471,8 +471,9 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) { - //remove avatar id from cache to get fresh info - LLAvatarIconIDCache::getInstance()->remove(avatar_data->avatar_id); + // Refresh avatar id in cache with new info to prevent re-requests + // and to make sure icons in text will be up to date + LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); LLStringUtil::format_map_t args; { -- cgit v1.2.3 From 8a3fce881fbf971046be50d9d7198e58772e3164 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 18 Apr 2019 19:26:37 +0300 Subject: SL-10791 [Legacy Profiles] Functionality to copy agent id and name from profile --- indra/newview/llpanelprofile.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index e5fa8de6a0..d40f874f24 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -34,7 +34,7 @@ // UI #include "llavatariconctrl.h" -// #include "llclipboard.h" //gClipboard +#include "llclipboard.h" #include "llcheckboxctrl.h" #include "lllineeditor.h" #include "llloadingindicator.h" @@ -269,8 +269,10 @@ BOOL LLPanelProfileSecondLife::postBuild() mGroupInviteButton = getChild("group_invite"); mPayButton = getChild("pay"); mIMButton = getChild("im"); + mCopyMenuButton = getChild("copy_btn"); mStatusText->setVisible(FALSE); + mCopyMenuButton->setVisible(FALSE); mAddFriendButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onAddFriendButtonClick, this)); mIMButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onIMButtonClick, this)); @@ -283,6 +285,9 @@ BOOL LLPanelProfileSecondLife::postBuild() mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); mSecondLifePic->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onCommitTexture, this)); + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; + commit.add("Profile.CopyName", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); enable.add("Profile.EnableGod", [](LLUICtrl*, const LLSD&) { return gAgent.isGodlike(); }); @@ -291,6 +296,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); + mCopyMenuButton->setMenu("menu_name_field.xml", LLMenuButton::MP_BOTTOM_RIGHT); return TRUE; } @@ -407,6 +413,7 @@ void LLPanelProfileSecondLife::resetData() mDescriptionEdit->setValue(LLStringUtil::null); mStatusText->setVisible(FALSE); + mCopyMenuButton->setVisible(FALSE); mGroups.clear(); mGroupList->setGroups(mGroups); } @@ -467,6 +474,7 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L mAvatarNameCacheConnection.disconnect(); getChild("complete_name")->setValue( av_name.getCompleteName() ); + mCopyMenuButton->setVisible(TRUE); } void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) @@ -763,6 +771,33 @@ void LLPanelProfileSecondLife::onCommitTexture() } } +void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) +{ + LLAvatarName av_name; + if (!LLAvatarNameCache::get(getAvatarId(), &av_name)) + { + // shouldn't happen, button(menu) is supposed to be invisible while name is fetching + LL_WARNS() << "Failed to get agent data" << LL_ENDL; + return; + } + + const std::string item_name = userdata.asString(); + LLWString wstr; + if (item_name == "display") + { + wstr = utf8str_to_wstring(av_name.getDisplayName()); + } + else if (item_name == "name") + { + wstr = utf8str_to_wstring(av_name.getAccountName()); + } + else if (item_name == "id") + { + wstr = utf8str_to_wstring(getAvatarId().asString()); + } + LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); +} + void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name) { if (av_name.getDisplayName().empty()) -- cgit v1.2.3 From 04eee0ac24de1bf1744ed7a8707a847961fe7192 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 25 Apr 2019 16:07:20 +0300 Subject: SL-11031 [Legacy Profiles] "Drop inventory" field visible for own profile --- indra/newview/llpanelprofile.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index d40f874f24..6c0b1b9047 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -270,6 +270,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mPayButton = getChild("pay"); mIMButton = getChild("im"); mCopyMenuButton = getChild("copy_btn"); + mGiveInvPanel = getChild("give_stack"); mStatusText->setVisible(FALSE); mCopyMenuButton->setVisible(FALSE); @@ -321,6 +322,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mBlockButton->setVisible(!own_profile); mUnblockButton->setVisible(!own_profile); mGroupList->setShowNone(!own_profile); + mGiveInvPanel->setVisible(!own_profile); if (own_profile && !getEmbedded()) { -- cgit v1.2.3 From 023a69720876eaec0135b8536e1945db95336a36 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Mon, 3 Jun 2019 17:19:05 +0300 Subject: SL-11344 FIXED Private notes are not saved for another avatar --- indra/newview/llpanelprofile.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 6c0b1b9047..a60493a360 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1514,6 +1514,13 @@ void LLPanelProfile::onTabChange() { active_panel->updateData(); } + updateBtnsVisibility(); +} + +void LLPanelProfile::updateBtnsVisibility() +{ + getChild("ok_btn")->setVisible(((getSelfProfile() && !getEmbedded()) || isNotesTabSelected())); + getChild("cancel_btn")->setVisible(((getSelfProfile() && !getEmbedded()) || isNotesTabSelected())); } void LLPanelProfile::onOpen(const LLSD& key) @@ -1557,12 +1564,7 @@ void LLPanelProfile::onOpen(const LLSD& key) resetLoading(); updateData(); - // Only show commit buttons on own profile on floater version - if (getSelfProfile() && !getEmbedded()) - { - getChild("ok_btn")->setVisible(TRUE); - getChild("cancel_btn")->setVisible(TRUE); - } + updateBtnsVisibility(); // KC - Not handling pick and classified opening thru onOpen // because this would make unique profile floaters per slurl @@ -1597,6 +1599,10 @@ void LLPanelProfile::apply() //KC - Classifieds handles this itself } + else + { + mPanelNotes->apply(); + } } void LLPanelProfile::showPick(const LLUUID& pick_id) @@ -1613,6 +1619,10 @@ bool LLPanelProfile::isPickTabSelected() return (mTabContainer->getCurrentPanel() == mPanelPicks); } +bool LLPanelProfile::isNotesTabSelected() +{ + return (mTabContainer->getCurrentPanel() == mPanelNotes); +} void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) { -- cgit v1.2.3 From 69a85e3ed0960d90c2a093029768a550fb3f591d Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Wed, 12 Jun 2019 13:43:29 +0300 Subject: SL-11409 [Legacy Profiles] Copy Display name correctly regardless of View Display Names setting. --- indra/newview/llpanelprofile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index a60493a360..472285e3d9 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -787,7 +787,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) LLWString wstr; if (item_name == "display") { - wstr = utf8str_to_wstring(av_name.getDisplayName()); + wstr = utf8str_to_wstring(av_name.getDisplayName(true)); } else if (item_name == "name") { -- cgit v1.2.3 From dbe5eb8a1dc18811f945f689f026cdcf180496dd Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Tue, 25 Jun 2019 17:54:21 +0300 Subject: SL-11431 [Legacy Profiles] Clicking someone else's profile picture should open image modal. --- indra/newview/llpanelprofile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 472285e3d9..86b6163f45 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -324,6 +324,8 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mGroupList->setShowNone(!own_profile); mGiveInvPanel->setVisible(!own_profile); + mSecondLifePic->setOpenTexPreview(!own_profile); + if (own_profile && !getEmbedded()) { // Group list control cannot toggle ForAgent loading @@ -716,7 +718,6 @@ void LLPanelProfileSecondLife::updateButtons() mShowInSearchCheckbox->setVisible(TRUE); mShowInSearchCheckbox->setEnabled(TRUE); mDescriptionEdit->setEnabled(TRUE); - mSecondLifePic->setEnabled(TRUE); } if (!getSelfProfile()) -- cgit v1.2.3 From 38a0a95431a67a9fac924a372189b6c4364d5c5f Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Mon, 8 Jul 2019 13:47:21 +0300 Subject: SL-11554 [Legacy Profiles] The avatar permissions values are not saved/shown correctly in some cases --- indra/newview/llpanelprofile.cpp | 64 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 35 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 86b6163f45..2c07ff576d 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1294,8 +1294,6 @@ BOOL LLPanelProfileNotes::postBuild() mEditObjectRights = getChild("objects_check"); mNotesEditor = getChild("notes_edit"); - mOnlineStatus->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); - mMapRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); mNotesEditor->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitNotes,this)); @@ -1315,6 +1313,7 @@ void LLPanelProfileNotes::onOpen(const LLSD& key) void LLPanelProfileNotes::apply() { onCommitNotes(); + applyRights(); } void LLPanelProfileNotes::fillRightsData() @@ -1347,39 +1346,47 @@ void LLPanelProfileNotes::onCommitNotes() } void LLPanelProfileNotes::rightsConfirmationCallback(const LLSD& notification, - const LLSD& response, S32 rights) + const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), rights); - } - else + if (option != 0) { mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); } } -void LLPanelProfileNotes::confirmModifyRights(bool grant, S32 rights) +void LLPanelProfileNotes::confirmModifyRights(bool grant) { LLSD args; args["NAME"] = LLSLURL("agent", getAvatarId(), "completename").getSLURLString(); - if (grant) - { - LLNotificationsUtil::add("GrantModifyRights", args, LLSD(), - boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, - _1, _2, rights)); - } - else - { - LLNotificationsUtil::add("RevokeModifyRights", args, LLSD(), - boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, - _1, _2, rights)); - } + + LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(), + boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, _1, _2)); + } void LLPanelProfileNotes::onCommitRights() +{ + const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + + if (!buddy_relationship) + { + LL_WARNS("LegacyProfile") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; + return; + } + + bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); + + // if modify objects checkbox clicked + if (buddy_relationship->isRightGrantedTo( + LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) + { + confirmModifyRights(allow_modify_objects); + } +} + +void LLPanelProfileNotes::applyRights() { const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); @@ -1405,20 +1412,7 @@ void LLPanelProfileNotes::onCommitRights() rights |= LLRelationship::GRANT_MODIFY_OBJECTS; } - bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); - - // if modify objects checkbox clicked - if (buddy_relationship->isRightGrantedTo( - LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) - { - confirmModifyRights(allow_modify_objects, rights); - } - // only one checkbox can trigger commit, so store the rest of rights - else - { - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights( - getAvatarId(), rights); - } + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), rights); } void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) -- cgit v1.2.3 From 59a8f73725a23e748d9f54e033735535e617dce7 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Tue, 16 Jul 2019 13:43:39 +0300 Subject: SL-11594 FIXED [Viewer Profile Project] 'OK' button does not save changes at 'Profile' - 'Classifieds' tab --- indra/newview/llpanelprofile.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 2c07ff576d..1b3462176e 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1591,6 +1591,7 @@ void LLPanelProfile::apply() mPanelInterests->apply(); mPanelPicks->apply(); mPanelNotes->apply(); + mPanelClassifieds->apply(); //KC - Classifieds handles this itself } -- cgit v1.2.3 From b1ac8092eecf5fc9dc4b4867370a51e5dfba4331 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Wed, 13 Nov 2019 09:31:26 +0200 Subject: SL-10790 Don't show excessive information on the Profile Feed tab --- indra/newview/llpanelprofile.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 1b3462176e..1620a01d1c 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -904,16 +904,13 @@ void LLPanelProfileWeb::apply(LLAvatarData* data) void LLPanelProfileWeb::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull()) + if (!getIsLoading() && avatar_id.notNull() && !mURLWebProfile.empty()) { setIsLoading(); - if (!mURLWebProfile.empty()) - { - mWebBrowser->setVisible(TRUE); - mPerformanceTimer.start(); - mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML); - } + mWebBrowser->setVisible(TRUE); + mPerformanceTimer.start(); + mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML); } } @@ -931,17 +928,14 @@ void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatar LLStringUtil::replaceChar(username, ' ', '.'); } - mURLWebProfile = getProfileURL(username); + mURLWebProfile = getProfileURL(username, true); if (mURLWebProfile.empty()) { return; } //if the tab was opened before name was resolved, load the panel now - if (getIsLoading()) - { - updateData(); - } + updateData(); } void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl) -- cgit v1.2.3 From 81c107180bc2698aec10d655111cdb8a584a7a3a Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Fri, 3 Jan 2020 05:54:15 +0200 Subject: SL-12470 Force the feed browser to open the links in the same window --- indra/newview/llpanelprofile.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 0e50e8bdd0..cc5332a7db 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -854,6 +854,11 @@ void LLPanelProfileWeb::onOpen(const LLSD& key) resetData(); mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2)); + + if (mWebBrowser->getMediaPlugin()) + { + mWebBrowser->getMediaPlugin()->setOverrideClickTarget("_navigate"); + } } BOOL LLPanelProfileWeb::postBuild() @@ -1000,6 +1005,7 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e LLStringUtil::format_map_t args; args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32()); childSetValue("status_text", LLSD( getString("LoadTime", args)) ); + resetLoading(); } break; -- cgit v1.2.3 From 1d1f2e95f2da9cd530f2336a8e661d16a512c064 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 5 Feb 2020 18:32:29 +0200 Subject: Revert "SL-12470 Force the feed browser to open the links in the same window" This reverts commit 81c107180bc2698aec10d655111cdb8a584a7a3a. --- indra/newview/llpanelprofile.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index cc5332a7db..0e50e8bdd0 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -854,11 +854,6 @@ void LLPanelProfileWeb::onOpen(const LLSD& key) resetData(); mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2)); - - if (mWebBrowser->getMediaPlugin()) - { - mWebBrowser->getMediaPlugin()->setOverrideClickTarget("_navigate"); - } } BOOL LLPanelProfileWeb::postBuild() @@ -1005,7 +1000,6 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e LLStringUtil::format_map_t args; args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32()); childSetValue("status_text", LLSD( getString("LoadTime", args)) ); - resetLoading(); } break; -- cgit v1.2.3 From ad1052039cfdd0e9a95304874cf1347e1472d36f Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 5 Feb 2020 19:33:36 +0200 Subject: SL-12550 Profile feed tab cleanup SL-12550 Profile feed tab cleanup --- indra/newview/llpanelprofile.cpp | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 0e50e8bdd0..2cd5aecc2e 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -858,19 +858,10 @@ void LLPanelProfileWeb::onOpen(const LLSD& key) BOOL LLPanelProfileWeb::postBuild() { - mUrlEdit = getChild("url_edit"); - mLoadButton = getChild("load"); - mWebProfileButton = getChild("web_profile_popout_btn"); - - mLoadButton->setCommitCallback(boost::bind(&LLPanelProfileWeb::onCommitLoad, this, _1)); - mWebProfileButton->setCommitCallback(boost::bind(&LLPanelProfileWeb::onCommitWebProfile, this)); - mWebBrowser = getChild("profile_html"); mWebBrowser->addObserver(this); mWebBrowser->setHomePageUrl("about:blank"); - mUrlEdit->setEnabled(FALSE); - return TRUE; } @@ -881,9 +872,6 @@ void LLPanelProfileWeb::processProperties(void* data, EAvatarProcessorType type) const LLAvatarData* avatar_data = static_cast(data); if (avatar_data && getAvatarId() == avatar_data->avatar_id) { - mURLHome = avatar_data->profile_url; - mUrlEdit->setValue(mURLHome); - mLoadButton->setEnabled(mURLHome.length() > 0); updateButtons(); } } @@ -891,14 +879,12 @@ void LLPanelProfileWeb::processProperties(void* data, EAvatarProcessorType type) void LLPanelProfileWeb::resetData() { - mURLHome = LLStringUtil::null; - mUrlEdit->setValue(mURLHome); mWebBrowser->navigateHome(); } void LLPanelProfileWeb::apply(LLAvatarData* data) { - data->profile_url = mUrlEdit->getValue().asString(); + } void LLPanelProfileWeb::updateData() @@ -962,12 +948,6 @@ void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl) } } -void LLPanelProfileWeb::onCommitWebProfile() -{ - // open the web profile floater - LLAvatarActions::showProfileWeb(getAvatarId()); -} - void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) { switch(event) @@ -976,12 +956,6 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e childSetValue("status_text", LLSD( self->getStatusText() ) ); break; - case MEDIA_EVENT_LOCATION_CHANGED: - // don't set this or user will set there url to profile url - // when clicking ok on there own profile. - // childSetText("url_edit", self->getLocation() ); - break; - case MEDIA_EVENT_NAVIGATE_BEGIN: { if (mFirstNavigate) @@ -1012,11 +986,6 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e void LLPanelProfileWeb::updateButtons() { LLPanelProfileTab::updateButtons(); - - if (getSelfProfile() && !getEmbedded()) - { - mUrlEdit->setEnabled(TRUE); - } } ////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 2d113743f2943a1ab614a41d29cef7e13bc4e878 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 14 Jan 2021 18:02:09 +0200 Subject: SL-14504 FIXED Classified links always launch your Profile Classifieds --- indra/newview/llpanelprofile.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 2cd5aecc2e..82515c8d4a 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -63,6 +63,7 @@ #include "llpanelprofilepicks.h" #include "lltrans.h" #include "llviewercontrol.h" +#include "llviewermenu.h" //is_agent_mappable #include "llvoiceclient.h" #include "llweb.h" -- cgit v1.2.3 From 1d0f25714e17d1f65ee7ef4c9394fed9210e3cd4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 28 Jan 2021 21:54:52 +0200 Subject: SL-14486 Avoid accidental truncation of avatar notes field Server sided limitation, web page allows more than server sends to viewer. This is a workaround untill server sided restriction gets lifted. --- indra/newview/llpanelprofile.cpp | 81 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 82515c8d4a..49b18874f3 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1237,10 +1237,24 @@ void LLPanelProfileFirstLife::updateButtons() LLPanelProfileNotes::LLPanelProfileNotes() : LLPanelProfileTab() +, mAvatarNameCacheConnection() { } +LLPanelProfileNotes::~LLPanelProfileNotes() +{ + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } +} + void LLPanelProfileNotes::updateData() { LLUUID avatar_id = getAvatarId(); @@ -1257,6 +1271,7 @@ BOOL LLPanelProfileNotes::postBuild() mMapRights = getChild("map_check"); mEditObjectRights = getChild("objects_check"); mNotesEditor = getChild("notes_edit"); + mCharacterLimitWarning = getChild("character_limit_warning"); mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); @@ -1272,6 +1287,8 @@ void LLPanelProfileNotes::onOpen(const LLSD& key) resetData(); fillRightsData(); + + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileNotes::onAvatarNameCache, this, _1, _2)); } void LLPanelProfileNotes::apply() @@ -1379,6 +1396,27 @@ void LLPanelProfileNotes::applyRights() LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), rights); } +void LLPanelProfileNotes::updateWarning() +{ + mCharacterLimitWarning->setText(std::string()); + + std::string str = getString("header_symbol_limit"); + mCharacterLimitWarning->appendText(str, false, LLStyle::Params().color(LLColor4::yellow)); + mCharacterLimitWarning->appendText(" ", false, LLStyle::Params()); + + LLStringUtil::format_map_t args; + if (!mURLWebProfile.empty()) + { + args["[PROFILE_URL]"] = mURLWebProfile; + } + else + { + args["[PROFILE_URL]"] = getProfileURL(getAvatarId().asString()); + } + str = getString("body_symbol_limit", args); + mCharacterLimitWarning->appendText(str, false, LLStyle::Params()); +} + void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) { if (APT_NOTES == type) @@ -1390,6 +1428,16 @@ void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType typ mNotesEditor->setEnabled(TRUE); updateButtons(); + if (avatar_notes->notes.size() > 1000) + { + mCharacterLimitWarning->setVisible(TRUE); + updateWarning(); + } + else + { + mCharacterLimitWarning->setVisible(FALSE); + } + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); } } @@ -1402,6 +1450,9 @@ void LLPanelProfileNotes::resetData() mOnlineStatus->setValue(FALSE); mMapRights->setValue(FALSE); mEditObjectRights->setValue(FALSE); + mCharacterLimitWarning->setVisible(FALSE); + + mURLWebProfile.clear(); } void LLPanelProfileNotes::enableCheckboxes(bool enable) @@ -1411,14 +1462,6 @@ void LLPanelProfileNotes::enableCheckboxes(bool enable) mEditObjectRights->setEnabled(enable); } -LLPanelProfileNotes::~LLPanelProfileNotes() -{ - if (getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } -} - // virtual, called by LLAvatarTracker void LLPanelProfileNotes::changed(U32 mask) { @@ -1439,6 +1482,28 @@ void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) } } +void LLPanelProfileNotes::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + mAvatarNameCacheConnection.disconnect(); + + std::string username = av_name.getAccountName(); + if (username.empty()) + { + username = LLCacheName::buildUsername(av_name.getDisplayName()); + } + else + { + LLStringUtil::replaceChar(username, ' ', '.'); + } + + mURLWebProfile = getProfileURL(username, false); + + if (mCharacterLimitWarning->getVisible()) + { + updateWarning(); + } +} + ////////////////////////////////////////////////////////////////////////// // LLPanelProfile -- cgit v1.2.3 From 259c5e3ffe101f75775a9e574e5436b434af58c1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 12 Mar 2022 00:04:18 +0200 Subject: SL-16937 New Profile capability, PUT method #2 --- indra/newview/llpanelprofile.cpp | 317 ++++++++++++++++++++++++++++++++++----- 1 file changed, 283 insertions(+), 34 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 49b18874f3..e3dd27f102 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -29,6 +29,7 @@ // Common #include "llavatarnamecache.h" +#include "llsdutil.h" #include "llslurl.h" #include "lldateutil.h" //ageFromDate @@ -84,6 +85,178 @@ static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds"; static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife"; static const std::string PANEL_NOTES = "panel_profile_notes"; +static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile"; + + +////////////////////////////////////////////////////////////////////////// + +void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status + || !result.has("id") + || agent_id != result["id"].asUUID()) + { + LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; + return; + } + + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + + + // Avatar Data + + LLAvatarData avatar_data; + std::string birth_date; + + avatar_data.agent_id = agent_id; + avatar_data.avatar_id = agent_id; + avatar_data.image_id = result["sl_image_id"].asUUID(); + avatar_data.fl_image_id = result["fl_image_id"].asUUID(); + avatar_data.partner_id = result["partner_id"].asUUID(); + avatar_data.about_text = result["sl_about_text"].asString(); + avatar_data.fl_about_text = result["fl_about_text"].asString(); + avatar_data.born_on = result["member_since"].asDate(); + avatar_data.profile_url = getProfileURL(agent_id.asString()); + + avatar_data.flags = 0; + avatar_data.caption_index = 0; + + LLPanel *panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); + LLPanelProfileSecondLife *panel_sl = dynamic_cast(panel); + if (panel_sl) + { + panel_sl->fillCommonData(&avatar_data); + panel_sl->fillPartnerData(&avatar_data); + panel_sl->updateButtons(); + } + + panel = floater_profile->findChild(PANEL_WEB, TRUE); + LLPanelProfileWeb *panel_web = dynamic_cast(panel); + if (panel_web) + { + panel_web->updateButtons(); + } + + panel = floater_profile->findChild(PANEL_FIRSTLIFE, TRUE); + LLPanelProfileFirstLife *panel_first = dynamic_cast(panel); + if (panel_first) + { + panel_first->mCurrentDescription = avatar_data.fl_about_text; + panel_first->mDescriptionEdit->setValue(panel_first->mCurrentDescription); + panel_first->mPicture->setValue(avatar_data.fl_image_id); + panel_first->updateButtons(); + } + + // Picks + + LLSD picks_array = result["picks"]; + LLAvatarPicks avatar_picks; + avatar_picks.agent_id = agent_id; // Not in use? + avatar_picks.target_id = agent_id; + + for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it) + { + const LLSD& pick_data = *it; + avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); + } + + panel = floater_profile->findChild(PANEL_PICKS, TRUE); + LLPanelProfilePicks *panel_picks = dynamic_cast(panel); + if (panel_picks) + { + panel_picks->processProperties(&avatar_picks); + } + + // Groups + + LLSD groups_array = result["groups"]; + LLAvatarGroups avatar_groups; + avatar_groups.agent_id = agent_id; // Not in use? + avatar_groups.avatar_id = agent_id; // target_id + + for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it) + { + const LLSD& group_info = *it; + LLAvatarGroups::LLGroupData group_data; + group_data.group_powers = 0; // Not in use? + group_data.group_title = group_info["name"].asString(); // Missing data, not in use? + group_data.group_id = group_info["id"].asUUID(); + group_data.group_name = group_info["name"].asString(); + group_data.group_insignia_id = group_info["image_id"].asUUID(); + + avatar_groups.group_list.push_back(group_data); + } + + if (panel_sl) + { + panel_sl->processGroupProperties(&avatar_groups); + } + + // Notes + LLAvatarNotes avatar_notes; + + avatar_notes.agent_id = agent_id; + avatar_notes.target_id = agent_id; + avatar_notes.notes = result["notes"].asString(); + + panel = floater_profile->findChild(PANEL_NOTES, TRUE); + LLPanelProfileNotes *panel_notes = dynamic_cast(panel); + if (panel_notes) + { + panel_notes->processProperties(&avatar_notes); + } +} + +//TODO: changes take two minutes to propagate! +// Add some storage that holds updated data for two minutes +// for new instances to reuse the data +// Profile data is only relevant to won avatar, but notes +// are for everybody +void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to put agent information for id " << agent_id << LL_ENDL; + return; + } +} ////////////////////////////////////////////////////////////////////////// // LLProfileHandler @@ -363,11 +536,34 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) { if (getIsLoaded() && getSelfProfile()) { - data->image_id = mSecondLifePic->getImageAssetID(); - data->about_text = mDescriptionEdit->getValue().asString(); - data->allow_publish = mShowInSearchCheckbox->getValue(); + // Might be a better idea to accumulate changes in floater + // instead of sending a request per tab + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLSD params = LLSDMap(); + if (data->image_id != mSecondLifePic->getImageAssetID()) + { + params["sl_image_id"] = mSecondLifePic->getImageAssetID(); + } + if (data->about_text != mDescriptionEdit->getValue().asString()) + { + params["sl_about_text"] = mDescriptionEdit->getValue().asString(); + } + if (!params.emptyMap()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + } + } - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(data); + if ((bool)data->allow_publish != mShowInSearchCheckbox->getValue().asBoolean()) + { + data->image_id = mSecondLifePic->getImageAssetID(); + data->about_text = mDescriptionEdit->getValue().asString(); + data->allow_publish = mShowInSearchCheckbox->getValue(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(data); + } } } @@ -377,7 +573,16 @@ void LLPanelProfileSecondLife::updateData() if (!getIsLoading() && avatar_id.notNull() && !(getSelfProfile() && !getEmbedded())) { setIsLoading(); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarGroupsRequest(avatar_id); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); + + // needed for online status for other avatars and 'payment' for self + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + } } } @@ -390,15 +595,6 @@ void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorTyp if(avatar_data && getAvatarId() == avatar_data->avatar_id) { processProfileProperties(avatar_data); - updateButtons(); - } - } - else if (APT_GROUPS == type) - { - LLAvatarGroups* avatar_groups = static_cast(data); - if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) - { - processGroupProperties(avatar_groups); } } } @@ -437,11 +633,13 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat processOnlineStatus(avatar_data->flags & AVATAR_ONLINE); } - fillCommonData(avatar_data); + //fillCommonData(avatar_data); - fillPartnerData(avatar_data); + //fillPartnerData(avatar_data); fillAccountStatus(avatar_data); + + updateButtons(); } void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups) @@ -1208,6 +1406,14 @@ void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType } } +void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) +{ + mCurrentDescription = avatar_data->fl_about_text; + mDescriptionEdit->setValue(mCurrentDescription); + mPicture->setValue(avatar_data->fl_image_id); + updateButtons(); +} + void LLPanelProfileFirstLife::resetData() { mDescriptionEdit->setValue(LLStringUtil::null); @@ -1216,6 +1422,26 @@ void LLPanelProfileFirstLife::resetData() void LLPanelProfileFirstLife::apply(LLAvatarData* data) { + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (getIsLoaded() && !cap_url.empty()) + { + LLSD params = LLSDMap(); + if (data->fl_image_id != mPicture->getImageAssetID()) + { + params["fl_image_id"] = mPicture->getImageAssetID(); + } + if (data->fl_about_text != mDescriptionEdit->getValue().asString()) + { + params["fl_about_text"] = mDescriptionEdit->getValue().asString(); + } + if (!params.emptyMap()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + } + } + data->fl_image_id = mPicture->getImageAssetID(); data->fl_about_text = mDescriptionEdit->getValue().asString(); } @@ -1261,7 +1487,13 @@ void LLPanelProfileNotes::updateData() if (!getIsLoading() && avatar_id.notNull()) { setIsLoading(); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarNotesRequest(avatar_id); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); + } } } @@ -1319,10 +1551,12 @@ void LLPanelProfileNotes::fillRightsData() void LLPanelProfileNotes::onCommitNotes() { - if (getIsLoaded()) + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (getIsLoaded() && !cap_url.empty()) { std::string notes = mNotesEditor->getValue().asString(); - LLAvatarPropertiesProcessor::getInstance()->sendNotes(getAvatarId(),notes); + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", notes))); } } @@ -1424,25 +1658,29 @@ void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType typ LLAvatarNotes* avatar_notes = static_cast(data); if (avatar_notes && getAvatarId() == avatar_notes->target_id) { - mNotesEditor->setValue(avatar_notes->notes); - mNotesEditor->setEnabled(TRUE); - updateButtons(); - - if (avatar_notes->notes.size() > 1000) - { - mCharacterLimitWarning->setVisible(TRUE); - updateWarning(); - } - else - { - mCharacterLimitWarning->setVisible(FALSE); - } - + processProperties(avatar_notes); LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); } } } +void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) +{ + mNotesEditor->setValue(avatar_notes->notes); + mNotesEditor->setEnabled(TRUE); + updateButtons(); + + /*if (avatar_notes->notes.size() > 1000) + { + mCharacterLimitWarning->setVisible(TRUE); + updateWarning(); + } + else + {*/ + mCharacterLimitWarning->setVisible(FALSE); + //} +} + void LLPanelProfileNotes::resetData() { resetLoading(); @@ -1598,10 +1836,21 @@ void LLPanelProfile::onOpen(const LLSD& key) void LLPanelProfile::updateData() { LLUUID avatar_id = getAvatarId(); + // Todo: getIsloading functionality needs to be expanded to + // include 'inited' or 'data_provided' state to not rerequest if (!getIsLoading() && avatar_id.notNull()) { setIsLoading(); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); + + // needed for online status for other avatars and 'payment' for self + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + } } } -- cgit v1.2.3 From cf15fa72f719a50e008d4310c93ee17643db3313 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 15 Mar 2022 15:50:36 +0200 Subject: SL-16937 New Profile capability, cap updates #3 --- indra/newview/llpanelprofile.cpp | 151 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 79 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index e3dd27f102..d6f88047d1 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -84,6 +84,7 @@ static const std::string PANEL_PICKS = "panel_profile_picks"; static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds"; static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife"; static const std::string PANEL_NOTES = "panel_profile_notes"; +static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile"; @@ -123,32 +124,59 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) return; } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + LLPanelProfile *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + return; + } + // Avatar Data - LLAvatarData avatar_data; + LLAvatarData *avatar_data = &panel_profile->mAvatarData; std::string birth_date; - avatar_data.agent_id = agent_id; - avatar_data.avatar_id = agent_id; - avatar_data.image_id = result["sl_image_id"].asUUID(); - avatar_data.fl_image_id = result["fl_image_id"].asUUID(); - avatar_data.partner_id = result["partner_id"].asUUID(); - avatar_data.about_text = result["sl_about_text"].asString(); - avatar_data.fl_about_text = result["fl_about_text"].asString(); - avatar_data.born_on = result["member_since"].asDate(); - avatar_data.profile_url = getProfileURL(agent_id.asString()); + avatar_data->agent_id = agent_id; + avatar_data->avatar_id = agent_id; + avatar_data->image_id = result["sl_image_id"].asUUID(); + avatar_data->fl_image_id = result["fl_image_id"].asUUID(); + avatar_data->partner_id = result["partner_id"].asUUID(); + // Todo: new descriptio size is 65536, check if it actually fits or has scroll + avatar_data->about_text = result["sl_about_text"].asString(); + // Todo: new descriptio size is 65536, check if it actually fits or has scroll + avatar_data->fl_about_text = result["fl_about_text"].asString(); + avatar_data->born_on = result["member_since"].asDate(); + avatar_data->profile_url = getProfileURL(agent_id.asString()); - avatar_data.flags = 0; - avatar_data.caption_index = 0; + avatar_data->flags = 0; - LLPanel *panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); + if (result["online"].asBoolean()) + { + avatar_data->flags |= AVATAR_ONLINE; + } + if (result["allow_publish"].asBoolean()) + { + avatar_data->flags |= AVATAR_ALLOW_PUBLISH; + } + + if (result["charter_member"].asBoolean()) + { + const S32 TYPE_CHARTER_MEMBER = 2; + avatar_data->caption_index = TYPE_CHARTER_MEMBER; + } + else + { + const S32 TYPE_RESIDENT = 0; // See ACCT_TYPE + avatar_data->caption_index = TYPE_RESIDENT; + } + + panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); LLPanelProfileSecondLife *panel_sl = dynamic_cast(panel); if (panel_sl) { - panel_sl->fillCommonData(&avatar_data); - panel_sl->fillPartnerData(&avatar_data); - panel_sl->updateButtons(); + panel_sl->processProfileProperties(avatar_data); } panel = floater_profile->findChild(PANEL_WEB, TRUE); @@ -162,9 +190,9 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) LLPanelProfileFirstLife *panel_first = dynamic_cast(panel); if (panel_first) { - panel_first->mCurrentDescription = avatar_data.fl_about_text; + panel_first->mCurrentDescription = avatar_data->fl_about_text; panel_first->mDescriptionEdit->setValue(panel_first->mCurrentDescription); - panel_first->mPicture->setValue(avatar_data.fl_image_id); + panel_first->mPicture->setValue(avatar_data->fl_image_id); panel_first->updateButtons(); } @@ -550,19 +578,19 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) { params["sl_about_text"] = mDescriptionEdit->getValue().asString(); } + if ((bool)data->allow_publish != mShowInSearchCheckbox->getValue().asBoolean()) + { + params["allow_publish"] = mShowInSearchCheckbox->getValue().asBoolean(); + } if (!params.emptyMap()) { LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); } } - - if ((bool)data->allow_publish != mShowInSearchCheckbox->getValue().asBoolean()) + else { - data->image_id = mSecondLifePic->getImageAssetID(); - data->about_text = mDescriptionEdit->getValue().asString(); - data->allow_publish = mShowInSearchCheckbox->getValue(); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(data); + LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; } } } @@ -579,9 +607,10 @@ void LLPanelProfileSecondLife::updateData() { LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); - - // needed for online status for other avatars and 'payment' for self - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + } + else + { + LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; } } } @@ -633,9 +662,9 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat processOnlineStatus(avatar_data->flags & AVATAR_ONLINE); } - //fillCommonData(avatar_data); + fillCommonData(avatar_data); - //fillPartnerData(avatar_data); + fillPartnerData(avatar_data); fillAccountStatus(avatar_data); @@ -1503,7 +1532,6 @@ BOOL LLPanelProfileNotes::postBuild() mMapRights = getChild("map_check"); mEditObjectRights = getChild("objects_check"); mNotesEditor = getChild("notes_edit"); - mCharacterLimitWarning = getChild("character_limit_warning"); mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); @@ -1552,11 +1580,18 @@ void LLPanelProfileNotes::fillRightsData() void LLPanelProfileNotes::onCommitNotes() { std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (getIsLoaded() && !cap_url.empty()) + if (getIsLoaded()) { - std::string notes = mNotesEditor->getValue().asString(); - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", notes))); + if (!cap_url.empty()) + { + std::string notes = mNotesEditor->getValue().asString(); + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", notes))); + } + else + { + LL_WARNS() << "Failed to update notes, no cap found" << LL_ENDL; + } } } @@ -1630,27 +1665,6 @@ void LLPanelProfileNotes::applyRights() LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), rights); } -void LLPanelProfileNotes::updateWarning() -{ - mCharacterLimitWarning->setText(std::string()); - - std::string str = getString("header_symbol_limit"); - mCharacterLimitWarning->appendText(str, false, LLStyle::Params().color(LLColor4::yellow)); - mCharacterLimitWarning->appendText(" ", false, LLStyle::Params()); - - LLStringUtil::format_map_t args; - if (!mURLWebProfile.empty()) - { - args["[PROFILE_URL]"] = mURLWebProfile; - } - else - { - args["[PROFILE_URL]"] = getProfileURL(getAvatarId().asString()); - } - str = getString("body_symbol_limit", args); - mCharacterLimitWarning->appendText(str, false, LLStyle::Params()); -} - void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) { if (APT_NOTES == type) @@ -1669,16 +1683,6 @@ void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) mNotesEditor->setValue(avatar_notes->notes); mNotesEditor->setEnabled(TRUE); updateButtons(); - - /*if (avatar_notes->notes.size() > 1000) - { - mCharacterLimitWarning->setVisible(TRUE); - updateWarning(); - } - else - {*/ - mCharacterLimitWarning->setVisible(FALSE); - //} } void LLPanelProfileNotes::resetData() @@ -1688,7 +1692,6 @@ void LLPanelProfileNotes::resetData() mOnlineStatus->setValue(FALSE); mMapRights->setValue(FALSE); mEditObjectRights->setValue(FALSE); - mCharacterLimitWarning->setVisible(FALSE); mURLWebProfile.clear(); } @@ -1735,11 +1738,6 @@ void LLPanelProfileNotes::onAvatarNameCache(const LLUUID& agent_id, const LLAvat } mURLWebProfile = getProfileURL(username, false); - - if (mCharacterLimitWarning->getVisible()) - { - updateWarning(); - } } @@ -1847,9 +1845,6 @@ void LLPanelProfile::updateData() { LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); - - // needed for online status for other avatars and 'payment' for self - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); } } } @@ -1860,11 +1855,9 @@ void LLPanelProfile::apply() { //KC - AvatarData is spread over 3 different panels // collect data from the last 2 and give to the first to save - LLAvatarData data = LLAvatarData(); - data.avatar_id = gAgentID; - mPanelFirstlife->apply(&data); - mPanelWeb->apply(&data); - mPanelSecondlife->apply(&data); + mPanelFirstlife->apply(&mAvatarData); + mPanelWeb->apply(&mAvatarData); + mPanelSecondlife->apply(&mAvatarData); mPanelInterests->apply(); mPanelPicks->apply(); -- cgit v1.2.3 From 7e040000c6c3471f53011994d95bc3b3d721782d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 16 Mar 2022 17:52:41 +0200 Subject: SL-16937 New Profile capability, updated charter_member #4 --- indra/newview/llpanelprofile.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index d6f88047d1..5e85fa227e 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -161,15 +161,14 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_data->flags |= AVATAR_ALLOW_PUBLISH; } - if (result["charter_member"].asBoolean()) + avatar_data->caption_index = 0; + if (result.has("charter_member")) // won't be present if "caption" is set { - const S32 TYPE_CHARTER_MEMBER = 2; - avatar_data->caption_index = TYPE_CHARTER_MEMBER; + avatar_data->caption_index = result["charter_member"].asInteger(); } - else + else if (result.has("caption")) { - const S32 TYPE_RESIDENT = 0; // See ACCT_TYPE - avatar_data->caption_index = TYPE_RESIDENT; + avatar_data->caption_text = result["caption"].asString(); } panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); -- cgit v1.2.3 From b7bd7029eb7c38a70c20278298ee650e0dbbdfa1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 25 Mar 2022 21:54:07 +0200 Subject: SL-16937 New Profile capability, image uploader cap #5 --- indra/newview/llpanelprofile.cpp | 190 +++++++++++++++++++++++++++++++++++---- 1 file changed, 173 insertions(+), 17 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 5e85fa227e..5986ef7171 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -47,6 +47,9 @@ #include "lltoggleablemenu.h" #include "llgrouplist.h" +// Image +#include "llimagej2c.h" + // Newview #include "llagent.h" //gAgent #include "llagentpicksinfo.h" @@ -65,6 +68,7 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llviewermenu.h" //is_agent_mappable +#include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llweb.h" @@ -87,6 +91,7 @@ static const std::string PANEL_NOTES = "panel_profile_notes"; static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile"; +static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage"; ////////////////////////////////////////////////////////////////////////// @@ -264,7 +269,7 @@ void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy)); + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLCore::HttpHeaders::ptr_t httpHeaders; @@ -285,6 +290,136 @@ void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) } } +enum EProfileImageType +{ + PROFILE_IMAGE_SL, + PROFILE_IMAGE_FL, +}; + +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string &path_to_image) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + LLSD first_data; + switch (type) + { + case PROFILE_IMAGE_SL: + first_data["profile-image-asset"] = "sl_image_id"; + break; + case PROFILE_IMAGE_FL: + first_data["profile-image-asset"] = "fl_image_id"; + break; + } + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + return; + } + if (!result.has("uploader")) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + return; + } + std::string uploader_cap = result["uploader"].asString(); + if (uploader_cap.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + return; + } + + // Load the image + + + // Convert and validate: the upload procedure is the same for all images, + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(path_to_image)); + + LLPointer image = LLImageFormatted::createFromType(codec); + if (image.isNull()) + { + LL_WARNS("AvatarProperties") << "Couldn't open the image to be uploaded." << LL_ENDL; + return; + } + if (!image->load(path_to_image)) + { + LL_WARNS("AvatarProperties") << "Couldn't load the image to be uploaded." << LL_ENDL; + return; + } + // Decompress or expand it in a raw image structure + LLPointer raw_image = new LLImageRaw; + if (!image->decode(raw_image, 0.0f)) + { + LL_WARNS("AvatarProperties") << "Couldn't decode the image to be uploaded." << LL_ENDL; + return; + } + + // Check the image constraints + if ((image->getComponents() != 3) && (image->getComponents() != 4)) + { + LL_WARNS("AvatarProperties") << "Image files with less than 3 or more than 4 components are not supported." << LL_ENDL; + return; + } + + const S32 MAX_DIM = 256; + raw_image->biasedScaleToPowerOfTwo(MAX_DIM); // should it actually be power of two? + + // Convert to j2c (JPEG2000) + LLPointer j2cImage = LLViewerTextureList::convertToUploadFile(raw_image); + if (j2cImage.isNull()) + { + LL_WARNS("AvatarProperties") << "Couldn't convert the image to jpeg2000." << LL_ENDL; + return; + } + S32 data_size = j2cImage->getDataSize(); + /*U8 *data_start = compressedImage->getData(); + LLSD::Binary bin_data(data_start, data_start + data_size);*/ + LLCore::BufferArray::ptr_t bin_data(new LLCore::BufferArray); + LLCore::BufferArrayStream bas(bin_data.get()); + + U8* image_data = j2cImage->getData(); + for (S32 i = 0; i < j2cImage->getDataSize(); ++i) + { + bas << image_data[i]; + } + + LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); + LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", data_size)); + uploaderhttpOpts->setFollowRedirects(true); + + + result = httpAdapter->postAndSuspend(uploaderhttpRequest, uploader_cap, bin_data, uploaderhttpOpts, uploaderhttpHeaders); + + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; + return; + } + + // Todo: + // handle 'message':'No Error','state':'failure' + // handle 'state':'complete' + + LL_WARNS() << result << LL_ENDL; +} + ////////////////////////////////////////////////////////////////////////// // LLProfileHandler @@ -565,32 +700,53 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) { // Might be a better idea to accumulate changes in floater // instead of sending a request per tab - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) + + LLSD params = LLSDMap(); + // we have an image, check if it is local. Server won't recognize local ids. + if (data->image_id != mSecondLifePic->getImageAssetID() + && !LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) + { + params["sl_image_id"] = mSecondLifePic->getImageAssetID(); + } + if (data->about_text != mDescriptionEdit->getValue().asString()) + { + params["sl_about_text"] = mDescriptionEdit->getValue().asString(); + } + if ((bool)data->allow_publish != mShowInSearchCheckbox->getValue().asBoolean()) + { + params["allow_publish"] = mShowInSearchCheckbox->getValue().asBoolean(); + } + if (!params.emptyMap()) { - LLSD params = LLSDMap(); - if (data->image_id != mSecondLifePic->getImageAssetID()) + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - params["sl_image_id"] = mSecondLifePic->getImageAssetID(); + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); } - if (data->about_text != mDescriptionEdit->getValue().asString()) + else { - params["sl_about_text"] = mDescriptionEdit->getValue().asString(); + LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; } - if ((bool)data->allow_publish != mShowInSearchCheckbox->getValue().asBoolean()) + } + + // Only if image is local + if (data->image_id != mSecondLifePic->getImageAssetID() + && LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) + { + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (!cap_url.empty()) { - params["allow_publish"] = mShowInSearchCheckbox->getValue().asBoolean(); + // Temp path, will add a proper one once UI updates to support this + std::string full_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_profile_image_coro, cap_url, PROFILE_IMAGE_SL, full_path)); } - if (!params.emptyMap()) + else { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + LL_WARNS() << "Failed to upload sl profile image, no cap found" << LL_ENDL; } } - else - { - LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; - } } } -- cgit v1.2.3 From 43fcf86b3b8863fa6f9eb00d0a18aca0a3d675ff Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 28 Mar 2022 19:45:25 +0300 Subject: SL-16937 New Profile capability, image uploader cap #6 --- indra/newview/llpanelprofile.cpp | 170 +++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 89 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 5986ef7171..d202f62910 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -296,7 +296,7 @@ enum EProfileImageType PROFILE_IMAGE_FL, }; -void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string &path_to_image) +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t @@ -340,69 +340,28 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s return; } - // Load the image + // Upload the image + LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); + LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); + S64 length; - // Convert and validate: the upload procedure is the same for all images, - U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(path_to_image)); - - LLPointer image = LLImageFormatted::createFromType(codec); - if (image.isNull()) - { - LL_WARNS("AvatarProperties") << "Couldn't open the image to be uploaded." << LL_ENDL; - return; - } - if (!image->load(path_to_image)) - { - LL_WARNS("AvatarProperties") << "Couldn't load the image to be uploaded." << LL_ENDL; - return; - } - // Decompress or expand it in a raw image structure - LLPointer raw_image = new LLImageRaw; - if (!image->decode(raw_image, 0.0f)) - { - LL_WARNS("AvatarProperties") << "Couldn't decode the image to be uploaded." << LL_ENDL; - return; - } - - // Check the image constraints - if ((image->getComponents() != 3) && (image->getComponents() != 4)) - { - LL_WARNS("AvatarProperties") << "Image files with less than 3 or more than 4 components are not supported." << LL_ENDL; - return; - } - - const S32 MAX_DIM = 256; - raw_image->biasedScaleToPowerOfTwo(MAX_DIM); // should it actually be power of two? - - // Convert to j2c (JPEG2000) - LLPointer j2cImage = LLViewerTextureList::convertToUploadFile(raw_image); - if (j2cImage.isNull()) - { - LL_WARNS("AvatarProperties") << "Couldn't convert the image to jpeg2000." << LL_ENDL; - return; - } - S32 data_size = j2cImage->getDataSize(); - /*U8 *data_start = compressedImage->getData(); - LLSD::Binary bin_data(data_start, data_start + data_size);*/ - LLCore::BufferArray::ptr_t bin_data(new LLCore::BufferArray); - LLCore::BufferArrayStream bas(bin_data.get()); - - U8* image_data = j2cImage->getData(); - for (S32 i = 0; i < j2cImage->getDataSize(); ++i) { - bas << image_data[i]; + llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); + if (!instream.is_open()) + { + LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + return; + } + length = instream.tellg(); } - LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); - LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); - uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); - uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", data_size)); + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! uploaderhttpOpts->setFollowRedirects(true); - - result = httpAdapter->postAndSuspend(uploaderhttpRequest, uploader_cap, bin_data, uploaderhttpOpts, uploaderhttpHeaders); + result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -413,11 +372,44 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s return; } - // Todo: - // handle 'message':'No Error','state':'failure' - // handle 'state':'complete' + if (result["state"].asString() != "complete") + { + if (result.has("message")) + { + LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; + } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; + } + return; + } + + LLFile::remove(path_to_image); +} - LL_WARNS() << result << LL_ENDL; +void launch_profile_image_coro(EProfileImageType type, const std::string &file_path) +{ + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (!cap_url.empty()) + { + // todo: createUploadFile needs to be done when user picks up a file, + // not when user clicks 'ok', but coroutine should happen on 'ok'. + // but this waits for a UI update, the main point is a functional coroutine + std::string temp_file = gDirUtilp->getTempFilename(); + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); + const S32 MAX_DIM = 256; + + if (LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) + { + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_profile_image_coro, cap_url, type, temp_file)); + } + } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; + } } ////////////////////////////////////////////////////////////////////////// @@ -726,7 +718,7 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) } else { - LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -734,18 +726,9 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) if (data->image_id != mSecondLifePic->getImageAssetID() && LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) { - std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); - if (!cap_url.empty()) - { - // Temp path, will add a proper one once UI updates to support this - std::string full_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); - LLCoros::instance().launch("postAgentUserImageCoro", - boost::bind(post_profile_image_coro, cap_url, PROFILE_IMAGE_SL, full_path)); - } - else - { - LL_WARNS() << "Failed to upload sl profile image, no cap found" << LL_ENDL; - } + // todo: temporary file, connect to UI + std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); + launch_profile_image_coro(PROFILE_IMAGE_SL, file_path); } } } @@ -1606,28 +1589,37 @@ void LLPanelProfileFirstLife::resetData() void LLPanelProfileFirstLife::apply(LLAvatarData* data) { - - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (getIsLoaded() && !cap_url.empty()) + LLSD params = LLSDMap(); + if (data->fl_image_id != mPicture->getImageAssetID() + && !LLLocalBitmapMgr::getInstance()->isLocal(mPicture->getImageAssetID())) { - LLSD params = LLSDMap(); - if (data->fl_image_id != mPicture->getImageAssetID()) - { - params["fl_image_id"] = mPicture->getImageAssetID(); - } - if (data->fl_about_text != mDescriptionEdit->getValue().asString()) - { - params["fl_about_text"] = mDescriptionEdit->getValue().asString(); - } - if (!params.emptyMap()) + params["fl_image_id"] = mPicture->getImageAssetID(); + } + if (data->fl_about_text != mDescriptionEdit->getValue().asString()) + { + params["fl_about_text"] = mDescriptionEdit->getValue().asString(); + } + if (!params.emptyMap()) + { + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (getIsLoaded() && !cap_url.empty()) { LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload profile data " << PROFILE_PROPERTIES_CAP << " cap not found" << LL_ENDL; + } } - data->fl_image_id = mPicture->getImageAssetID(); - data->fl_about_text = mDescriptionEdit->getValue().asString(); + if (data->fl_image_id != mPicture->getImageAssetID() + && LLLocalBitmapMgr::getInstance()->isLocal(mPicture->getImageAssetID())) + { + // todo: temporary file, connect to UI + std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); + launch_profile_image_coro(PROFILE_IMAGE_FL, file_path); + } } void LLPanelProfileFirstLife::updateButtons() -- cgit v1.2.3 From cd61dbe6eea8d9a7e4bdb594179bafc24a504146 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 29 Mar 2022 10:57:29 +0300 Subject: SL-17084 Remove 'interests' tab 'Legacy interests' are obsolete --- indra/newview/llpanelprofile.cpp | 162 --------------------------------------- 1 file changed, 162 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index d202f62910..156d2671f4 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -75,7 +75,6 @@ static LLPanelInjector t_panel_profile_secondlife("panel_profile_secondlife"); static LLPanelInjector t_panel_web("panel_profile_web"); -static LLPanelInjector t_panel_interests("panel_profile_interests"); static LLPanelInjector t_panel_picks("panel_profile_picks"); static LLPanelInjector t_panel_firstlife("panel_profile_firstlife"); static LLPanelInjector t_panel_notes("panel_profile_notes"); @@ -83,7 +82,6 @@ static LLPanelInjector t_panel_profile("panel_profile") static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife"; static const std::string PANEL_WEB = "panel_profile_web"; -static const std::string PANEL_INTERESTS = "panel_profile_interests"; static const std::string PANEL_PICKS = "panel_profile_picks"; static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds"; static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife"; @@ -1354,162 +1352,6 @@ void LLPanelProfileWeb::updateButtons() LLPanelProfileTab::updateButtons(); } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -static const S32 WANT_CHECKS = 8; -static const S32 SKILL_CHECKS = 6; - -LLPanelProfileInterests::LLPanelProfileInterests() - : LLPanelProfileTab() -{ -} - -LLPanelProfileInterests::~LLPanelProfileInterests() -{ -} - -void LLPanelProfileInterests::onOpen(const LLSD& key) -{ - LLPanelProfileTab::onOpen(key); - - resetData(); -} - -BOOL LLPanelProfileInterests::postBuild() -{ - mWantToEditor = getChild("want_to_edit"); - mSkillsEditor = getChild("skills_edit"); - mLanguagesEditor = getChild("languages_edit"); - - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - std::string check_name = llformat("chk%d", i); - mWantChecks[i] = getChild(check_name); - } - - for (S32 i = 0; i < SKILL_CHECKS; ++i) - { - std::string check_name = llformat("schk%d", i); - mSkillChecks[i] = getChild(check_name); - } - - return TRUE; -} - - -void LLPanelProfileInterests::processProperties(void* data, EAvatarProcessorType type) -{ - if (APT_INTERESTS_INFO == type) - { - const LLInterestsData* interests_data = static_cast(data); - if (interests_data && getAvatarId() == interests_data->avatar_id) - { - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - if (interests_data->want_to_mask & (1<setValue(TRUE); - } - else - { - mWantChecks[i]->setValue(FALSE); - } - } - - for (S32 i = 0; i < SKILL_CHECKS; ++i) - { - if (interests_data->skills_mask & (1<setValue(TRUE); - } - else - { - mSkillChecks[i]->setValue(FALSE); - } - } - - mWantToEditor->setText(interests_data->want_to_text); - mSkillsEditor->setText(interests_data->skills_text); - mLanguagesEditor->setText(interests_data->languages_text); - - updateButtons(); - } - } -} - -void LLPanelProfileInterests::resetData() -{ - mWantToEditor->setValue(LLStringUtil::null); - mSkillsEditor->setValue(LLStringUtil::null); - mLanguagesEditor->setValue(LLStringUtil::null); - - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - mWantChecks[i]->setValue(FALSE); - } - - for (S32 i = 0; i < SKILL_CHECKS; ++i) - { - mSkillChecks[i]->setValue(FALSE); - } -} - -void LLPanelProfileInterests::apply() -{ - if (getIsLoaded() && getSelfProfile()) - { - LLInterestsData interests_data = LLInterestsData(); - - interests_data.want_to_mask = 0; - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - if (mWantChecks[i]->getValue().asBoolean()) - { - interests_data.want_to_mask |= (1 << i); - } - } - - interests_data.skills_mask = 0; - for (S32 i = 0; i < SKILL_CHECKS; ++i) - { - if (mSkillChecks[i]->getValue().asBoolean()) - { - interests_data.skills_mask |= (1 << i); - } - } - - interests_data.want_to_text = mWantToEditor->getText(); - interests_data.skills_text = mSkillsEditor->getText(); - interests_data.languages_text = mLanguagesEditor->getText(); - - LLAvatarPropertiesProcessor::getInstance()->sendInterestsInfoUpdate(&interests_data); - } - -} - -void LLPanelProfileInterests::updateButtons() -{ - LLPanelProfileTab::updateButtons(); - - if (getSelfProfile() && !getEmbedded()) - { - mWantToEditor->setEnabled(TRUE); - mSkillsEditor->setEnabled(TRUE); - mLanguagesEditor->setEnabled(TRUE); - - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - mWantChecks[i]->setEnabled(TRUE); - } - - for (S32 i = 0; i < SKILL_CHECKS; ++i) - { - mSkillChecks[i]->setEnabled(TRUE); - } - } -} ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1945,7 +1787,6 @@ void LLPanelProfile::onOpen(const LLSD& key) mTabContainer = getChild("panel_profile_tabs"); mPanelSecondlife = findChild(PANEL_SECONDLIFE); mPanelWeb = findChild(PANEL_WEB); - mPanelInterests = findChild(PANEL_INTERESTS); mPanelPicks = findChild(PANEL_PICKS); mPanelClassifieds = findChild(PANEL_CLASSIFIEDS); mPanelFirstlife = findChild(PANEL_FIRSTLIFE); @@ -1953,7 +1794,6 @@ void LLPanelProfile::onOpen(const LLSD& key) mPanelSecondlife->onOpen(avatar_id); mPanelWeb->onOpen(avatar_id); - mPanelInterests->onOpen(avatar_id); mPanelPicks->onOpen(avatar_id); mPanelClassifieds->onOpen(avatar_id); mPanelFirstlife->onOpen(avatar_id); @@ -1961,7 +1801,6 @@ void LLPanelProfile::onOpen(const LLSD& key) mPanelSecondlife->setEmbedded(getEmbedded()); mPanelWeb->setEmbedded(getEmbedded()); - mPanelInterests->setEmbedded(getEmbedded()); mPanelPicks->setEmbedded(getEmbedded()); mPanelClassifieds->setEmbedded(getEmbedded()); mPanelFirstlife->setEmbedded(getEmbedded()); @@ -2006,7 +1845,6 @@ void LLPanelProfile::apply() mPanelWeb->apply(&mAvatarData); mPanelSecondlife->apply(&mAvatarData); - mPanelInterests->apply(); mPanelPicks->apply(); mPanelNotes->apply(); mPanelClassifieds->apply(); -- cgit v1.2.3 From 8f6d149fadf635f6698e2e68aa4f48db13eff648 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 30 Mar 2022 18:32:42 +0300 Subject: SL-16937 New Profile capability, image uploader for testing This commit is mostly to simplify cap testing for server side. Plan is to remove LLLocalBitmap and draw texture more directly instead --- indra/newview/llpanelprofile.cpp | 141 +++++++++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 26 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 156d2671f4..c19688191b 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -58,6 +58,7 @@ #include "llcallingcard.h" #include "llcommandhandler.h" #include "llfloaterreg.h" +#include "llfilepicker.h" #include "llfirstuse.h" #include "llgroupactions.h" #include "llmutelist.h" @@ -68,6 +69,7 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llviewermenu.h" //is_agent_mappable +#include "llviewermenufile.h" #include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llweb.h" @@ -324,17 +326,20 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!status) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + LLFile::remove(path_to_image); return; } if (!result.has("uploader")) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + LLFile::remove(path_to_image); return; } std::string uploader_cap = result["uploader"].asString(); if (uploader_cap.empty()) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + LLFile::remove(path_to_image); return; } @@ -350,6 +355,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!instream.is_open()) { LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + LLFile::remove(path_to_image); return; } length = instream.tellg(); @@ -367,6 +373,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!status) { LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; + LLFile::remove(path_to_image); return; } @@ -380,6 +387,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s { LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; } + LLFile::remove(path_to_image); return; } @@ -575,6 +583,8 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife() { mAvatarNameCacheConnection.disconnect(); } + + clearUploadProfileImagePath(); } BOOL LLPanelProfileSecondLife::postBuild() @@ -582,7 +592,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mStatusText = getChild("status"); mGroupList = getChild("group_list"); mShowInSearchCheckbox = getChild("show_in_search_checkbox"); - mSecondLifePic = getChild("2nd_life_pic"); + mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); mTeleportButton = getChild("teleport"); @@ -610,7 +620,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); - mSecondLifePic->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onCommitTexture, this)); + mSecondLifePic->setMouseUpCallback(boost::bind(&LLPanelProfileSecondLife::onPickTexture, this)); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; commit.add("Profile.CopyName", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); @@ -650,8 +660,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mGroupList->setShowNone(!own_profile); mGiveInvPanel->setVisible(!own_profile); - mSecondLifePic->setOpenTexPreview(!own_profile); - if (own_profile && !getEmbedded()) { // Group list control cannot toggle ForAgent loading @@ -693,10 +701,11 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) LLSD params = LLSDMap(); // we have an image, check if it is local. Server won't recognize local ids. - if (data->image_id != mSecondLifePic->getImageAssetID() - && !LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) + if (data->image_id != mImageAssetId + && mImageFile.empty() + && !LLLocalBitmapMgr::getInstance()->isLocal(mImageAssetId)) { - params["sl_image_id"] = mSecondLifePic->getImageAssetID(); + params["sl_image_id"] = mImageAssetId; } if (data->about_text != mDescriptionEdit->getValue().asString()) { @@ -721,12 +730,19 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) } // Only if image is local - if (data->image_id != mSecondLifePic->getImageAssetID() - && LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) + if (!mImageFile.empty()) { - // todo: temporary file, connect to UI - std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); - launch_profile_image_coro(PROFILE_IMAGE_SL, file_path); + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_profile_image_coro, cap_url, PROFILE_IMAGE_SL, mImageFile)); + mImageFile.clear(); // coro should do the deleting + } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; + } } } } @@ -773,7 +789,7 @@ void LLPanelProfileSecondLife::resetData() getChild("partner_text")->setValue(LLStringUtil::null); // Set default image and 1:1 dimensions for it - mSecondLifePic->setValue(mSecondLifePic->getDefaultImageAssetID()); + mSecondLifePic->setValue("Generic_Person_Large"); LLRect imageRect = mSecondLifePicLayout->getRect(); mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); @@ -782,6 +798,7 @@ void LLPanelProfileSecondLife::resetData() mCopyMenuButton->setVisible(FALSE); mGroups.clear(); mGroupList->setGroups(mGroups); + clearUploadProfileImagePath(); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -845,6 +862,37 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L mCopyMenuButton->setVisible(TRUE); } +void LLPanelProfileSecondLife::setUploadProfileImagePath(const std::string &path, const std::string &orig_path) +{ + clearUploadProfileImagePath(); + // todo: display this in floater, + // LLIconCtrl can't show a path, only by id or name, so may be draw directly or add as a local bitmap? + // LLLocalBitmap* unit = new LLLocalBitmap(path); + + // assign a local texture to view in viewer + // Todo: remove LLLocalBitmap and just draw texture instead + // orig_path was used instead of path, since LLLocalBitmapMgr does not support j2c + LLUUID tracking_id = LLLocalBitmapMgr::getInstance()->addUnit(orig_path); + if (tracking_id.isNull()) + { + // todo: error handling + return; + } + + mImageFile = path; + mImageAssetId = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); + mSecondLifePic->setValue(mImageAssetId); +} + +void LLPanelProfileSecondLife::clearUploadProfileImagePath() +{ + if (!mImageFile.empty()) + { + LLFile::remove(mImageFile); //todo: supress errors, may be not need to remove if it becomes a LLLocalBitmap + } + mImageFile.clear(); +} + void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) { // Refresh avatar id in cache with new info to prevent re-requests @@ -862,7 +910,8 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) std::string register_date = getString("RegisterDateFormat", args); getChild("register_date")->setValue(register_date ); mDescriptionEdit->setValue(avatar_data->about_text); - mSecondLifePic->setValue(avatar_data->image_id); + mImageAssetId = avatar_data->image_id; + mSecondLifePic->setValue(mImageAssetId); //Don't bother about boost level, picker will set it LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); @@ -1119,23 +1168,63 @@ void LLPanelProfileSecondLife::onClickSetName() LLFirstUse::setDisplayName(false); } -void LLPanelProfileSecondLife::onCommitTexture() + + +class LLProfileImagePicker : public LLFilePickerThread { - LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(mSecondLifePic->getImageAssetID()); - if (imagep->getFullHeight()) +public: + LLProfileImagePicker(LLHandle *handle); + ~LLProfileImagePicker(); + virtual void notify(const std::vector& filenames); + +private: + LLHandle *mHandle; +}; + +LLProfileImagePicker::LLProfileImagePicker(LLHandle *handle) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), + mHandle(handle) +{ +} + +LLProfileImagePicker::~LLProfileImagePicker() +{ + delete mHandle; +} + +void LLProfileImagePicker::notify(const std::vector& filenames) +{ + /*if (LLAppViewer::instance()->quitRequested()) { - onImageLoaded(true, imagep); + return; + }*/ + if (mHandle->isDead()) + { + return; } - else + std::string file_path = filenames[0]; + if (file_path.empty()) { - imagep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, - FALSE, - FALSE, - new LLHandle(getHandle()), - NULL, - FALSE); + return; + } + + // generate a temp texture file for coroutine + std::string temp_file = gDirUtilp->getTempFilename(); + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); + const S32 MAX_DIM = 256; + if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) + { + // todo: error handling + return; } + + LLPanelProfileSecondLife* panel = static_cast(mHandle->get()); + panel->setUploadProfileImagePath(temp_file, file_path); +} + +void LLPanelProfileSecondLife::onPickTexture() +{ + (new LLProfileImagePicker(new LLHandle(getHandle())))->getFile(); } void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) -- cgit v1.2.3 From 8163eeb43bdfa806c306ba5caf2457c59efed2d4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 6 Apr 2022 22:16:39 +0300 Subject: SL-15312 Legacy profiles remake #1 Initial layout --- indra/newview/llpanelprofile.cpp | 150 +++------------------------------------ 1 file changed, 10 insertions(+), 140 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index c19688191b..5453c87013 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -562,7 +562,6 @@ LLAgentHandler gAgentHandler; LLPanelProfileSecondLife::LLPanelProfileSecondLife() : LLPanelProfileTab() - , mStatusText(NULL) , mAvatarNameCacheConnection() { } @@ -589,42 +588,13 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife() BOOL LLPanelProfileSecondLife::postBuild() { - mStatusText = getChild("status"); mGroupList = getChild("group_list"); mShowInSearchCheckbox = getChild("show_in_search_checkbox"); mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); - mTeleportButton = getChild("teleport"); - mShowOnMapButton = getChild("show_on_map_btn"); - mBlockButton = getChild("block"); - mUnblockButton = getChild("unblock"); - mNameLabel = getChild("name_label"); - mDisplayNameButton = getChild("set_name"); - mAddFriendButton = getChild("add_friend"); - mGroupInviteButton = getChild("group_invite"); - mPayButton = getChild("pay"); - mIMButton = getChild("im"); - mCopyMenuButton = getChild("copy_btn"); mGiveInvPanel = getChild("give_stack"); - mStatusText->setVisible(FALSE); - mCopyMenuButton->setVisible(FALSE); - - mAddFriendButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onAddFriendButtonClick, this)); - mIMButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onIMButtonClick, this)); - mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onTeleportButtonClick, this)); - mShowOnMapButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onMapButtonClick, this)); - mPayButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::pay, this)); - mBlockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); - mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); - mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); - mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); - mSecondLifePic->setMouseUpCallback(boost::bind(&LLPanelProfileSecondLife::onPickTexture, this)); - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; - commit.add("Profile.CopyName", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); enable.add("Profile.EnableGod", [](LLUICtrl*, const LLSD&) { return gAgent.isGodlike(); }); @@ -632,8 +602,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mGroupList->setDoubleClickCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); - LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); - mCopyMenuButton->setMenu("menu_name_field.xml", LLMenuButton::MP_BOTTOM_RIGHT); + //mAgentActionMenuButton->setMenu("menu_name_field.xml", LLMenuButton::MP_BOTTOM_RIGHT); return TRUE; } @@ -649,16 +618,11 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) BOOL own_profile = getSelfProfile(); - mGroupInviteButton->setVisible(!own_profile); - mShowOnMapButton->setVisible(!own_profile); - mPayButton->setVisible(!own_profile); - mTeleportButton->setVisible(!own_profile); - mIMButton->setVisible(!own_profile); - mAddFriendButton->setVisible(!own_profile); - mBlockButton->setVisible(!own_profile); - mUnblockButton->setVisible(!own_profile); mGroupList->setShowNone(!own_profile); - mGiveInvPanel->setVisible(!own_profile); + //mGiveInvPanel->setVisible(!own_profile); + + childSetVisible("notes_panel", !own_profile); + childSetVisible("settings_panel", own_profile); if (own_profile && !getEmbedded()) { @@ -667,11 +631,8 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mGroupList->enableForAgent(false); } - if (own_profile && !getEmbedded() ) + if (own_profile) { - mNameLabel->setVisible(FALSE); - mDisplayNameButton->setVisible(TRUE); - mDisplayNameButton->setEnabled(TRUE); } mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded()); @@ -794,11 +755,10 @@ void LLPanelProfileSecondLife::resetData() mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); mDescriptionEdit->setValue(LLStringUtil::null); - mStatusText->setVisible(FALSE); - mCopyMenuButton->setVisible(FALSE); mGroups.clear(); mGroupList->setGroups(mGroups); clearUploadProfileImagePath(); + //mAgentActionMenuButton set menu } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -858,8 +818,7 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L { mAvatarNameCacheConnection.disconnect(); - getChild("complete_name")->setValue( av_name.getCompleteName() ); - mCopyMenuButton->setVisible(TRUE); + //getChild("complete_name")->setValue( av_name.getCompleteName() ); } void LLPanelProfileSecondLife::setUploadProfileImagePath(const std::string &path, const std::string &orig_path) @@ -900,14 +859,8 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); LLStringUtil::format_map_t args; - { - std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); - LLStringUtil::format(birth_date, LLSD().with("datetime", (S32) avatar_data->born_on.secondsSinceEpoch())); - args["[REG_DATE]"] = birth_date; - } - args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); - std::string register_date = getString("RegisterDateFormat", args); + std::string register_date = getString("AgeFormat", args); getChild("register_date")->setValue(register_date ); mDescriptionEdit->setValue(avatar_data->about_text); mImageAssetId = avatar_data->image_id; @@ -956,53 +909,7 @@ void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); std::string caption_text = getString("CaptionTextAcctInfo", args); - getChild("acc_status_text")->setValue(caption_text); -} - -void LLPanelProfileSecondLife::onMapButtonClick() -{ - LLAvatarActions::showOnMap(getAvatarId()); -} - -void LLPanelProfileSecondLife::pay() -{ - LLAvatarActions::pay(getAvatarId()); -} - -void LLPanelProfileSecondLife::onClickToggleBlock() -{ - bool blocked = LLAvatarActions::toggleBlock(getAvatarId()); - - updateButtons(); - // we are hiding one button and showing another, set focus - if (blocked) - { - mUnblockButton->setFocus(true); - } - else - { - mBlockButton->setFocus(true); - } -} - -void LLPanelProfileSecondLife::onAddFriendButtonClick() -{ - LLAvatarActions::requestFriendshipDialog(getAvatarId()); -} - -void LLPanelProfileSecondLife::onIMButtonClick() -{ - LLAvatarActions::startIM(getAvatarId()); -} - -void LLPanelProfileSecondLife::onTeleportButtonClick() -{ - LLAvatarActions::offerTeleport(getAvatarId()); -} - -void LLPanelProfileSecondLife::onGroupInvite() -{ - LLAvatarActions::inviteToGroup(getAvatarId()); + getChild("account_info")->setValue(caption_text); } void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) @@ -1112,14 +1019,6 @@ void LLPanelProfileSecondLife::updateOnlineStatus() void LLPanelProfileSecondLife::processOnlineStatus(bool online) { - mStatusText->setVisible(isGrantedToSeeOnlineStatus()); - - std::string status = getString(online ? "status_online" : "status_offline"); - - mStatusText->setValue(status); - mStatusText->setColor(online ? - LLUIColorTable::instance().getColor("StatusUserOnline") : - LLUIColorTable::instance().getColor("StatusUserOffline")); } void LLPanelProfileSecondLife::updateButtons() @@ -1132,33 +1031,6 @@ void LLPanelProfileSecondLife::updateButtons() mShowInSearchCheckbox->setEnabled(TRUE); mDescriptionEdit->setEnabled(TRUE); } - - if (!getSelfProfile()) - { - LLUUID av_id = getAvatarId(); - bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); - - if (LLAvatarActions::isFriend(av_id)) - { - mTeleportButton->setEnabled(is_buddy_online); - //Disable "Add Friend" button for friends. - mAddFriendButton->setEnabled(false); - } - else - { - mTeleportButton->setEnabled(true); - mAddFriendButton->setEnabled(true); - } - - bool enable_map_btn = (is_buddy_online && is_agent_mappable(av_id)) || gAgent.isGodlike(); - mShowOnMapButton->setEnabled(enable_map_btn); - - bool enable_block_btn = LLAvatarActions::canBlock(av_id) && !LLAvatarActions::isBlocked(av_id); - mBlockButton->setVisible(enable_block_btn); - - bool enable_unblock_btn = LLAvatarActions::isBlocked(av_id); - mUnblockButton->setVisible(enable_unblock_btn); - } } void LLPanelProfileSecondLife::onClickSetName() @@ -1857,8 +1729,6 @@ void LLPanelProfile::onTabChange() void LLPanelProfile::updateBtnsVisibility() { - getChild("ok_btn")->setVisible(((getSelfProfile() && !getEmbedded()) || isNotesTabSelected())); - getChild("cancel_btn")->setVisible(((getSelfProfile() && !getEmbedded()) || isNotesTabSelected())); } void LLPanelProfile::onOpen(const LLSD& key) -- cgit v1.2.3 From 2f776a38af873163d6b5d5e030ce4b57a3e10e93 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 8 Apr 2022 00:18:22 +0300 Subject: SL-15312 Legacy profiles remake #2 --- indra/newview/llpanelprofile.cpp | 145 ++++++++++++++++++++++++++++++++------- 1 file changed, 119 insertions(+), 26 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 5453c87013..adf5036498 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -61,6 +61,7 @@ #include "llfilepicker.h" #include "llfirstuse.h" #include "llgroupactions.h" +#include "lllogchat.h" #include "llmutelist.h" #include "llnotificationsutil.h" #include "llpanelblockedlist.h" @@ -148,7 +149,6 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_data->image_id = result["sl_image_id"].asUUID(); avatar_data->fl_image_id = result["fl_image_id"].asUUID(); avatar_data->partner_id = result["partner_id"].asUUID(); - // Todo: new descriptio size is 65536, check if it actually fits or has scroll avatar_data->about_text = result["sl_about_text"].asString(); // Todo: new descriptio size is 65536, check if it actually fits or has scroll avatar_data->fl_about_text = result["fl_about_text"].asString(); @@ -250,6 +250,7 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_notes.agent_id = agent_id; avatar_notes.target_id = agent_id; + // Todo: new notes size is 65536, check that field has a scroll avatar_notes.notes = result["notes"].asString(); panel = floater_profile->findChild(PANEL_NOTES, TRUE); @@ -594,16 +595,11 @@ BOOL LLPanelProfileSecondLife::postBuild() mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); mGiveInvPanel = getChild("give_stack"); - - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; - enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); - enable.add("Profile.EnableGod", [](LLUICtrl*, const LLSD&) { return gAgent.isGodlike(); }); + mAgentActionMenuButton = getChild("agent_actions_menu"); mGroupList->setDoubleClickCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); - //mAgentActionMenuButton->setMenu("menu_name_field.xml", LLMenuButton::MP_BOTTOM_RIGHT); - return TRUE; } @@ -623,6 +619,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) childSetVisible("notes_panel", !own_profile); childSetVisible("settings_panel", own_profile); + childSetVisible("permissions_panel", !own_profile); if (own_profile && !getEmbedded()) { @@ -631,8 +628,23 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mGroupList->enableForAgent(false); } + // Init menu, menu needs to be created in scope of a registar to work correctly. + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; + commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; + enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); }); + enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); }); + if (own_profile) { + //mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT); + } + else + { + // Todo: use PeopleContextMenu instead? + // Todo: add options to copy name, display name, id, may be slurl + mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); } mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded()); @@ -817,8 +829,9 @@ void LLPanelProfileSecondLife::openGroupProfile() void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { mAvatarNameCacheConnection.disconnect(); - - //getChild("complete_name")->setValue( av_name.getCompleteName() ); + // Should be possible to get this from AgentProfile capability + getChild("display_name")->setValue( av_name.getDisplayName() ); + getChild("user_name")->setValue(av_name.getUserName() ); } void LLPanelProfileSecondLife::setUploadProfileImagePath(const std::string &path, const std::string &orig_path) @@ -861,7 +874,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) LLStringUtil::format_map_t args; args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); std::string register_date = getString("AgeFormat", args); - getChild("register_date")->setValue(register_date ); + getChild("user_age")->setValue(register_date ); mDescriptionEdit->setValue(avatar_data->about_text); mImageAssetId = avatar_data->image_id; mSecondLifePic->setValue(mImageAssetId); @@ -891,14 +904,17 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) { - LLTextEditor* partner_text = getChild("partner_text"); + LLTextBox* partner_text_ctrl = getChild("partner_link"); if (avatar_data->partner_id.notNull()) { - partner_text->setText(LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString()); + LLStringUtil::format_map_t args; + args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); + std::string partner_text = getString("partner_text", args); + partner_text_ctrl->setText(partner_text); } else { - partner_text->setText(getString("no_partner_text")); + partner_text_ctrl->setText(getString("no_partner_text")); } } @@ -1101,29 +1117,106 @@ void LLPanelProfileSecondLife::onPickTexture() void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) { - LLAvatarName av_name; - if (!LLAvatarNameCache::get(getAvatarId(), &av_name)) + const std::string item_name = userdata.asString(); + const LLUUID agent_id = getAvatarId(); + // todo: consider moving this into LLAvatarActions::onCommit(name, id) + // and making all other flaoters, like people menu do the same + if (item_name == "im") { - // shouldn't happen, button(menu) is supposed to be invisible while name is fetching - LL_WARNS() << "Failed to get agent data" << LL_ENDL; - return; + LLAvatarActions::startIM(agent_id); + } + else if (item_name == "offer_teleport") + { + LLAvatarActions::offerTeleport(agent_id); + } + else if (item_name == "request_teleport") + { + LLAvatarActions::teleportRequest(agent_id); + } + else if (item_name == "voice_call") + { + LLAvatarActions::startCall(agent_id); + } + else if (item_name == "callog") + { + LLAvatarActions::viewChatHistory(agent_id); + } + else if (item_name == "add_friend") + { + LLAvatarActions::requestFriendshipDialog(agent_id); + } + else if (item_name == "remove_friend") + { + LLAvatarActions::removeFriendDialog(agent_id); + } + else if (item_name == "invite_to_group") + { + LLAvatarActions::inviteToGroup(agent_id); + } + else if (item_name == "can_show_on_map") + { + LLAvatarActions::showOnMap(agent_id); + } + else if (item_name == "share") + { + LLAvatarActions::share(agent_id); + } + else if (item_name == "pay") + { + LLAvatarActions::pay(agent_id); } + else if (item_name == "toggle_block_agent") + { + LLAvatarActions::toggleBlock(agent_id); + } +} +bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) +{ const std::string item_name = userdata.asString(); - LLWString wstr; - if (item_name == "display") + const LLUUID agent_id = getAvatarId(); + if (item_name == "offer_teleport" || item_name == "request_teleport") + { + return LLAvatarActions::canOfferTeleport(agent_id); + } + else if (item_name == "voice_call") { - wstr = utf8str_to_wstring(av_name.getDisplayName(true)); + return LLAvatarActions::canCall(); } - else if (item_name == "name") + else if (item_name == "callog") { - wstr = utf8str_to_wstring(av_name.getAccountName()); + return LLLogChat::isTranscriptExist(agent_id); } - else if (item_name == "id") + else if (item_name == "add_friend") + { + return !LLAvatarActions::isFriend(agent_id); + } + else if (item_name == "remove_friend") + { + return LLAvatarActions::isFriend(agent_id); + } + else if (item_name == "can_show_on_map") + { + return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && is_agent_mappable(agent_id)) + || gAgent.isGodlike(); + } + else if (item_name == "toggle_block_agent") + { + return LLAvatarActions::canBlock(agent_id); + } + + return false; +} + +bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata) +{ + const std::string item_name = userdata.asString(); + const LLUUID agent_id = getAvatarId(); + if (item_name == "toggle_block_agent") { - wstr = utf8str_to_wstring(getAvatarId().asString()); + return LLAvatarActions::isBlocked(agent_id); } - LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); + return false; } void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name) -- cgit v1.2.3 From 285e36b57ea895f660f06095652b8cf03b7cbc09 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 9 Apr 2022 00:57:19 +0300 Subject: SL-15312 Legacy profiles remake #3 --- indra/newview/llpanelprofile.cpp | 326 ++++++++++++++++++++++++++------------- 1 file changed, 221 insertions(+), 105 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index adf5036498..53d0cbec9f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -291,13 +291,7 @@ void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) } } -enum EProfileImageType -{ - PROFILE_IMAGE_SL, - PROFILE_IMAGE_FL, -}; - -void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image) +LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle *handle) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t @@ -307,17 +301,6 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); httpOpts->setFollowRedirects(true); - - LLSD first_data; - switch (type) - { - case PROFILE_IMAGE_SL: - first_data["profile-image-asset"] = "sl_image_id"; - break; - case PROFILE_IMAGE_FL: - first_data["profile-image-asset"] = "fl_image_id"; - break; - } LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); @@ -326,22 +309,21 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!status) { + // todo: notification? LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; - LLFile::remove(path_to_image); - return; + return LLUUID::null; } if (!result.has("uploader")) { + // todo: notification? LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; - LLFile::remove(path_to_image); - return; + return LLUUID::null; } std::string uploader_cap = result["uploader"].asString(); if (uploader_cap.empty()) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; - LLFile::remove(path_to_image); - return; + return LLUUID::null; } // Upload the image @@ -356,8 +338,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!instream.is_open()) { LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; - LLFile::remove(path_to_image); - return; + return LLUUID::null; } length = instream.tellg(); } @@ -371,11 +352,12 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LL_WARNS("AvatarProperties") << result << LL_ENDL; + if (!status) { LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; - LLFile::remove(path_to_image); - return; + return LLUUID::null; } if (result["state"].asString() != "complete") @@ -388,14 +370,62 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s { LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; } - LLFile::remove(path_to_image); - return; + return LLUUID::null; + } + + return result["new_asset"].asUUID(); +} + +enum EProfileImageType +{ + PROFILE_IMAGE_SL, + PROFILE_IMAGE_FL, +}; + +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle *handle) +{ + LLSD data; + switch (type) + { + case PROFILE_IMAGE_SL: + data["profile-image-asset"] = "sl_image_id"; + break; + case PROFILE_IMAGE_FL: + data["profile-image-asset"] = "fl_image_id"; + break; } + LLUUID result = post_profile_image(cap_url, data, path_to_image, handle); + + // reset loading indicator + switch (type) + { + case PROFILE_IMAGE_SL: + if (!handle->isDead()) + { + LLPanelProfileSecondLife* panel = static_cast(handle->get()); + if (result.notNull()) + { + panel->setProfileImageUploaded(result); + } + else + { + // failure, just stop progress indicator + panel->setProfileImageUploading(false); + } + } + break; + case PROFILE_IMAGE_FL: + // Todo: refresh the panel + break; + } + + // Cleanup LLFile::remove(path_to_image); + delete handle; } -void launch_profile_image_coro(EProfileImageType type, const std::string &file_path) +void launch_profile_image_coro(EProfileImageType type, const std::string &file_path, LLHandle *handle) { std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); if (!cap_url.empty()) @@ -410,7 +440,7 @@ void launch_profile_image_coro(EProfileImageType type, const std::string &file_p if (LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) { LLCoros::instance().launch("postAgentUserImageCoro", - boost::bind(post_profile_image_coro, cap_url, type, temp_file)); + boost::bind(post_profile_image_coro, cap_url, type, temp_file, handle)); } } else @@ -564,6 +594,7 @@ LLAgentHandler gAgentHandler; LLPanelProfileSecondLife::LLPanelProfileSecondLife() : LLPanelProfileTab() , mAvatarNameCacheConnection() + , mWaitingForImageUpload(false) { } @@ -583,8 +614,6 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife() { mAvatarNameCacheConnection.disconnect(); } - - clearUploadProfileImagePath(); } BOOL LLPanelProfileSecondLife::postBuild() @@ -594,11 +623,14 @@ BOOL LLPanelProfileSecondLife::postBuild() mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); - mGiveInvPanel = getChild("give_stack"); mAgentActionMenuButton = getChild("agent_actions_menu"); + mSaveDescriptionChanges = getChild("save_description_changes"); + mDiscardDescriptionChanges = getChild("discard_description_changes"); - mGroupList->setDoubleClickCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); - mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); + mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); + mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); + mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); + mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); return TRUE; } @@ -615,10 +647,10 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) BOOL own_profile = getSelfProfile(); mGroupList->setShowNone(!own_profile); - //mGiveInvPanel->setVisible(!own_profile); childSetVisible("notes_panel", !own_profile); childSetVisible("settings_panel", own_profile); + childSetVisible("about_buttons_panel", own_profile); childSetVisible("permissions_panel", !own_profile); if (own_profile && !getEmbedded()) @@ -638,12 +670,11 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) if (own_profile) { - //mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT); + mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT); } else { // Todo: use PeopleContextMenu instead? - // Todo: add options to copy name, display name, id, may be slurl mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); } @@ -665,6 +696,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); } +// todo:: remove apply void LLPanelProfileSecondLife::apply(LLAvatarData* data) { if (getIsLoaded() && getSelfProfile()) @@ -675,7 +707,6 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) LLSD params = LLSDMap(); // we have an image, check if it is local. Server won't recognize local ids. if (data->image_id != mImageAssetId - && mImageFile.empty() && !LLLocalBitmapMgr::getInstance()->isLocal(mImageAssetId)) { params["sl_image_id"] = mImageAssetId; @@ -701,22 +732,6 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } - - // Only if image is local - if (!mImageFile.empty()) - { - std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("postAgentUserImageCoro", - boost::bind(post_profile_image_coro, cap_url, PROFILE_IMAGE_SL, mImageFile)); - mImageFile.clear(); // coro should do the deleting - } - else - { - LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; - } - } } } @@ -769,8 +784,6 @@ void LLPanelProfileSecondLife::resetData() mDescriptionEdit->setValue(LLStringUtil::null); mGroups.clear(); mGroupList->setGroups(mGroups); - clearUploadProfileImagePath(); - //mAgentActionMenuButton set menu } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -834,35 +847,34 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L getChild("user_name")->setValue(av_name.getUserName() ); } -void LLPanelProfileSecondLife::setUploadProfileImagePath(const std::string &path, const std::string &orig_path) +void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) { - clearUploadProfileImagePath(); - // todo: display this in floater, - // LLIconCtrl can't show a path, only by id or name, so may be draw directly or add as a local bitmap? - // LLLocalBitmap* unit = new LLLocalBitmap(path); - - // assign a local texture to view in viewer - // Todo: remove LLLocalBitmap and just draw texture instead - // orig_path was used instead of path, since LLLocalBitmapMgr does not support j2c - LLUUID tracking_id = LLLocalBitmapMgr::getInstance()->addUnit(orig_path); - if (tracking_id.isNull()) - { - // todo: error handling - return; - } - - mImageFile = path; - mImageAssetId = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); - mSecondLifePic->setValue(mImageAssetId); + // Todo: loading indicator here + mWaitingForImageUpload = loading; } -void LLPanelProfileSecondLife::clearUploadProfileImagePath() +void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id) { - if (!mImageFile.empty()) + mSecondLifePic->setValue(image_asset_id); + + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id); + if (imagep->getFullHeight()) + { + onImageLoaded(true, imagep); + } + else { - LLFile::remove(mImageFile); //todo: supress errors, may be not need to remove if it becomes a LLLocalBitmap + imagep->setLoadedCallback(onImageLoaded, + MAX_DISCARD_LEVEL, + FALSE, + FALSE, + new LLHandle(getHandle()), + NULL, + FALSE); } - mImageFile.clear(); + + mWaitingForImageUpload = false; + // Todo: reset loading indicator here } void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) @@ -879,7 +891,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) mImageAssetId = avatar_data->image_id; mSecondLifePic->setValue(mImageAssetId); - //Don't bother about boost level, picker will set it + // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); if (imagep->getFullHeight()) { @@ -1046,14 +1058,11 @@ void LLPanelProfileSecondLife::updateButtons() mShowInSearchCheckbox->setVisible(TRUE); mShowInSearchCheckbox->setEnabled(TRUE); mDescriptionEdit->setEnabled(TRUE); - } -} -void LLPanelProfileSecondLife::onClickSetName() -{ - LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); - - LLFirstUse::setDisplayName(false); + // todo: enable/disble buttons based on text changes + //mSaveDescriptionChanges-> + //mDiscardDescriptionChanges-> + } } @@ -1061,17 +1070,19 @@ void LLPanelProfileSecondLife::onClickSetName() class LLProfileImagePicker : public LLFilePickerThread { public: - LLProfileImagePicker(LLHandle *handle); + LLProfileImagePicker(EProfileImageType type, LLHandle *handle); ~LLProfileImagePicker(); virtual void notify(const std::vector& filenames); private: LLHandle *mHandle; + EProfileImageType mType; }; -LLProfileImagePicker::LLProfileImagePicker(LLHandle *handle) +LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle *handle) : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), - mHandle(handle) + mHandle(handle), + mType(type) { } @@ -1082,10 +1093,6 @@ LLProfileImagePicker::~LLProfileImagePicker() void LLProfileImagePicker::notify(const std::vector& filenames) { - /*if (LLAppViewer::instance()->quitRequested()) - { - return; - }*/ if (mHandle->isDead()) { return; @@ -1102,17 +1109,25 @@ void LLProfileImagePicker::notify(const std::vector& filenames) const S32 MAX_DIM = 256; if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) { - // todo: error handling + //todo: image not supported notification + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; + return; + } + + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (cap_url.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; return; } LLPanelProfileSecondLife* panel = static_cast(mHandle->get()); - panel->setUploadProfileImagePath(temp_file, file_path); -} + panel->setProfileImageUploading(true); -void LLPanelProfileSecondLife::onPickTexture() -{ - (new LLProfileImagePicker(new LLHandle(getHandle())))->getFile(); + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle)); + + mHandle = nullptr; // transferred to post_profile_image_coro } void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) @@ -1169,6 +1184,63 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) { LLAvatarActions::toggleBlock(agent_id); } + else if (item_name == "copy_user_id") + { + LLWString wstr = utf8str_to_wstring(getAvatarId().asString()); + LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); + } + else if (item_name == "copy_display_name" + || item_name == "copy_username") + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(getAvatarId(), &av_name)) + { + // shouldn't happen, option is supposed to be invisible while name is fetching + LL_WARNS() << "Failed to get agent data" << LL_ENDL; + return; + } + LLWString wstr; + if (item_name == "copy_display_name") + { + wstr = utf8str_to_wstring(av_name.getDisplayName(true)); + } + else if (item_name == "copy_username") + { + wstr = utf8str_to_wstring(av_name.getUserName()); + } + LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); + } + else if (item_name == "edit_display_name") + { + LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); + LLFirstUse::setDisplayName(false); + } + else if (item_name == "edit_partner") + { + // todo: open https://secondlife.com/my/account/partners.php or whatever link is correct for the grid + } + else if (item_name == "change_photo") + { + (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle(getHandle())))->getFile(); + } + else if (item_name == "remove_photo") + { + LLSD params; + params["sl_image_id"] = LLUUID::null; // todo: verify that it works and matches Generic_Person_Large + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + + mSecondLifePic->setValue("Generic_Person_Large"); + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } + } } bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) @@ -1181,7 +1253,7 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) } else if (item_name == "voice_call") { - return LLAvatarActions::canCall(); + return mVoiceStatus; } else if (item_name == "callog") { @@ -1204,6 +1276,21 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) { return LLAvatarActions::canBlock(agent_id); } + else if (item_name == "copy_display_name" + || item_name == "copy_username") + { + return !mAvatarNameCacheConnection.connected(); + } + else if (item_name == "change_photo") + { + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + return !cap_url.empty() && !mWaitingForImageUpload; + } + else if (item_name == "remove_photo") + { + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + return !cap_url.empty() && !mWaitingForImageUpload; + } return false; } @@ -1247,6 +1334,35 @@ void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, LLFloaterReg::showInstance("display_name"); } +void LLPanelProfileSecondLife::onSaveDescriptionChanges() +{ + // todo: force commit changes in mDescriptionEdit, reset dirty flags + // todo: check if mDescriptionEdit can be made to not commit immediately + + LLSD params; + params["sl_about_text"] = mDescriptionEdit->getValue().asString(); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } + + updateButtons(); +} + +void LLPanelProfileSecondLife::onDiscardDescriptionChanges() +{ + // todo: restore mDescriptionEdit + + updateButtons(); +} + ////////////////////////////////////////////////////////////////////////// // LLPanelProfileWeb @@ -1514,7 +1630,7 @@ void LLPanelProfileFirstLife::apply(LLAvatarData* data) { // todo: temporary file, connect to UI std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); - launch_profile_image_coro(PROFILE_IMAGE_FL, file_path); + launch_profile_image_coro(PROFILE_IMAGE_FL, file_path, new LLHandle(getHandle())); } } -- cgit v1.2.3 From f42dba8d928da51ee93eae4e15b64280bfcf7ffd Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 12 Apr 2022 00:41:40 +0300 Subject: SL-15312 Legacy profiles remake #4 --- indra/newview/llpanelprofile.cpp | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 53d0cbec9f..c00e25a31d 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -46,6 +46,7 @@ #include "lltexturectrl.h" #include "lltoggleablemenu.h" #include "llgrouplist.h" +#include "llurlaction.h" // Image #include "llimagej2c.h" @@ -622,7 +623,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mShowInSearchCheckbox = getChild("show_in_search_checkbox"); mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_stack"); - mDescriptionEdit = getChild("sl_description_edit"); + mDescriptionEdit = getChild("sl_description_edit"); mAgentActionMenuButton = getChild("agent_actions_menu"); mSaveDescriptionChanges = getChild("save_description_changes"); mDiscardDescriptionChanges = getChild("discard_description_changes"); @@ -631,6 +632,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); + mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); return TRUE; } @@ -781,7 +783,7 @@ void LLPanelProfileSecondLife::resetData() LLRect imageRect = mSecondLifePicLayout->getRect(); mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); - mDescriptionEdit->setValue(LLStringUtil::null); + setDescriptionText(LLStringUtil::null); mGroups.clear(); mGroupList->setGroups(mGroups); } @@ -887,7 +889,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); std::string register_date = getString("AgeFormat", args); getChild("user_age")->setValue(register_date ); - mDescriptionEdit->setValue(avatar_data->about_text); + setDescriptionText(avatar_data->about_text); mImageAssetId = avatar_data->image_id; mSecondLifePic->setValue(mImageAssetId); @@ -1058,10 +1060,6 @@ void LLPanelProfileSecondLife::updateButtons() mShowInSearchCheckbox->setVisible(TRUE); mShowInSearchCheckbox->setEnabled(TRUE); mDescriptionEdit->setEnabled(TRUE); - - // todo: enable/disble buttons based on text changes - //mSaveDescriptionChanges-> - //mDiscardDescriptionChanges-> } } @@ -1217,7 +1215,10 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) } else if (item_name == "edit_partner") { - // todo: open https://secondlife.com/my/account/partners.php or whatever link is correct for the grid + std::string url = "https://[GRID]/my/account/partners.php"; + LLSD subs; + url = LLWeb::expandURLSubstitutions(url, subs); + LLUrlAction::openURL(url); } else if (item_name == "change_photo") { @@ -1334,13 +1335,28 @@ void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, LLFloaterReg::showInstance("display_name"); } +void LLPanelProfileSecondLife::setDescriptionText(const std::string &text) +{ + mSaveDescriptionChanges->setEnabled(FALSE); + mDiscardDescriptionChanges->setEnabled(FALSE); + mDescriptionText = text; + mDescriptionEdit->setValue(mDescriptionText); +} + +void LLPanelProfileSecondLife::onSetDescriptionDirty() +{ + mSaveDescriptionChanges->setEnabled(TRUE); + mDiscardDescriptionChanges->setEnabled(TRUE); +} + void LLPanelProfileSecondLife::onSaveDescriptionChanges() { // todo: force commit changes in mDescriptionEdit, reset dirty flags // todo: check if mDescriptionEdit can be made to not commit immediately + mDescriptionText = mDescriptionEdit->getValue().asString(); LLSD params; - params["sl_about_text"] = mDescriptionEdit->getValue().asString(); + params["sl_about_text"] = mDescriptionText; std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) @@ -1358,9 +1374,7 @@ void LLPanelProfileSecondLife::onSaveDescriptionChanges() void LLPanelProfileSecondLife::onDiscardDescriptionChanges() { - // todo: restore mDescriptionEdit - - updateButtons(); + setDescriptionText(mDescriptionText); } ////////////////////////////////////////////////////////////////////////// @@ -1547,6 +1561,11 @@ BOOL LLPanelProfileFirstLife::postBuild() mDescriptionEdit = getChild("fl_description_edit"); mPicture = getChild("real_world_pic"); + mChangePhoto = getChild("fl_upload_image"); + mRemovePhoto = getChild("fl_remove_image"); + mSaveChanges = getChild("fl_save_changes"); + mDiscardChanges = getChild("fl_discard_changes"); + mDescriptionEdit->setFocusReceivedCallback(boost::bind(&LLPanelProfileFirstLife::onDescriptionFocusReceived, this)); return TRUE; @@ -1597,6 +1616,11 @@ void LLPanelProfileFirstLife::resetData() { mDescriptionEdit->setValue(LLStringUtil::null); mPicture->setValue(mPicture->getDefaultImageAssetID()); + + mChangePhoto->setVisible(getSelfProfile()); + mRemovePhoto->setVisible(getSelfProfile()); + mSaveChanges->setVisible(getSelfProfile()); + mDiscardChanges->setVisible(getSelfProfile()); } void LLPanelProfileFirstLife::apply(LLAvatarData* data) -- cgit v1.2.3 From 1483c05c9f61e7ce44e8883d8e10d976867882fa Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 12 Apr 2022 21:46:53 +0300 Subject: SL-15312 Legacy profiles remake #5 Mostly changes for notes tab and first life tab --- indra/newview/llpanelprofile.cpp | 388 ++++++++++++++++++--------------------- 1 file changed, 175 insertions(+), 213 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index c00e25a31d..b7bc1e2cba 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -195,10 +195,7 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) LLPanelProfileFirstLife *panel_first = dynamic_cast(panel); if (panel_first) { - panel_first->mCurrentDescription = avatar_data->fl_about_text; - panel_first->mDescriptionEdit->setValue(panel_first->mCurrentDescription); - panel_first->mPicture->setValue(avatar_data->fl_image_id); - panel_first->updateButtons(); + panel_first->processProperties(avatar_data); } // Picks @@ -399,26 +396,39 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s LLUUID result = post_profile_image(cap_url, data, path_to_image, handle); // reset loading indicator - switch (type) + if (!handle->isDead()) { - case PROFILE_IMAGE_SL: - if (!handle->isDead()) + switch (type) { - LLPanelProfileSecondLife* panel = static_cast(handle->get()); - if (result.notNull()) + case PROFILE_IMAGE_SL: { - panel->setProfileImageUploaded(result); + LLPanelProfileSecondLife* panel = static_cast(handle->get()); + if (result.notNull()) + { + panel->setProfileImageUploaded(result); + } + else + { + // failure, just stop progress indicator + panel->setProfileImageUploading(false); + } + break; } - else + case PROFILE_IMAGE_FL: { - // failure, just stop progress indicator - panel->setProfileImageUploading(false); + LLPanelProfileFirstLife* panel = static_cast(handle->get()); + if (result.notNull()) + { + panel->setProfileImageUploaded(result); + } + else + { + // failure, just stop progress indicator + panel->setProfileImageUploading(false); + } + break; } } - break; - case PROFILE_IMAGE_FL: - // Todo: refresh the panel - break; } // Cleanup @@ -426,30 +436,6 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s delete handle; } -void launch_profile_image_coro(EProfileImageType type, const std::string &file_path, LLHandle *handle) -{ - std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); - if (!cap_url.empty()) - { - // todo: createUploadFile needs to be done when user picks up a file, - // not when user clicks 'ok', but coroutine should happen on 'ok'. - // but this waits for a UI update, the main point is a functional coroutine - std::string temp_file = gDirUtilp->getTempFilename(); - U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); - const S32 MAX_DIM = 256; - - if (LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) - { - LLCoros::instance().launch("postAgentUserImageCoro", - boost::bind(post_profile_image_coro, cap_url, type, temp_file, handle)); - } - } - else - { - LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; - } -} - ////////////////////////////////////////////////////////////////////////// // LLProfileHandler @@ -682,14 +668,9 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded()); - LLProfileDropTarget* drop_target = getChild("drop_target"); - drop_target->setVisible(!own_profile); - drop_target->setEnabled(!own_profile); - if (!own_profile) { mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE); - drop_target->setAgentID(avatar_id); updateOnlineStatus(); } @@ -698,45 +679,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); } -// todo:: remove apply -void LLPanelProfileSecondLife::apply(LLAvatarData* data) -{ - if (getIsLoaded() && getSelfProfile()) - { - // Might be a better idea to accumulate changes in floater - // instead of sending a request per tab - - LLSD params = LLSDMap(); - // we have an image, check if it is local. Server won't recognize local ids. - if (data->image_id != mImageAssetId - && !LLLocalBitmapMgr::getInstance()->isLocal(mImageAssetId)) - { - params["sl_image_id"] = mImageAssetId; - } - if (data->about_text != mDescriptionEdit->getValue().asString()) - { - params["sl_about_text"] = mDescriptionEdit->getValue().asString(); - } - if ((bool)data->allow_publish != mShowInSearchCheckbox->getValue().asBoolean()) - { - params["allow_publish"] = mShowInSearchCheckbox->getValue().asBoolean(); - } - if (!params.emptyMap()) - { - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } - } - } -} - void LLPanelProfileSecondLife::updateData() { LLUUID avatar_id = getAvatarId(); @@ -846,7 +788,7 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L mAvatarNameCacheConnection.disconnect(); // Should be possible to get this from AgentProfile capability getChild("display_name")->setValue( av_name.getDisplayName() ); - getChild("user_name")->setValue(av_name.getUserName() ); + getChild("user_name")->setValue(av_name.getAccountName()); } void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) @@ -888,10 +830,17 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) LLStringUtil::format_map_t args; args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); std::string register_date = getString("AgeFormat", args); - getChild("user_age")->setValue(register_date ); + getChild("user_age")->setValue(register_date); setDescriptionText(avatar_data->about_text); - mImageAssetId = avatar_data->image_id; - mSecondLifePic->setValue(mImageAssetId); + + if (avatar_data->image_id.notNull()) + { + mSecondLifePic->setValue(avatar_data->image_id); + } + else + { + mSecondLifePic->setValue("Generic_Person_Large"); + } // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); @@ -1227,7 +1176,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) else if (item_name == "remove_photo") { LLSD params; - params["sl_image_id"] = LLUUID::null; // todo: verify that it works and matches Generic_Person_Large + params["sl_image_id"] = LLUUID::null; std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) @@ -1351,25 +1300,20 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() void LLPanelProfileSecondLife::onSaveDescriptionChanges() { - // todo: force commit changes in mDescriptionEdit, reset dirty flags - // todo: check if mDescriptionEdit can be made to not commit immediately - mDescriptionText = mDescriptionEdit->getValue().asString(); - LLSD params; - params["sl_about_text"] = mDescriptionText; - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) { LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText))); } else { LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } - updateButtons(); + mSaveDescriptionChanges->setEnabled(FALSE); + mDiscardDescriptionChanges->setEnabled(FALSE); } void LLPanelProfileSecondLife::onDiscardDescriptionChanges() @@ -1430,11 +1374,6 @@ void LLPanelProfileWeb::resetData() mWebBrowser->navigateHome(); } -void LLPanelProfileWeb::apply(LLAvatarData* data) -{ - -} - void LLPanelProfileWeb::updateData() { LLUUID avatar_id = getAvatarId(); @@ -1547,8 +1486,7 @@ void LLPanelProfileWeb::updateButtons() ////////////////////////////////////////////////////////////////////////// LLPanelProfileFirstLife::LLPanelProfileFirstLife() - : LLPanelProfileTab(), - mIsEditing(false) + : LLPanelProfileTab() { } @@ -1559,14 +1497,18 @@ LLPanelProfileFirstLife::~LLPanelProfileFirstLife() BOOL LLPanelProfileFirstLife::postBuild() { mDescriptionEdit = getChild("fl_description_edit"); - mPicture = getChild("real_world_pic"); + mPicture = getChild("real_world_pic"); mChangePhoto = getChild("fl_upload_image"); mRemovePhoto = getChild("fl_remove_image"); mSaveChanges = getChild("fl_save_changes"); mDiscardChanges = getChild("fl_discard_changes"); - mDescriptionEdit->setFocusReceivedCallback(boost::bind(&LLPanelProfileFirstLife::onDescriptionFocusReceived, this)); + mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr); + mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr); + mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); + mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); + mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); return TRUE; } @@ -1578,15 +1520,82 @@ void LLPanelProfileFirstLife::onOpen(const LLSD& key) resetData(); } +void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) +{ + mChangePhoto->setEnabled(loading); + mRemovePhoto->setEnabled(loading); + + // Todo: loading indicator here +} + +void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id) +{ + mPicture->setValue(image_asset_id); + mChangePhoto->setEnabled(TRUE); + mRemovePhoto->setEnabled(TRUE); + + // Todo: reset loading indicator here +} + +void LLPanelProfileFirstLife::onChangePhoto() +{ + (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle(getHandle())))->getFile(); +} + +void LLPanelProfileFirstLife::onRemovePhoto() +{ + LLSD params; + params["fl_image_id"] = LLUUID::null; + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + + mPicture->setValue("Generic_Person_Large"); + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } +} + +void LLPanelProfileFirstLife::setDescriptionText(const std::string &text) +{ + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); + mCurrentDescription = text; + mDescriptionEdit->setValue(mCurrentDescription); +} + +void LLPanelProfileFirstLife::onSetDescriptionDirty() +{ + mSaveChanges->setEnabled(TRUE); + mDiscardChanges->setEnabled(TRUE); +} -void LLPanelProfileFirstLife::onDescriptionFocusReceived() +void LLPanelProfileFirstLife::onSaveDescriptionChanges() { - if (!mIsEditing && getSelfProfile()) + mCurrentDescription = mDescriptionEdit->getValue().asString(); + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - mIsEditing = true; - mDescriptionEdit->setParseHTML(false); - mDescriptionEdit->setText(mCurrentDescription); + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mCurrentDescription))); } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } + + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); +} + +void LLPanelProfileFirstLife::onDiscardDescriptionChanges() +{ + setDescriptionText(mCurrentDescription); } void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type) @@ -1596,68 +1605,36 @@ void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType const LLAvatarData* avatar_data = static_cast(data); if (avatar_data && getAvatarId() == avatar_data->avatar_id) { - mCurrentDescription = avatar_data->fl_about_text; - mDescriptionEdit->setValue(mCurrentDescription); - mPicture->setValue(avatar_data->fl_image_id); - updateButtons(); + processProperties(avatar_data); } } } void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { - mCurrentDescription = avatar_data->fl_about_text; - mDescriptionEdit->setValue(mCurrentDescription); - mPicture->setValue(avatar_data->fl_image_id); + setDescriptionText(avatar_data->fl_about_text); + if (avatar_data->fl_image_id.notNull()) + { + mPicture->setValue(avatar_data->fl_image_id); + } + else + { + mPicture->setValue("Generic_Person_Large"); + } updateButtons(); } void LLPanelProfileFirstLife::resetData() { mDescriptionEdit->setValue(LLStringUtil::null); - mPicture->setValue(mPicture->getDefaultImageAssetID()); - + mPicture->setValue("Generic_Person_Large"); + mChangePhoto->setVisible(getSelfProfile()); mRemovePhoto->setVisible(getSelfProfile()); mSaveChanges->setVisible(getSelfProfile()); mDiscardChanges->setVisible(getSelfProfile()); } -void LLPanelProfileFirstLife::apply(LLAvatarData* data) -{ - LLSD params = LLSDMap(); - if (data->fl_image_id != mPicture->getImageAssetID() - && !LLLocalBitmapMgr::getInstance()->isLocal(mPicture->getImageAssetID())) - { - params["fl_image_id"] = mPicture->getImageAssetID(); - } - if (data->fl_about_text != mDescriptionEdit->getValue().asString()) - { - params["fl_about_text"] = mDescriptionEdit->getValue().asString(); - } - if (!params.emptyMap()) - { - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (getIsLoaded() && !cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to upload profile data " << PROFILE_PROPERTIES_CAP << " cap not found" << LL_ENDL; - } - } - - if (data->fl_image_id != mPicture->getImageAssetID() - && LLLocalBitmapMgr::getInstance()->isLocal(mPicture->getImageAssetID())) - { - // todo: temporary file, connect to UI - std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); - launch_profile_image_coro(PROFILE_IMAGE_FL, file_path, new LLHandle(getHandle())); - } -} - void LLPanelProfileFirstLife::updateButtons() { LLPanelProfileTab::updateButtons(); @@ -1675,7 +1652,6 @@ void LLPanelProfileFirstLife::updateButtons() LLPanelProfileNotes::LLPanelProfileNotes() : LLPanelProfileTab() -, mAvatarNameCacheConnection() { } @@ -1686,11 +1662,6 @@ LLPanelProfileNotes::~LLPanelProfileNotes() { LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); } - - if (mAvatarNameCacheConnection.connected()) - { - mAvatarNameCacheConnection.disconnect(); - } } void LLPanelProfileNotes::updateData() @@ -1715,10 +1686,13 @@ BOOL LLPanelProfileNotes::postBuild() mMapRights = getChild("map_check"); mEditObjectRights = getChild("objects_check"); mNotesEditor = getChild("notes_edit"); + mSaveChanges = getChild("notes_save_changes"); + mDiscardChanges = getChild("notes_discard_changes"); mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); - - mNotesEditor->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitNotes,this)); + mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr); + mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr); + mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); }); return TRUE; } @@ -1730,14 +1704,6 @@ void LLPanelProfileNotes::onOpen(const LLSD& key) resetData(); fillRightsData(); - - mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileNotes::onAvatarNameCache, this, _1, _2)); -} - -void LLPanelProfileNotes::apply() -{ - onCommitNotes(); - applyRights(); } void LLPanelProfileNotes::fillRightsData() @@ -1778,6 +1744,43 @@ void LLPanelProfileNotes::onCommitNotes() } } +void LLPanelProfileNotes::setNotesText(const std::string &text) +{ + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); + mCurrentNotes = text; + mNotesEditor->setValue(mCurrentNotes); +} + +void LLPanelProfileNotes::onSetNotesDirty() +{ + mSaveChanges->setEnabled(TRUE); + mDiscardChanges->setEnabled(TRUE); +} + +void LLPanelProfileNotes::onSaveNotesChanges() +{ + mCurrentNotes = mNotesEditor->getValue().asString(); + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } + + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); +} + +void LLPanelProfileNotes::onDiscardNotesChanges() +{ + setNotesText(mCurrentNotes); +} + void LLPanelProfileNotes::rightsConfirmationCallback(const LLSD& notification, const LLSD& response) { @@ -1875,8 +1878,6 @@ void LLPanelProfileNotes::resetData() mOnlineStatus->setValue(FALSE); mMapRights->setValue(FALSE); mEditObjectRights->setValue(FALSE); - - mURLWebProfile.clear(); } void LLPanelProfileNotes::enableCheckboxes(bool enable) @@ -1906,23 +1907,6 @@ void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) } } -void LLPanelProfileNotes::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) -{ - mAvatarNameCacheConnection.disconnect(); - - std::string username = av_name.getAccountName(); - if (username.empty()) - { - username = LLCacheName::buildUsername(av_name.getDisplayName()); - } - else - { - LLStringUtil::replaceChar(username, ' ', '.'); - } - - mURLWebProfile = getProfileURL(username, false); -} - ////////////////////////////////////////////////////////////////////////// // LLPanelProfile @@ -2027,28 +2011,6 @@ void LLPanelProfile::updateData() } } -void LLPanelProfile::apply() -{ - if (getSelfProfile()) - { - //KC - AvatarData is spread over 3 different panels - // collect data from the last 2 and give to the first to save - mPanelFirstlife->apply(&mAvatarData); - mPanelWeb->apply(&mAvatarData); - mPanelSecondlife->apply(&mAvatarData); - - mPanelPicks->apply(); - mPanelNotes->apply(); - mPanelClassifieds->apply(); - - //KC - Classifieds handles this itself - } - else - { - mPanelNotes->apply(); - } -} - void LLPanelProfile::showPick(const LLUUID& pick_id) { if (pick_id.notNull()) -- cgit v1.2.3 From 4f38a63b076044e9578a91b769a4e1856241f2ba Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 13 Apr 2022 23:38:02 +0300 Subject: SL-15312 Legacy profiles remake #6 --- indra/newview/llpanelprofile.cpp | 352 +++++++++++++++++++++++++-------------- 1 file changed, 223 insertions(+), 129 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index b7bc1e2cba..34caa61fbf 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -574,6 +574,163 @@ public: LLAgentHandler gAgentHandler; +///---------------------------------------------------------------------------- +/// LLFloaterInventoryFinder +///---------------------------------------------------------------------------- + +class LLFloaterProfilePermissions + : public LLFloater + , public LLFriendObserver +{ +public: + LLFloaterProfilePermissions(const LLUUID &avatar_id); + ~LLFloaterProfilePermissions(); + BOOL postBuild() override; + void changed(U32 mask) override; // LLFriendObserver + // todo: check if this (and inventory filters) need a drawFrustum() + +private: + void fillRightsData(); + void rightsConfirmationCallback(const LLSD& notification, const LLSD& response); + void confirmModifyRights(bool grant); + void onCommitRights(); + + void onApplyRights(); + void onCancel(); + + LLCheckBoxCtrl* mOnlineStatus; + LLCheckBoxCtrl* mMapRights; + LLCheckBoxCtrl* mEditObjectRights; + LLButton* mOkBtn; + LLButton* mCancelBtn; + + LLUUID mAvatarID; +}; + +LLFloaterProfilePermissions::LLFloaterProfilePermissions(const LLUUID &avatar_id) + : LLFloater(LLSD()) + , mAvatarID(avatar_id) +{ + buildFromFile("floater_profile_permissions.xml"); +} + +LLFloaterProfilePermissions::~LLFloaterProfilePermissions() +{ +} + +BOOL LLFloaterProfilePermissions::postBuild() +{ + mOnlineStatus = getChild("online_check"); + mMapRights = getChild("map_check"); + mEditObjectRights = getChild("objects_check"); + mOkBtn = getChild("perms_btn_ok"); + mCancelBtn = getChild("perms_btn_cancel"); + + mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitRights(); }, nullptr); + mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr); + mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr); + + fillRightsData(); // is it possible to not be friends at this point? This might need to be onOpen() + + return TRUE; +} + +void LLFloaterProfilePermissions::changed(U32 mask) +{ + //todo +} + +void LLFloaterProfilePermissions::fillRightsData() +{ + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + // If true - we are viewing friend's profile, enable check boxes and set values. + if (relation) + { + S32 rights = relation->getRightsGrantedTo(); + + mOnlineStatus->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); + mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + } + else + { + closeFloater(); + LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL; + } +} + +void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification, + const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); + } +} + +void LLFloaterProfilePermissions::confirmModifyRights(bool grant) +{ + LLSD args; + args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString(); + LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(), + boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2)); +} + +void LLFloaterProfilePermissions::onCommitRights() +{ + const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + + if (!buddy_relationship) + { + LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; + return; + } + + bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); + + // if modify objects checkbox clicked + if (buddy_relationship->isRightGrantedTo( + LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) + { + confirmModifyRights(allow_modify_objects); + } +} + +void LLFloaterProfilePermissions::onApplyRights() +{ + const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + + if (!buddy_relationship) + { + LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; + return; + } + + S32 rights = 0; + + if (mOnlineStatus->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_ONLINE_STATUS; + } + if (mMapRights->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_MAP_LOCATION; + } + if (mEditObjectRights->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + } + + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights); + + closeFloater(); +} + +void LLFloaterProfilePermissions::onCancel() +{ + closeFloater(); +} ////////////////////////////////////////////////////////////////////////// // LLPanelProfileSecondLife @@ -613,12 +770,21 @@ BOOL LLPanelProfileSecondLife::postBuild() mAgentActionMenuButton = getChild("agent_actions_menu"); mSaveDescriptionChanges = getChild("save_description_changes"); mDiscardDescriptionChanges = getChild("discard_description_changes"); + mSeeOnlineToggle = getChild("allow_to_see_online"); + mSeeOnMapToggle = getChild("allow_to_see_on_map"); + mEditObjectsToggle = getChild("allow_edit_my_objects"); mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); + //mSeeOnlineToggle->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); + mSeeOnlineToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); + // mSeeOnMapToggle->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); + mSeeOnMapToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); + //mEditObjectsToggle->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); + mEditObjectsToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); return TRUE; } @@ -639,7 +805,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) childSetVisible("notes_panel", !own_profile); childSetVisible("settings_panel", own_profile); childSetVisible("about_buttons_panel", own_profile); - childSetVisible("permissions_panel", !own_profile); if (own_profile && !getEmbedded()) { @@ -672,6 +837,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) { mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE); updateOnlineStatus(); + fillRightsData(); } updateButtons(); @@ -715,10 +881,6 @@ void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorTyp void LLPanelProfileSecondLife::resetData() { resetLoading(); - getChild("complete_name")->setValue(LLStringUtil::null); - getChild("register_date")->setValue(LLStringUtil::null); - getChild("acc_status_text")->setValue(LLStringUtil::null); - getChild("partner_text")->setValue(LLStringUtil::null); // Set default image and 1:1 dimensions for it mSecondLifePic->setValue("Generic_Person_Large"); @@ -728,6 +890,11 @@ void LLPanelProfileSecondLife::resetData() setDescriptionText(LLStringUtil::null); mGroups.clear(); mGroupList->setGroups(mGroups); + + mSeeOnlineToggle->setToggleState(false); + mSeeOnMapToggle->setToggleState(false); + mEditObjectsToggle->setToggleState(false); + childSetVisible("permissions_panel", false); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -891,6 +1058,28 @@ void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data getChild("account_info")->setValue(caption_text); } +void LLPanelProfileSecondLife::fillRightsData() +{ + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + // If true - we are viewing friend's profile, enable check boxes and set values. + if (relation) + { + S32 rights = relation->getRightsGrantedTo(); + + mSeeOnlineToggle->setToggleState(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); + mSeeOnMapToggle->setToggleState(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + mEditObjectsToggle->setToggleState(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + } + else + { + mSeeOnlineToggle->setToggleState(false); + mSeeOnMapToggle->setToggleState(false); + mEditObjectsToggle->setToggleState(false); + } + + childSetVisible("permissions_panel", NULL != relation); +} + void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) { LLRect imageRect = mSecondLifePicLayout->getRect(); @@ -936,7 +1125,14 @@ void LLPanelProfileSecondLife::onImageLoaded(BOOL success, // virtual, called by LLAvatarTracker void LLPanelProfileSecondLife::changed(U32 mask) { - updateOnlineStatus(); + if (mask & LLFriendObserver::ONLINE) + { + updateOnlineStatus(); + } + if (mask != LLFriendObserver::ONLINE) + { + fillRightsData(); + } updateButtons(); } @@ -1000,6 +1196,7 @@ void LLPanelProfileSecondLife::processOnlineStatus(bool online) { } +//todo: remove? void LLPanelProfileSecondLife::updateButtons() { LLPanelProfileTab::updateButtons(); @@ -1019,7 +1216,7 @@ class LLProfileImagePicker : public LLFilePickerThread public: LLProfileImagePicker(EProfileImageType type, LLHandle *handle); ~LLProfileImagePicker(); - virtual void notify(const std::vector& filenames); + void notify(const std::vector& filenames) override; private: LLHandle *mHandle; @@ -1321,6 +1518,25 @@ void LLPanelProfileSecondLife::onDiscardDescriptionChanges() setDescriptionText(mDescriptionText); } +void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() +{ + LLFloater *floater = mFloaterPermissionsHandle.get(); + if (!floater) + { + LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(getAvatarId()); + mFloaterPermissionsHandle = perms->getHandle(); + perms->openFloater(); + + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + parent_floater->addDependentFloater(mFloaterPermissionsHandle); + } + else // already open + { + floater->closeFloater(); + } +} + ////////////////////////////////////////////////////////////////////////// // LLPanelProfileWeb @@ -1658,10 +1874,6 @@ LLPanelProfileNotes::LLPanelProfileNotes() LLPanelProfileNotes::~LLPanelProfileNotes() { - if (getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } } void LLPanelProfileNotes::updateData() @@ -1682,14 +1894,10 @@ void LLPanelProfileNotes::updateData() BOOL LLPanelProfileNotes::postBuild() { - mOnlineStatus = getChild("status_check"); - mMapRights = getChild("map_check"); - mEditObjectRights = getChild("objects_check"); mNotesEditor = getChild("notes_edit"); mSaveChanges = getChild("notes_save_changes"); mDiscardChanges = getChild("notes_discard_changes"); - mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr); mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr); mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); }); @@ -1702,28 +1910,6 @@ void LLPanelProfileNotes::onOpen(const LLSD& key) LLPanelProfileTab::onOpen(key); resetData(); - - fillRightsData(); -} - -void LLPanelProfileNotes::fillRightsData() -{ - mOnlineStatus->setValue(FALSE); - mMapRights->setValue(FALSE); - mEditObjectRights->setValue(FALSE); - - const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - // If true - we are viewing friend's profile, enable check boxes and set values. - if(relation) - { - S32 rights = relation->getRightsGrantedTo(); - - mOnlineStatus->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); - mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); - mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); - } - - enableCheckboxes(NULL != relation); } void LLPanelProfileNotes::onCommitNotes() @@ -1781,76 +1967,6 @@ void LLPanelProfileNotes::onDiscardNotesChanges() setNotesText(mCurrentNotes); } -void LLPanelProfileNotes::rightsConfirmationCallback(const LLSD& notification, - const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); - } -} - -void LLPanelProfileNotes::confirmModifyRights(bool grant) -{ - LLSD args; - args["NAME"] = LLSLURL("agent", getAvatarId(), "completename").getSLURLString(); - - - LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(), - boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, _1, _2)); - -} - -void LLPanelProfileNotes::onCommitRights() -{ - const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - - if (!buddy_relationship) - { - LL_WARNS("LegacyProfile") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; - return; - } - - bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); - - // if modify objects checkbox clicked - if (buddy_relationship->isRightGrantedTo( - LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) - { - confirmModifyRights(allow_modify_objects); - } -} - -void LLPanelProfileNotes::applyRights() -{ - const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - - if (!buddy_relationship) - { - // Lets have a warning log message instead of having a crash. EXT-4947. - LL_WARNS("LegacyProfile") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; - return; - } - - S32 rights = 0; - - if (mOnlineStatus->getValue().asBoolean()) - { - rights |= LLRelationship::GRANT_ONLINE_STATUS; - } - if (mMapRights->getValue().asBoolean()) - { - rights |= LLRelationship::GRANT_MAP_LOCATION; - } - if (mEditObjectRights->getValue().asBoolean()) - { - rights |= LLRelationship::GRANT_MODIFY_OBJECTS; - } - - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), rights); -} - void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) { if (APT_NOTES == type) @@ -1875,35 +1991,13 @@ void LLPanelProfileNotes::resetData() { resetLoading(); mNotesEditor->setValue(LLStringUtil::null); - mOnlineStatus->setValue(FALSE); - mMapRights->setValue(FALSE); - mEditObjectRights->setValue(FALSE); -} - -void LLPanelProfileNotes::enableCheckboxes(bool enable) -{ - mOnlineStatus->setEnabled(enable); - mMapRights->setEnabled(enable); - mEditObjectRights->setEnabled(enable); -} - -// virtual, called by LLAvatarTracker -void LLPanelProfileNotes::changed(U32 mask) -{ - // update rights to avoid have checkboxes enabled when friendship is terminated. EXT-4947. - fillRightsData(); } void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - if (getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } LLPanelProfileTab::setAvatarId(avatar_id); - LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); } } -- cgit v1.2.3 From 3678678506d9d026ebdb88d3775920e6b0b32f8a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Apr 2022 01:02:39 +0300 Subject: SL-15312 Legacy profiles remake #7 Finalized agent profile permissions floater --- indra/newview/llpanelprofile.cpp | 74 ++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 14 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 34caa61fbf..3e7dd57965 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -583,11 +583,14 @@ class LLFloaterProfilePermissions , public LLFriendObserver { public: - LLFloaterProfilePermissions(const LLUUID &avatar_id); + LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id); ~LLFloaterProfilePermissions(); BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void draw() override; void changed(U32 mask) override; // LLFriendObserver - // todo: check if this (and inventory filters) need a drawFrustum() + + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); private: void fillRightsData(); @@ -598,28 +601,41 @@ private: void onApplyRights(); void onCancel(); + LLTextBase* mDescription; LLCheckBoxCtrl* mOnlineStatus; LLCheckBoxCtrl* mMapRights; LLCheckBoxCtrl* mEditObjectRights; LLButton* mOkBtn; LLButton* mCancelBtn; - LLUUID mAvatarID; + LLUUID mAvatarID; + F32 mContextConeOpacity; + LLHandle mOwnerHandle; + + boost::signals2::connection mAvatarNameCacheConnection; }; -LLFloaterProfilePermissions::LLFloaterProfilePermissions(const LLUUID &avatar_id) +LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id) : LLFloater(LLSD()) , mAvatarID(avatar_id) + , mContextConeOpacity(0.0f) + , mOwnerHandle(owner->getHandle()) { buildFromFile("floater_profile_permissions.xml"); } LLFloaterProfilePermissions::~LLFloaterProfilePermissions() { + mAvatarNameCacheConnection.disconnect(); + if (mAvatarID.notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); + } } BOOL LLFloaterProfilePermissions::postBuild() { + mDescription = getChild("perm_description"); mOnlineStatus = getChild("online_check"); mMapRights = getChild("map_check"); mEditObjectRights = getChild("objects_check"); @@ -630,14 +646,45 @@ BOOL LLFloaterProfilePermissions::postBuild() mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr); mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr); - fillRightsData(); // is it possible to not be friends at this point? This might need to be onOpen() - return TRUE; } +void LLFloaterProfilePermissions::onOpen(const LLSD& key) +{ + if (LLAvatarActions::isFriend(mAvatarID)) + { + LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this); + fillRightsData(); + } + + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2)); +} + +void LLFloaterProfilePermissions::draw() +{ + // drawFrustum + LLView *owner = mOwnerHandle.get(); + static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); + drawConeToOwner(mContextConeOpacity, max_opacity, owner); + LLFloater::draw(); +} + void LLFloaterProfilePermissions::changed(U32 mask) { - //todo + if (mask != LLFriendObserver::ONLINE) + { + fillRightsData(); + } +} + +void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + mAvatarNameCacheConnection.disconnect(); + + LLStringUtil::format_map_t args; + args["[AGENT_NAME]"] = av_name.getDisplayName(); + std::string descritpion = getString("description_string", args); + mDescription->setValue(descritpion); } void LLFloaterProfilePermissions::fillRightsData() @@ -779,11 +826,8 @@ BOOL LLPanelProfileSecondLife::postBuild() mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); - //mSeeOnlineToggle->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); mSeeOnlineToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); - // mSeeOnMapToggle->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); mSeeOnMapToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); - //mEditObjectsToggle->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); mEditObjectsToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); return TRUE; @@ -1523,13 +1567,15 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() LLFloater *floater = mFloaterPermissionsHandle.get(); if (!floater) { - LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(getAvatarId()); - mFloaterPermissionsHandle = perms->getHandle(); - perms->openFloater(); - LLFloater* parent_floater = gFloaterView->getParentFloater(this); if (parent_floater) + { + LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId()); + mFloaterPermissionsHandle = perms->getHandle(); + perms->openFloater(); + parent_floater->addDependentFloater(mFloaterPermissionsHandle); + } } else // already open { -- cgit v1.2.3 From c9b83e8117026aa7fc70da3972049152a669b0fc Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 16 Apr 2022 01:01:01 +0300 Subject: SL-15312 Legacy profiles remake #8 Progress indicators, loading states and 'embedded' cleanup --- indra/newview/llpanelprofile.cpp | 106 ++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 57 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 3e7dd57965..175fb4dbdc 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -188,7 +188,7 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) LLPanelProfileWeb *panel_web = dynamic_cast(panel); if (panel_web) { - panel_web->updateButtons(); + panel_web->setLoaded(); } panel = floater_profile->findChild(PANEL_FIRSTLIFE, TRUE); @@ -850,7 +850,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) childSetVisible("settings_panel", own_profile); childSetVisible("about_buttons_panel", own_profile); - if (own_profile && !getEmbedded()) + if (own_profile) { // Group list control cannot toggle ForAgent loading // Less than ideal, but viewing own profile via search is edge case @@ -875,7 +875,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); } - mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded()); + mDescriptionEdit->setParseHTML(!own_profile); if (!own_profile) { @@ -884,15 +884,13 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) fillRightsData(); } - updateButtons(); - mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); } void LLPanelProfileSecondLife::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull() && !(getSelfProfile() && !getEmbedded())) + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); @@ -961,20 +959,11 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat fillAccountStatus(avatar_data); - updateButtons(); + setLoaded(); } void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups) { - //KC: the group_list ctrl can handle all this for us on our own profile - if (getSelfProfile() && !getEmbedded()) - { - return; - } - - // *NOTE dzaporozhan - // Group properties may arrive in two callbacks, we need to save them across - // different calls. We can't do that in textbox as textbox may change the text. LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); @@ -1004,7 +993,16 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) { - // Todo: loading indicator here + LLLoadingIndicator* indicator = getChild("image_upload_indicator"); + indicator->setVisible(loading); + if (loading) + { + indicator->start(); + } + else + { + indicator->stop(); + } mWaitingForImageUpload = loading; } @@ -1028,8 +1026,7 @@ void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset FALSE); } - mWaitingForImageUpload = false; - // Todo: reset loading indicator here + setProfileImageUploading(false); } void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) @@ -1177,7 +1174,6 @@ void LLPanelProfileSecondLife::changed(U32 mask) { fillRightsData(); } - updateButtons(); } // virtual, called by LLVoiceClient @@ -1240,12 +1236,11 @@ void LLPanelProfileSecondLife::processOnlineStatus(bool online) { } -//todo: remove? -void LLPanelProfileSecondLife::updateButtons() +void LLPanelProfileSecondLife::setLoaded() { - LLPanelProfileTab::updateButtons(); + LLPanelProfileTab::setLoaded(); - if (getSelfProfile() && !getEmbedded()) + if (getSelfProfile()) { mShowInSearchCheckbox->setVisible(TRUE); mShowInSearchCheckbox->setEnabled(TRUE); @@ -1377,6 +1372,10 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) LLWString wstr = utf8str_to_wstring(getAvatarId().asString()); LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); } + else if (item_name == "agent_permissions") + { + onShowAgentPermissionsDialog(); + } else if (item_name == "copy_display_name" || item_name == "copy_username") { @@ -1467,6 +1466,10 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) { return LLAvatarActions::canBlock(agent_id); } + else if (item_name == "agent_permissions") + { + return LLAvatarActions::isFriend(agent_id); + } else if (item_name == "copy_display_name" || item_name == "copy_username") { @@ -1626,7 +1629,7 @@ void LLPanelProfileWeb::processProperties(void* data, EAvatarProcessorType type) const LLAvatarData* avatar_data = static_cast(data); if (avatar_data && getAvatarId() == avatar_data->avatar_id) { - updateButtons(); + setLoaded(); } } } @@ -1639,7 +1642,7 @@ void LLPanelProfileWeb::resetData() void LLPanelProfileWeb::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull() && !mURLWebProfile.empty()) + if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty()) { setIsLoading(); @@ -1732,16 +1735,6 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e } } -void LLPanelProfileWeb::updateButtons() -{ - LLPanelProfileTab::updateButtons(); -} - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1784,19 +1777,25 @@ void LLPanelProfileFirstLife::onOpen(const LLSD& key) void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) { - mChangePhoto->setEnabled(loading); - mRemovePhoto->setEnabled(loading); + mChangePhoto->setEnabled(!loading); + mRemovePhoto->setEnabled(!loading); - // Todo: loading indicator here + LLLoadingIndicator* indicator = getChild("image_upload_indicator"); + indicator->setVisible(loading); + if (loading) + { + indicator->start(); + } + else + { + indicator->stop(); + } } void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id) { mPicture->setValue(image_asset_id); - mChangePhoto->setEnabled(TRUE); - mRemovePhoto->setEnabled(TRUE); - - // Todo: reset loading indicator here + setProfileImageUploading(false); } void LLPanelProfileFirstLife::onChangePhoto() @@ -1883,7 +1882,7 @@ void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { mPicture->setValue("Generic_Person_Large"); } - updateButtons(); + setLoaded(); } void LLPanelProfileFirstLife::resetData() @@ -1897,11 +1896,11 @@ void LLPanelProfileFirstLife::resetData() mDiscardChanges->setVisible(getSelfProfile()); } -void LLPanelProfileFirstLife::updateButtons() +void LLPanelProfileFirstLife::setLoaded() { - LLPanelProfileTab::updateButtons(); + LLPanelProfileTab::setLoaded(); - if (getSelfProfile() && !getEmbedded()) + if (getSelfProfile()) { mDescriptionEdit->setEnabled(TRUE); mPicture->setEnabled(TRUE); @@ -1925,7 +1924,7 @@ LLPanelProfileNotes::~LLPanelProfileNotes() void LLPanelProfileNotes::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull()) + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); @@ -2030,7 +2029,7 @@ void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) { mNotesEditor->setValue(avatar_notes->notes); mNotesEditor->setEnabled(TRUE); - updateButtons(); + setLoaded(); } void LLPanelProfileNotes::resetData() @@ -2115,13 +2114,6 @@ void LLPanelProfile::onOpen(const LLSD& key) mPanelFirstlife->onOpen(avatar_id); mPanelNotes->onOpen(avatar_id); - mPanelSecondlife->setEmbedded(getEmbedded()); - mPanelWeb->setEmbedded(getEmbedded()); - mPanelPicks->setEmbedded(getEmbedded()); - mPanelClassifieds->setEmbedded(getEmbedded()); - mPanelFirstlife->setEmbedded(getEmbedded()); - mPanelNotes->setEmbedded(getEmbedded()); - // Always request the base profile info resetLoading(); updateData(); @@ -2138,7 +2130,7 @@ void LLPanelProfile::updateData() LLUUID avatar_id = getAvatarId(); // Todo: getIsloading functionality needs to be expanded to // include 'inited' or 'data_provided' state to not rerequest - if (!getIsLoading() && avatar_id.notNull()) + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); -- cgit v1.2.3 From 3fb9993a4a74c19b872bb96ed4878cd7b7143208 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 16 Apr 2022 02:09:03 +0300 Subject: SL-15312 Legacy profiles remake #9 Cleanup obsolete properties processesing --- indra/newview/llpanelprofile.cpp | 68 ++-------------------------------------- 1 file changed, 2 insertions(+), 66 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 175fb4dbdc..7d3a98ba96 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -840,7 +840,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) resetData(); LLUUID avatar_id = getAvatarId(); - LLAvatarPropertiesProcessor::getInstance()->addObserver(avatar_id, this); BOOL own_profile = getSelfProfile(); @@ -907,19 +906,6 @@ void LLPanelProfileSecondLife::updateData() } } -void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorType type) -{ - - if (APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast(data); - if(avatar_data && getAvatarId() == avatar_data->avatar_id) - { - processProfileProperties(avatar_data); - } - } -} - void LLPanelProfileSecondLife::resetData() { resetLoading(); @@ -944,9 +930,6 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat LLUUID avatar_id = getAvatarId(); if (!LLAvatarActions::isFriend(avatar_id) && !getSelfProfile()) { - // this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor. - // in LLPanelProfileSecondLife::processOnlineStatus() - // subscribe observer to get online status. Request will be sent by LLPanelProfileSecondLife itself. // do not subscribe for friend avatar because online status can be wrong overridden // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. @@ -1622,18 +1605,6 @@ BOOL LLPanelProfileWeb::postBuild() return TRUE; } -void LLPanelProfileWeb::processProperties(void* data, EAvatarProcessorType type) -{ - if (APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast(data); - if (avatar_data && getAvatarId() == avatar_data->avatar_id) - { - setLoaded(); - } - } -} - void LLPanelProfileWeb::resetData() { mWebBrowser->navigateHome(); @@ -1859,18 +1830,6 @@ void LLPanelProfileFirstLife::onDiscardDescriptionChanges() setDescriptionText(mCurrentDescription); } -void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type) -{ - if (APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast(data); - if (avatar_data && getAvatarId() == avatar_data->avatar_id) - { - processProperties(avatar_data); - } - } -} - void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { setDescriptionText(avatar_data->fl_about_text); @@ -2012,19 +1971,6 @@ void LLPanelProfileNotes::onDiscardNotesChanges() setNotesText(mCurrentNotes); } -void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) -{ - if (APT_NOTES == type) - { - LLAvatarNotes* avatar_notes = static_cast(data); - if (avatar_notes && getAvatarId() == avatar_notes->target_id) - { - processProperties(avatar_notes); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - } -} - void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) { mNotesEditor->setValue(avatar_notes->notes); @@ -2064,15 +2010,6 @@ BOOL LLPanelProfile::postBuild() return TRUE; } -void LLPanelProfile::processProperties(void* data, EAvatarProcessorType type) -{ - //*TODO: figure out what this does - mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this)); - - // Load data on currently opened tab as well - onTabChange(); -} - void LLPanelProfile::onTabChange() { LLPanelProfileTab* active_panel = dynamic_cast(mTabContainer->getCurrentPanel()); @@ -2120,9 +2057,8 @@ void LLPanelProfile::onOpen(const LLSD& key) updateBtnsVisibility(); - // KC - Not handling pick and classified opening thru onOpen - // because this would make unique profile floaters per slurl - // and result in multiple profile floaters for the same avatar + // Some tabs only request data when opened + mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this)); } void LLPanelProfile::updateData() -- cgit v1.2.3 From 8a39aaa3a485d9f1d4486c02e98286cfb08761d4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Apr 2022 21:35:41 +0300 Subject: SL-15312 Legacy profiles remake #10 Fixed Typo changed 'show in search' checkbox into combobox, implemented commit Fixed fl textbox setting sl text instead of fl text Fixed fl save/discard buttons not following resize --- indra/newview/llpanelprofile.cpp | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 7d3a98ba96..46b2d032e1 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -37,6 +37,7 @@ #include "llavatariconctrl.h" #include "llclipboard.h" #include "llcheckboxctrl.h" +#include "llcombobox.h" #include "lllineeditor.h" #include "llloadingindicator.h" #include "llmenubutton.h" @@ -116,6 +117,8 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL; + if (!status || !result.has("id") || agent_id != result["id"].asUUID()) @@ -151,7 +154,6 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_data->fl_image_id = result["fl_image_id"].asUUID(); avatar_data->partner_id = result["partner_id"].asUUID(); avatar_data->about_text = result["sl_about_text"].asString(); - // Todo: new descriptio size is 65536, check if it actually fits or has scroll avatar_data->fl_about_text = result["fl_about_text"].asString(); avatar_data->born_on = result["member_since"].asDate(); avatar_data->profile_url = getProfileURL(agent_id.asString()); @@ -248,7 +250,6 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_notes.agent_id = agent_id; avatar_notes.target_id = agent_id; - // Todo: new notes size is 65536, check that field has a scroll avatar_notes.notes = result["notes"].asString(); panel = floater_profile->findChild(PANEL_NOTES, TRUE); @@ -284,9 +285,11 @@ void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) if (!status) { - LL_WARNS("AvatarProperties") << "Failed to put agent information for id " << agent_id << LL_ENDL; + LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; return; } + + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; } LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle *handle) @@ -810,7 +813,7 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife() BOOL LLPanelProfileSecondLife::postBuild() { mGroupList = getChild("group_list"); - mShowInSearchCheckbox = getChild("show_in_search_checkbox"); + mShowInSearchCombo = getChild("show_in_search"); mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); @@ -821,6 +824,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mSeeOnMapToggle = getChild("allow_to_see_on_map"); mEditObjectsToggle = getChild("allow_edit_my_objects"); + mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr); mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); @@ -1052,7 +1056,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) if (getSelfProfile()) { - mShowInSearchCheckbox->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); + mShowInSearchCombo->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); } } @@ -1225,8 +1229,7 @@ void LLPanelProfileSecondLife::setLoaded() if (getSelfProfile()) { - mShowInSearchCheckbox->setVisible(TRUE); - mShowInSearchCheckbox->setEnabled(TRUE); + mShowInSearchCombo->setEnabled(TRUE); mDescriptionEdit->setEnabled(TRUE); } } @@ -1525,6 +1528,22 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() mDiscardDescriptionChanges->setEnabled(TRUE); } +void LLPanelProfileSecondLife::onShowInSearchCallback() +{ + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLSD data; + data["allow_publish"] = mShowInSearchCombo->getValue().asBoolean(); + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data)); + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } +} + void LLPanelProfileSecondLife::onSaveDescriptionChanges() { mDescriptionText = mDescriptionEdit->getValue().asString(); @@ -1814,7 +1833,7 @@ void LLPanelProfileFirstLife::onSaveDescriptionChanges() if (!cap_url.empty()) { LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mCurrentDescription))); + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription))); } else { -- cgit v1.2.3 From ea0c810d2d082a9684d9ce6b9cbd888c87f06612 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Apr 2022 23:39:21 +0300 Subject: SL-15312 Small tweaks for profiles --- indra/newview/llpanelprofile.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 46b2d032e1..bb6fdc1757 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -786,9 +786,10 @@ void LLFloaterProfilePermissions::onCancel() // LLPanelProfileSecondLife LLPanelProfileSecondLife::LLPanelProfileSecondLife() - : LLPanelProfileTab() - , mAvatarNameCacheConnection() - , mWaitingForImageUpload(false) + : LLPanelProfileTab() + , mAvatarNameCacheConnection() + , mWaitingForImageUpload(false) + , mAllowPublish(false) { } @@ -1056,7 +1057,8 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) if (getSelfProfile()) { - mShowInSearchCombo->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); + mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH; + mShowInSearchCombo->setValue((BOOL)mAllowPublish); } } @@ -1530,11 +1532,16 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() void LLPanelProfileSecondLife::onShowInSearchCallback() { + if (mAllowPublish == mShowInSearchCombo->getValue().asBoolean()) + { + return; + } std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) { + mAllowPublish = mShowInSearchCombo->getValue().asBoolean(); LLSD data; - data["allow_publish"] = mShowInSearchCombo->getValue().asBoolean(); + data["allow_publish"] = mAllowPublish; LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data)); } -- cgit v1.2.3 From 76beebae685d859d4afbff6db3ae6d7785b204da Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 9 May 2022 20:53:21 +0300 Subject: SL-15312 Fixed picks tabs being too thin --- indra/newview/llpanelprofile.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index bb6fdc1757..031c1db7e2 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -258,6 +258,10 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) { panel_notes->processProperties(&avatar_notes); } + if (panel_sl) + { + panel_sl->processNotesProperties(&avatar_notes); + } } //TODO: changes take two minutes to propagate! @@ -818,6 +822,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_stack"); mDescriptionEdit = getChild("sl_description_edit"); + mNotesSnippet = getChild("notes_snippet"); mAgentActionMenuButton = getChild("agent_actions_menu"); mSaveDescriptionChanges = getChild("save_description_changes"); mDiscardDescriptionChanges = getChild("discard_description_changes"); @@ -965,6 +970,11 @@ void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avat mGroupList->setGroups(mGroups); } +void LLPanelProfileSecondLife::processNotesProperties(LLAvatarNotes* avatar_notes) +{ + mNotesSnippet->setValue(avatar_notes->notes); +} + void LLPanelProfileSecondLife::openGroupProfile() { LLUUID group_id = mGroupList->getSelectedUUID(); @@ -1532,14 +1542,15 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() void LLPanelProfileSecondLife::onShowInSearchCallback() { - if (mAllowPublish == mShowInSearchCombo->getValue().asBoolean()) + S32 value = mShowInSearchCombo->getValue().asInteger(); + if (mAllowPublish == (bool)value) { return; } std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) { - mAllowPublish = mShowInSearchCombo->getValue().asBoolean(); + mAllowPublish = value; LLSD data; data["allow_publish"] = mAllowPublish; LLCoros::instance().launch("putAgentUserInfoCoro", -- cgit v1.2.3 From 1e84d0e6494df1f5ccb3f69e53849bf26b01e385 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 11 May 2022 20:38:13 +0300 Subject: SL-15312 Profiles tweaks Fix loading indicators to be at the center of picls and classified Hide classifieds and picks related buttons for other agents 10px distance from image Fix chat history menu button not working Changed 'partner' field behavior Prevent selection of disabled FL text field --- indra/newview/llpanelprofile.cpp | 54 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 22 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 031c1db7e2..542ecf8b42 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -217,6 +217,8 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) LLPanelProfilePicks *panel_picks = dynamic_cast(panel); if (panel_picks) { + // Refresh pick limit before processing + LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks); panel_picks->processProperties(&avatar_picks); } @@ -820,7 +822,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mGroupList = getChild("group_list"); mShowInSearchCombo = getChild("show_in_search"); mSecondLifePic = getChild("2nd_life_pic"); - mSecondLifePicLayout = getChild("image_stack"); + mSecondLifePicLayout = getChild("image_panel"); mDescriptionEdit = getChild("sl_description_edit"); mNotesSnippet = getChild("notes_snippet"); mAgentActionMenuButton = getChild("agent_actions_menu"); @@ -989,6 +991,11 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L getChild("user_name")->setValue(av_name.getAccountName()); } +void LLPanelProfileSecondLife::setNotesSnippet(std::string ¬es) +{ + mNotesSnippet->setValue(notes); +} + void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) { LLLoadingIndicator* indicator = getChild("image_upload_indicator"); @@ -1077,6 +1084,7 @@ void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) LLTextBox* partner_text_ctrl = getChild("partner_link"); if (avatar_data->partner_id.notNull()) { + childSetVisible("partner_layout", TRUE); LLStringUtil::format_map_t args; args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); std::string partner_text = getString("partner_text", args); @@ -1084,7 +1092,7 @@ void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) } else { - partner_text_ctrl->setText(getString("no_partner_text")); + childSetVisible("partner_layout", FALSE); } } @@ -1333,7 +1341,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) { LLAvatarActions::startCall(agent_id); } - else if (item_name == "callog") + else if (item_name == "chat_history") { LLAvatarActions::viewChatHistory(agent_id); } @@ -1443,7 +1451,7 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) { return mVoiceStatus; } - else if (item_name == "callog") + else if (item_name == "chat_history") { return LLLogChat::isTranscriptExist(agent_id); } @@ -1780,6 +1788,12 @@ void LLPanelProfileFirstLife::onOpen(const LLSD& key) { LLPanelProfileTab::onOpen(key); + if (!getSelfProfile()) + { + // Otherwise as the only focusable element it will be selected + mDescriptionEdit->setTabStop(FALSE); + } + resetData(); } @@ -1953,24 +1967,6 @@ void LLPanelProfileNotes::onOpen(const LLSD& key) resetData(); } -void LLPanelProfileNotes::onCommitNotes() -{ - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (getIsLoaded()) - { - if (!cap_url.empty()) - { - std::string notes = mNotesEditor->getValue().asString(); - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", notes))); - } - else - { - LL_WARNS() << "Failed to update notes, no cap found" << LL_ENDL; - } - } -} - void LLPanelProfileNotes::setNotesText(const std::string &text) { mSaveChanges->setEnabled(FALSE); @@ -1993,6 +1989,20 @@ void LLPanelProfileNotes::onSaveNotesChanges() { LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); + + + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", getAvatarId())); + if (!floater_profile) + { + return; + } + + LLPanel* panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); + LLPanelProfileSecondLife *panel_sl = dynamic_cast(panel); + if (panel_sl) + { + panel_sl->setNotesSnippet(mCurrentNotes); + } } else { -- cgit v1.2.3 From de8a61f71a16f950cbf64b5704b9952cb733403e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sun, 15 May 2022 12:31:49 +0300 Subject: SL-15312 Shortcut to notes --- indra/newview/llpanelprofile.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 542ecf8b42..fb5d2d2051 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -842,6 +842,8 @@ BOOL LLPanelProfileSecondLife::postBuild() mSeeOnMapToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); mEditObjectsToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); + getChild("open_notes")->setCommitCallback([this](LLUICtrl*, void*) { onOpenNotes(); }, nullptr); + return TRUE; } @@ -1614,6 +1616,23 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() } } +void LLPanelProfileSecondLife::onOpenNotes() +{ + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (!parent_floater) + { + return; + } + + LLTabContainer* tab_container = parent_floater->findChild("panel_profile_tabs", TRUE); + if (!tab_container) + { + return; + } + + tab_container->selectTabByName(PANEL_NOTES); +} + ////////////////////////////////////////////////////////////////////////// // LLPanelProfileWeb @@ -1991,13 +2010,13 @@ void LLPanelProfileNotes::onSaveNotesChanges() boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); - LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", getAvatarId())); - if (!floater_profile) + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (!parent_floater) { return; } - LLPanel* panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); + LLPanel* panel = parent_floater->findChild(PANEL_SECONDLIFE, TRUE); LLPanelProfileSecondLife *panel_sl = dynamic_cast(panel); if (panel_sl) { -- cgit v1.2.3 From 35a5fc74c0df29b496d42e89845d00a366034b68 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 18 May 2022 23:53:53 +0300 Subject: SL-15312 Added permission indicators --- indra/newview/llpanelprofile.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index fb5d2d2051..7a28dd11f8 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1614,6 +1614,10 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() { floater->closeFloater(); } + + mSeeOnlineToggle->setFocus(false); + mSeeOnMapToggle->setFocus(false); + mEditObjectsToggle->setFocus(false); } void LLPanelProfileSecondLife::onOpenNotes() -- cgit v1.2.3 From 23d310436a664f7303d627095f8972de6cb17334 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 24 May 2022 00:35:22 +0300 Subject: SL-15312 Change permission status to be icons instead of buttons --- indra/newview/llpanelprofile.cpp | 47 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 7a28dd11f8..38308f2498 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -828,9 +828,12 @@ BOOL LLPanelProfileSecondLife::postBuild() mAgentActionMenuButton = getChild("agent_actions_menu"); mSaveDescriptionChanges = getChild("save_description_changes"); mDiscardDescriptionChanges = getChild("discard_description_changes"); - mSeeOnlineToggle = getChild("allow_to_see_online"); - mSeeOnMapToggle = getChild("allow_to_see_on_map"); - mEditObjectsToggle = getChild("allow_edit_my_objects"); + mCanSeeOnlineIcon = getChild("can_see_online"); + mCantSeeOnlineIcon = getChild("cant_see_online"); + mCanSeeOnMapIcon = getChild("can_see_on_map"); + mCantSeeOnMapIcon = getChild("cant_see_on_map"); + mCanEditObjectsIcon = getChild("can_edit_objects"); + mCantEditObjectsIcon = getChild("cant_edit_objects"); mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr); mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); @@ -838,9 +841,6 @@ BOOL LLPanelProfileSecondLife::postBuild() mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); - mSeeOnlineToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); - mSeeOnMapToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); - mEditObjectsToggle->setMouseUpCallback([this](LLUICtrl*, const LLSD&) { onShowAgentPermissionsDialog(); }); getChild("open_notes")->setCommitCallback([this](LLUICtrl*, void*) { onOpenNotes(); }, nullptr); @@ -933,9 +933,13 @@ void LLPanelProfileSecondLife::resetData() mGroups.clear(); mGroupList->setGroups(mGroups); - mSeeOnlineToggle->setToggleState(false); - mSeeOnMapToggle->setToggleState(false); - mEditObjectsToggle->setToggleState(false); + mCanSeeOnlineIcon->setVisible(false); + mCantSeeOnlineIcon->setVisible(true); + mCanSeeOnMapIcon->setVisible(false); + mCantSeeOnMapIcon->setVisible(true); + mCanEditObjectsIcon->setVisible(false); + mCantEditObjectsIcon->setVisible(true); + childSetVisible("permissions_panel", false); } @@ -1115,16 +1119,25 @@ void LLPanelProfileSecondLife::fillRightsData() if (relation) { S32 rights = relation->getRightsGrantedTo(); + bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights; + bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights; + bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights; - mSeeOnlineToggle->setToggleState(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); - mSeeOnMapToggle->setToggleState(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); - mEditObjectsToggle->setToggleState(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + mCanSeeOnlineIcon->setVisible(can_see_online); + mCantSeeOnlineIcon->setVisible(!can_see_online); + mCanSeeOnMapIcon->setVisible(can_see_on_map); + mCantSeeOnMapIcon->setVisible(!can_see_on_map); + mCanEditObjectsIcon->setVisible(can_edit_objects); + mCantEditObjectsIcon->setVisible(!can_edit_objects); } else { - mSeeOnlineToggle->setToggleState(false); - mSeeOnMapToggle->setToggleState(false); - mEditObjectsToggle->setToggleState(false); + mCanSeeOnlineIcon->setVisible(false); + mCantSeeOnlineIcon->setVisible(true); + mCanSeeOnMapIcon->setVisible(false); + mCantSeeOnMapIcon->setVisible(true); + mCanEditObjectsIcon->setVisible(false); + mCantEditObjectsIcon->setVisible(true); } childSetVisible("permissions_panel", NULL != relation); @@ -1614,10 +1627,6 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() { floater->closeFloater(); } - - mSeeOnlineToggle->setFocus(false); - mSeeOnMapToggle->setFocus(false); - mEditObjectsToggle->setFocus(false); } void LLPanelProfileSecondLife::onOpenNotes() -- cgit v1.2.3 From d4a799a1a8ce11a808c97d73c03f16d3b3e41597 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 May 2022 17:55:04 +0300 Subject: SL-15312 Online status --- indra/newview/llpanelprofile.cpp | 55 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 38308f2498..8a07315035 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -946,12 +946,13 @@ void LLPanelProfileSecondLife::resetData() void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) { LLUUID avatar_id = getAvatarId(); - if (!LLAvatarActions::isFriend(avatar_id) && !getSelfProfile()) + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + if (relationship != NULL && !getSelfProfile()) { // subscribe observer to get online status. Request will be sent by LLPanelProfileSecondLife itself. // do not subscribe for friend avatar because online status can be wrong overridden // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. - processOnlineStatus(avatar_data->flags & AVATAR_ONLINE); + processOnlineStatus(relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS), avatar_data->flags & AVATAR_ONLINE); } fillCommonData(avatar_data); @@ -1141,6 +1142,10 @@ void LLPanelProfileSecondLife::fillRightsData() } childSetVisible("permissions_panel", NULL != relation); + childSetVisible("spacer_layout", NULL == relation); + childSetVisible("frind_layout", NULL != relation); + childSetVisible("online_layout", false); + childSetVisible("offline_layout", false); } void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) @@ -1188,10 +1193,7 @@ void LLPanelProfileSecondLife::onImageLoaded(BOOL success, // virtual, called by LLAvatarTracker void LLPanelProfileSecondLife::changed(U32 mask) { - if (mask & LLFriendObserver::ONLINE) - { - updateOnlineStatus(); - } + updateOnlineStatus(); if (mask != LLFriendObserver::ONLINE) { fillRightsData(); @@ -1227,35 +1229,32 @@ void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) } } -bool LLPanelProfileSecondLife::isGrantedToSeeOnlineStatus() -{ - // set text box visible to show online status for non-friends who has not set in Preferences - // "Only Friends & Groups can see when I am online" - if (!LLAvatarActions::isFriend(getAvatarId())) - { - return true; - } - - // *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status. - // When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer - // see comments for ChangeUserRights template message. EXT-453. - // If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880 - const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); -} - // method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880 void LLPanelProfileSecondLife::updateOnlineStatus() { - if (!LLAvatarActions::isFriend(getAvatarId())) return; - // For friend let check if he allowed me to see his status const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - bool online = relationship->isOnline(); - processOnlineStatus(online); + if (relationship != NULL) + { + // For friend let check if he allowed me to see his status + bool online = relationship->isOnline(); + bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); + processOnlineStatus(perm_granted, online); + } + else + { + childSetVisible("spacer_layout", true); + childSetVisible("frind_layout", false); + childSetVisible("online_layout", false); + childSetVisible("offline_layout", false); + } } -void LLPanelProfileSecondLife::processOnlineStatus(bool online) +void LLPanelProfileSecondLife::processOnlineStatus(bool show_online, bool online) { + childSetVisible("spacer_layout", false); + childSetVisible("frind_layout", true); + childSetVisible("online_layout", online && show_online); + childSetVisible("offline_layout", !online && show_online); } void LLPanelProfileSecondLife::setLoaded() -- cgit v1.2.3 From 4ffc6c3fde17de5e18370139274bbd44b1b61a23 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 30 May 2022 22:06:59 +0300 Subject: SL-15312 Tweaks and fixes - Allowed resizing text fields for classifieds in profiles - Fixed mislabeled floater from picks to classifieds - Fixed classified floater's title - Added support to see multiple classifieds - Removed obsolete panels - Fixed pick requests for various menus - Fixed pick creation from landmarks - Improved online status handling - Updated headers in files --- indra/newview/llpanelprofile.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 8a07315035..41d8a3e51c 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -2,9 +2,9 @@ * @file llpanelprofile.cpp * @brief Profile panel implementation * -* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code -* Copyright (C) 2010, Linden Research, Inc. +* Copyright (C) 2022, 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 @@ -947,12 +947,14 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat { LLUUID avatar_id = getAvatarId(); const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - if (relationship != NULL && !getSelfProfile()) + if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile()) { - // subscribe observer to get online status. Request will be sent by LLPanelProfileSecondLife itself. - // do not subscribe for friend avatar because online status can be wrong overridden - // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. - processOnlineStatus(relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS), avatar_data->flags & AVATAR_ONLINE); + // Relies onto friend observer to get information about online status updates. + // Once SL-17506 gets implemented, condition might need to become: + // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE) + processOnlineStatus(relationship != NULL, + gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS), + (avatar_data->flags & AVATAR_ONLINE)); } fillCommonData(avatar_data); @@ -1238,7 +1240,7 @@ void LLPanelProfileSecondLife::updateOnlineStatus() // For friend let check if he allowed me to see his status bool online = relationship->isOnline(); bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); - processOnlineStatus(perm_granted, online); + processOnlineStatus(true, perm_granted, online); } else { @@ -1249,10 +1251,10 @@ void LLPanelProfileSecondLife::updateOnlineStatus() } } -void LLPanelProfileSecondLife::processOnlineStatus(bool show_online, bool online) +void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online) { childSetVisible("spacer_layout", false); - childSetVisible("frind_layout", true); + childSetVisible("frind_layout", is_friend); childSetVisible("online_layout", online && show_online); childSetVisible("offline_layout", !online && show_online); } @@ -2095,11 +2097,6 @@ void LLPanelProfile::onTabChange() { active_panel->updateData(); } - updateBtnsVisibility(); -} - -void LLPanelProfile::updateBtnsVisibility() -{ } void LLPanelProfile::onOpen(const LLSD& key) @@ -2133,8 +2130,6 @@ void LLPanelProfile::onOpen(const LLSD& key) resetLoading(); updateData(); - updateBtnsVisibility(); - // Some tabs only request data when opened mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this)); } @@ -2148,6 +2143,11 @@ void LLPanelProfile::updateData() { setIsLoading(); + mPanelSecondlife->setIsLoading(); + mPanelPicks->setIsLoading(); + mPanelFirstlife->setIsLoading(); + mPanelNotes->setIsLoading(); + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) { @@ -2157,6 +2157,12 @@ void LLPanelProfile::updateData() } } +void LLPanelProfile::createPick(const LLPickData &data) +{ + mTabContainer->selectTabPanel(mPanelPicks); + mPanelPicks->createPick(data); +} + void LLPanelProfile::showPick(const LLUUID& pick_id) { if (pick_id.notNull()) -- cgit v1.2.3 From ab3d986ac82e6c54804e8216d8ba2f72f8e8dfc8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 31 May 2022 22:41:21 +0300 Subject: SL-15312 Tweaks and fixes #2 - changed 'is friend' color - fixed off/online status vanishing - changed user name format - fixed rights behavior - cleaned up some unused code - readded click functionality to permission icons (might need to return buttons instead) --- indra/newview/llpanelprofile.cpp | 207 ++++++++++++++------------------------- 1 file changed, 74 insertions(+), 133 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 41d8a3e51c..85f443635d 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -468,123 +468,8 @@ public: }; LLProfileHandler gProfileHandler; - -////////////////////////////////////////////////////////////////////////// -// LLAgentHandler - -class LLAgentHandler : public LLCommandHandler -{ -public: - // requires trusted browser to trigger - LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } - - bool handle(const LLSD& params, const LLSD& query_map, - LLMediaCtrl* web) - { - if (params.size() < 2) return false; - LLUUID avatar_id; - if (!avatar_id.set(params[0], FALSE)) - { - return false; - } - - const std::string verb = params[1].asString(); - if (verb == "about") - { - LLAvatarActions::showProfile(avatar_id); - return true; - } - - if (verb == "inspect") - { - LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id)); - return true; - } - - if (verb == "im") - { - LLAvatarActions::startIM(avatar_id); - return true; - } - - if (verb == "pay") - { - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableAvatarPay")) - { - LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - - LLAvatarActions::pay(avatar_id); - return true; - } - - if (verb == "offerteleport") - { - LLAvatarActions::offerTeleport(avatar_id); - return true; - } - - if (verb == "requestfriend") - { - LLAvatarActions::requestFriendshipDialog(avatar_id); - return true; - } - - if (verb == "removefriend") - { - LLAvatarActions::removeFriendDialog(avatar_id); - return true; - } - - if (verb == "mute") - { - if (! LLAvatarActions::isBlocked(avatar_id)) - { - LLAvatarActions::toggleBlock(avatar_id); - } - return true; - } - - if (verb == "unmute") - { - if (LLAvatarActions::isBlocked(avatar_id)) - { - LLAvatarActions::toggleBlock(avatar_id); - } - return true; - } - - if (verb == "block") - { - if (params.size() > 2) - { - const std::string object_name = LLURI::unescape(params[2].asString()); - LLMute mute(avatar_id, object_name, LLMute::OBJECT); - LLMuteList::getInstance()->add(mute); - LLPanelBlockedList::showPanelAndSelect(mute.mID); - } - return true; - } - - if (verb == "unblock") - { - if (params.size() > 2) - { - const std::string object_name = params[2].asString(); - LLMute mute(avatar_id, object_name, LLMute::OBJECT); - LLMuteList::getInstance()->remove(mute); - } - return true; - } - return false; - } -}; -LLAgentHandler gAgentHandler; - - ///---------------------------------------------------------------------------- -/// LLFloaterInventoryFinder +/// LLFloaterProfilePermissions ///---------------------------------------------------------------------------- class LLFloaterProfilePermissions @@ -605,7 +490,8 @@ private: void fillRightsData(); void rightsConfirmationCallback(const LLSD& notification, const LLSD& response); void confirmModifyRights(bool grant); - void onCommitRights(); + void onCommitSeeOnlineRights(); + void onCommitEditRights(); void onApplyRights(); void onCancel(); @@ -651,7 +537,8 @@ BOOL LLFloaterProfilePermissions::postBuild() mOkBtn = getChild("perms_btn_ok"); mCancelBtn = getChild("perms_btn_cancel"); - mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitRights(); }, nullptr); + mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr); + mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr); mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr); mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr); @@ -704,7 +591,9 @@ void LLFloaterProfilePermissions::fillRightsData() { S32 rights = relation->getRightsGrantedTo(); - mOnlineStatus->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); + BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE; + mOnlineStatus->setValue(see_online); + mMapRights->setEnabled(see_online); mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); } @@ -733,13 +622,38 @@ void LLFloaterProfilePermissions::confirmModifyRights(bool grant) boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2)); } -void LLFloaterProfilePermissions::onCommitRights() +void LLFloaterProfilePermissions::onCommitSeeOnlineRights() +{ + bool see_online = mOnlineStatus->getValue().asBoolean(); + mMapRights->setEnabled(see_online); + if (see_online) + { + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + if (relation) + { + S32 rights = relation->getRightsGrantedTo(); + mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + } + else + { + closeFloater(); + LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL; + } + } + else + { + mMapRights->setValue(FALSE); + } +} + +void LLFloaterProfilePermissions::onCommitEditRights() { const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); if (!buddy_relationship) { - LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; + LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL; + closeFloater(); return; } @@ -844,6 +758,13 @@ BOOL LLPanelProfileSecondLife::postBuild() getChild("open_notes")->setCommitCallback([this](LLUICtrl*, void*) { onOpenNotes(); }, nullptr); + mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + return TRUE; } @@ -995,9 +916,10 @@ void LLPanelProfileSecondLife::openGroupProfile() void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { mAvatarNameCacheConnection.disconnect(); - // Should be possible to get this from AgentProfile capability - getChild("display_name")->setValue( av_name.getDisplayName() ); - getChild("user_name")->setValue(av_name.getAccountName()); + if (getIsLoaded()) + { + fillNameAgeData(av_name, mBornOn); + } } void LLPanelProfileSecondLife::setNotesSnippet(std::string ¬es) @@ -1049,10 +971,21 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) // and to make sure icons in text will be up to date LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); - LLStringUtil::format_map_t args; - args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); - std::string register_date = getString("AgeFormat", args); - getChild("user_age")->setValue(register_date); + mBornOn = avatar_data->born_on; + + // Should be possible to get user and display names from AgentProfile capability + // but at the moment contraining this to limits of LLAvatarData + LLAvatarName av_name; + if (LLAvatarNameCache::get(avatar_data->avatar_id, &av_name)) + { + fillNameAgeData(av_name, mBornOn); + } + else if (!mAvatarNameCacheConnection.connected()) + { + // shouldn't happen, but just in case + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); + } + setDescriptionText(avatar_data->about_text); if (avatar_data->image_id.notNull()) @@ -1144,10 +1077,16 @@ void LLPanelProfileSecondLife::fillRightsData() } childSetVisible("permissions_panel", NULL != relation); - childSetVisible("spacer_layout", NULL == relation); - childSetVisible("frind_layout", NULL != relation); - childSetVisible("online_layout", false); - childSetVisible("offline_layout", false); +} + +void LLPanelProfileSecondLife::fillNameAgeData(const LLAvatarName &av_name, const LLDate &born_on) +{ + LLStringUtil::format_map_t args; + args["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); + args["[NAME]"] = av_name.getAccountName(); + std::string register_date = getString("NameAgeFormat", args); + getChild("user_name_age")->setValue(register_date); + getChild("display_name")->setValue(av_name.getDisplayName()); } void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) @@ -1620,13 +1559,15 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId()); mFloaterPermissionsHandle = perms->getHandle(); perms->openFloater(); + perms->setVisibleAndFrontmost(TRUE); parent_floater->addDependentFloater(mFloaterPermissionsHandle); } } else // already open { - floater->closeFloater(); + floater->setMinimized(FALSE); + floater->setVisibleAndFrontmost(TRUE); } } -- cgit v1.2.3 From d7459d87e0b7507b3452aa4effa4dc97e06e8551 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 1 Jun 2022 21:26:29 +0300 Subject: SL-15312 Reverted accidentally deleted slurl handling --- indra/newview/llpanelprofile.cpp | 115 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 85f443635d..470f3fa17e 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -468,6 +468,121 @@ public: }; LLProfileHandler gProfileHandler; + +////////////////////////////////////////////////////////////////////////// +// LLAgentHandler + +class LLAgentHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 2) return false; + LLUUID avatar_id; + if (!avatar_id.set(params[0], FALSE)) + { + return false; + } + + const std::string verb = params[1].asString(); + if (verb == "about") + { + LLAvatarActions::showProfile(avatar_id); + return true; + } + + if (verb == "inspect") + { + LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id)); + return true; + } + + if (verb == "im") + { + LLAvatarActions::startIM(avatar_id); + return true; + } + + if (verb == "pay") + { + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableAvatarPay")) + { + LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); + return true; + } + + LLAvatarActions::pay(avatar_id); + return true; + } + + if (verb == "offerteleport") + { + LLAvatarActions::offerTeleport(avatar_id); + return true; + } + + if (verb == "requestfriend") + { + LLAvatarActions::requestFriendshipDialog(avatar_id); + return true; + } + + if (verb == "removefriend") + { + LLAvatarActions::removeFriendDialog(avatar_id); + return true; + } + + if (verb == "mute") + { + if (! LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + if (verb == "unmute") + { + if (LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + if (verb == "block") + { + if (params.size() > 2) + { + const std::string object_name = LLURI::unescape(params[2].asString()); + LLMute mute(avatar_id, object_name, LLMute::OBJECT); + LLMuteList::getInstance()->add(mute); + LLPanelBlockedList::showPanelAndSelect(mute.mID); + } + return true; + } + + if (verb == "unblock") + { + if (params.size() > 2) + { + const std::string object_name = params[2].asString(); + LLMute mute(avatar_id, object_name, LLMute::OBJECT); + LLMuteList::getInstance()->remove(mute); + } + return true; + } + return false; + } +}; +LLAgentHandler gAgentHandler; + + ///---------------------------------------------------------------------------- /// LLFloaterProfilePermissions ///---------------------------------------------------------------------------- -- cgit v1.2.3 From 3efe64619b772ce8cab596d7e74de48dcc7f6c20 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jun 2022 00:17:54 +0300 Subject: SL-15312 Confirm usaved changes dialog when closing floater --- indra/newview/llpanelprofile.cpp | 101 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 470f3fa17e..f608712133 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -600,6 +600,9 @@ public: void changed(U32 mask) override; // LLFriendObserver void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + bool hasUnsavedChanges() { return mHasUnsavedPermChanges; } + + void onApplyRights(); private: void fillRightsData(); @@ -607,8 +610,6 @@ private: void confirmModifyRights(bool grant); void onCommitSeeOnlineRights(); void onCommitEditRights(); - - void onApplyRights(); void onCancel(); LLTextBase* mDescription; @@ -620,6 +621,7 @@ private: LLUUID mAvatarID; F32 mContextConeOpacity; + bool mHasUnsavedPermChanges; LLHandle mOwnerHandle; boost::signals2::connection mAvatarNameCacheConnection; @@ -629,6 +631,7 @@ LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const L : LLFloater(LLSD()) , mAvatarID(avatar_id) , mContextConeOpacity(0.0f) + , mHasUnsavedPermChanges(false) , mOwnerHandle(owner->getHandle()) { buildFromFile("floater_profile_permissions.xml"); @@ -653,6 +656,7 @@ BOOL LLFloaterProfilePermissions::postBuild() mCancelBtn = getChild("perms_btn_cancel"); mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr); + mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr); mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr); mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr); mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr); @@ -723,10 +727,14 @@ void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notific const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) + if (option != 0) // canceled { mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); } + else + { + mHasUnsavedPermChanges = true; + } } void LLFloaterProfilePermissions::confirmModifyRights(bool grant) @@ -759,6 +767,7 @@ void LLFloaterProfilePermissions::onCommitSeeOnlineRights() { mMapRights->setValue(FALSE); } + mHasUnsavedPermChanges = true; } void LLFloaterProfilePermissions::onCommitEditRights() @@ -823,6 +832,7 @@ void LLFloaterProfilePermissions::onCancel() LLPanelProfileSecondLife::LLPanelProfileSecondLife() : LLPanelProfileTab() , mAvatarNameCacheConnection() + , mHasUnsavedDescriptionChanges(false) , mWaitingForImageUpload(false) , mAllowPublish(false) { @@ -1080,6 +1090,38 @@ void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset setProfileImageUploading(false); } +bool LLPanelProfileSecondLife::hasUnsavedChanges() +{ + LLFloater *floater = mFloaterPermissionsHandle.get(); + if (floater) + { + LLFloaterProfilePermissions* perm = dynamic_cast(floater); + if (perm && perm->hasUnsavedChanges()) + { + return true; + } + } + // if floater + return mHasUnsavedDescriptionChanges; +} + +void LLPanelProfileSecondLife::commitUnsavedChanges() +{ + LLFloater *floater = mFloaterPermissionsHandle.get(); + if (floater) + { + LLFloaterProfilePermissions* perm = dynamic_cast(floater); + if (perm && perm->hasUnsavedChanges()) + { + perm->onApplyRights(); + } + } + if (mHasUnsavedDescriptionChanges) + { + onSaveDescriptionChanges(); + } +} + void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) { // Refresh avatar id in cache with new info to prevent re-requests @@ -1608,6 +1650,8 @@ void LLPanelProfileSecondLife::setDescriptionText(const std::string &text) { mSaveDescriptionChanges->setEnabled(FALSE); mDiscardDescriptionChanges->setEnabled(FALSE); + mHasUnsavedDescriptionChanges = false; + mDescriptionText = text; mDescriptionEdit->setValue(mDescriptionText); } @@ -1616,6 +1660,7 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() { mSaveDescriptionChanges->setEnabled(TRUE); mDiscardDescriptionChanges->setEnabled(TRUE); + mHasUnsavedDescriptionChanges = true; } void LLPanelProfileSecondLife::onShowInSearchCallback() @@ -1656,6 +1701,7 @@ void LLPanelProfileSecondLife::onSaveDescriptionChanges() mSaveDescriptionChanges->setEnabled(FALSE); mDiscardDescriptionChanges->setEnabled(FALSE); + mHasUnsavedDescriptionChanges = false; } void LLPanelProfileSecondLife::onDiscardDescriptionChanges() @@ -1847,6 +1893,7 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e LLPanelProfileFirstLife::LLPanelProfileFirstLife() : LLPanelProfileTab() + , mHasUnsavedChanges(false) { } @@ -1909,6 +1956,14 @@ void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_ setProfileImageUploading(false); } +void LLPanelProfileFirstLife::commitUnsavedChanges() +{ + if (mHasUnsavedChanges) + { + onSaveDescriptionChanges(); + } +} + void LLPanelProfileFirstLife::onChangePhoto() { (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle(getHandle())))->getFile(); @@ -1937,6 +1992,8 @@ void LLPanelProfileFirstLife::setDescriptionText(const std::string &text) { mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; + mCurrentDescription = text; mDescriptionEdit->setValue(mCurrentDescription); } @@ -1945,6 +2002,7 @@ void LLPanelProfileFirstLife::onSetDescriptionDirty() { mSaveChanges->setEnabled(TRUE); mDiscardChanges->setEnabled(TRUE); + mHasUnsavedChanges = true; } void LLPanelProfileFirstLife::onSaveDescriptionChanges() @@ -1963,6 +2021,7 @@ void LLPanelProfileFirstLife::onSaveDescriptionChanges() mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; } void LLPanelProfileFirstLife::onDiscardDescriptionChanges() @@ -2012,6 +2071,7 @@ void LLPanelProfileFirstLife::setLoaded() LLPanelProfileNotes::LLPanelProfileNotes() : LLPanelProfileTab() + , mHasUnsavedChanges(false) { } @@ -2036,6 +2096,14 @@ void LLPanelProfileNotes::updateData() } } +void LLPanelProfileNotes::commitUnsavedChanges() +{ + if (mHasUnsavedChanges) + { + onSaveNotesChanges(); + } +} + BOOL LLPanelProfileNotes::postBuild() { mNotesEditor = getChild("notes_edit"); @@ -2060,6 +2128,8 @@ void LLPanelProfileNotes::setNotesText(const std::string &text) { mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; + mCurrentNotes = text; mNotesEditor->setValue(mCurrentNotes); } @@ -2068,6 +2138,7 @@ void LLPanelProfileNotes::onSetNotesDirty() { mSaveChanges->setEnabled(TRUE); mDiscardChanges->setEnabled(TRUE); + mHasUnsavedChanges = true; } void LLPanelProfileNotes::onSaveNotesChanges() @@ -2100,6 +2171,7 @@ void LLPanelProfileNotes::onSaveNotesChanges() mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; } void LLPanelProfileNotes::onDiscardNotesChanges() @@ -2238,6 +2310,29 @@ bool LLPanelProfile::isNotesTabSelected() return (mTabContainer->getCurrentPanel() == mPanelNotes); } +bool LLPanelProfile::hasUnsavedChanges() +{ + return mPanelSecondlife->hasUnsavedChanges() + || mPanelPicks->hasUnsavedChanges() + || mPanelClassifieds->hasUnsavedChanges() + || mPanelFirstlife->hasUnsavedChanges() + || mPanelNotes->hasUnsavedChanges(); +} + +bool LLPanelProfile::hasUnpublishedClassifieds() +{ + return mPanelClassifieds->hasNewClassifieds(); +} + +void LLPanelProfile::commitUnsavedChanges() +{ + mPanelSecondlife->commitUnsavedChanges(); + mPanelPicks->commitUnsavedChanges(); + mPanelClassifieds->commitUnsavedChanges(); + mPanelFirstlife->commitUnsavedChanges(); + mPanelNotes->commitUnsavedChanges(); +} + void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) { if (classified_id.notNull()) -- cgit v1.2.3 From 6354a053e366e1b6228c45a5dc9f92b262862dbe Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 3 Jun 2022 01:41:25 +0300 Subject: SL-15312 Show user's sl birthday --- indra/newview/llpanelprofile.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index f608712133..cb10dd75fb 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1238,12 +1238,20 @@ void LLPanelProfileSecondLife::fillRightsData() void LLPanelProfileSecondLife::fillNameAgeData(const LLAvatarName &av_name, const LLDate &born_on) { - LLStringUtil::format_map_t args; - args["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); - args["[NAME]"] = av_name.getAccountName(); - std::string register_date = getString("NameAgeFormat", args); - getChild("user_name_age")->setValue(register_date); getChild("display_name")->setValue(av_name.getDisplayName()); + + std::string name_and_date = getString("name_date_format"); + LLSD args_name; + args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); + args_name["[NAME]"] = av_name.getAccountName(); + LLStringUtil::format(name_and_date, args_name); + getChild("user_name_date")->setValue(name_and_date); + + std::string register_date = getString("age_format"); + LLSD args_age; + args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); + LLStringUtil::format(register_date, args_age); + getChild("user_age")->setValue(register_date); } void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) -- cgit v1.2.3 From 4f92a3222efac36b2355550ed55ca0a2fcb9591d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 3 Jun 2022 21:24:09 +0300 Subject: SL-15312 Updated picks's layout - better emphasis onto saving - better resize logic - ability to discard changes --- indra/newview/llpanelprofile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index cb10dd75fb..17c557e4f9 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1246,11 +1246,11 @@ void LLPanelProfileSecondLife::fillNameAgeData(const LLAvatarName &av_name, cons args_name["[NAME]"] = av_name.getAccountName(); LLStringUtil::format(name_and_date, args_name); getChild("user_name_date")->setValue(name_and_date); - + std::string register_date = getString("age_format"); - LLSD args_age; + LLSD args_age; args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); - LLStringUtil::format(register_date, args_age); + LLStringUtil::format(register_date, args_age); getChild("user_age")->setValue(register_date); } -- cgit v1.2.3 From c88e30736bc6e8e005bbe9d9edde34f31f5012ab Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 4 Jun 2022 23:33:18 +0300 Subject: SL-15312 Updated sl bio layout --- indra/newview/llpanelprofile.cpp | 84 ++++++++++------------------------------ 1 file changed, 21 insertions(+), 63 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 17c557e4f9..8db9658837 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -260,10 +260,6 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) { panel_notes->processProperties(&avatar_notes); } - if (panel_sl) - { - panel_sl->processNotesProperties(&avatar_notes); - } } //TODO: changes take two minutes to propagate! @@ -863,7 +859,6 @@ BOOL LLPanelProfileSecondLife::postBuild() mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_panel"); mDescriptionEdit = getChild("sl_description_edit"); - mNotesSnippet = getChild("notes_snippet"); mAgentActionMenuButton = getChild("agent_actions_menu"); mSaveDescriptionChanges = getChild("save_description_changes"); mDiscardDescriptionChanges = getChild("discard_description_changes"); @@ -979,14 +974,16 @@ void LLPanelProfileSecondLife::resetData() mGroups.clear(); mGroupList->setGroups(mGroups); + bool own_profile = getSelfProfile(); mCanSeeOnlineIcon->setVisible(false); - mCantSeeOnlineIcon->setVisible(true); + mCantSeeOnlineIcon->setVisible(!own_profile); mCanSeeOnMapIcon->setVisible(false); - mCantSeeOnMapIcon->setVisible(true); + mCantSeeOnMapIcon->setVisible(!own_profile); mCanEditObjectsIcon->setVisible(false); - mCantEditObjectsIcon->setVisible(true); + mCantEditObjectsIcon->setVisible(!own_profile); - childSetVisible("permissions_panel", false); + childSetVisible("partner_layout", FALSE); + childSetVisible("partner_spacer_layout", TRUE); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -1027,11 +1024,6 @@ void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avat mGroupList->setGroups(mGroups); } -void LLPanelProfileSecondLife::processNotesProperties(LLAvatarNotes* avatar_notes) -{ - mNotesSnippet->setValue(avatar_notes->notes); -} - void LLPanelProfileSecondLife::openGroupProfile() { LLUUID group_id = mGroupList->getSelectedUUID(); @@ -1041,15 +1033,8 @@ void LLPanelProfileSecondLife::openGroupProfile() void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { mAvatarNameCacheConnection.disconnect(); - if (getIsLoaded()) - { - fillNameAgeData(av_name, mBornOn); - } -} - -void LLPanelProfileSecondLife::setNotesSnippet(std::string ¬es) -{ - mNotesSnippet->setValue(notes); + getChild("display_name")->setValue(av_name.getDisplayName()); + getChild("user_name")->setValue(av_name.getAccountName()); } void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) @@ -1128,20 +1113,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) // and to make sure icons in text will be up to date LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); - mBornOn = avatar_data->born_on; - - // Should be possible to get user and display names from AgentProfile capability - // but at the moment contraining this to limits of LLAvatarData - LLAvatarName av_name; - if (LLAvatarNameCache::get(avatar_data->avatar_id, &av_name)) - { - fillNameAgeData(av_name, mBornOn); - } - else if (!mAvatarNameCacheConnection.connected()) - { - // shouldn't happen, but just in case - mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); - } + fillAgeData(avatar_data->born_on); setDescriptionText(avatar_data->about_text); @@ -1184,6 +1156,7 @@ void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) if (avatar_data->partner_id.notNull()) { childSetVisible("partner_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); LLStringUtil::format_map_t args; args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); std::string partner_text = getString("partner_text", args); @@ -1192,6 +1165,7 @@ void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) else { childSetVisible("partner_layout", FALSE); + childSetVisible("partner_spacer_layout", TRUE); } } @@ -1207,6 +1181,11 @@ void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data void LLPanelProfileSecondLife::fillRightsData() { + if (getSelfProfile()) + { + return; + } + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); // If true - we are viewing friend's profile, enable check boxes and set values. if (relation) @@ -1232,20 +1211,15 @@ void LLPanelProfileSecondLife::fillRightsData() mCanEditObjectsIcon->setVisible(false); mCantEditObjectsIcon->setVisible(true); } - - childSetVisible("permissions_panel", NULL != relation); } -void LLPanelProfileSecondLife::fillNameAgeData(const LLAvatarName &av_name, const LLDate &born_on) +void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) { - getChild("display_name")->setValue(av_name.getDisplayName()); - - std::string name_and_date = getString("name_date_format"); + std::string name_and_date = getString("date_format"); LLSD args_name; args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); - args_name["[NAME]"] = av_name.getAccountName(); LLStringUtil::format(name_and_date, args_name); - getChild("user_name_date")->setValue(name_and_date); + getChild("sl_birth_date")->setValue(name_and_date); std::string register_date = getString("age_format"); LLSD args_age; @@ -1259,12 +1233,12 @@ void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTextur LLRect imageRect = mSecondLifePicLayout->getRect(); if (!success || imagep->getFullWidth() == imagep->getFullHeight()) { - mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); + mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth()); } else { // assume 3:4, for sake of firestorm - mSecondLifePicLayout->reshape(imageRect.getHeight() * 4 / 3, imageRect.getHeight()); + mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4); } } @@ -1348,7 +1322,6 @@ void LLPanelProfileSecondLife::updateOnlineStatus() } else { - childSetVisible("spacer_layout", true); childSetVisible("frind_layout", false); childSetVisible("online_layout", false); childSetVisible("offline_layout", false); @@ -1357,7 +1330,6 @@ void LLPanelProfileSecondLife::updateOnlineStatus() void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online) { - childSetVisible("spacer_layout", false); childSetVisible("frind_layout", is_friend); childSetVisible("online_layout", online && show_online); childSetVisible("offline_layout", !online && show_online); @@ -2157,20 +2129,6 @@ void LLPanelProfileNotes::onSaveNotesChanges() { LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); - - - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - if (!parent_floater) - { - return; - } - - LLPanel* panel = parent_floater->findChild(PANEL_SECONDLIFE, TRUE); - LLPanelProfileSecondLife *panel_sl = dynamic_cast(panel); - if (panel_sl) - { - panel_sl->setNotesSnippet(mCurrentNotes); - } } else { -- cgit v1.2.3 From c4aa8b1636b92f2b746df4ef319c10679883eb59 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 6 Jun 2022 18:22:57 +0300 Subject: SL-15312 Header fixes fixed 'remove_proto' being active even if there is no photo. --- indra/newview/llpanelprofile.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 8db9658837..1542c425ce 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -967,6 +967,8 @@ void LLPanelProfileSecondLife::resetData() // Set default image and 1:1 dimensions for it mSecondLifePic->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; + LLRect imageRect = mSecondLifePicLayout->getRect(); mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); @@ -1055,6 +1057,7 @@ void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id) { mSecondLifePic->setValue(image_asset_id); + mImageId = image_asset_id; LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id); if (imagep->getFullHeight()) @@ -1120,10 +1123,12 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) if (avatar_data->image_id.notNull()) { mSecondLifePic->setValue(avatar_data->image_id); + mImageId = avatar_data->image_id; } else { mSecondLifePic->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; } // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic @@ -1523,6 +1528,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); mSecondLifePic->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; } else { @@ -1581,7 +1587,7 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) else if (item_name == "remove_photo") { std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - return !cap_url.empty() && !mWaitingForImageUpload; + return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload; } return false; -- cgit v1.2.3 From 0c6afa58de6b57ad41d31a3dddaac9ef30321960 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 6 Jun 2022 18:55:33 +0300 Subject: SL-15312 Larger image preview At the moment without cursor handling --- indra/newview/llpanelprofile.cpp | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 1542c425ce..441a69bc5d 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -59,6 +59,7 @@ #include "llavatarpropertiesprocessor.h" #include "llcallingcard.h" #include "llcommandhandler.h" +#include "llfloaterprofiletexture.h" #include "llfloaterreg.h" #include "llfilepicker.h" #include "llfirstuse.h" @@ -884,6 +885,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); }); return TRUE; } @@ -1075,6 +1077,20 @@ void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset FALSE); } + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast(floater); + if (mImageId.notNull()) + { + texture_view->loadAsset(mImageId); + } + else + { + texture_view->resetAsset(); + } + } + setProfileImageUploading(false); } @@ -1529,6 +1545,13 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) mSecondLifePic->setValue("Generic_Person_Large"); mImageId = LLUUID::null; + + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast(floater); + texture_view->resetAsset(); + } } else { @@ -1718,6 +1741,51 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() } } +void LLPanelProfileSecondLife::onShowAgentProfileTexture() +{ + if (!getIsLoaded()) + { + return; + } + + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (!floater) + { + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + { + LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater); + mFloaterProfileTextureHandle = texture_view->getHandle(); + if (mImageId.notNull()) + { + texture_view->loadAsset(mImageId); + } + else + { + texture_view->resetAsset(); + } + texture_view->openFloater(); + texture_view->setVisibleAndFrontmost(TRUE); + + parent_floater->addDependentFloater(mFloaterProfileTextureHandle); + } + } + else // already open + { + LLFloaterProfileTexture * texture_view = dynamic_cast(floater); + texture_view->setMinimized(FALSE); + texture_view->setVisibleAndFrontmost(TRUE); + if (mImageId.notNull()) + { + texture_view->loadAsset(mImageId); + } + else + { + texture_view->resetAsset(); + } + } +} + void LLPanelProfileSecondLife::onOpenNotes() { LLFloater* parent_floater = gFloaterView->getParentFloater(this); -- cgit v1.2.3 From 111d1d7c94887cb91bcb82ec6c86aaed133d8043 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 6 Jun 2022 21:27:13 +0300 Subject: SL-15312 Fixed group names not having padding Plus some focus and interactibility fixes --- indra/newview/llpanelprofile.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 441a69bc5d..69e36a2df7 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -669,6 +669,8 @@ void LLFloaterProfilePermissions::onOpen(const LLSD& key) fillRightsData(); } + mCancelBtn->setFocus(true); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2)); } @@ -986,6 +988,13 @@ void LLPanelProfileSecondLife::resetData() mCanEditObjectsIcon->setVisible(false); mCantEditObjectsIcon->setVisible(!own_profile); + mCanSeeOnlineIcon->setEnabled(false); + mCantSeeOnlineIcon->setEnabled(false); + mCanSeeOnMapIcon->setEnabled(false); + mCantSeeOnMapIcon->setEnabled(false); + mCanEditObjectsIcon->setEnabled(false); + mCantEditObjectsIcon->setEnabled(false); + childSetVisible("partner_layout", FALSE); childSetVisible("partner_spacer_layout", TRUE); } @@ -1222,15 +1231,22 @@ void LLPanelProfileSecondLife::fillRightsData() mCantSeeOnMapIcon->setVisible(!can_see_on_map); mCanEditObjectsIcon->setVisible(can_edit_objects); mCantEditObjectsIcon->setVisible(!can_edit_objects); + + mCanSeeOnlineIcon->setEnabled(true); + mCantSeeOnlineIcon->setEnabled(true); + mCanSeeOnMapIcon->setEnabled(true); + mCantSeeOnMapIcon->setEnabled(true); + mCanEditObjectsIcon->setEnabled(true); + mCantEditObjectsIcon->setEnabled(true); } else { mCanSeeOnlineIcon->setVisible(false); - mCantSeeOnlineIcon->setVisible(true); + mCantSeeOnlineIcon->setVisible(false); mCanSeeOnMapIcon->setVisible(false); - mCantSeeOnMapIcon->setVisible(true); + mCantSeeOnMapIcon->setVisible(false); mCanEditObjectsIcon->setVisible(false); - mCantEditObjectsIcon->setVisible(true); + mCantEditObjectsIcon->setVisible(false); } } -- cgit v1.2.3 From 206892fe9e03b906fad94e83f58e263b4d6745c6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 7 Jun 2022 21:00:56 +0300 Subject: SL-17532 Apply padding after 'partner' --- indra/newview/llpanelprofile.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 69e36a2df7..6c4e0e9878 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -996,7 +996,6 @@ void LLPanelProfileSecondLife::resetData() mCantEditObjectsIcon->setEnabled(false); childSetVisible("partner_layout", FALSE); - childSetVisible("partner_spacer_layout", TRUE); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -1186,7 +1185,6 @@ void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) if (avatar_data->partner_id.notNull()) { childSetVisible("partner_layout", TRUE); - childSetVisible("partner_spacer_layout", FALSE); LLStringUtil::format_map_t args; args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); std::string partner_text = getString("partner_text", args); @@ -1195,7 +1193,6 @@ void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) else { childSetVisible("partner_layout", FALSE); - childSetVisible("partner_spacer_layout", TRUE); } } -- cgit v1.2.3 From ababcc700cc956c4c024f03bf69ca2fdb3e7baed Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 9 Jun 2022 00:22:02 +0300 Subject: SL-17532 Ability to pick inventory image as a profile image --- indra/newview/llpanelprofile.cpp | 275 ++++++++++++++++++++++++++++++++++----- 1 file changed, 243 insertions(+), 32 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 6c4e0e9878..dbb83b0da2 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -169,6 +169,14 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) { avatar_data->flags |= AVATAR_ALLOW_PUBLISH; } + if (result["identified"].asBoolean()) + { + avatar_data->flags |= AVATAR_IDENTIFIED; + } + if (result["transacted"].asBoolean()) + { + avatar_data->flags |= AVATAR_TRANSACTED; + } avatar_data->caption_index = 0; if (result.has("charter_member")) // won't be present if "caption" is set @@ -1412,6 +1420,10 @@ void LLProfileImagePicker::notify(const std::vector& filenames) { return; } + if (filenames.empty()) + { + return; + } std::string file_path = filenames[0]; if (file_path.empty()) { @@ -1541,34 +1553,28 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) url = LLWeb::expandURLSubstitutions(url, subs); LLUrlAction::openURL(url); } - else if (item_name == "change_photo") + else if (item_name == "upload_photo") { (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle(getHandle())))->getFile(); + + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } + } + else if (item_name == "change_photo") + { + onShowTexturePicker(); } else if (item_name == "remove_photo") { - LLSD params; - params["sl_image_id"] = LLUUID::null; + onCommitProfileImage(LLUUID::null); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); - - mSecondLifePic->setValue("Generic_Person_Large"); - mImageId = LLUUID::null; - - LLFloater *floater = mFloaterProfileTextureHandle.get(); - if (floater) - { - LLFloaterProfileTexture * texture_view = dynamic_cast(floater); - texture_view->resetAsset(); - } - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + floaterp->closeFloater(); } } } @@ -1615,15 +1621,16 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) { return !mAvatarNameCacheConnection.connected(); } - else if (item_name == "change_photo") + else if (item_name == "upload_photo" + || item_name == "change_photo") { std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); - return !cap_url.empty() && !mWaitingForImageUpload; + return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); } else if (item_name == "remove_photo") { std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload; + return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); } return false; @@ -1799,6 +1806,117 @@ void LLPanelProfileSecondLife::onShowAgentProfileTexture() } } +void LLPanelProfileSecondLife::onShowTexturePicker() +{ + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + + // Show the dialog + if (!floaterp) + { + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + { + // because inventory construction is somewhat slow + getWindow()->setCursor(UI_CURSOR_WAIT); + LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( + this, + mImageId, + LLUUID::null, + mImageId, + FALSE, + FALSE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mFloaterTexturePickerHandle = texture_floaterp->getHandle(); + + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) + { + if (op == LLTextureCtrl::TEXTURE_SELECT) + { + LLUUID image_asset_id; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get(); + if (floaterp) + { + if (id.notNull()) + { + image_asset_id = id; + } + else + { + image_asset_id = floaterp->getAssetID(); + } + } + + onCommitProfileImage(image_asset_id); + } + }); + texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setBakeTextureEnabled(FALSE); + texture_floaterp->setCanApply(false, true); + + parent_floater->addDependentFloater(mFloaterTexturePickerHandle); + + texture_floaterp->openFloater(); + texture_floaterp->setFocus(TRUE); + } + } + else + { + floaterp->setMinimized(FALSE); + floaterp->setVisibleAndFrontmost(TRUE); + } +} + +void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) +{ + if (mImageId == id) + { + return; + } + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLSD params; + params["sl_image_id"] = id; + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + + mImageId = id; + if (mImageId == LLUUID::null) + { + mSecondLifePic->setValue("Generic_Person_Large"); + } + else + { + mSecondLifePic->setValue(mImageId); + } + + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast(floater); + if (mImageId == LLUUID::null) + { + texture_view->resetAsset(); + } + else + { + texture_view->loadAsset(mImageId); + } + } + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } +} + void LLPanelProfileSecondLife::onOpenNotes() { LLFloater* parent_floater = gFloaterView->getParentFloater(this); @@ -1973,11 +2091,13 @@ BOOL LLPanelProfileFirstLife::postBuild() mDescriptionEdit = getChild("fl_description_edit"); mPicture = getChild("real_world_pic"); - mChangePhoto = getChild("fl_upload_image"); + mUploadPhoto = getChild("fl_upload_image"); + mChangePhoto = getChild("fl_change_image"); mRemovePhoto = getChild("fl_remove_image"); mSaveChanges = getChild("fl_save_changes"); mDiscardChanges = getChild("fl_discard_changes"); + mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr); mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr); mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr); mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); @@ -2002,8 +2122,9 @@ void LLPanelProfileFirstLife::onOpen(const LLSD& key) void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) { + mUploadPhoto->setEnabled(!loading); mChangePhoto->setEnabled(!loading); - mRemovePhoto->setEnabled(!loading); + mRemovePhoto->setEnabled(!loading && mImageId.notNull()); LLLoadingIndicator* indicator = getChild("image_upload_indicator"); indicator->setVisible(loading); @@ -2031,23 +2152,107 @@ void LLPanelProfileFirstLife::commitUnsavedChanges() } } -void LLPanelProfileFirstLife::onChangePhoto() +void LLPanelProfileFirstLife::onUploadPhoto() { (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle(getHandle())))->getFile(); } +void LLPanelProfileFirstLife::onChangePhoto() +{ + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + + // Show the dialog + if (!floaterp) + { + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + { + // because inventory construction is somewhat slow + getWindow()->setCursor(UI_CURSOR_WAIT); + LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( + this, + mImageId, + LLUUID::null, + mImageId, + FALSE, + FALSE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mFloaterTexturePickerHandle = texture_floaterp->getHandle(); + + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) + { + if (op == LLTextureCtrl::TEXTURE_SELECT) + { + LLUUID image_asset_id; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get(); + if (floaterp) + { + if (id.notNull()) + { + image_asset_id = id; + } + else + { + image_asset_id = floaterp->getAssetID(); + } + } + + onCommitPhoto(image_asset_id); + } + }); + texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setCanApply(false, true); + + parent_floater->addDependentFloater(mFloaterTexturePickerHandle); + + texture_floaterp->openFloater(); + texture_floaterp->setFocus(TRUE); + } + } + else + { + floaterp->setMinimized(FALSE); + floaterp->setVisibleAndFrontmost(TRUE); + } +} + void LLPanelProfileFirstLife::onRemovePhoto() { - LLSD params; - params["fl_image_id"] = LLUUID::null; + onCommitPhoto(LLUUID::null); +} + +void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) +{ + if (mImageId == id) + { + return; + } std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) { + LLSD params; + params["fl_image_id"] = id; LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); - mPicture->setValue("Generic_Person_Large"); + mImageId = id; + if (mImageId.notNull()) + { + mPicture->setValue(mImageId); + } + else + { + mPicture->setValue("Generic_Person_Large"); + } + + mRemovePhoto->setEnabled(mImageId.notNull()); } else { @@ -2099,14 +2304,18 @@ void LLPanelProfileFirstLife::onDiscardDescriptionChanges() void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { setDescriptionText(avatar_data->fl_about_text); - if (avatar_data->fl_image_id.notNull()) + + mImageId = avatar_data->fl_image_id; + + if (mImageId.notNull()) { - mPicture->setValue(avatar_data->fl_image_id); + mPicture->setValue(mImageId); } else { mPicture->setValue("Generic_Person_Large"); } + setLoaded(); } @@ -2115,6 +2324,7 @@ void LLPanelProfileFirstLife::resetData() mDescriptionEdit->setValue(LLStringUtil::null); mPicture->setValue("Generic_Person_Large"); + mUploadPhoto->setVisible(getSelfProfile()); mChangePhoto->setVisible(getSelfProfile()); mRemovePhoto->setVisible(getSelfProfile()); mSaveChanges->setVisible(getSelfProfile()); @@ -2129,6 +2339,7 @@ void LLPanelProfileFirstLife::setLoaded() { mDescriptionEdit->setEnabled(TRUE); mPicture->setEnabled(TRUE); + mRemovePhoto->setEnabled(mImageId.notNull()); } } -- cgit v1.2.3 From 750606c7a5ddf5cb8e46609d5715b8892e20d09f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jun 2022 20:16:55 +0300 Subject: SL-17624 In profiles 'Remove Photo' remains inactive after uploading a photo --- indra/newview/llpanelprofile.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index dbb83b0da2..559e6abfdb 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -2141,6 +2141,7 @@ void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id) { mPicture->setValue(image_asset_id); + mImageId = image_asset_id; setProfileImageUploading(false); } @@ -2323,6 +2324,7 @@ void LLPanelProfileFirstLife::resetData() { mDescriptionEdit->setValue(LLStringUtil::null); mPicture->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; mUploadPhoto->setVisible(getSelfProfile()); mChangePhoto->setVisible(getSelfProfile()); -- cgit v1.2.3 From 2c940a1d8015601f5eea628b8940fde0547756d6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jun 2022 22:51:08 +0300 Subject: SL-17633 Crash at LLFocusableElement --- indra/newview/llpanelprofile.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 559e6abfdb..d531bee79f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1448,8 +1448,21 @@ void LLProfileImagePicker::notify(const std::vector& filenames) return; } - LLPanelProfileSecondLife* panel = static_cast(mHandle->get()); - panel->setProfileImageUploading(true); + switch (mType) + { + case PROFILE_IMAGE_SL: + { + LLPanelProfileSecondLife* panel = static_cast(mHandle->get()); + panel->setProfileImageUploading(true); + } + break; + case PROFILE_IMAGE_FL: + { + LLPanelProfileFirstLife* panel = static_cast(mHandle->get()); + panel->setProfileImageUploading(true); + } + break; + } LLCoros::instance().launch("postAgentUserImageCoro", boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle)); @@ -2156,6 +2169,12 @@ void LLPanelProfileFirstLife::commitUnsavedChanges() void LLPanelProfileFirstLife::onUploadPhoto() { (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle(getHandle())))->getFile(); + + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } } void LLPanelProfileFirstLife::onChangePhoto() @@ -2226,6 +2245,12 @@ void LLPanelProfileFirstLife::onChangePhoto() void LLPanelProfileFirstLife::onRemovePhoto() { onCommitPhoto(LLUUID::null); + + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } } void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) -- cgit v1.2.3 From e0360ee13ac683007210cf13a49ca2c4178207fe Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 14 Jul 2022 17:41:17 +0300 Subject: SL-17773 Discard changes clears notes instead of setting previous version --- indra/newview/llpanelprofile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index d531bee79f..2b6be5f5fe 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -2472,7 +2472,7 @@ void LLPanelProfileNotes::onDiscardNotesChanges() void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) { - mNotesEditor->setValue(avatar_notes->notes); + setNotesText(avatar_notes->notes); mNotesEditor->setEnabled(TRUE); setLoaded(); } @@ -2480,7 +2480,7 @@ void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) void LLPanelProfileNotes::resetData() { resetLoading(); - mNotesEditor->setValue(LLStringUtil::null); + setNotesText(std::string()); } void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) -- cgit v1.2.3 From 1f53aab286a89dc246a8bdc5a4db3ee524d4412c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 14 Jul 2022 17:41:17 +0300 Subject: SL-17773 Properly reset buttons --- indra/newview/llpanelprofile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 2b6be5f5fe..195244ea22 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -2347,7 +2347,7 @@ void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) void LLPanelProfileFirstLife::resetData() { - mDescriptionEdit->setValue(LLStringUtil::null); + setDescriptionText(std::string()); mPicture->setValue("Generic_Person_Large"); mImageId = LLUUID::null; -- cgit v1.2.3 From 946bdc1ee352618f0d333292272aceb48b6d8dd8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 8 Aug 2022 22:38:56 +0300 Subject: SL-14556 Profile floater does not update after a name change --- indra/newview/llpanelprofile.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 195244ea22..2f4da59cfd 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -973,6 +973,14 @@ void LLPanelProfileSecondLife::updateData() } } +void LLPanelProfileSecondLife::refreshName() +{ + if (!mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); + } +} + void LLPanelProfileSecondLife::resetData() { resetLoading(); @@ -2576,6 +2584,11 @@ void LLPanelProfile::updateData() } } +void LLPanelProfile::refreshName() +{ + mPanelSecondlife->refreshName(); +} + void LLPanelProfile::createPick(const LLPickData &data) { mTabContainer->selectTabPanel(mPanelPicks); -- cgit v1.2.3 From c4335939d90346a778eb18acb7611135742231df Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 10 Aug 2022 19:03:12 +0300 Subject: SL-17925 Fix SLURL based creation of picks and classifieds --- indra/newview/llpanelprofile.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra/newview/llpanelprofile.cpp') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 2f4da59cfd..29c9329a26 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -2646,5 +2646,9 @@ void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) mTabContainer->selectTabPanel(mPanelClassifieds); } - +void LLPanelProfile::createClassified() +{ + mPanelClassifieds->createClassified(); + mTabContainer->selectTabPanel(mPanelClassifieds); +} -- cgit v1.2.3