diff options
Diffstat (limited to 'indra/newview/llpanelavatar.cpp')
-rw-r--r-- | indra/newview/llpanelavatar.cpp | 1000 |
1 files changed, 602 insertions, 398 deletions
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index d7929cc5c2..68ca65420a 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -2,49 +2,50 @@ * @file llpanelavatar.cpp * @brief LLPanelAvatar and related class implementations * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" - #include "llpanelavatar.h" #include "llagent.h" -#include "llavatarconstants.h" +#include "llavataractions.h" +#include "llavatarconstants.h" // AVATAR_ONLINE #include "llcallingcard.h" #include "llcombobox.h" -#include "llfriendactions.h" +#include "lldateutil.h" // ageFromDate() #include "llimview.h" +#include "llnotificationsutil.h" #include "lltexteditor.h" #include "lltexturectrl.h" +#include "lltoggleablemenu.h" #include "lltooldraganddrop.h" -#include "llviewermenu.h" // *FIX: for is_agent_friend() #include "llscrollcontainer.h" +#include "llavatariconctrl.h" +#include "llfloaterreg.h" +#include "llnotificationsutil.h" +#include "llvoiceclient.h" +#include "llnamebox.h" +#include "lltrans.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLDropTarget @@ -61,6 +62,7 @@ public: { Optional<LLUUID> agent_id; Params() + : agent_id("agent_id") { mouse_opaque(false); follows.flags(FOLLOWS_ALL); @@ -114,553 +116,755 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, return FALSE; } -static LLDefaultWidgetRegistry::Register<LLDropTarget> r("drop_target"); +static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target"); + +static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile("panel_profile"); +static LLRegisterPanelClassWrapper<LLPanelMyProfile> t_panel_my_profile("panel_my_profile"); +static LLRegisterPanelClassWrapper<LLPanelAvatarNotes> t_panel_notes("panel_notes"); -////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- -// LLPanelProfileTab() +// LLPanelAvatarNotes() //----------------------------------------------------------------------------- -////////////////////////////////////////////////////////////////////////// -LLPanelProfileTab::LLPanelProfileTab(const LLUUID& avatar_id) - : LLPanel() - , mAvatarId(LLUUID::null) - , mProfileType(PT_UNKNOWN) +LLPanelAvatarNotes::LLPanelAvatarNotes() +: LLPanelProfileTab() { - setAvatarId(avatar_id); + } -LLPanelProfileTab::LLPanelProfileTab(const Params& params ) - : LLPanel() - , mAvatarId(LLUUID::null) - , mProfileType(PT_UNKNOWN) +void LLPanelAvatarNotes::updateData() { + LLAvatarPropertiesProcessor::getInstance()-> + sendAvatarNotesRequest(getAvatarId()); +} +BOOL LLPanelAvatarNotes::postBuild() +{ + childSetCommitCallback("status_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); + childSetCommitCallback("map_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); + childSetCommitCallback("objects_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); + + childSetCommitCallback("add_friend", boost::bind(&LLPanelAvatarNotes::onAddFriendButtonClick, this),NULL); + childSetCommitCallback("im", boost::bind(&LLPanelAvatarNotes::onIMButtonClick, this), NULL); + childSetCommitCallback("call", boost::bind(&LLPanelAvatarNotes::onCallButtonClick, this), NULL); + childSetCommitCallback("teleport", boost::bind(&LLPanelAvatarNotes::onTeleportButtonClick, this), NULL); + childSetCommitCallback("share", boost::bind(&LLPanelAvatarNotes::onShareButtonClick, this), NULL); + childSetCommitCallback("show_on_map_btn", (boost::bind( + &LLPanelAvatarNotes::onMapButtonClick, this)), NULL); + + LLTextEditor* te = getChild<LLTextEditor>("notes_edit"); + te->setCommitCallback(boost::bind(&LLPanelAvatarNotes::onCommitNotes,this)); + te->setCommitOnFocusLost(TRUE); + + resetControls(); + resetData(); + + LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); + + return TRUE; } -LLPanelProfileTab::~LLPanelProfileTab() +void LLPanelAvatarNotes::onOpen(const LLSD& key) { - // *TODO Vadim: use notNull() instead. (there are several similar cases below) - if(mAvatarId.notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } + LLPanelProfileTab::onOpen(key); + + fillRightsData(); + + //Disable "Add Friend" button for friends. + getChildView("add_friend")->setEnabled(!LLAvatarActions::isFriend(getAvatarId())); } -void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id) +void LLPanelAvatarNotes::fillRightsData() { - if(avatar_id.notNull()) + getChild<LLUICtrl>("status_check")->setValue(FALSE); + getChild<LLUICtrl>("map_check")->setValue(FALSE); + getChild<LLUICtrl>("objects_check")->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) { - if(mAvatarId.notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this); - } - mAvatarId = avatar_id; - LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this); - setProfileType(); + S32 rights = relation->getRightsGrantedTo(); + + getChild<LLUICtrl>("status_check")->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); + getChild<LLUICtrl>("map_check")->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + getChild<LLUICtrl>("objects_check")->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + } + + enableCheckboxes(NULL != relation); } -void LLPanelProfileTab::setProfileType() +void LLPanelAvatarNotes::onCommitNotes() { - mProfileType = (gAgentID == mAvatarId) ? PT_OWN : PT_OTHER; + std::string notes = getChild<LLUICtrl>("notes_edit")->getValue().asString(); + LLAvatarPropertiesProcessor::getInstance()-> sendNotes(getAvatarId(),notes); } -void LLPanelProfileTab::onActivate(const LLUUID& id) +void LLPanelAvatarNotes::rightsConfirmationCallback(const LLSD& notification, + const LLSD& response, S32 rights) { - setAvatarId(id); - updateData(); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights( + getAvatarId(), rights); + } + else + { + getChild<LLUICtrl>("objects_check")->setValue( + getChild<LLUICtrl>("objects_check")->getValue().asBoolean() ? FALSE : TRUE); + } } -void LLPanelProfileTab::onAddFriend() +void LLPanelAvatarNotes::confirmModifyRights(bool grant, S32 rights) { - if (getAvatarId().notNull()) + std::string first, last; + LLSD args; + if (gCacheName->getName(getAvatarId(), first, last)) + { + args["FIRST_NAME"] = first; + args["LAST_NAME"] = last; + } + + if (grant) { - std::string name; - gCacheName->getFullName(getAvatarId(),name); - LLFriendActions::requestFriendshipDialog(getAvatarId(), name); + LLNotificationsUtil::add("GrantModifyRights", args, LLSD(), + boost::bind(&LLPanelAvatarNotes::rightsConfirmationCallback, this, + _1, _2, rights)); + } + else + { + LLNotificationsUtil::add("RevokeModifyRights", args, LLSD(), + boost::bind(&LLPanelAvatarNotes::rightsConfirmationCallback, this, + _1, _2, rights)); } } -void LLPanelProfileTab::onIM() +void LLPanelAvatarNotes::onCommitRights() { - if (getAvatarId().notNull()) + const LLRelationship* buddy_relationship = + LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + + if (NULL == buddy_relationship) { - std::string name; - gCacheName->getFullName(getAvatarId(), name); - gIMMgr->addSession(name, IM_NOTHING_SPECIAL, getAvatarId()); + // Lets have a warning log message instead of having a crash. EXT-4947. + llwarns << "Trying to modify rights for non-friend avatar. Skipped." << llendl; + return; + } + + + S32 rights = 0; + + if(getChild<LLUICtrl>("status_check")->getValue().asBoolean()) + rights |= LLRelationship::GRANT_ONLINE_STATUS; + if(getChild<LLUICtrl>("map_check")->getValue().asBoolean()) + rights |= LLRelationship::GRANT_MAP_LOCATION; + if(getChild<LLUICtrl>("objects_check")->getValue().asBoolean()) + rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + + bool allow_modify_objects = getChild<LLUICtrl>("objects_check")->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 LLPanelProfileTab::onTeleport() +void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type) { - if(getAvatarId().notNull()) + if(APT_NOTES == type) { - LLFriendActions::offerTeleport(getAvatarId()); + LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); + if(avatar_notes && getAvatarId() == avatar_notes->target_id) + { + getChild<LLUICtrl>("notes_edit")->setValue(avatar_notes->notes); + getChildView("notes edit")->setEnabled(true); + + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + } } } -////////////////////////////////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// LLPanelAvatarProfile() -//----------------------------------------------------------------------------- -////////////////////////////////////////////////////////////////////////// -LLPanelAvatarProfile::LLPanelAvatarProfile(const LLUUID& avatar_id /* = LLUUID::null */) - : LLPanelProfileTab(avatar_id), mUpdated(false), mEditMode(false), mStatusCombobox(NULL), mStatusMessage(NULL) +void LLPanelAvatarNotes::resetData() { - updateData(); + getChild<LLUICtrl>("notes_edit")->setValue(LLStringUtil::null); + // Default value is TRUE + getChild<LLUICtrl>("status_check")->setValue(TRUE); } -LLPanelAvatarProfile::LLPanelAvatarProfile(const Params& params ) - : LLPanelProfileTab(params), mUpdated(false), mEditMode(false), mStatusCombobox(NULL), mStatusMessage(NULL) +void LLPanelAvatarNotes::resetControls() { + //Disable "Add Friend" button for friends. + getChildView("add_friend")->setEnabled(TRUE); + + enableCheckboxes(false); } -LLPanelAvatarProfile::~LLPanelAvatarProfile() +void LLPanelAvatarNotes::onAddFriendButtonClick() { - if(getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } + LLAvatarActions::requestFriendshipDialog(getAvatarId()); } -void* LLPanelAvatarProfile::create(void* data /* = NULL */) +void LLPanelAvatarNotes::onIMButtonClick() { - LLSD* id = NULL; - if(data) - { - id = static_cast<LLSD*>(data); - return new LLPanelAvatarProfile(LLUUID(id->asUUID())); - } - return new LLPanelAvatarProfile(); + LLAvatarActions::startIM(getAvatarId()); } -void LLPanelAvatarProfile::updateData() +void LLPanelAvatarNotes::onTeleportButtonClick() { - if (getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_PROPERTIES); - LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_GROUPS); - } + LLAvatarActions::offerTeleport(getAvatarId()); } -void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType type) +void LLPanelAvatarNotes::onCallButtonClick() { - if(APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if(avatar_data && getAvatarId() == avatar_data->avatar_id) - { - childSetValue("register_date", avatar_data->born_on); - childSetValue("sl_description_edit", avatar_data->about_text); - childSetValue("fl_description_edit",avatar_data->fl_about_text); - childSetValue("2nd_life_pic", avatar_data->image_id); - childSetValue("1st_life_pic", avatar_data->fl_image_id); - childSetValue("homepage_edit", avatar_data->profile_url); - - if (!isEditMode()) - { - setCaptionText(avatar_data); - } - childSetValue("show_in_search_checkbox", (BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); - - if (avatar_data->partner_id.notNull()) - { - std::string first, last; - BOOL found = gCacheName->getName(avatar_data->partner_id, first, last); - if (found) - { - childSetTextArg("partner_text", "[FIRST]", first); - childSetTextArg("partner_text", "[LAST]", last); - } - } - //http://secondlife.com/partner - - bool online = avatar_data->flags & AVATAR_ONLINE; - if(is_agent_friend(avatar_data->avatar_id)) - { - // Online status NO could be because they are hidden - // If they are a friend, we may know the truth! - online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id); - } - childSetValue("online_status", online ? - "Online" : "Offline"); - childSetColor("online_status", online ? - LLColor4::green : LLColor4::red); + LLAvatarActions::startCall(getAvatarId()); +} - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - if (isOwnProfile() && NULL != mStatusCombobox) +void LLPanelAvatarNotes::onShareButtonClick() +{ + //*TODO not implemented. +} + +void LLPanelAvatarNotes::enableCheckboxes(bool enable) +{ + getChildView("status_check")->setEnabled(enable); + getChildView("map_check")->setEnabled(enable); + getChildView("objects_check")->setEnabled(enable); +} + +LLPanelAvatarNotes::~LLPanelAvatarNotes() +{ + if(getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + if(LLVoiceClient::instanceExists()) { - std::string status; - if (gAgent.getAFK()) - { - status = "away"; - } - else if (gAgent.getBusy()) - { - status = "busy"; - } - else - { - status = "online"; - } - mStatusCombobox->setValue(status); + LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); } } - else if(APT_GROUPS == type) +} + +// virtual, called by LLAvatarTracker +void LLPanelAvatarNotes::changed(U32 mask) +{ + getChildView("teleport")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(getAvatarId())); + + // update rights to avoid have checkboxes enabled when friendship is terminated. EXT-4947. + fillRightsData(); +} + +// virtual +void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) { - LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); - if(avatar_groups) - { - std::string groups; - LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); - for(; avatar_groups->group_list.end() != it; ++it) - { - LLAvatarGroups::LLGroupData group_data = *it; - groups += group_data.group_name; - groups += ", "; - } - childSetValue("sl_groups",groups); - } + return; } + + getChildView("call")->setEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()); } -void LLPanelAvatarProfile::clear() -{ - clearControls(); -} - -void LLPanelAvatarProfile::clearControls() -{ - childSetValue("2nd_life_pic",LLUUID::null); - childSetValue("1st_life_pic",LLUUID::null); - childSetValue("online_status",LLStringUtil::null); - childSetValue("status_message",LLStringUtil::null); - childSetValue("sl_description_edit",LLStringUtil::null); - childSetValue("fl_description_edit",LLStringUtil::null); - childSetValue("sl_groups",LLStringUtil::null); - childSetValue("homepage_edit",LLStringUtil::null); - childSetValue("register_date",LLStringUtil::null); - childSetValue("acc_status_text",LLStringUtil::null); - childSetTextArg("partner_text", "[FIRST]", LLStringUtil::null); - childSetTextArg("partner_text", "[LAST]", LLStringUtil::null); -} - -void LLPanelAvatarProfile::setCaptionText(const LLAvatarData* avatar_data) -{ - std::string caption_text = avatar_data->caption_text; - if(caption_text.empty()) - { - LLStringUtil::format_map_t args; - caption_text = getString("CaptionTextAcctInfo"); - BOOL transacted = (avatar_data->flags & AVATAR_TRANSACTED); - BOOL identified = (avatar_data->flags & AVATAR_IDENTIFIED); - BOOL age_verified = (avatar_data->flags & AVATAR_AGEVERIFIED); // Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations - - const char* ACCT_TYPE[] = { - "AcctTypeResident", - "AcctTypeTrial", - "AcctTypeCharterMember", - "AcctTypeEmployee" - }; - U8 caption_index = llclamp(avatar_data->caption_index, (U8)0, (U8)(LL_ARRAY_SIZE(ACCT_TYPE)-1)); - args["[ACCTTYPE]"] = getString(ACCT_TYPE[caption_index]); - - std::string payment_text = " "; - const S32 DEFAULT_CAPTION_LINDEN_INDEX = 3; - if(caption_index != DEFAULT_CAPTION_LINDEN_INDEX) - { - if(transacted) - { - payment_text = "PaymentInfoUsed"; - } - else if (identified) - { - payment_text = "PaymentInfoOnFile"; - } - else - { - payment_text = "NoPaymentInfoOnFile"; - } - args["[PAYMENTINFO]"] = getString(payment_text); - - std::string age_text = age_verified ? "AgeVerified" : "NotAgeVerified"; - // Do not display age verification status at this time - //args["[[AGEVERIFICATION]]"] = mPanelSecondLife->getString(age_text); - args["[AGEVERIFICATION]"] = " "; - } - else +void LLPanelAvatarNotes::setAvatarId(const LLUUID& id) +{ + if(id.notNull()) + { + if(getAvatarId().notNull()) { - args["[PAYMENTINFO]"] = " "; - args["[AGEVERIFICATION]"] = " "; + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); } - LLStringUtil::format(caption_text, args); + LLPanelProfileTab::setAvatarId(id); + LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); } - - childSetValue("acc_status_text", caption_text); } -void LLPanelAvatarProfile::onAddFriendButtonClick() +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelProfileTab::LLPanelProfileTab() +: LLPanel() +, mAvatarId(LLUUID::null) { - onAddFriend(); } -void LLPanelAvatarProfile::onIMButtonClick() +LLPanelProfileTab::~LLPanelProfileTab() { - onIM(); + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + } } -void LLPanelAvatarProfile::onTeleportButtonClick() +void LLPanelProfileTab::setAvatarId(const LLUUID& id) { - onTeleport(); + if(id.notNull()) + { + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this); + } + mAvatarId = id; + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this); + } } -void LLPanelAvatarProfile::onCallButtonClick() +void LLPanelProfileTab::onOpen(const LLSD& key) { + // Don't reset panel if we are opening it for same avatar. + if(getAvatarId() != key.asUUID()) + { + resetControls(); + resetData(); + + scrollToTop(); + } + // Update data even if we are viewing same avatar profile as some data might been changed. + setAvatarId(key.asUUID()); + updateData(); + updateButtons(); } -void LLPanelAvatarProfile::onShareButtonClick() +void LLPanelProfileTab::scrollToTop() { + LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll"); + if (scrollContainer) + scrollContainer->goToTop(); +} +void LLPanelProfileTab::onMapButtonClick() +{ + LLAvatarActions::showOnMap(getAvatarId()); } -/*virtual*/ BOOL LLPanelAvatarProfile::postBuild(void) +void LLPanelProfileTab::updateButtons() { - mStatusCombobox = getChild<LLComboBox>("status_combo", TRUE, FALSE); - if (NULL != mStatusCombobox) + bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); + + if(LLAvatarActions::isFriend(getAvatarId())) { - mStatusCombobox->setCommitCallback(boost::bind(&LLPanelAvatarProfile::onStatusChanged, this)); + getChildView("teleport")->setEnabled(is_buddy_online); } - mStatusMessage = getChild<LLLineEditor>("status_me_message_edit", TRUE, FALSE); - if (NULL != mStatusMessage) + else { - mStatusMessage->setCommitCallback(boost::bind(&LLPanelAvatarProfile::onStatusMessageChanged, this)); + getChildView("teleport")->setEnabled(true); } + bool enable_map_btn = (is_buddy_online && + is_agent_mappable(getAvatarId())) + || gAgent.isGodlike(); + getChildView("show_on_map_btn")->setEnabled(enable_map_btn); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +bool enable_god() +{ + return gAgent.isGodlike(); +} + +LLPanelAvatarProfile::LLPanelAvatarProfile() +: LLPanelProfileTab() +{ +} + +BOOL LLPanelAvatarProfile::postBuild() +{ childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL); childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL); + childSetCommitCallback("overflow_btn", boost::bind(&LLPanelAvatarProfile::onOverflowButtonClicked, this), NULL); childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL); + childSetCommitCallback("show_on_map_btn", (boost::bind( + &LLPanelAvatarProfile::onMapButtonClick, this)), NULL); - LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic",TRUE,FALSE); - if(pic) - { - pic->setFallbackImageName("default_land_picture.j2c"); - } - pic = getChild<LLTextureCtrl>("1st_life_pic",TRUE,FALSE); - if(pic) - { - pic->setFallbackImageName("default_land_picture.j2c"); - } + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("Profile.ShowOnMap", boost::bind(&LLPanelAvatarProfile::onMapButtonClick, this)); + registrar.add("Profile.Pay", boost::bind(&LLPanelAvatarProfile::pay, this)); + registrar.add("Profile.Share", boost::bind(&LLPanelAvatarProfile::share, this)); + registrar.add("Profile.BlockUnblock", boost::bind(&LLPanelAvatarProfile::toggleBlock, this)); + registrar.add("Profile.Kick", boost::bind(&LLPanelAvatarProfile::kick, this)); + registrar.add("Profile.Freeze", boost::bind(&LLPanelAvatarProfile::freeze, this)); + registrar.add("Profile.Unfreeze", boost::bind(&LLPanelAvatarProfile::unfreeze, this)); + registrar.add("Profile.CSR", boost::bind(&LLPanelAvatarProfile::csr, this)); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; + enable.add("Profile.EnableShowOnMap", boost::bind(&LLPanelAvatarProfile::enableShowOnMap, this)); + enable.add("Profile.EnableGod", boost::bind(&enable_god)); + enable.add("Profile.EnableBlock", boost::bind(&LLPanelAvatarProfile::enableBlock, this)); + enable.add("Profile.EnableUnblock", boost::bind(&LLPanelAvatarProfile::enableUnblock, this)); + + mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - clearControls(); - updateChildrenList(); + LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); + + resetControls(); + resetData(); return TRUE; } + void LLPanelAvatarProfile::onOpen(const LLSD& key) { - setAvatarId(key); - scrollToTop(); - updateChildrenList(); - updateData(); + LLPanelProfileTab::onOpen(key); + + mGroups.clear(); + + //Disable "Add Friend" button for friends. + getChildView("add_friend")->setEnabled(!LLAvatarActions::isFriend(getAvatarId())); } -void LLPanelAvatarProfile::scrollToTop() +void LLPanelAvatarProfile::updateData() { - LLScrollContainer* scrollContainer = getChild<LLScrollContainer>("profile_scroll", FALSE, FALSE); - if (NULL != scrollContainer) + if (getAvatarId().notNull()) { - scrollContainer->goToTop(); + LLAvatarPropertiesProcessor::getInstance()-> + sendAvatarPropertiesRequest(getAvatarId()); + LLAvatarPropertiesProcessor::getInstance()-> + sendAvatarGroupsRequest(getAvatarId()); } } -void LLPanelAvatarProfile::updateChildrenList() +void LLPanelAvatarProfile::resetControls() +{ + getChildView("status_panel")->setVisible( true); + getChildView("profile_buttons_panel")->setVisible( true); + getChildView("title_groups_text")->setVisible( true); + getChildView("sl_groups")->setVisible( true); + getChildView("add_friend")->setEnabled(true); + + getChildView("status_me_panel")->setVisible( false); + getChildView("profile_me_buttons_panel")->setVisible( false); + getChildView("account_actions_panel")->setVisible( false); +} + +void LLPanelAvatarProfile::resetData() { - if (mUpdated || isEditMode()) + mGroups.clear(); + getChild<LLUICtrl>("2nd_life_pic")->setValue(LLUUID::null); + getChild<LLUICtrl>("real_world_pic")->setValue(LLUUID::null); + getChild<LLUICtrl>("online_status")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("status_message")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("sl_description_edit")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("fl_description_edit")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("sl_groups")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("homepage_edit")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("register_date")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("acc_status_text")->setValue(LLStringUtil::null); + getChild<LLUICtrl>("partner_text")->setTextArg("[FIRST]", LLStringUtil::null); + getChild<LLUICtrl>("partner_text")->setTextArg("[LAST]", LLStringUtil::null); +} + +void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType type) +{ + if(APT_PROPERTIES == type) { - return; + const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); + if(avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProfileProperties(avatar_data); + } } - switch (mProfileType) - { - case PT_OWN: - childSetVisible("status_panel",FALSE); - childSetVisible("profile_buttons_panel",FALSE); - childSetVisible("title_groups_text",FALSE); - childSetVisible("sl_groups",FALSE); - mUpdated = true; - childSetVisible("status_me_panel",TRUE); - childSetVisible("profile_me_buttons_panel",TRUE); - - break; - case PT_OTHER: - childSetVisible("status_me_panel",FALSE); - childSetVisible("profile_me_buttons_panel",FALSE); - - childSetVisible("status_panel",TRUE); - childSetVisible("profile_buttons_panel",TRUE); - childSetVisible("title_groups_text",TRUE); - childSetVisible("sl_groups",TRUE); - - // account actions - childSetVisible("account_actions_panel", FALSE); - childSetVisible("partner_edit_link", FALSE); - - mUpdated = true; - break; - case PT_UNKNOWN: break;//do nothing - default: - llassert(false); + else if(APT_GROUPS == type) + { + LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); + if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) + { + processGroupProperties(avatar_groups); + } } } -void LLPanelAvatarProfile::onStatusChanged() + +void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_data) { - LLSD::String status = mStatusCombobox->getValue().asString(); - - if ("online" == status) + fillCommonData(avatar_data); + + fillPartnerData(avatar_data); + + fillAccountStatus(avatar_data); +} + +void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_groups) +{ + // *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) { - gAgent.clearAFK(); - gAgent.clearBusy(); + LLAvatarGroups::LLGroupData group_data = *it; + mGroups[group_data.group_name] = group_data.group_id; } - else if ("away" == status) + + // Creating string, containing group list + std::string groups = ""; + for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it) { - gAgent.clearBusy(); - gAgent.setAFK(); + if (it != mGroups.begin()) + groups += ", "; + + std::string group_name = LLURI::escape(it->first); + std::string group_url= it->second.notNull() + ? "[secondlife:///app/group/" + it->second.asString() + "/about " + group_name + "]" + : getString("no_group_text"); + + groups += group_url; } - else if ("busy" == status) + + getChild<LLUICtrl>("sl_groups")->setValue(groups); +} + +void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) +{ + //remove avatar id from cache to get fresh info + LLAvatarIconIDCache::getInstance()->remove(avatar_data->avatar_id); + + LLStringUtil::format_map_t args; { - gAgent.clearAFK(); - gAgent.setBusy(); - LLNotifications::instance().add("BusyModeSet"); + 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); + getChild<LLUICtrl>("register_date")->setValue(register_date ); + getChild<LLUICtrl>("sl_description_edit")->setValue(avatar_data->about_text); + getChild<LLUICtrl>("fl_description_edit")->setValue(avatar_data->fl_about_text); + getChild<LLUICtrl>("2nd_life_pic")->setValue(avatar_data->image_id); + getChild<LLUICtrl>("real_world_pic")->setValue(avatar_data->fl_image_id); + getChild<LLUICtrl>("homepage_edit")->setValue(avatar_data->profile_url); + + // Hide home page textbox if no page was set to fix "homepage URL appears clickable without URL - EXT-4734" + getChildView("homepage_edit")->setVisible( !avatar_data->profile_url.empty()); +} + +void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data) +{ + LLNameBox* name_box = getChild<LLNameBox>("partner_text"); + if (avatar_data->partner_id.notNull()) + { + name_box->setNameID(avatar_data->partner_id, FALSE); } else { + name_box->setNameID(LLUUID::null, FALSE); + name_box->setText(getString("no_partner_text")); } +} +void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data) +{ + LLStringUtil::format_map_t args; + args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data); + args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); + // *NOTE: AVATAR_AGEVERIFIED not currently getting set in + // dataserver/lldataavatar.cpp for privacy considerations + args["[AGEVERIFICATION]"] = ""; + std::string caption_text = getString("CaptionTextAcctInfo", args); + getChild<LLUICtrl>("acc_status_text")->setValue(caption_text); } -void LLPanelAvatarProfile::onStatusMessageChanged() +void LLPanelAvatarProfile::pay() { - updateData(); + LLAvatarActions::pay(getAvatarId()); } +void LLPanelAvatarProfile::share() +{ + LLAvatarActions::share(getAvatarId()); +} -//----------------------------------------------------------------------------- -// LLPanelAvatarNotes() -//----------------------------------------------------------------------------- -LLPanelAvatarNotes::LLPanelAvatarNotes(const LLUUID& id /* = LLUUID::null */) -:LLPanelProfileTab(id) +void LLPanelAvatarProfile::toggleBlock() { - updateData(); + LLAvatarActions::toggleBlock(getAvatarId()); } -LLPanelAvatarNotes::LLPanelAvatarNotes(const Params& params) -: LLPanelProfileTab(params) +bool LLPanelAvatarProfile::enableShowOnMap() { + bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); + bool enable_map_btn = (is_buddy_online && is_agent_mappable(getAvatarId())) + || gAgent.isGodlike(); + return enable_map_btn; } -LLPanelAvatarNotes::~LLPanelAvatarNotes() +bool LLPanelAvatarProfile::enableBlock() { - if(getAvatarId().notNull()) + return LLAvatarActions::canBlock(getAvatarId()) && !LLAvatarActions::isBlocked(getAvatarId()); +} + +bool LLPanelAvatarProfile::enableUnblock() +{ + return LLAvatarActions::isBlocked(getAvatarId()); +} + +void LLPanelAvatarProfile::kick() +{ + LLAvatarActions::kick(getAvatarId()); +} + +void LLPanelAvatarProfile::freeze() +{ + LLAvatarActions::freeze(getAvatarId()); +} + +void LLPanelAvatarProfile::unfreeze() +{ + LLAvatarActions::unfreeze(getAvatarId()); +} + +void LLPanelAvatarProfile::csr() +{ + std::string name; + gCacheName->getFullName(getAvatarId(), name); + LLAvatarActions::csr(getAvatarId(), name); +} + +void LLPanelAvatarProfile::onAddFriendButtonClick() +{ + LLAvatarActions::requestFriendshipDialog(getAvatarId()); +} + +void LLPanelAvatarProfile::onIMButtonClick() +{ + LLAvatarActions::startIM(getAvatarId()); +} + +void LLPanelAvatarProfile::onTeleportButtonClick() +{ + LLAvatarActions::offerTeleport(getAvatarId()); +} + +void LLPanelAvatarProfile::onCallButtonClick() +{ + LLAvatarActions::startCall(getAvatarId()); +} + +void LLPanelAvatarProfile::onShareButtonClick() +{ + //*TODO not implemented +} + +void LLPanelAvatarProfile::onOverflowButtonClicked() +{ + if (!mProfileMenu->toggleVisibility()) + return; + + LLView* btn = getChild<LLView>("overflow_btn"); + + if (mProfileMenu->getButtonRect().isEmpty()) { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + mProfileMenu->setButtonRect(btn); } + mProfileMenu->updateParent(LLMenuGL::sMenuContainer); + + LLRect rect = btn->getRect(); + LLMenuGL::showPopup(this, mProfileMenu, rect.mRight, rect.mTop); } -void* LLPanelAvatarNotes::create(void* data) +LLPanelAvatarProfile::~LLPanelAvatarProfile() { - if(data) + if(getAvatarId().notNull()) { - LLSD* id = static_cast<LLSD*>(data); - return new LLPanelAvatarNotes(LLUUID(id->asUUID())); + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); + } } - return new LLPanelAvatarNotes(); } -void LLPanelAvatarNotes::updateData() +// virtual, called by LLAvatarTracker +void LLPanelAvatarProfile::changed(U32 mask) { - LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_NOTES); + getChildView("teleport")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(getAvatarId())); +} - const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - if(relation) +// virtual +void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) { - childSetEnabled("status_check",TRUE); - childSetEnabled("map_check",TRUE); - childSetEnabled("objects_check",TRUE); + return; + } - S32 rights = relation->getRightsGrantedTo(); + getChildView("call")->setEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()); +} - childSetValue("status_check",LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); - childSetValue("map_check",LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); - childSetValue("objects_check",LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); +void LLPanelAvatarProfile::setAvatarId(const LLUUID& id) +{ + if(id.notNull()) + { + if(getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + LLPanelProfileTab::setAvatarId(id); + LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); } } -BOOL LLPanelAvatarNotes::postBuild() +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelMyProfile::LLPanelMyProfile() +: LLPanelAvatarProfile() { - childSetCommitCallback("status_check",boost::bind(&LLPanelAvatarNotes::onCommitRights,this),NULL); - childSetCommitCallback("map_check",boost::bind(&LLPanelAvatarNotes::onCommitRights,this),NULL); - childSetCommitCallback("objects_check",boost::bind(&LLPanelAvatarNotes::onCommitRights,this),NULL); +} - childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriend,this)),NULL); - childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIM,this)),NULL); -// childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this))); - childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleport,this)),NULL); -// childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this))); +BOOL LLPanelMyProfile::postBuild() +{ + LLPanelAvatarProfile::postBuild(); - LLTextEditor* te = getChild<LLTextEditor>("notes_edit",TRUE,FALSE); - if(te) - { - te->setCommitCallback(boost::bind(&LLPanelAvatarNotes::onCommitNotes,this)); - te->setCommitOnFocusLost(TRUE); - } + childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelMyProfile::onStatusMessageChanged, this), NULL); + + resetControls(); + resetData(); return TRUE; } -void LLPanelAvatarNotes::onCommitNotes() +void LLPanelMyProfile::onOpen(const LLSD& key) { - std::string notes = childGetValue("notes_edit").asString(); - LLAvatarPropertiesProcessor::getInstance()-> sendNotes(getAvatarId(),notes); + LLPanelProfileTab::onOpen(key); } -void LLPanelAvatarNotes::onCommitRights() +void LLPanelMyProfile::processProfileProperties(const LLAvatarData* avatar_data) { - S32 rights = 0; + fillCommonData(avatar_data); - if(childGetValue("status_check").asBoolean()) - rights |= LLRelationship::GRANT_ONLINE_STATUS; - if(childGetValue("map_check").asBoolean()) - rights |= LLRelationship::GRANT_MAP_LOCATION; - if(childGetValue("objects_check").asBoolean()) - rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + fillPartnerData(avatar_data); - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(),rights); + fillAccountStatus(avatar_data); } -void LLPanelAvatarNotes::clear() +void LLPanelMyProfile::resetControls() { - childSetValue("notes_edit",LLStringUtil::null); - - childSetEnabled("status_check",FALSE); - childSetEnabled("map_check",FALSE); - childSetEnabled("objects_check",FALSE); + getChildView("status_panel")->setVisible( false); + getChildView("profile_buttons_panel")->setVisible( false); + getChildView("title_groups_text")->setVisible( false); + getChildView("sl_groups")->setVisible( false); + getChildView("status_me_panel")->setVisible( true); + getChildView("profile_me_buttons_panel")->setVisible( true); } -void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type) -{ - if(APT_NOTES == type) - { - LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); - if(avatar_notes && getAvatarId() == avatar_notes->target_id) - { - childSetValue("notes_edit",avatar_notes->notes); - childSetEnabled("notes edit", true); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - } +void LLPanelMyProfile::onStatusMessageChanged() +{ + updateData(); } |