From f945415210f0e18c2c6d941fda6b7d45cb0f06f1 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Wed, 13 Mar 2013 06:26:25 +0000 Subject: Large changes to the LLCurl::Responder API, as well as pulling in some changes to common libraries from the server codebase: * Additional error checking in http handlers. * Uniform log spam for http errors. * Switch to using constants for http heads and status codes. * Fixed bugs in incorrectly checking if parsing LLSD xml resulted in an error. * Reduced spam regarding LLSD parsing errors in the default completedRaw http handler. It should not longer be necessary to short-circuit completedRaw to avoid spam. * Ported over a few bug fixes from the server code. * Switch mode http status codes to use S32 instead of U32. * Ported LLSD::asStringRef from server code; avoids copying strings all over the place. * Ported server change to LLSD::asBinary; this always returns a reference now instead of copying the entire binary blob. * Ported server pretty notation format (and pretty binary format) to llsd serialization. * The new LLCurl::Responder API no longer has two error handlers to choose from. Overriding the following methods have been deprecated: ** error - use httpFailure ** errorWithContent - use httpFailure ** result - use httpSuccess ** completed - use httpCompleted ** completedHeader - no longer necessary; call getResponseHeaders() from a completion method to obtain these headers. * In order to 'catch' a completed http request, override one of these methods: ** httpSuccess - Called for any 2xx status code. ** httpFailure - Called for any non-2xx status code. ** httpComplete - Called for all status codes. Default implementation is to call either httpSuccess or httpFailure. * It is recommended to keep these methods protected/private in order to avoid triggering of these methods without using a 'push' method (see below). * Uniform error handling should followed whenever possible by calling a variant of this during httpFailure: ** llwarns << dumpResponse() << llendl; * Be sure to include LOG_CLASS(your_class_name) in your class in order for the log entry to give more context. * In order to 'push' a result into the responder, you should no longer call error, errorWithContent, result, or completed. * Nor should you directly call httpSuccess/Failure/Completed (unless passing a message up to a parent class). * Instead, you can set the internal content of a responder and trigger a corresponding method using the following methods: ** successResult - Sets results and calls httpSuccess ** failureResult - Sets results and calls httpFailure ** completedResult - Sets results and calls httpCompleted * To obtain information about a the response from a reponder method, use the following getters: ** getStatus - HTTP status code ** getReason - Reason string ** getContent - Content (Parsed body LLSD) ** getResponseHeaders - Response Headers (LLSD map) ** getHTTPMethod - HTTP method of the request ** getURL - URL of the request * It is still possible to override completeRaw if you want to manipulate data directly out of LLPumpIO. * See indra/llmessage/llcurl.h for more information. --- indra/newview/llinspectavatar.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinspectavatar.cpp') diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index aafc43b02d..1f719a22ef 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -495,21 +495,23 @@ void LLInspectAvatar::toggleSelectedVoice(bool enabled) class MuteVoiceResponder : public LLHTTPClient::Responder { + LOG_CLASS(MuteVoiceResponder); public: MuteVoiceResponder(const LLUUID& session_id) { mSessionID = session_id; } - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) + protected: + virtual void httpFailure() { - llwarns << "MuteVoiceResponder error [status:" << status << "]: " << content << llendl; + llwarns << dumpResponse() << llendl; if ( gIMMgr ) { //403 == you're not a mod //should be disabled if you're not a moderator - if ( 403 == status ) + if ( HTTP_FORBIDDEN == getStatus() ) { gIMMgr->showSessionEventError( "mute", -- cgit v1.3 From 985b7277e824c39275d9a06c6262b6f394b02133 Mon Sep 17 00:00:00 2001 From: prep Date: Mon, 8 Apr 2013 17:10:46 -0400 Subject: WIP SH-4035: confirmation when closing appearance window when changes present --- indra/newview/llfloatersidepanelcontainer.cpp | 16 ++-- indra/newview/llfloatersidepanelcontainer.h | 2 + indra/newview/llinspectavatar.cpp | 5 +- indra/newview/llsidepanelappearance.cpp | 88 +++++++++++++++++++++- indra/newview/llsidepanelappearance.h | 16 +++- indra/newview/llspeakers.cpp | 5 +- .../newview/skins/default/xui/en/notifications.xml | 13 ++++ 7 files changed, 126 insertions(+), 19 deletions(-) (limited to 'indra/newview/llinspectavatar.cpp') diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp index 5f9556a870..b1f9a18d6f 100644 --- a/indra/newview/llfloatersidepanelcontainer.cpp +++ b/indra/newview/llfloatersidepanelcontainer.cpp @@ -67,15 +67,17 @@ void LLFloaterSidePanelContainer::onClickCloseBtn() if (parent == this ) { LLSidepanelAppearance* panel_appearance = dynamic_cast(getPanel("appearance")); - if ( panel_appearance ) - { - panel_appearance->getWearable()->onClose(); - panel_appearance->showOutfitsInventoryPanel(); - } + panel_appearance->onClose(this); } } - - LLFloater::onClickCloseBtn(); + else + { + LLFloater::onClickCloseBtn(); + } +} +void LLFloaterSidePanelContainer::close() +{ + LLFloater::onClickCloseBtn(); } LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params) diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h index 491723471f..940673b643 100644 --- a/indra/newview/llfloatersidepanelcontainer.h +++ b/indra/newview/llfloatersidepanelcontainer.h @@ -55,6 +55,8 @@ public: LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params); + void close(); + static void showPanel(const std::string& floater_name, const LLSD& key); static void showPanel(const std::string& floater_name, const std::string& panel_name, const LLSD& key); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 0b3268eb54..6ff16742dd 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -292,10 +292,7 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data) delete mPropertiesRequest; mPropertiesRequest = NULL; } -/* -prep# - virtual void httpFailure() - */ + void LLInspectAvatar::updateVolumeSlider() { diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 74fa5a87bb..53b5593ac9 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -48,6 +48,8 @@ #include "llviewerregion.h" #include "llvoavatarself.h" #include "llviewerwearable.h" +#include "llnotificationsutil.h" +#include "llfloatersidepanelcontainer.h" static LLRegisterPanelClassWrapper t_appearance("sidepanel_appearance"); @@ -70,13 +72,84 @@ private: LLSidepanelAppearance *mPanel; }; +bool LLSidepanelAppearance::callBackExitWithoutSaveViaBack(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( option == 0 ) + { + gSavedSettings.setBOOL("ExitOutfitEditWithoutSave", TRUE); + LLAppearanceMgr::instance().setOutfitDirty( true ); + showOutfitsInventoryPanel(); + LLAppearanceMgr::getInstance()->wearBaseOutfit(); + return true; + } + gSavedSettings.setBOOL("ExitOutfitEditWithoutSave", FALSE); + return false; +} + +bool LLSidepanelAppearance::callBackExitWithoutSaveViaClose(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( option == 0 ) + { + gSavedSettings.setBOOL("ExitOutfitEditWithoutSave", TRUE); + mEditWearable->revertChanges(); + LLAppearanceMgr::getInstance()->wearBaseOutfit(); + mLLFloaterSidePanelContainer->close(); + return true; + } + gSavedSettings.setBOOL("ExitOutfitEditWithoutSave", FALSE); + return false; +} + +void LLSidepanelAppearance::onClickConfirmExitWithoutSaveViaClose() +{ + if ( LLAppearanceMgr::getInstance()->isOutfitDirty() && !LLAppearanceMgr::getInstance()->isOutfitLocked() ) + { + LLSidepanelAppearance* pSelf = (LLSidepanelAppearance *)this; + LLNotificationsUtil::add("ConfirmExitWithoutSave", LLSD(), LLSD(), boost::bind(&LLSidepanelAppearance::callBackExitWithoutSaveViaClose,pSelf,_1,_2) ); + } + else + { + showOutfitsInventoryPanel(); + } +} + +void LLSidepanelAppearance::onClickConfirmExitWithoutSaveViaBack() +{ + if ( LLAppearanceMgr::getInstance()->isOutfitDirty() && !mSidePanelJustOpened && !LLAppearanceMgr::getInstance()->isOutfitLocked() ) + { + LLSidepanelAppearance* pSelf = (LLSidepanelAppearance *)this; + LLNotificationsUtil::add("ConfirmExitWithoutSave", LLSD(), LLSD(), boost::bind(&LLSidepanelAppearance::callBackExitWithoutSaveViaBack,pSelf,_1,_2) ); + } + else + { + showOutfitsInventoryPanel(); + } +} + +void LLSidepanelAppearance::onClose(LLFloaterSidePanelContainer* obj) +{ + mLLFloaterSidePanelContainer = obj; + if ( LLAppearanceMgr::getInstance()->isOutfitDirty() && !LLAppearanceMgr::getInstance()->isOutfitLocked() ) + { + LLSidepanelAppearance* pSelf = (LLSidepanelAppearance *)this; + LLNotificationsUtil::add("ConfirmExitWithoutSave", LLSD(), LLSD(), boost::bind(&LLSidepanelAppearance::callBackExitWithoutSaveViaClose,pSelf,_1,_2) ); + } + else + { + mLLFloaterSidePanelContainer->close(); + } +} + LLSidepanelAppearance::LLSidepanelAppearance() : LLPanel(), mFilterSubString(LLStringUtil::null), mFilterEditor(NULL), mOutfitEdit(NULL), mCurrOutfitPanel(NULL), - mOpened(false) + mOpened(false), + mSidePanelJustOpened(true) { LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); outfit_observer.addBOFReplacedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, "")); @@ -85,6 +158,8 @@ LLSidepanelAppearance::LLSidepanelAppearance() : gAgentWearables.addLoadingStartedCallback(boost::bind(&LLSidepanelAppearance::setWearablesLoading, this, true)); gAgentWearables.addLoadedCallback(boost::bind(&LLSidepanelAppearance::setWearablesLoading, this, false)); + + } LLSidepanelAppearance::~LLSidepanelAppearance() @@ -119,8 +194,8 @@ BOOL LLSidepanelAppearance::postBuild() { LLButton* back_btn = mOutfitEdit->getChild("back_btn"); if (back_btn) - { - back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::showOutfitsInventoryPanel, this)); + { + back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onClickConfirmExitWithoutSaveViaBack, this)); } } @@ -144,6 +219,7 @@ BOOL LLSidepanelAppearance::postBuild() setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChange,this,_2)); + return TRUE; } @@ -183,6 +259,12 @@ void LLSidepanelAppearance::onOpen(const LLSD& key) void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility) { + //handle leaving and subsequent user verification of discarding any unsaved data + if ( mSidePanelJustOpened ) + { + mSidePanelJustOpened = false; + } + LLSD visibility; visibility["visible"] = new_visibility.asBoolean(); visibility["reset_accordion"] = false; diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 762f557a80..85e7734567 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -38,9 +38,11 @@ class LLCurrentlyWornFetchObserver; class LLPanelEditWearable; class LLViewerWearable; class LLPanelOutfitsInventory; +class LLFloaterSidePanelContainer; class LLSidepanelAppearance : public LLPanel -{ +{ + LOG_CLASS(LLSidepanelAppearance); public: LLSidepanelAppearance(); @@ -48,6 +50,8 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); + void onClose(LLFloaterSidePanelContainer* obj); + void onClickCloseBtn(); void refreshCurrentOutfitName(const std::string& name = ""); @@ -65,6 +69,11 @@ public: void updateScrollingPanelList(); void updateToVisibility( const LLSD& new_visibility ); LLPanelEditWearable* getWearable(){ return mEditWearable; } + bool callBackExitWithoutSaveViaBack(const LLSD& notification, const LLSD& response); + void onClickConfirmExitWithoutSaveViaBack(); + bool callBackExitWithoutSaveViaClose(const LLSD& notification, const LLSD& response); + void onClickConfirmExitWithoutSaveViaClose(); + private: void onFilterEdit(const std::string& search_string); @@ -85,6 +94,7 @@ private: LLButton* mOpenOutfitBtn; LLButton* mEditAppearanceBtn; LLButton* mNewOutfitBtn; + LLPanel* mCurrOutfitPanel; LLTextBox* mCurrentLookName; @@ -99,6 +109,10 @@ private: // Gets set to true when we're opened for the first time. bool mOpened; + // Set to true if sidepanel has just been opened + bool mSidePanelJustOpened; + LLFloaterSidePanelContainer* mLLFloaterSidePanelContainer; + }; #endif //LL_LLSIDEPANELAPPEARANCE_H diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 3c3c699d17..bf209df863 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -855,10 +855,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) } } } -/*prep# - virtual void httpFailure() - llwarns << dumpResponse() << llendl; - */ + void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id) { LLPointer speakerp = findSpeaker(speaker_id); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 105bef7321..2170283af2 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -10030,5 +10030,18 @@ Cannot create large prims that intersect other players. Please re-try when othe name="okignore" yestext="OK"/> + + + + Closing this window will discard any changes you have made. + confirm + + -- cgit v1.3