From a8fd107029eca04b2804923cf05bd66c41b655c4 Mon Sep 17 00:00:00 2001 From: Beq Date: Wed, 28 Sep 2022 19:20:45 +0100 Subject: [PATCH] Restore udp profiles for opensim Restore UDP and remove superfluous buttons when no cap is available Image updates work as before (no direct from disk updates) --- indra/newview/llavatarpropertiesprocessor.cpp | 43 ++- indra/newview/llavatarpropertiesprocessor.h | 4 + indra/newview/llpanelprofile.cpp | 294 +++++++++++++++++- indra/newview/llpanelprofile.h | 15 +- indra/newview/llpanelprofileclassifieds.cpp | 2 + indra/newview/llpanelprofilepicks.cpp | 3 +- .../default/xui/en/panel_profile_picks.xml | 2 +- 7 files changed, 338 insertions(+), 25 deletions(-) diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index ea39f73a61..699f7d54b5 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -147,8 +147,18 @@ void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarPr void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method) { - // indicate we're going to make a request - addPendingRequest(avatar_id, type); +// First run at profile behaviour fix for OpenSim +#ifdef OPENSIM // maintain legacy behaviour for now + // Suppress duplicate requests while waiting for a response from the network + if (isPendingRequest(avatar_id, type)) + { + // waiting for a response, don't re-request + return; + } +#endif //OPENSIM +// + // indicate we're going to make a request + addPendingRequest(avatar_id, type); std::vector strings; strings.push_back(avatar_id.asString()); @@ -178,11 +188,36 @@ void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avata LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id)); } - void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) { - sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); +// maintian legacy behaviour for OpenSim + if(!gAgent.getRegionCapability("AgentProfile").empty()) + { +// + sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); + } +// maintian legacy behaviour for OpenSim +#ifdef OPENSIM + else + { + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this, the AvatarPropertiesRequest message + // won't work so don't bother trying + if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) + { + return; + } + + if (isPendingRequest(avatar_id, APT_PROPERTIES)) + { + // waiting for a response, don't re-request + return; + } + sendAvatarPropertiesRequestMessage(avatar_id); + } +#endif } +// void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id) { diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index f778634d25..51198e8898 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -215,6 +215,10 @@ public: void sendAvatarGroupsRequest(const LLUUID& avatar_id); void sendAvatarTexturesRequest(const LLUUID& avatar_id); void sendAvatarClassifiedsRequest(const LLUUID& avatar_id); + // enable legacy profile access for OpenSim to work with new profile + void sendGenericRequestLegacy(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method); + void sendAvatarPropertiesRequestLegacy(const LLUUID& avatar_id); + // // Duplicate pick info requests are not suppressed. void sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 68bed8e54e..fe623dadce 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -78,6 +78,7 @@ #include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llweb.h" +#include "llviewernetwork.h" // For LLGridManager #include "fsdata.h" #include "llviewermenu.h" @@ -884,7 +885,7 @@ void LLFloaterProfilePermissions::onCancel() // LLPanelProfileSecondLife LLPanelProfileSecondLife::LLPanelProfileSecondLife() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() // alter ancestry to re-enable UDP , mAvatarNameCacheConnection() , mHasUnsavedDescriptionChanges(false) , mWaitingForImageUpload(false) @@ -1011,8 +1012,7 @@ void LLPanelProfileSecondLife::onAvatarProperties(const LLAvatarData* d) void LLPanelProfileSecondLife::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); - + LLPanelProfilePropertiesProcessorTab::onOpen(key); // alter ancestry to re-enable UDP resetData(); LLUUID avatar_id = getAvatarId(); @@ -1055,7 +1055,16 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) // // Todo: use PeopleContextMenu instead? // mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); //} +// Remove the menu thingy and just have click picture to change +// if (own_profile) +// only if we are in opensim and opensim doesn't have the image upload cap +#ifdef OPENSIM + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if( own_profile && (!LLGridManager::instance().isInOpenSim() || !cap_url.empty() ) ) +#else if (own_profile) +#endif +// { mImageActionMenuButton->setVisible(TRUE); mImageActionMenuButton->setMenu("menu_fs_profile_image_actions.xml", LLMenuButton::MP_BOTTOM_RIGHT); @@ -1103,6 +1112,15 @@ void LLPanelProfileSecondLife::updateData() } else { + // restore UDP profiles for opensim that does not support the cap +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim() && !(getSelfProfile() /* TODO(Beq):No longer neeed? && !getEmbedded()*/)) + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarGroupsRequest(avatar_id); + } + else +#endif + // LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -1116,6 +1134,43 @@ void LLPanelProfileSecondLife::refreshName() } } +// Restore UDP profiles +void LLPanelProfileSecondLife::apply(LLAvatarData* data) +{ +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim() && getIsLoaded() && getSelfProfile()) + { + data->image_id = mImageId; + data->about_text = mDescriptionEdit->getValue().asString(); + data->allow_publish = mShowInSearchCheckbox->getValue(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(data); + } +#endif +} + +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); + setLoaded(); + } + } + else if (APT_GROUPS == type) + { + LLAvatarGroups* avatar_groups = static_cast(data); + if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) + { + processGroupProperties(avatar_groups); + } + } +} +// + void LLPanelProfileSecondLife::resetData() { resetLoading(); @@ -1206,6 +1261,26 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat fillPartnerData(avatar_data); fillAccountStatus(avatar_data); +// Restore UDP profiles +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim()) + { + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", avatar_id)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + auto *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + } + panel_profile->setAvatarData(avatar_data); + } +#endif +// setLoaded(); @@ -1612,7 +1687,7 @@ void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); } - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); // Change ancestry to restore UDP profiles if (LLAvatarActions::isFriend(getAvatarId())) { @@ -2154,6 +2229,39 @@ void LLPanelProfileSecondLife::onSaveDescriptionChanges() LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText))); } +// Restore UDP profiles +#ifdef OPENSIM + else if(LLGridManager::getInstance()->isInOpenSim()) + { + if (getIsLoaded() && getSelfProfile()) + { + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", gAgentID)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + auto *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + } + else + { + auto avatar_data = panel_profile->getAvatarData(); + avatar_data.agent_id = gAgentID; + avatar_data.avatar_id = gAgentID; + avatar_data.image_id = mImageId; + avatar_data.about_text = mDescriptionEdit->getValue().asString(); + avatar_data.allow_publish = mShowInSearchCheckbox->getValue(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&avatar_data); + } + } + } +#endif +// else { LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; @@ -2369,6 +2477,21 @@ void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) } else { +// Make OpenSim profiles work again +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + mImageId = id; + // save immediately only if description changes are not pending. + if(!mHasUnsavedDescriptionChanges) + { + onSaveDescriptionChanges(); + } + } + else +#endif +// + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -2437,6 +2560,14 @@ void LLPanelProfileWeb::updateData() } } +// Restore UDP profiles +#ifdef OPENSIM +void LLPanelProfileWeb::apply(LLAvatarData* data) +{ + data->profile_url = mURLHome; +} +#endif +// void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { mAvatarNameCacheConnection.disconnect(); @@ -2526,7 +2657,7 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e ////////////////////////////////////////////////////////////////////////// LLPanelProfileFirstLife::LLPanelProfileFirstLife() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() // alter ancestry to re-enable UDP , mHasUnsavedChanges(false) { } @@ -2562,7 +2693,7 @@ BOOL LLPanelProfileFirstLife::postBuild() void LLPanelProfileFirstLife::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); + LLPanelProfilePropertiesProcessorTab::onOpen(key); // alter ancestry to re-enable UDP if (!getSelfProfile()) { @@ -2733,6 +2864,21 @@ void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) } else { +// Make OpenSim profiles work again +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + mImageId = id; + mImageId = id; + // save immediately only if description changes are not pending. + if(!mHasUnsavedChanges) + { + onSaveDescriptionChanges(); + } + } + else +#endif +// LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -2763,6 +2909,38 @@ void LLPanelProfileFirstLife::onSaveDescriptionChanges() LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription))); } +// Restore UDP profiles +#ifdef OPENSIM + else if(LLGridManager::getInstance()->isInOpenSim()) + { + if (getIsLoaded() && getSelfProfile()) + { + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", gAgentID)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + auto *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + } + else + { + auto avatar_data = panel_profile->getAvatarData(); + avatar_data.agent_id = gAgentID; + avatar_data.avatar_id = gAgentID; + avatar_data.fl_image_id = mImageId; + avatar_data.fl_about_text = mDescriptionEdit->getValue().asString(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&avatar_data); + } + } + } +#endif +// else { LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; @@ -2778,6 +2956,20 @@ void LLPanelProfileFirstLife::onDiscardDescriptionChanges() setDescriptionText(mCurrentDescription); } +// Restore UDP profiles +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); @@ -2796,15 +2988,38 @@ void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) setLoaded(); } +// Restore UDP profiles +#ifdef OPENSIM +void LLPanelProfileFirstLife::apply(LLAvatarData* data) +{ + data->fl_image_id = mImageId; + data->fl_about_text = mDescriptionEdit->getValue().asString(); +} +#endif +// + void LLPanelProfileFirstLife::resetData() { setDescriptionText(std::string()); mPicture->setValue("Generic_Person_Large"); mImageId = LLUUID::null; - mUploadPhoto->setVisible(getSelfProfile()); - mChangePhoto->setVisible(getSelfProfile()); - mRemovePhoto->setVisible(getSelfProfile()); +// remove the buttons and just have click image to update profile +// mUploadPhoto->setVisible(getSelfProfile()); +// mChangePhoto->setVisible(getSelfProfile()); +// mRemovePhoto->setVisible(getSelfProfile()); + auto show_image_buttons = getSelfProfile(); +#ifdef OPENSIM + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if( cap_url.empty() && LLGridManager::instance().isInOpenSim() ) + { + show_image_buttons = false; + } +#endif + mUploadPhoto->setVisible(show_image_buttons); + mChangePhoto->setVisible(show_image_buttons); + mRemovePhoto->setVisible(show_image_buttons); +// mSaveChanges->setVisible(getSelfProfile()); mDiscardChanges->setVisible(getSelfProfile()); } @@ -2826,7 +3041,7 @@ void LLPanelProfileFirstLife::setLoaded() ////////////////////////////////////////////////////////////////////////// LLPanelProfileNotes::LLPanelProfileNotes() -: LLPanelProfileTab() +: LLPanelProfilePropertiesProcessorTab() // alter ancestry to re-enable UDP , mHasUnsavedChanges(false) { @@ -2849,6 +3064,14 @@ void LLPanelProfileNotes::updateData() LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); } +// Restore UDO profiles +#ifdef OPENSIM + else + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarNotesRequest(avatar_id); + } +#endif +// } } @@ -2927,6 +3150,19 @@ void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) mNotesEditor->setEnabled(TRUE); setLoaded(); } +// Restore UDP profiles +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); + } + } +} +// void LLPanelProfileNotes::resetData() { @@ -2938,7 +3174,7 @@ void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); // alter ancestry to re-enable UDP } } @@ -3012,18 +3248,30 @@ void LLPanelProfile::updateData() if (!getStarted() && avatar_id.notNull()) { setIsLoading(); - mPanelSecondlife->setIsLoading(); mPanelPicks->setIsLoading(); mPanelFirstlife->setIsLoading(); mPanelNotes->setIsLoading(); - +// Restore UDP profiles +#ifdef OPENSIM + mPanelSecondlife->updateData(); + mPanelPicks->updateData(); + mPanelFirstlife->updateData(); + mPanelNotes->updateData(); +#endif +// 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)); } +// Restore UDP profiles + else + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + } +// } } @@ -3078,8 +3326,26 @@ void LLPanelProfile::commitUnsavedChanges() mPanelClassifieds->commitUnsavedChanges(); mPanelFirstlife->commitUnsavedChanges(); mPanelNotes->commitUnsavedChanges(); + // restore UDP - this is effectvely the apply() method from the previous incarnation +#ifdef OPENSIM + if ( (gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP).empty()) && getSelfProfile() ) + { + //KC - Avatar data is spread over 3 different panels + // collect data from the last 2 and give to the first to save + LLAvatarData data = mAvatarData; + data.avatar_id = gAgentID; + // these three collate data so need to be called in sequence. + mPanelFirstlife->apply(&data); + mPanelWeb->apply(&data); + mPanelSecondlife->apply(&data); + // These three triggered above + // mPanelInterests->apply(); + // mPanelPicks->apply(); + // mPanelNotes->apply(); + } +#endif + // } - void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) { if (classified_id.notNull()) diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 57f4fba6d4..8b097ead19 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -82,7 +82,7 @@ public: * Panel for displaying Avatar's second life related info. */ class LLPanelProfileSecondLife - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab , public LLFriendObserver , public LLVoiceClientStatusObserver { @@ -110,6 +110,8 @@ public: /** * Sends update data request to server. */ + void apply(LLAvatarData* data); + void processProperties(void* data, EAvatarProcessorType type) override; void updateData() override; void refreshName(); @@ -293,6 +295,7 @@ public: * Loads web profile. */ void updateData() override; + void apply(LLAvatarData* data); void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; @@ -318,7 +321,7 @@ private: * Panel for displaying Avatar's first life related info. */ class LLPanelProfileFirstLife - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileFirstLife(); @@ -329,7 +332,8 @@ public: BOOL postBuild() override; void processProperties(const LLAvatarData* avatar_data); - + void processProperties(void * data, EAvatarProcessorType type) override; + void apply(LLAvatarData* data); void resetData() override; void setProfileImageUploading(bool loading); @@ -375,7 +379,7 @@ protected: * Panel for displaying Avatar's notes and modifying friend's rights. */ class LLPanelProfileNotes - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileNotes(); @@ -388,7 +392,7 @@ public: BOOL postBuild() override; void processProperties(LLAvatarNotes* avatar_notes); - + void processProperties(void * data, EAvatarProcessorType type) override; void resetData() override; void updateData() override; @@ -440,6 +444,7 @@ public: void createClassified(); LLAvatarData getAvatarData() { return mAvatarData; }; + void setAvatarData(const LLAvatarData* avatar_data){ mAvatarData = *avatar_data; }; friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp index aa58ba08d9..e05bf6993e 100644 --- a/indra/newview/llpanelprofileclassifieds.cpp +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -218,6 +218,8 @@ LLPanelProfileClassifieds::~LLPanelProfileClassifieds() void LLPanelProfileClassifieds::onOpen(const LLSD& key) { + LL_INFOS("profiles") << "Inside onOpen classifieds panel" << LL_ENDL; + LLPanelProfilePropertiesProcessorTab::onOpen(key); resetData(); diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 80a76ac95b..f5ef2ca7a0 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -140,6 +140,8 @@ LLPanelProfilePicks::~LLPanelProfilePicks() void LLPanelProfilePicks::onOpen(const LLSD& key) { + LL_INFOS("profiles") << "Inside onOpen picks panel" << LL_ENDL; + LLPanelProfilePropertiesProcessorTab::onOpen(key); resetData(); @@ -227,7 +229,6 @@ BOOL LLPanelProfilePicks::postBuild() LLTextBox* intro_txt = getChild("header_text"); intro_txt->setTextArg("[GRID]", LLTrans::getString("SECOND_LIFE")); // - return TRUE; } diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml index bcd669700f..7064d1d01c 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml @@ -1,6 +1,6 @@