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/newview | |
parent | d7459d87e0b7507b3452aa4effa4dc97e06e8551 (diff) |
SL-15312 Confirm usaved changes dialog when closing floater
Diffstat (limited to 'indra/newview')
-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"> |