/** * @file llpanelprofile.h * @brief Profile panel * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * 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 * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef LL_LLPANELPROFILE_H #define LL_LLPANELPROFILE_H #include "llavatarpropertiesprocessor.h" #include "llcallingcard.h" #include "llfloater.h" #include "llpanel.h" #include "llpanelavatar.h" #include "llmediactrl.h" #include "llvoiceclient.h" // class LLPanelProfileClassifieds; // class LLTabContainer; // class LLPanelProfileSecondLife; // class LLPanelProfileWeb; // class LLPanelProfilePicks; // class LLPanelProfileFirstLife; // class LLPanelProfileNotes; class LLAvatarName; class LLButton; class LLCheckBoxCtrl; class LLComboBox; class LLIconCtrl; class LLTabContainer; class LLTextBox; class LLTextureCtrl; class LLMediaCtrl; class LLGroupList; class LLTextBase; class LLMenuButton; class LLLineEditor; class LLTextEditor; class LLThumbnailCtrl; class LLPanelProfileClassifieds; class LLPanelProfilePicks; class LLViewerFetchedTexture; /** * Panel for displaying Avatar's second life related info. */ class LLPanelProfileSecondLife : public LLPanelProfileTab , public LLFriendObserver , public LLVoiceClientStatusObserver { public: LLPanelProfileSecondLife(); /*virtual*/ ~LLPanelProfileSecondLife(); void onOpen(const LLSD& key) override; /** * LLFriendObserver trigger */ void changed(U32 mask) override; // Implements LLVoiceClientStatusObserver::onChange() to enable the call // button when voice is available void onChange(EStatusType status, const LLSD& channelInfo, bool proximal) override; void setAvatarId(const LLUUID& avatar_id) override; BOOL postBuild() override; void resetData() override; /** * Sends update data request to server. */ void updateData() override; void refreshName(); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); void setProfileImageUploading(bool loading); void setProfileImageUploaded(const LLUUID &image_asset_id); bool hasUnsavedChanges() override; void commitUnsavedChanges() override; friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); protected: /** * Process profile related data received from server. */ void processProfileProperties(const LLAvatarData* avatar_data); /** * Processes group related data received from server. */ void processGroupProperties(const LLAvatarGroups* avatar_groups); /** * Fills common for Avatar profile and My Profile fields. */ void fillCommonData(const LLAvatarData* avatar_data); /** * Fills partner data. */ void fillPartnerData(const LLAvatarData* avatar_data); /** * Fills account status. */ void fillAccountStatus(const LLAvatarData* avatar_data); /** * Sets permissions specific icon */ void fillRightsData(); /** * Fills user name, display name, age. */ void fillAgeData(const LLDate &born_on); void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep); static void onImageLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); /** * Displays avatar's online status if possible. * * Requirements from EXT-3880: * For friends: * - Online when online and privacy settings allow to show * - Offline when offline and privacy settings allow to show * - Else: nothing * For other avatars: * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online" * - Else: Offline */ void updateOnlineStatus(); void processOnlineStatus(bool is_friend, bool show_online, bool online); private: void setLoaded() override; void onCommitMenu(const LLSD& userdata); bool onEnableMenu(const LLSD& userdata); bool onCheckMenu(const LLSD& userdata); void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name); void setDescriptionText(const std::string &text); void onSetDescriptionDirty(); void onShowInSearchCallback(); void onSaveDescriptionChanges(); void onDiscardDescriptionChanges(); void onShowAgentPermissionsDialog(); void onShowAgentProfileTexture(); void onShowTexturePicker(); void onCommitProfileImage(const LLUUID& id); private: typedef std::map group_map_t; group_map_t mGroups; void openGroupProfile(); LLGroupList* mGroupList; LLComboBox* mShowInSearchCombo; LLThumbnailCtrl* mSecondLifePic; LLPanel* mSecondLifePicLayout; LLTextEditor* mDescriptionEdit; LLMenuButton* mAgentActionMenuButton; LLButton* mSaveDescriptionChanges; LLButton* mDiscardDescriptionChanges; LLIconCtrl* mCanSeeOnlineIcon; LLIconCtrl* mCantSeeOnlineIcon; LLIconCtrl* mCanSeeOnMapIcon; LLIconCtrl* mCantSeeOnMapIcon; LLIconCtrl* mCanEditObjectsIcon; LLIconCtrl* mCantEditObjectsIcon; LLHandle mFloaterPermissionsHandle; LLHandle mFloaterProfileTextureHandle; LLHandle mFloaterTexturePickerHandle; bool mHasUnsavedDescriptionChanges; bool mVoiceStatus; bool mWaitingForImageUpload; bool mAllowPublish; std::string mDescriptionText; LLUUID mImageId; boost::signals2::connection mAvatarNameCacheConnection; }; /** * Panel for displaying Avatar's web profile and home page. */ class LLPanelProfileWeb : public LLPanelProfileTab , public LLViewerMediaObserver { public: LLPanelProfileWeb(); /*virtual*/ ~LLPanelProfileWeb(); void onOpen(const LLSD& key) override; BOOL postBuild() override; void resetData() override; /** * Loads web profile. */ void updateData() override; void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); protected: void onCommitLoad(LLUICtrl* ctrl); private: std::string mURLHome; std::string mURLWebProfile; LLMediaCtrl* mWebBrowser; LLFrameTimer mPerformanceTimer; bool mFirstNavigate; boost::signals2::connection mAvatarNameCacheConnection; }; /** * Panel for displaying Avatar's first life related info. */ class LLPanelProfileFirstLife : public LLPanelProfileTab { public: LLPanelProfileFirstLife(); /*virtual*/ ~LLPanelProfileFirstLife(); void onOpen(const LLSD& key) override; BOOL postBuild() override; void processProperties(const LLAvatarData* avatar_data); void resetData() override; void setProfileImageUploading(bool loading); void setProfileImageUploaded(const LLUUID &image_asset_id); bool hasUnsavedChanges() override { return mHasUnsavedChanges; } void commitUnsavedChanges() override; friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); protected: void setLoaded() override; void onUploadPhoto(); void onChangePhoto(); void onRemovePhoto(); void onCommitPhoto(const LLUUID& id); void setDescriptionText(const std::string &text); void onSetDescriptionDirty(); void onSaveDescriptionChanges(); void onDiscardDescriptionChanges(); LLTextEditor* mDescriptionEdit; LLThumbnailCtrl* mPicture; LLButton* mUploadPhoto; LLButton* mChangePhoto; LLButton* mRemovePhoto; LLButton* mSaveChanges; LLButton* mDiscardChanges; LLHandle mFloaterTexturePickerHandle; std::string mCurrentDescription; LLUUID mImageId; bool mHasUnsavedChanges; }; /** * Panel for displaying Avatar's notes and modifying friend's rights. */ class LLPanelProfileNotes : public LLPanelProfileTab { public: LLPanelProfileNotes(); /*virtual*/ ~LLPanelProfileNotes(); void setAvatarId(const LLUUID& avatar_id) override; void onOpen(const LLSD& key) override; BOOL postBuild() override; void processProperties(LLAvatarNotes* avatar_notes); void resetData() override; void updateData() override; bool hasUnsavedChanges() override { return mHasUnsavedChanges; } void commitUnsavedChanges() override; protected: void setNotesText(const std::string &text); void onSetNotesDirty(); void onSaveNotesChanges(); void onDiscardNotesChanges(); LLTextEditor* mNotesEditor; LLButton* mSaveChanges; LLButton* mDiscardChanges; std::string mCurrentNotes; bool mHasUnsavedChanges; }; /** * Container panel for the profile tabs */ class LLPanelProfile : public LLPanelProfileTab { public: LLPanelProfile(); /*virtual*/ ~LLPanelProfile(); BOOL postBuild() override; void updateData() override; void refreshName(); void onOpen(const LLSD& key) override; void createPick(const LLPickData &data); void showPick(const LLUUID& pick_id = LLUUID::null); bool isPickTabSelected(); bool isNotesTabSelected(); bool hasUnsavedChanges() override; bool hasUnpublishedClassifieds(); void commitUnsavedChanges() override; void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false); void createClassified(); LLAvatarData getAvatarData() { return mAvatarData; }; friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); private: void onTabChange(); LLPanelProfileSecondLife* mPanelSecondlife; LLPanelProfileWeb* mPanelWeb; LLPanelProfilePicks* mPanelPicks; LLPanelProfileClassifieds* mPanelClassifieds; LLPanelProfileFirstLife* mPanelFirstlife; LLPanelProfileNotes* mPanelNotes; LLTabContainer* mTabContainer; // Todo: due to server taking minutes to update this needs a more long term storage // to reuse recently saved values if user opens floater again // Storage implementation depends onto how a cap will be implemented, if cap will be // enought to fully update LLAvatarPropertiesProcessor, then this storage can be // implemented there. LLAvatarData mAvatarData; }; #endif //LL_LLPANELPROFILE_H