summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-06-02 00:17:54 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-06-02 00:20:30 +0300
commit3efe64619b772ce8cab596d7e74de48dcc7f6c20 (patch)
treeb951db7f2784ab5af8301151b01cccff5a7bd0b0 /indra/newview
parentd7459d87e0b7507b3452aa4effa4dc97e06e8551 (diff)
SL-15312 Confirm usaved changes dialog when closing floater
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloaterprofile.cpp59
-rw-r--r--indra/newview/llfloaterprofile.h7
-rw-r--r--indra/newview/llpanelavatar.h3
-rw-r--r--indra/newview/llpanelprofile.cpp101
-rw-r--r--indra/newview/llpanelprofile.h49
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp38
-rw-r--r--indra/newview/llpanelprofileclassifieds.h67
-rw-r--r--indra/newview/llpanelprofilepicks.cpp27
-rw-r--r--indra/newview/llpanelprofilepicks.h35
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml40
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 &lt;nolink&gt;[CLASSIFIED]&lt;/nolink&gt;?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProfileDeletePick"
type="alertmodal">
Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<tag>confirm</tag>
@@ -1507,6 +1519,32 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
</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">