diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-06-02 00:17:54 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-06-02 00:20:30 +0300 | 
| commit | 3efe64619b772ce8cab596d7e74de48dcc7f6c20 (patch) | |
| tree | b951db7f2784ab5af8301151b01cccff5a7bd0b0 /indra | |
| parent | d7459d87e0b7507b3452aa4effa4dc97e06e8551 (diff) | |
SL-15312 Confirm usaved changes dialog when closing floater
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llfloaterprofile.cpp | 59 | ||||
| -rw-r--r-- | indra/newview/llfloaterprofile.h | 7 | ||||
| -rw-r--r-- | indra/newview/llpanelavatar.h | 3 | ||||
| -rw-r--r-- | indra/newview/llpanelprofile.cpp | 101 | ||||
| -rw-r--r-- | indra/newview/llpanelprofile.h | 49 | ||||
| -rw-r--r-- | indra/newview/llpanelprofileclassifieds.cpp | 38 | ||||
| -rw-r--r-- | indra/newview/llpanelprofileclassifieds.h | 67 | ||||
| -rw-r--r-- | indra/newview/llpanelprofilepicks.cpp | 27 | ||||
| -rw-r--r-- | indra/newview/llpanelprofilepicks.h | 35 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 40 | 
10 files changed, 329 insertions, 97 deletions
diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp index 78920863e2..a4a9fe8410 100644 --- a/indra/newview/llfloaterprofile.cpp +++ b/indra/newview/llfloaterprofile.cpp @@ -28,9 +28,10 @@  #include "llfloaterprofile.h" +#include "llagent.h" //gAgent +#include "llnotificationsutil.h"  #include "llpanelavatar.h"  #include "llpanelprofile.h" -#include "llagent.h" //gAgent  static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; @@ -65,6 +66,62 @@ BOOL LLFloaterProfile::postBuild()      return TRUE;  } +void LLFloaterProfile::onClickCloseBtn(bool app_quitting) +{ +    if (!app_quitting) +    { +        if (mPanelProfile->hasUnpublishedClassifieds()) +        { +            LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(), +                boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false)); +        } +        else if (mPanelProfile->hasUnsavedChanges()) +        { +            LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(), +                boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true)); +        } +        else +        { +            closeFloater(); +        } +    } +    else +    { +        closeFloater(); +    } +} + +void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    if (can_save) +    { +        // savable content + +        if (option == 0) // Save +        { +            mPanelProfile->commitUnsavedChanges(); +            closeFloater(); +        } +        if (option == 1) // Discard +        { +            closeFloater(); +        } +        // else cancel +    } +    else +    { +        // classifieds + +        if (option == 0) // Ok +        { +            closeFloater(); +        } +        // else cancel +    } + +} +  void LLFloaterProfile::createPick(const LLPickData &data)  {      mPanelProfile->createPick(data); diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h index 1d0450be9c..36023077d3 100644 --- a/indra/newview/llfloaterprofile.h +++ b/indra/newview/llfloaterprofile.h @@ -40,8 +40,11 @@ public:      LLFloaterProfile(const LLSD& key);      virtual ~LLFloaterProfile(); -    /*virtual*/ void onOpen(const LLSD& key); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override; + +    void onOpen(const LLSD& key) override; +    void onClickCloseBtn(bool app_quitting = false) override; +    void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);      void createPick(const LLPickData &data);      void showPick(const LLUUID& pick_id = LLUUID::null); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 98fd97f00a..f182660c8e 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -140,6 +140,9 @@ public:      bool getStarted() { return mLoadingState != PROFILE_INIT; }      bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; } +    virtual bool hasUnsavedChanges() { return false; } +    virtual void commitUnsavedChanges() {} +  private:      LLUUID  mAvatarId; 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<LLView>    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<LLButton>("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<LLFloaterProfilePermissions*>(floater); +        if (perm && perm->hasUnsavedChanges()) +        { +            return true; +        } +    } +    // if floater +    return mHasUnsavedDescriptionChanges; +} + +void LLPanelProfileSecondLife::commitUnsavedChanges() +{ +    LLFloater *floater = mFloaterPermissionsHandle.get(); +    if (floater) +    { +        LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(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<LLPanel>(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<LLTextEditor>("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()) diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 4985ec0015..5b30a6c536 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -75,27 +75,27 @@ public:  	LLPanelProfileSecondLife();  	/*virtual*/ ~LLPanelProfileSecondLife(); -	/*virtual*/ void onOpen(const LLSD& key); +	void onOpen(const LLSD& key) override;  	/**  	 * LLFriendObserver trigger  	 */ -	virtual void changed(U32 mask); +	void changed(U32 mask) override;  	// Implements LLVoiceClientStatusObserver::onChange() to enable the call  	// button when voice is available -	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); +	void onChange(EStatusType status, const std::string &channelURI, bool proximal) override; -	/*virtual*/ void setAvatarId(const LLUUID& avatar_id); +	void setAvatarId(const LLUUID& avatar_id) override; -	/*virtual*/ BOOL postBuild(); +	BOOL postBuild() override;  	void resetData();  	/**  	 * Sends update data request to server.  	 */ -	/*virtual*/ void updateData(); +	void updateData() override;  	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); @@ -103,6 +103,9 @@ public:      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: @@ -171,7 +174,7 @@ protected:  	void processOnlineStatus(bool is_friend, bool show_online, bool online);  private: -    /*virtual*/ void setLoaded(); +    void setLoaded() override;      void onCommitMenu(const LLSD& userdata);      bool onEnableMenu(const LLSD& userdata);      bool onCheckMenu(const LLSD& userdata); @@ -208,6 +211,7 @@ private:      LLHandle<LLFloater>	mFloaterPermissionsHandle; +    bool				mHasUnsavedDescriptionChanges;  	bool				mVoiceStatus;      bool				mWaitingForImageUpload;      bool				mAllowPublish; @@ -270,9 +274,9 @@ public:  	LLPanelProfileFirstLife();  	/*virtual*/ ~LLPanelProfileFirstLife(); -	/*virtual*/ void onOpen(const LLSD& key); +	void onOpen(const LLSD& key) override; -	/*virtual*/ BOOL postBuild(); +	BOOL postBuild() override;      void processProperties(const LLAvatarData* avatar_data); @@ -281,10 +285,13 @@ public:      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: -	/*virtual*/ void setLoaded(); +	void setLoaded() override;      void onChangePhoto();      void onRemovePhoto(); @@ -301,6 +308,7 @@ protected:      LLButton* mDiscardChanges;  	std::string		mCurrentDescription; +    bool			mHasUnsavedChanges;  };  /** @@ -313,17 +321,20 @@ public:  	LLPanelProfileNotes();  	/*virtual*/ ~LLPanelProfileNotes(); -	virtual void setAvatarId(const LLUUID& avatar_id); +	void setAvatarId(const LLUUID& avatar_id) override; -	/*virtual*/ void onOpen(const LLSD& key); +	void onOpen(const LLSD& key) override; -	/*virtual*/ BOOL postBuild(); +	BOOL postBuild() override;      void processProperties(LLAvatarNotes* avatar_notes);  	void resetData(); -	/*virtual*/ void updateData(); +	void updateData() override; + +    bool hasUnsavedChanges() override { return mHasUnsavedChanges; } +    void commitUnsavedChanges() override;  protected:      void setNotesText(const std::string &text); @@ -336,6 +347,7 @@ protected:      LLButton* mDiscardChanges;      std::string		mCurrentNotes; +    bool			mHasUnsavedChanges;  }; @@ -349,16 +361,19 @@ public:      LLPanelProfile();      /*virtual*/ ~LLPanelProfile(); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override; -    /*virtual*/ void updateData(); +    void updateData() override; -    /*virtual*/ void onOpen(const LLSD& key); +    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); diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp index 91243169a9..a961422dfe 100644 --- a/indra/newview/llpanelprofileclassifieds.cpp +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -287,11 +287,11 @@ void LLPanelProfileClassifieds::onClickDelete()      {          LLUUID classified_id = classified_panel->getClassifiedId();          LLSD args; -        args["PICK"] = classified_panel->getClassifiedName(); +        args["CLASSIFIED"] = classified_panel->getClassifiedName();          LLSD payload;          payload["classified_id"] = classified_id;          payload["tab_idx"] = mTabContainer->getCurrentPanelIndex(); -        LLNotificationsUtil::add("DeleteAvatarPick", args, payload, +        LLNotificationsUtil::add("ProfileDeleteClassified", args, payload,              boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2));      }  } @@ -417,6 +417,32 @@ void LLPanelProfileClassifieds::updateData()      }  } +bool LLPanelProfileClassifieds::hasNewClassifieds() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (classified_panel && classified_panel->isNew()) +        { +            return true; +        } +    } +    return false; +} + +bool LLPanelProfileClassifieds::hasUnsavedChanges() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (classified_panel && classified_panel->isDirty()) // includes 'new' +        { +            return true; +        } +    } +    return false; +} +  bool LLPanelProfileClassifieds::canAddNewClassified()  {      return (mTabContainer->getTabCount() < MAX_AVATAR_CLASSIFIEDS); @@ -427,7 +453,7 @@ bool LLPanelProfileClassifieds::canDeleteClassified()      return (mTabContainer->getTabCount() > 0);  } -void LLPanelProfileClassifieds::apply() +void LLPanelProfileClassifieds::commitUnsavedChanges()  {      if (getIsLoaded())      { @@ -701,6 +727,7 @@ void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorTyp      {          // see LLPanelProfileClassified::sendUpdate() for notes          mIsNewWithErrors = false; +        mIsNew = false;          setClassifiedName(c_info->name);          setDescription(c_info->description); @@ -773,7 +800,10 @@ void LLPanelProfileClassified::updateButtons()      mTeleportBtnCnt->setVisible(!edit_mode);      mMapBtnCnt->setVisible(!edit_mode);      mEditBtnCnt->setVisible(!edit_mode); -    mCancelBtnCnt->setVisible(edit_mode); + +    // cancel button should either delete unpublished +    // classified or not be there at all +    mCancelBtnCnt->setVisible(edit_mode && !mIsNew);      mSaveBtnCnt->setVisible(edit_mode);      mEditButton->setVisible(!edit_mode && getSelfProfile());  } diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h index 368718e9dc..000c35a5a1 100644 --- a/indra/newview/llpanelprofileclassifieds.h +++ b/indra/newview/llpanelprofileclassifieds.h @@ -54,7 +54,7 @@ public:      LLPublishClassifiedFloater(const LLSD& key);      virtual ~LLPublishClassifiedFloater(); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override;      void setPrice(S32 price);      S32 getPrice(); @@ -74,21 +74,24 @@ public:      LLPanelProfileClassifieds();      /*virtual*/ ~LLPanelProfileClassifieds(); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override; -    /*virtual*/ void onOpen(const LLSD& key); +    void onOpen(const LLSD& key) override;      void selectClassified(const LLUUID& classified_id, bool edit); -    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); +    void processProperties(void* data, EAvatarProcessorType type) override; -    /*virtual*/ void resetData(); +    void resetData() override;      void updateButtons(); -    /*virtual*/ void updateData(); +    void updateData() override; -    /*virtual*/ void apply(); +    bool hasNewClassifieds(); +    bool hasUnsavedChanges() override; +    // commits changes to existing classifieds, but does not publish new classified! +    void commitUnsavedChanges() override;  private:      void onClickNewBtn(); @@ -119,11 +122,11 @@ public:      /*virtual*/ ~LLPanelProfileClassified(); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override;      void onOpen(const LLSD& key); -    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); +    void processProperties(void* data, EAvatarProcessorType type) override;      void setSnapshotId(const LLUUID& id); @@ -165,9 +168,9 @@ public:      void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; } -    /*virtual*/ BOOL isDirty() const; +    BOOL isDirty() const override; -    /*virtual*/ void resetDirty(); +    void resetDirty() override;      bool isNew() { return mIsNew; } @@ -209,7 +212,7 @@ public:  protected: -    /*virtual*/ void resetData(); +    void resetData() override;      void resetControls(); @@ -259,46 +262,6 @@ protected:      void onTextureSelected(); - - - -    /** -     * Callback for "Map" button, opens Map -     */ -    void onClickMap(); - -    /** -     * Callback for "Teleport" button, teleports user to Pick location. -     */ -    void onClickTeleport(); - -    /** -     * Enables/disables "Save" button -     */ -    void enableSaveButton(BOOL enable); - -    /** -     * Called when snapshot image changes. -     */ -    void onSnapshotChanged(); - -    /** -     * Callback for Pick snapshot, name and description changed event. -     */ -    void onPickChanged(LLUICtrl* ctrl); - -    /** -     * Callback for "Set Location" button click -     */ -    void onClickSetLocation(); - -    /** -     * Callback for "Save" button click -     */ -    void onClickSave(); - -    void onDescriptionFocusReceived(); -      void updateTabLabel(const std::string& title);  private: diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index f5c0fb46c8..7142051f17 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -229,7 +229,7 @@ void LLPanelProfilePicks::onClickDelete()          LLSD payload;          payload["pick_id"] = pick_id;          payload["tab_idx"] = mTabContainer->getCurrentPanelIndex(); -        LLNotificationsUtil::add("DeleteAvatarPick", args, payload, +        LLNotificationsUtil::add("ProfileDeletePick", args, payload,              boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));      }  } @@ -400,6 +400,31 @@ void LLPanelProfilePicks::updateData()      }  } +bool LLPanelProfilePicks::hasUnsavedChanges() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty())) +        { +            return true; +        } +    } +    return false; +} + +void LLPanelProfilePicks::commitUnsavedChanges() +{ +    for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) +    { +        LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); +        if (pick_panel) +        { +            pick_panel->apply(); +        } +    } +} +  bool LLPanelProfilePicks::canAddNewPick()  {      return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() && diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index e1c424ca24..d5df7b7f12 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -50,17 +50,17 @@ public:      LLPanelProfilePicks();      /*virtual*/ ~LLPanelProfilePicks(); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override; -    /*virtual*/ void onOpen(const LLSD& key); +    void onOpen(const LLSD& key) override;      void createPick(const LLPickData &data);      void selectPick(const LLUUID& pick_id); -    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); +    void processProperties(void* data, EAvatarProcessorType type) override;      void processProperties(const LLAvatarPicks* avatar_picks); -    /*virtual*/ void resetData(); +    void resetData() override;      void updateButtons(); @@ -72,7 +72,10 @@ public:      /**       * Sends update data request to server.       */ -    /*virtual*/ void updateData(); +    void updateData() override; + +    bool hasUnsavedChanges() override; +    void commitUnsavedChanges() override;      friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); @@ -107,7 +110,7 @@ public:      /*virtual*/ ~LLPanelProfilePick(); -    /*virtual*/ BOOL postBuild(); +    BOOL postBuild() override;      void setAvatarId(const LLUUID& avatar_id); @@ -117,10 +120,15 @@ public:      virtual void setPickName(const std::string& name);      const std::string getPickName(); -    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); +    void processProperties(void* data, EAvatarProcessorType type) override;      void processProperties(const LLPickData* pick_data);      /** +     * Returns true if any of Pick properties was changed by user. +     */ +    BOOL isDirty() const override; + +    /**       * Saves changes.       */      virtual void apply(); @@ -128,9 +136,9 @@ public:      void updateTabLabel(const std::string& title);      //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing -    /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); -    /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; } -    /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {}; +    void processParcelInfo(const LLParcelData& parcel_data) override; +    void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } +    void setErrorStatus(S32 status, const std::string& reason) override {};  protected: @@ -191,12 +199,7 @@ protected:      /**       * Resets panel and all cantrols to unedited state       */ -    /*virtual*/ void resetDirty(); - -    /** -     * Returns true if any of Pick properties was changed by user. -     */ -    /*virtual*/ BOOL isDirty() const; +    void resetDirty() override;      /**       * Callback for "Set Location" button click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index aa93601669..5899e6df4e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1496,7 +1496,19 @@ Insufficient funds to create classified.    <notification     icon="alertmodal.tga" -   name="DeleteAvatarPick" +   name="ProfileDeleteClassified" +   type="alertmodal"> +Delete classified <nolink>[CLASSIFIED]</nolink>? +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="ProfileDeletePick"     type="alertmodal">  Delete pick <nolink>[PICK]</nolink>?      <tag>confirm</tag> @@ -1507,6 +1519,32 @@ Delete pick <nolink>[PICK]</nolink>?    </notification>    <notification +   icon="alert.tga" +   name="ProfileUnpublishedClassified" +   type="alert"> +    You have unpublished classifieds. They will be lost if you close the window. +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alert.tga" +   name="ProfileUnsavedChanges" +   type="alert"> +    You have usaved changes. +    <tag>confirm</tag> +    <tag>save</tag> +    <usetemplate +     canceltext="Cancel" +     name="yesnocancelbuttons" +     notext="Discard" +     yestext="Save"/> +  </notification> + +  <notification     icon="alertmodal.tga"     name="DeleteOutfits"     type="alertmodal">  | 
