From af6877fbfe94e80948c559cf77f008049f8168dc Mon Sep 17 00:00:00 2001 From: RevolutionSmythe Date: Wed, 20 Oct 2010 16:31:09 -0500 Subject: Finishes the OpenRegionSettings module, adds a new panel to Region/Estate for OpenRegionSettings, adds the new CAPS based WindLight Settings module, cleans up a few UI parts, and rebuilds the ToS window to support OpenSim regions better. --- linden/etc/message.xml | 10 +- linden/indra/llcommon/lltimer.cpp | 28 + linden/indra/llcommon/lltimer.h | 1 + linden/indra/newview/CMakeLists.txt | 9 + linden/indra/newview/hippoLimits.cpp | 123 +- linden/indra/newview/hippoLimits.h | 33 +- linden/indra/newview/kowopenregionsettings.cpp | 92 +- linden/indra/newview/llagent.cpp | 10 +- linden/indra/newview/llagent.h | 2 + linden/indra/newview/llappviewer.cpp | 2 +- linden/indra/newview/llcloud.cpp | 30 +- linden/indra/newview/llfloaterenvsettings.cpp | 8 +- linden/indra/newview/llfloaterenvsettings.h | 3 + linden/indra/newview/llfloatermap.cpp | 4 +- linden/indra/newview/llfloaterregioninfo.cpp | 6734 ++++++++++---------- linden/indra/newview/llfloaterregioninfo.h | 20 + linden/indra/newview/llfloatertools.cpp | 49 +- linden/indra/newview/llfloatertos.cpp | 594 +- linden/indra/newview/llfloaterwater.cpp | 8 + linden/indra/newview/llfloaterwindlight.cpp | 58 +- linden/indra/newview/llfloaterwindlight.h | 4 + linden/indra/newview/llhomelocationresponder.cpp | 2 + linden/indra/newview/llmaniptranslate.cpp | 2 +- linden/indra/newview/llprefschat.cpp | 5 + linden/indra/newview/llsurface.cpp | 26 +- linden/indra/newview/llsurface.h | 2 + linden/indra/newview/lltooldraganddrop.cpp | 10 +- linden/indra/newview/llviewerdisplay.cpp | 20 +- linden/indra/newview/llviewerinventory.cpp | 2 +- linden/indra/newview/llviewermessage.cpp | 16 +- linden/indra/newview/llviewerregion.cpp | 9 + linden/indra/newview/llviewerregion.h | 4 +- linden/indra/newview/llvoavatar.cpp | 3 +- linden/indra/newview/llvoavatar.h | 1 + linden/indra/newview/llwaterparammanager.cpp | 38 +- linden/indra/newview/llwaterparammanager.h | 7 + linden/indra/newview/llwaterparamset.cpp | 92 + linden/indra/newview/llwlparammanager.cpp | 42 + linden/indra/newview/llwlparammanager.h | 7 + linden/indra/newview/llwlparamset.cpp | 5 + linden/indra/newview/llworld.cpp | 11 +- linden/indra/newview/llworld.h | 2 + linden/indra/newview/pipeline.cpp | 4 + .../default/xui/en-us/floater_avatar_picker.xml | 2 +- .../default/xui/en-us/floater_env_settings.xml | 10 +- .../default/xui/en-us/floater_script_ed_panel.xml | 2 +- .../skins/default/xui/en-us/floater_tos.xml | 9 +- .../skins/default/xui/en-us/floater_water.xml | 549 +- .../xui/en-us/floater_windlight_manager.xml | 35 + .../xui/en-us/floater_windlight_options.xml | 45 +- .../xui/en-us/floater_windlight_remote_save.xml | 123 + .../skins/default/xui/en-us/floater_world_map.xml | 366 +- .../xui/en-us/legacy_menu_pie_attachment.xml | 46 +- .../skins/default/xui/en-us/notifications.xml | 84 + .../skins/default/xui/en-us/panel_avatar.xml | 10 +- .../default/xui/en-us/panel_preferences_chat.xml | 8 +- .../xui/en-us/panel_preferences_general.xml | 46 +- .../default/xui/en-us/panel_preferences_skins.xml | 28 +- .../skins/default/xui/en-us/panel_radar.xml | 8 +- .../default/xui/en-us/panel_region_estate.xml | 13 +- .../default/xui/en-us/panel_region_general.xml | 13 +- .../en-us/panel_region_open_region_settings.xml | 76 + linden/indra/newview/viewertime.cpp | 20 +- linden/indra/newview/viewertime.h | 3 + linden/indra/newview/windlightsettingsupdate.cpp | 200 + linden/indra/newview/wlfloatermanager.cpp | 281 + linden/indra/newview/wlfloatermanager.h | 93 + linden/indra/newview/wlfloaterwindlightsend.cpp | 300 + linden/indra/newview/wlfloaterwindlightsend.h | 88 + linden/indra/newview/wlretrievesettings.cpp | 238 + linden/indra/newview/wlretrievesettings.h | 59 + linden/indra/newview/wlsettingsmanager.cpp | 249 + linden/indra/newview/wlsettingsmanager.h | 90 + 73 files changed, 7006 insertions(+), 4220 deletions(-) create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_windlight_manager.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_windlight_remote_save.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/panel_region_open_region_settings.xml create mode 100644 linden/indra/newview/windlightsettingsupdate.cpp create mode 100644 linden/indra/newview/wlfloatermanager.cpp create mode 100644 linden/indra/newview/wlfloatermanager.h create mode 100644 linden/indra/newview/wlfloaterwindlightsend.cpp create mode 100644 linden/indra/newview/wlfloaterwindlightsend.h create mode 100644 linden/indra/newview/wlretrievesettings.cpp create mode 100644 linden/indra/newview/wlretrievesettings.h create mode 100644 linden/indra/newview/wlsettingsmanager.cpp create mode 100644 linden/indra/newview/wlsettingsmanager.h diff --git a/linden/etc/message.xml b/linden/etc/message.xml index f9baf0b..c53e846 100644 --- a/linden/etc/message.xml +++ b/linden/etc/message.xml @@ -378,7 +378,15 @@ true - ParcelVoiceInfo + WindLightSettingsUpdate + + flavor + llsd + trusted-sender + true + + + ParcelVoiceInfo flavor llsd diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp index fa6efaf..fb3e1ef 100644 --- a/linden/indra/llcommon/lltimer.cpp +++ b/linden/indra/llcommon/lltimer.cpp @@ -527,6 +527,34 @@ struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) } +struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST) +{ + if (DST) + { + //Subtract one then + offset--; + } + + // We subtract off the PST/PDT offset _before_ getting + // "UTC" time, because this will handle wrapping around + // for 5 AM UTC -> 10 PM PDT of the previous day. + utc_time -= offset * MIN_PER_HOUR * SEC_PER_MIN; + + // Internal buffer to PST/PDT (see above) + struct tm* internal_time = gmtime(&utc_time); + + /* + // Don't do this, this won't correctly tell you if daylight savings is active in CA or not. + if (pacific_daylight_time) + { + internal_time->tm_isdst = 1; + } + */ + + return internal_time; +} + + void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) { U64 hours; diff --git a/linden/indra/llcommon/lltimer.h b/linden/indra/llcommon/lltimer.h index e2cf1c7..a653233 100644 --- a/linden/indra/llcommon/lltimer.h +++ b/linden/indra/llcommon/lltimer.h @@ -166,6 +166,7 @@ BOOL is_daylight_savings(); // utc_time = time_corrected(); // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); +struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST); void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); void secondsToTimecodeString(F32 current_time, std::string& tcstring); diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 1a6ad30..c3c6566 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -493,6 +493,11 @@ set(viewer_SOURCE_FILES rlvfloaterbehaviour.cpp viewertime.cpp viewerversion.cpp + windlightsettingsupdate.cpp + wlfloatermanager.cpp + wlfloaterwindlightsend.cpp + wlretrievesettings.cpp + wlsettingsmanager.cpp ) set(VIEWER_BINARY_NAME "imprudence-bin" CACHE STRING @@ -950,6 +955,10 @@ set(viewer_HEADER_FILES VorbisFramework.h viewertime.h viewerversion.h + wlfloatermanager.h + wlfloaterwindlightsend.h + wlretrievesettings.h + wlsettingsmanager.h ) source_group("CMake Rules" FILES ViewerInstall.cmake) diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippoLimits.cpp index 92e2ed3..88b86a9 100644 --- a/linden/indra/newview/hippoLimits.cpp +++ b/linden/indra/newview/hippoLimits.cpp @@ -43,11 +43,30 @@ void HippoLimits::setLimits() void HippoLimits::setOpenSimLimits() { mMaxAgentGroups = gHippoGridManager->getConnectedGrid()->getMaxAgentGroups(); - if (mMaxAgentGroups < 0) mMaxAgentGroups = 50; + + if (mMaxAgentGroups < 0) + mMaxAgentGroups = 50; + mMaxPrimScale = 256.0f; mMinPrimScale = 0.001f; + mMinPrimXPos = 0; + mMinPrimYPos = 0; + mMinPrimZPos = 0; + mMaxPrimXPos = F32_MAX; + mMaxPrimYPos = F32_MAX; + mMaxPrimZPos = F32_MAX; mMaxHeight = 10000.0f; mMaxLinkedPrims = -1; + mMaxPhysLinkedPrims = -1; + mAllowParcelWindLight = TRUE; + mAllowMinimap = TRUE; + mMaxInventoryItemsTransfer = -1; + mRenderName = 2; + mAllowPhysicalPrims = TRUE; + skyUseClassicClouds = TRUE; + mEnableTeenMode = FALSE; + mEnforceMaxBuild = FALSE; + mRenderWater = TRUE; if (gHippoGridManager->getConnectedGrid()->isRenderCompat()) { llinfos << "Using rendering compatible OpenSim limits" << llendl; @@ -72,11 +91,27 @@ void HippoLimits::setSecondLifeLimits() mMinHoleSize = 0.05f; mMaxHollow = 0.95f; mMaxLinkedPrims = 255; + mMaxPhysLinkedPrims = 32; + mMinPrimXPos = 0; + mMinPrimYPos = 0; + mMinPrimZPos = 0; + mMaxPrimXPos = 256; + mMaxPrimYPos = 256; + mMaxPrimZPos = 4096; + mAllowParcelWindLight = FALSE; + mAllowMinimap = TRUE; + mMaxInventoryItemsTransfer = 42; + mRenderName = 2; + mAllowPhysicalPrims = TRUE; + skyUseClassicClouds = TRUE; + mEnableTeenMode = FALSE; + mEnforceMaxBuild = FALSE; + mRenderWater = TRUE; } F32 HippoLimits::getMaxPrimScale() const { - if (gSavedSettings.getBOOL("DisableMaxBuildConstraints")) + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) { return FLT_MAX; } @@ -85,3 +120,87 @@ F32 HippoLimits::getMaxPrimScale() const return mMaxPrimScale; } } + +F32 HippoLimits::getMinPrimScale() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return 0; + } + else + { + return mMinPrimScale; + } +} + +F32 HippoLimits::getMaxPrimXPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMaxPrimXPos; + } +} + +F32 HippoLimits::getMaxPrimYPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMaxPrimYPos; + } +} + +F32 HippoLimits::getMaxPrimZPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMaxPrimZPos; + } +} + +F32 HippoLimits::getMinPrimXPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMinPrimXPos; + } +} + +F32 HippoLimits::getMinPrimYPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMinPrimYPos; + } +} + +F32 HippoLimits::getMinPrimZPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMinPrimZPos; + } +} diff --git a/linden/indra/newview/hippoLimits.h b/linden/indra/newview/hippoLimits.h index a5fe351..a5493eb 100644 --- a/linden/indra/newview/hippoLimits.h +++ b/linden/indra/newview/hippoLimits.h @@ -11,12 +11,23 @@ public: const F32& getMaxHeight() const { return mMaxHeight; } const F32& getMinHoleSize() const { return mMinHoleSize; } const F32& getMaxHollow() const { return mMaxHollow; } - const F32& getMinPrimScale() const { return mMinPrimScale; } const S32& getMaxLinkedPrims() const { return mMaxLinkedPrims; } + const F32& getMaxDragDistance() const { return mMaxDragDistance; } + const S32& getMaxPhysLinkedPrims() const { return mMaxPhysLinkedPrims; } + const F32& getMaxInventoryItemsTransfer() const { return mMaxInventoryItemsTransfer; } + // Returns the max prim size we can use on a grid + F32 getMinPrimScale() const; F32 getMaxPrimScale() const; + F32 getMinPrimXPos() const; + F32 getMinPrimYPos() const; + F32 getMinPrimZPos() const; + F32 getMaxPrimXPos() const; + F32 getMaxPrimYPos() const; + F32 getMaxPrimZPos() const; + void setLimits(); S32 mMaxAgentGroups; @@ -27,6 +38,26 @@ public: F32 mMaxPrimScale; F32 mMinPrimScale; S32 mMaxLinkedPrims; + S32 mMaxPhysLinkedPrims; + F32 mMaxPrimXPos; + F32 mMaxPrimYPos; + F32 mMaxPrimZPos; + F32 mMinPrimXPos; + F32 mMinPrimYPos; + F32 mMinPrimZPos; + + S32 mRenderName; + + F32 mMaxInventoryItemsTransfer; + F32 mMaxDragDistance; + + BOOL skyUseClassicClouds; + BOOL mAllowParcelWindLight; + BOOL mAllowMinimap; + BOOL mAllowPhysicalPrims; + BOOL mEnableTeenMode; + BOOL mEnforceMaxBuild; + BOOL mRenderWater; private: void setOpenSimLimits(); diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index f568473..3cceb0c 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp @@ -30,6 +30,12 @@ #include "hippoLimits.h" #include "llfloatertools.h" #include "llviewercontrol.h" +#include "llagent.h" +#include "llsurface.h" +#include "llviewerregion.h" +#include "llviewerobject.h" +#include "llfloaterregioninfo.h" +#include "llfloaterworldmap.h" //DEBUG includes //#include "llsdserialize.h" //LLSDNotationStreamer - for dumping LLSD to string @@ -62,19 +68,20 @@ class OpenRegionInfoUpdate : public LLHTTPNode if ( body.has("AllowMinimap") ) { - //IMPLEMENT ME + gHippoLimits->mAllowMinimap = body["AllowMinimap"].asInteger() == 1; } if ( body.has("AllowPhysicalPrims") ) { - //IMPLEMENT ME + gHippoLimits->mAllowPhysicalPrims = body["AllowPhysicalPrims"].asInteger() == 1; + limitschanged = TRUE; } if ( body.has("DrawDistance") ) { - //IMPLEMENT ME + gAgent.mDrawDistance = body["DrawDistance"].asReal(); } if ( body.has("ForceDrawDistance") ) { - //IMPLEMENT ME + gAgent.mLockedDrawDistance = body["ForceDrawDistance"].asInteger() == 1; } if ( body.has("LSLFunctions") ) { @@ -82,19 +89,23 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("MaxDragDistance") ) { - //IMPLEMENT ME + gHippoLimits->mMaxDragDistance = body["MaxDragDistance"].asReal(); } if ( body.has("MinHoleSize") ) { + //Note: does NOT update correctly gHippoLimits->mMinHoleSize = body["MinHoleSize"].asReal(); + limitschanged = TRUE; } if ( body.has("MaxHollowSize") ) { + //Note: does NOT update correctly gHippoLimits->mMaxHollow = body["MaxHollowSize"].asReal(); + limitschanged = TRUE; } if ( body.has("MaxInventoryItemsTransfer") ) { - //IMPLEMENT ME + gHippoLimits->mMaxInventoryItemsTransfer = body["MaxInventoryItemsTransfer"].asReal(); } if ( body.has("MaxLinkCount") ) { @@ -102,22 +113,28 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("MaxLinkCountPhys") ) { - //IMPLEMENT ME + gHippoLimits->mMaxPhysLinkedPrims = body["MaxLinkCountPhys"].asInteger(); } - if ( body.has("MaxPhysPrimScale") ) + if ( body.has("MaxPos") ) { - //IMPLEMENT ME + gHippoLimits->mMaxPrimXPos = body["MaxPosX"].asReal(); + gHippoLimits->mMaxPrimYPos = body["MaxPosY"].asReal(); + gHippoLimits->mMaxPrimZPos = body["MaxPosZ"].asReal(); + limitschanged = TRUE; } - if ( body.has("MaxPos") ) + if ( body.has("MinPos") ) { - //IMPLEMENT ME + gHippoLimits->mMinPrimXPos = body["MinPosX"].asReal(); + gHippoLimits->mMinPrimYPos = body["MinPosY"].asReal(); + gHippoLimits->mMinPrimZPos = body["MinPosZ"].asReal(); + limitschanged = TRUE; } if ( body.has("MaxPrimScale") ) { gHippoLimits->mMaxPrimScale = body["MaxPrimScale"].asReal(); limitschanged = TRUE; } - if ( body.has("MinPos") ) + if ( body.has("MaxPhysPrimScale") ) { //IMPLEMENT ME } @@ -128,32 +145,69 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("OffsetOfUTC") ) { - //IMPLEMENT ME + gSavedSettings.setS32("TimeOffset", body["OffsetOfUTC"].asReal()); + gSavedSettings.setBOOL("UseTimeOffset", true); + } + if ( body.has("OffsetOfUTCDST") ) + { + gSavedSettings.setBOOL("TimeOffsetDST", body["OffsetOfUTCDST"].asInteger() == 1 ? TRUE : FALSE); } if ( body.has("RenderWater") ) { - gSavedSettings.setBOOL("RenderWater", body["RenderWater"].asBoolean()); + gHippoLimits->mRenderWater = body["RenderWater"].asInteger() == 1 ? TRUE : FALSE; + gAgent.getRegion()->rebuildWater(); } if ( body.has("SayDistance") ) { - //IMPLEMENT ME + gSavedSettings.setU32("ChatDistance", body["SayDistance"].asReal()); } if ( body.has("ShoutDistance") ) { //IMPLEMENT ME } + if ( body.has("WhisperDistance") ) + { + //IMPLEMENT ME + } if ( body.has("ToggleTeenMode") ) { - gSavedSettings.setBOOL("ToggleTeenMode", body["ToggleTeenMode"].asBoolean()); - + gHippoLimits->mEnableTeenMode = body["ToggleTeenMode"].asInteger() == 1 ? TRUE : FALSE; } - if ( body.has("WhisperDistance") ) + if ( body.has("SetTeenMode") ) { - //IMPLEMENT ME + gAgent.setTeen( body["SetTeenMode"].asInteger() == 1 ? TRUE : FALSE ); + LLFloaterWorldMap::reloadIcons(NULL); + llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl; + } + if ( body.has("ShowTags") ) + { + gHippoLimits->mRenderName = body["ShowTags"].asReal(); + } + if ( body.has("EnforceMaxBuild") ) + { + gHippoLimits->mEnforceMaxBuild = body["EnforceMaxBuild"].asInteger() == 1 ? TRUE : FALSE; + limitschanged = TRUE; + } + if ( body.has("MaxGroups") ) + { + gHippoLimits->mMaxAgentGroups = body["MaxGroups"].asReal(); + } + if ( body.has("AllowParcelWindLight") ) + { + gHippoLimits->mAllowParcelWindLight = body["AllowParcelWindLight"].asInteger() == 1; } if (limitschanged) gFloaterTools->updateToolsSizeLimits(); + + //Update the floater if its around + LLPanelRegionOpenSettingsInfo* floater; + floater = LLFloaterRegionInfo::getPanelOpenSettings(); + + if(floater != NULL) + { + floater->refreshFromRegion(gAgent.getRegion()); + } } }; diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 758cae2..de1fc84 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -36,7 +36,6 @@ #include "stdenums.h" #include "llagent.h" - #include "llcamera.h" #include "llcoordframe.h" #include "indra_constants.h" @@ -441,6 +440,7 @@ LLAgent::LLAgent() : void LLAgent::init() { mDrawDistance = gSavedSettings.getF32("RenderFarClip"); + mLockedDrawDistance = FALSE; // *Note: this is where LLViewerCamera::getInstance() used to be constructed. @@ -6026,6 +6026,14 @@ void LLAgent::setHomePosRegion( const U64& region_handle, const LLVector3& pos_r mHomePosRegion = pos_region; } +void LLAgent::takeHomeScreenshot() +{ + std::string snap_filename = gDirUtilp->getLindenUserDir(); + snap_filename += gDirUtilp->getDirDelimiter(); + snap_filename += SCREEN_HOME_FILENAME; + gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight(), FALSE, FALSE); +} + BOOL LLAgent::getHomePosGlobal( LLVector3d* pos_global ) { if(!mHaveHomePosition) diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 6bc4dac..fe50bf5 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -584,6 +584,7 @@ public: EPointAtType getPointAtType(); void setHomePosRegion( const U64& region_handle, const LLVector3& pos_region ); + void takeHomeScreenshot(); BOOL getHomePosGlobal( LLVector3d* pos_global ); void setCameraAnimating( BOOL b ) { mCameraAnimating = b; } BOOL getCameraAnimating( ) { return mCameraAnimating; } @@ -742,6 +743,7 @@ public: LLUUID mSecureSessionID; // secure token for this login session F32 mDrawDistance; + BOOL mLockedDrawDistance; U64 mGroupPowers; BOOL mHideGroupTitle; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 4485cdf..c53ced6 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -360,7 +360,7 @@ void request_initial_instant_messages() static BOOL requested = FALSE; if (!requested && gMessageSystem - && LLMuteList::getInstance()->isLoaded() + //&& LLMuteList::getInstance()->isLoaded() //We don't always want to have a mute list module && gAgent.getAvatarObject()) { // Auto-accepted inventory items may require the avatar object diff --git a/linden/indra/newview/llcloud.cpp b/linden/indra/newview/llcloud.cpp index 0099817..f4f5761 100644 --- a/linden/indra/newview/llcloud.cpp +++ b/linden/indra/newview/llcloud.cpp @@ -38,6 +38,7 @@ #include "v4math.h" #include "llquaternion.h" #include "v4color.h" +#include "llviewercontrol.h" #include "llwind.h" #include "llcloud.h" @@ -56,15 +57,6 @@ extern LLPipeline gPipeline; -const F32 CLOUD_UPDATE_RATE = 1.0f; // Global time dilation for clouds -const F32 CLOUD_GROW_RATE = 0.05f; -const F32 CLOUD_DECAY_RATE = -0.05f; -const F32 CLOUD_VELOCITY_SCALE = 0.01f; -const F32 CLOUD_DENSITY = 25.f; -const S32 CLOUD_COUNT_MAX = 20; -const F32 CLOUD_HEIGHT_RANGE = 48.f; -const F32 CLOUD_HEIGHT_MEAN = 192.f; - enum { LL_PUFF_GROWING = 0, @@ -80,7 +72,7 @@ S32 LLCloudPuff::sPuffCount = 0; LLCloudPuff::LLCloudPuff() : mAlpha(0.01f), - mRate(CLOUD_GROW_RATE*CLOUD_UPDATE_RATE), + mRate((gSavedSettings.getF32("CloudGrowRate")/100)*gSavedSettings.getF32("CloudUpdateRate")), mLifeState(LL_PUFF_GROWING) { } @@ -121,7 +113,7 @@ void LLCloudGroup::updatePuffs(const F32 dt) mVOCloudsp->setPositionRegion(mCenterRegion); mVOCloudsp->setScale(LLVector3(256.f/CLOUD_GROUPS_PER_EDGE + CLOUD_PUFF_WIDTH, 256.f/CLOUD_GROUPS_PER_EDGE + CLOUD_PUFF_WIDTH, - CLOUD_HEIGHT_RANGE + CLOUD_PUFF_HEIGHT)*0.5f); + gSavedSettings.getF32("ClassicCloudRange") + CLOUD_PUFF_HEIGHT)*0.5f); gPipeline.createObject(mVOCloudsp); } @@ -132,7 +124,7 @@ void LLCloudGroup::updatePuffs(const F32 dt) { LLCloudPuff &puff = mCloudPuffs[i]; velocity = mCloudLayerp->getRegion()->mWind.getCloudVelocity(mCloudLayerp->getRegion()->getPosRegionFromGlobal(puff.mPositionGlobal)); - velocity *= CLOUD_VELOCITY_SCALE*CLOUD_UPDATE_RATE; + velocity *= (gSavedSettings.getF32("CloudVelocityScale")/100)*gSavedSettings.getF32("CloudUpdateRate"); vel_d.setVec(velocity); mCloudPuffs[i].mPositionGlobal += vel_d; mCloudPuffs[i].mAlpha += mCloudPuffs[i].mRate * dt; @@ -163,7 +155,7 @@ void LLCloudGroup::updatePuffOwnership() { //llinfos << "Killing puff not in group" << llendl; mCloudPuffs[i].setLifeState(LL_PUFF_DYING); - mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE; + mCloudPuffs[i].mRate = (gSavedSettings.getF32("CloudDecayRate")/100)*gSavedSettings.getF32("CloudUpdateRate"); i++; continue; } @@ -185,9 +177,9 @@ void LLCloudGroup::updatePuffCount() return; } S32 i; - S32 target_puff_count = llround(CLOUD_DENSITY * mDensity); + S32 target_puff_count = llround((S32)gSavedSettings.getF32("CloudDensity") * mDensity); target_puff_count = llmax(0, target_puff_count); - target_puff_count = llmin(CLOUD_COUNT_MAX, target_puff_count); + target_puff_count = llmin((S32)gSavedSettings.getF32("CloudCountMax"), target_puff_count); S32 current_puff_count = (S32) mCloudPuffs.size(); // Create a new cloud if we need one if (current_puff_count < target_puff_count) @@ -199,7 +191,7 @@ void LLCloudGroup::updatePuffCount() puff_pos_global = mVOCloudsp->getPositionGlobal(); F32 x = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE; F32 y = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE; - F32 z = ll_frand(CLOUD_HEIGHT_RANGE) - 0.5f*CLOUD_HEIGHT_RANGE; + F32 z = ll_frand(gSavedSettings.getF32("ClassicCloudRange")) - 0.5f*gSavedSettings.getF32("ClassicCloudRange"); puff_pos_global += LLVector3d(x, y, z); mCloudPuffs[i].mPositionGlobal = puff_pos_global; mCloudPuffs[i].mAlpha = 0.01f; @@ -227,7 +219,7 @@ void LLCloudGroup::updatePuffCount() { //llinfos << "Killing extra live cloud" << llendl; mCloudPuffs[i].setLifeState(LL_PUFF_DYING); - mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE; + mCloudPuffs[i].mRate = (gSavedSettings.getF32("CloudDecayRate")/100)*gSavedSettings.getF32("CloudUpdateRate"); new_dying_count--; } i++; @@ -294,7 +286,7 @@ LLCloudLayer::LLCloudLayer() x = (0.5f + j)*(256.f/CLOUD_GROUPS_PER_EDGE); mCloudGroups[i][j].setCloudLayerp(this); - mCloudGroups[i][j].setCenterRegion(LLVector3(x, y, CLOUD_HEIGHT_MEAN)); + mCloudGroups[i][j].setCenterRegion(LLVector3(x, y, gSavedSettings.getF32("ClassicCloudHeight"))); } } } @@ -348,8 +340,6 @@ void LLCloudLayer::destroy() void LLCloudLayer::reset() { } - - void LLCloudLayer::setWindPointer(LLWind *windp) { if (mWindp) diff --git a/linden/indra/newview/llfloaterenvsettings.cpp b/linden/indra/newview/llfloaterenvsettings.cpp index 557a5e1..801ff49 100644 --- a/linden/indra/newview/llfloaterenvsettings.cpp +++ b/linden/indra/newview/llfloaterenvsettings.cpp @@ -47,6 +47,7 @@ #include "llwaterparammanager.h" #include "llmath.h" #include "llviewerwindow.h" +#include "wlfloatermanager.h" #include "pipeline.h" @@ -87,7 +88,7 @@ void LLFloaterEnvSettings::initCallbacks(void) // WL Top childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL); childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL); - childSetAction("EnvSubmitWindlight", onSubmitWindlight, NULL); + childSetAction("EnvWLManager", onOpenWLManager, NULL); childSetAction("EnvUseEstateTimeButton", onUseEstateTime, NULL); childSetAction("EnvSettingsHelpButton", onClickHelp, this); } @@ -285,6 +286,11 @@ void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData) LLFloaterWater::show(); } +void LLFloaterEnvSettings::onOpenWLManager(void* userData) +{ + WLFloaterManager::show(); +} + void LLFloaterEnvSettings::onSubmitWindlight(void* userData) { Meta7WindlightPacket * wl = new Meta7WindlightPacket(); diff --git a/linden/indra/newview/llfloaterenvsettings.h b/linden/indra/newview/llfloaterenvsettings.h index 49bf4fd..8b44621 100644 --- a/linden/indra/newview/llfloaterenvsettings.h +++ b/linden/indra/newview/llfloaterenvsettings.h @@ -78,6 +78,9 @@ public: /// open the advanced water settings menu static void onOpenAdvancedWater(void* userData); + /// open the windlight manager floater + static void onOpenWLManager(void* userData); + /// submit windlight settings to the estate static void onSubmitWindlight(void* userData); diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index c15678d..34b8dde 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp @@ -44,6 +44,7 @@ #include "lluictrlfactory.h" #include "llfirstuse.h" #include "panelradar.h" +#include "hippoLimits.h" // [RLVa:KB] @@ -149,7 +150,7 @@ void LLFloaterMap::draw() drawChild(mPanelRadar); } } - else + else if (gHippoLimits->mAllowMinimap) //Check for if minimap is blocked { setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); @@ -215,7 +216,6 @@ void LLFloaterMap::setRadarButtonState( bool showing_radar ) } } - void LLFloaterMap::adjustLayout( bool expand ) { S32 radar_height = mPanelRadar->getRect().getHeight(); diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index deee0f6..c7f1c38 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -1,3298 +1,3436 @@ -/** - * @file llfloaterregioninfo.cpp - * @author Aaron Brashears - * @brief Implementation of the region info and controls floater and panels. - * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llfloaterregioninfo.h" - -#include -#include - -#include "llcachename.h" -#include "lldir.h" -#include "lldispatcher.h" -#include "llglheaders.h" -#include "llregionflags.h" -#include "llstl.h" -#include "indra_constants.h" -#include "message.h" - -#include "llagent.h" -#include "llalertdialog.h" -#include "llappviewer.h" -#include "llfloateravatarpicker.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llfilepicker.h" -#include "llfloaterdaycycle.h" -#include "llfloatergodtools.h" // for send_sim_wide_deletes() -#include "llfloatertopobjects.h" // added to fix SL-32336 -#include "llfloatergroups.h" -#include "llfloatertelehub.h" -#include "llfloaterwindlight.h" -#include "llinventorymodel.h" -#include "lllineeditor.h" -#include "llalertdialog.h" -#include "llnamelistctrl.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "lltabcontainer.h" -#include "lltextbox.h" -#include "llinventory.h" -#include "lltexturectrl.h" -#include "lltrans.h" -#include "llviewercontrol.h" -#include "lluictrlfactory.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" -#include "llviewerregion.h" -#include "llviewerstats.h" -#include "llviewertexteditor.h" -#include "llviewerwindow.h" -#include "llvlcomposition.h" - -// [RLVa:KB] -#include "rlvhandler.h" -// [/RLVa:KB] - -#define ELAR_ENABLED 0 // Enable when server support is implemented - -const S32 TERRAIN_TEXTURE_COUNT = 4; -const S32 CORNER_COUNT = 4; - -///---------------------------------------------------------------------------- -/// Local class declaration -///---------------------------------------------------------------------------- - -class LLDispatchEstateUpdateInfo : public LLDispatchHandler -{ -public: - LLDispatchEstateUpdateInfo() {} - virtual ~LLDispatchEstateUpdateInfo() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); -}; - -class LLDispatchSetEstateAccess : public LLDispatchHandler -{ -public: - LLDispatchSetEstateAccess() {} - virtual ~LLDispatchSetEstateAccess() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); -}; - - -/* -void unpack_request_params( - LLMessageSystem* msg, - LLDispatcher::sparam_t& strings, - LLDispatcher::iparam_t& integers) -{ - char str_buf[MAX_STRING]; - S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData); - S32 i; - for (i = 0; i < str_count; ++i) - { - // we treat the SParam as binary data (since it might be an - // LLUUID in compressed form which may have embedded \0's,) - str_buf[0] = '\0'; - S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam); - if (data_size >= 0) - { - msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam, - str_buf, data_size, i, MAX_STRING - 1); - strings.push_back(std::string(str_buf, data_size)); - } - } - - U32 int_buf; - S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData); - for (i = 0; i < int_count; ++i) - { - msg->getU32("IntegerData", "IParam", int_buf, i); - integers.push_back(int_buf); - } -} -*/ - - - -bool estate_dispatch_initialized = false; - - -///---------------------------------------------------------------------------- -/// LLFloaterRegionInfo -///---------------------------------------------------------------------------- - -//S32 LLFloaterRegionInfo::sRequestSerial = 0; -LLUUID LLFloaterRegionInfo::sRequestInvoice; - -LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", NULL, FALSE); -} - -BOOL LLFloaterRegionInfo::postBuild() -{ - mTab = getChild("region_panels"); - - // contruct the panels - LLPanelRegionInfo* panel; - panel = new LLPanelRegionGeneralInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml"); - mTab->addTabPanel(panel, panel->getLabel(), TRUE); - - panel = new LLPanelRegionDebugInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelRegionTextureInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_texture.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelRegionTerrainInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_terrain.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelEstateInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelEstateCovenant; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - gMessageSystem->setHandlerFunc( - "EstateOwnerMessage", - &processEstateOwnerRequest); - - return TRUE; -} - -LLFloaterRegionInfo::~LLFloaterRegionInfo() -{ -} - -void LLFloaterRegionInfo::onOpen() -{ - LLRect rect = gSavedSettings.getRect("FloaterRegionInfo"); - S32 left, top; - gFloaterView->getNewFloaterPosition(&left, &top); - rect.translate(left,top); - - refreshFromRegion(gAgent.getRegion()); - requestRegionInfo(); - LLFloater::onOpen(); -} - -// static -void LLFloaterRegionInfo::requestRegionInfo() -{ - LLTabContainer* tab = findInstance()->getChild("region_panels"); - - tab->getChild("General")->setCtrlsEnabled(FALSE); - tab->getChild("Debug")->setCtrlsEnabled(FALSE); - tab->getChild("Terrain")->setCtrlsEnabled(FALSE); - tab->getChild("Estate")->setCtrlsEnabled(FALSE); - - // Must allow anyone to request the RegionInfo data - // so non-owners/non-gods can see the values. - // Therefore can't use an EstateOwnerMessage JC - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("RequestRegionInfo"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - gAgent.sendReliableMessage(); -} - -// static -void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) -{ - static LLDispatcher dispatch; - if(!findInstance()) - { - return; - } - - if (!estate_dispatch_initialized) - { - LLPanelEstateInfo::initDispatch(dispatch); - } - - LLTabContainer* tab = findInstance()->getChild("region_panels"); - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); - - // unpack the message - std::string request; - LLUUID invoice; - LLDispatcher::sparam_t strings; - LLDispatcher::unpackMessage(msg, request, invoice, strings); - if(invoice != getLastInvoice()) - { - llwarns << "Mismatched Estate message: " << request << llendl; - return; - } - - //dispatch the message - dispatch.dispatch(request, invoice, strings); - - LLViewerRegion* region = gAgent.getRegion(); - panel->updateControls(region); -} - - -// static -void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) -{ - LLPanel* panel; - - llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; - if(!findInstance()) - { - return; - } - - LLTabContainer* tab = findInstance()->getChild("region_panels"); - - LLViewerRegion* region = gAgent.getRegion(); - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - - // extract message - std::string sim_name; - std::string sim_type = LLTrans::getString("land_type_unknown"); - U32 region_flags; - U8 agent_limit; - F32 object_bonus_factor; - U8 sim_access; - F32 water_height; - F32 terrain_raise_limit; - F32 terrain_lower_limit; - BOOL use_estate_sun; - F32 sun_hour; - msg->getString("RegionInfo", "SimName", sim_name); - msg->getU32("RegionInfo", "RegionFlags", region_flags); - msg->getU8("RegionInfo", "MaxAgents", agent_limit); - msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); - msg->getU8("RegionInfo", "SimAccess", sim_access); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); - msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun); - // actually the "last set" sun hour, not the current sun hour. JC - msg->getF32("RegionInfo", "SunHour", sun_hour); - // the only reasonable way to decide if we actually have any data is to - // check to see if any of these fields have nonzero sizes - if (msg->getSize("RegionInfo2", "ProductSKU") > 0 || - msg->getSize("RegionInfo2", "ProductName") > 0) - { - msg->getString("RegionInfo2", "ProductName", sim_type); - } - - // GENERAL PANEL - panel = tab->getChild("General"); - panel->childSetValue("region_text", LLSD(sim_name)); - panel->childSetValue("region_type", LLSD(sim_type)); - panel->childSetValue("version_channel_text", gLastVersionChannel); - - panel->childSetValue("block_terraform_check", (region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); - panel->childSetValue("block_fly_check", (region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); - panel->childSetValue("allow_damage_check", (region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); - panel->childSetValue("restrict_pushobject", (region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); - panel->childSetValue("allow_land_resell_check", (region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); - panel->childSetValue("allow_parcel_changes_check", (region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE ); - panel->childSetValue("block_parcel_search_check", (region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE ); - panel->childSetValue("agent_limit_spin", LLSD((F32)agent_limit) ); - panel->childSetValue("object_bonus_spin", LLSD(object_bonus_factor) ); - panel->childSetValue("access_combo", LLSD(sim_access) ); - - - // detect teen grid for maturity - - U32 parent_estate_id; - msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id); - BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that - panel->childSetEnabled("access_combo", gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid)); - panel->setCtrlsEnabled(allow_modify); - - - // DEBUG PANEL - panel = tab->getChild("Debug"); - - panel->childSetValue("region_text", LLSD(sim_name) ); - panel->childSetValue("disable_scripts_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) ); - panel->childSetValue("disable_collisions_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) ); - panel->childSetValue("disable_physics_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) ); - panel->setCtrlsEnabled(allow_modify); - - // TERRAIN PANEL - panel = tab->getChild("Terrain"); - - panel->childSetValue("region_text", LLSD(sim_name)); - panel->childSetValue("water_height_spin", LLSD(water_height)); - panel->childSetValue("terrain_raise_spin", LLSD(terrain_raise_limit)); - panel->childSetValue("terrain_lower_spin", LLSD(terrain_lower_limit)); - panel->childSetValue("use_estate_sun_check", LLSD(use_estate_sun)); - - panel->childSetValue("fixed_sun_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SUN_FIXED))); - panel->childSetEnabled("fixed_sun_check", allow_modify && !use_estate_sun); - panel->childSetValue("sun_hour_slider", LLSD(sun_hour)); - panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); - panel->setCtrlsEnabled(allow_modify); - - getInstance()->refreshFromRegion( gAgent.getRegion() ); -} - -// static -LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() -{ - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); - return panel; -} - -// static -LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() -{ - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild("Covenant"); - return panel; -} - -void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) -{ - // call refresh from region on all panels - std::for_each( - mInfoPanels.begin(), - mInfoPanels.end(), - llbind2nd( -#if LL_WINDOWS - std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion), -#else - std::mem_fun(&LLPanelRegionInfo::refreshFromRegion), -#endif - region)); -} - -// public -void LLFloaterRegionInfo::refresh() -{ - for(info_panels_t::iterator iter = mInfoPanels.begin(); - iter != mInfoPanels.end(); ++iter) - { - (*iter)->refresh(); - } -} - - -///---------------------------------------------------------------------------- -/// Local class implementation -///---------------------------------------------------------------------------- - -// -// LLPanelRegionInfo -// - -// static -void LLPanelRegionInfo::onBtnSet(void* user_data) -{ - LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; - if(!panel) return; - if (panel->sendUpdate()) - { - panel->disableButton("apply_btn"); - } -} - -//static -void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl, void* user_data) -{ - if (ctrl) - { - LLPanelRegionInfo* panel = (LLPanelRegionInfo*) ctrl->getParent(); - panel->updateChild(ctrl); - } -} - -// static -// Enables the "set" button if it is not already enabled -void LLPanelRegionInfo::onChangeAnything(LLUICtrl* ctrl, void* user_data) -{ - LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; - if(panel) - { - panel->enableButton("apply_btn"); - panel->refresh(); - } -} - -// static -// Enables set button on change to line editor -void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data) -{ - // reuse the previous method - onChangeAnything(0, user_data); -} - - -// virtual -BOOL LLPanelRegionInfo::postBuild() -{ - childSetAction("apply_btn", onBtnSet, this); - childDisable("apply_btn"); - refresh(); - return TRUE; -} - -// virtual -void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) -{ -} - -// virtual -bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region) -{ - if (region) mHost = region->getHost(); - return true; -} - -void LLPanelRegionInfo::sendEstateOwnerMessage( - LLMessageSystem* msg, - const std::string& request, - const LLUUID& invoice, - const strings_t& strings) -{ - llinfos << "Sending estate request '" << request << "'" << llendl; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", request); - msg->addUUID("Invoice", invoice); - if(strings.empty()) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", NULL); - } - else - { - strings_t::const_iterator it = strings.begin(); - strings_t::const_iterator end = strings.end(); - for(; it != end; ++it) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", *it); - } - } - msg->sendReliable(mHost); -} - -void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable) -{ - childSetEnabled(btn_name, enable); -} - -void LLPanelRegionInfo::disableButton(const std::string& btn_name) -{ - childDisable(btn_name); -} - -void LLPanelRegionInfo::initCtrl(const std::string& name) -{ - childSetCommitCallback(name, onChangeAnything, this); -} - -void LLPanelRegionInfo::initHelpBtn(const std::string& name, const std::string& xml_alert) -{ - childSetAction(name, onClickHelp, new std::string(xml_alert)); -} - -// static -void LLPanelRegionInfo::onClickHelp(void* data) -{ - std::string* xml_alert = (std::string*)data; - LLNotifications::instance().add(*xml_alert); -} - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionGeneralInfo -// -bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region) -{ - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - childDisable("apply_btn"); - childSetEnabled("access_text", allow_modify); - // childSetEnabled("access_combo", allow_modify); - // now set in processRegionInfo for teen grid detection - childSetEnabled("kick_btn", allow_modify); - childSetEnabled("kick_all_btn", allow_modify); - childSetEnabled("im_btn", allow_modify); - childSetEnabled("manage_telehub_btn", allow_modify); - - // Data gets filled in by processRegionInfo - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -BOOL LLPanelRegionGeneralInfo::postBuild() -{ - // Enable the "Apply" button if something is changed. JC - initCtrl("block_terraform_check"); - initCtrl("block_fly_check"); - initCtrl("allow_damage_check"); - initCtrl("allow_land_resell_check"); - initCtrl("allow_parcel_changes_check"); - initCtrl("agent_limit_spin"); - initCtrl("object_bonus_spin"); - initCtrl("access_combo"); - initCtrl("restrict_pushobject"); - initCtrl("block_parcel_search_check"); - - initHelpBtn("terraform_help", "HelpRegionBlockTerraform"); - initHelpBtn("fly_help", "HelpRegionBlockFly"); - initHelpBtn("damage_help", "HelpRegionAllowDamage"); - initHelpBtn("agent_limit_help", "HelpRegionAgentLimit"); - initHelpBtn("object_bonus_help", "HelpRegionObjectBonus"); - initHelpBtn("access_help", "HelpRegionMaturity"); - initHelpBtn("restrict_pushobject_help", "HelpRegionRestrictPushObject"); - initHelpBtn("land_resell_help", "HelpRegionLandResell"); - initHelpBtn("parcel_changes_help", "HelpParcelChanges"); - initHelpBtn("parcel_search_help", "HelpRegionSearch"); - - childSetAction("kick_btn", onClickKick, this); - childSetAction("kick_all_btn", onClickKickAll, this); - childSetAction("im_btn", onClickMessage, this); - childSetAction("manage_telehub_btn", onClickManageTelehub, this); - - return LLPanelRegionInfo::postBuild(); -} - -// static -void LLPanelRegionGeneralInfo::onClickKick(void* userdata) -{ - llinfos << "LLPanelRegionGeneralInfo::onClickKick" << llendl; - LLPanelRegionGeneralInfo* panelp = (LLPanelRegionGeneralInfo*)userdata; - - // this depends on the grandparent view being a floater - // in order to set up floater dependency - LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - LLFloater* child_floater = LLFloaterAvatarPicker::show(onKickCommit, userdata, FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); -} - -// static -void LLPanelRegionGeneralInfo::onKickCommit(const std::vector& names, const std::vector& ids, void* userdata) -{ - if (names.empty() || ids.empty()) return; - if(ids[0].notNull()) - { - LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata; - if(!self) return; - strings_t strings; - // [0] = our agent id - // [1] = target agent id - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - - ids[0].toString(buffer); - strings.push_back(strings_t::value_type(buffer)); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); - } -} - -// static -void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata) -{ - llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl; - LLNotifications::instance().add("KickUsersFromRegion", - LLSD(), - LLSD(), - boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); -} - -bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option == 0) - { - strings_t strings; - // [0] = our agent id - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - // historical message name - sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); - } - return false; -} - -// static -void LLPanelRegionGeneralInfo::onClickMessage(void* userdata) -{ - llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl; - LLNotifications::instance().add("MessageRegion", - LLSD(), - LLSD(), - boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); -} - -// static -bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response) -{ - if(LLNotification::getSelectedOption(notification, response) != 0) return false; - - std::string text = response["message"].asString(); - if (text.empty()) return false; - - llinfos << "Message to everyone: " << text << llendl; - strings_t strings; - // [0] grid_x, unused here - // [1] grid_y, unused here - // [2] agent_id of sender - // [3] sender name - // [4] message - strings.push_back("-1"); - strings.push_back("-1"); - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - std::string name; - gAgent.buildFullname(name); - strings.push_back(strings_t::value_type(name)); - strings.push_back(strings_t::value_type(text)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); - return false; -} - -// static -void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data) -{ - LLFloaterRegionInfo::getInstance()->close(); - - LLFloaterTelehub::show(); -} - -// setregioninfo -// strings[0] = 'Y' - block terraform, 'N' - not -// strings[1] = 'Y' - block fly, 'N' - not -// strings[2] = 'Y' - allow damage, 'N' - not -// strings[3] = 'Y' - allow land sale, 'N' - not -// strings[4] = agent limit -// strings[5] = object bonus -// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult) -// strings[7] = restrict pushobject -// strings[8] = 'Y' - allow parcel subdivide, 'N' - not -// strings[9] = 'Y' - block parcel search, 'N' - allow -BOOL LLPanelRegionGeneralInfo::sendUpdate() -{ - llinfos << "LLPanelRegionGeneralInfo::sendUpdate()" << llendl; - - // First try using a Cap. If that fails use the old method. - LLSD body; - std::string url = gAgent.getRegion()->getCapability("DispatchRegionInfo"); - if (!url.empty()) - { - body["block_terraform"] = childGetValue("block_terraform_check"); - body["block_fly"] = childGetValue("block_fly_check"); - body["allow_damage"] = childGetValue("allow_damage_check"); - body["allow_land_resell"] = childGetValue("allow_land_resell_check"); - body["agent_limit"] = childGetValue("agent_limit_spin"); - body["prim_bonus"] = childGetValue("object_bonus_spin"); - body["sim_access"] = childGetValue("access_combo"); - body["restrict_pushobject"] = childGetValue("restrict_pushobject"); - body["allow_parcel_changes"] = childGetValue("allow_parcel_changes_check"); - body["block_parcel_search"] = childGetValue("block_parcel_search_check"); - - LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); - } - else - { - strings_t strings; - std::string buffer; - - buffer = llformat("%s", (childGetValue("block_terraform_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("block_fly_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("allow_damage_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("allow_land_resell_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - F32 value = (F32)childGetValue("agent_limit_spin").asReal(); - buffer = llformat("%f", value); - strings.push_back(strings_t::value_type(buffer)); - - value = (F32)childGetValue("object_bonus_spin").asReal(); - buffer = llformat("%f", value); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%d", childGetValue("access_combo").asInteger()); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("restrict_pushobject").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("allow_parcel_changes_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); - } - - // if we changed access levels, tell user about it - LLViewerRegion* region = gAgent.getRegion(); - if (region && (childGetValue("access_combo").asInteger() != region->getSimAccess()) ) - { - LLNotifications::instance().add("RegionMaturityChange"); - } - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionDebugInfo -///////////////////////////////////////////////////////////////////////////// -BOOL LLPanelRegionDebugInfo::postBuild() -{ - LLPanelRegionInfo::postBuild(); - initCtrl("disable_scripts_check"); - initCtrl("disable_collisions_check"); - initCtrl("disable_physics_check"); - - initHelpBtn("disable_scripts_help", "HelpRegionDisableScripts"); - initHelpBtn("disable_collisions_help", "HelpRegionDisableCollisions"); - initHelpBtn("disable_physics_help", "HelpRegionDisablePhysics"); - initHelpBtn("top_colliders_help", "HelpRegionTopColliders"); - initHelpBtn("top_scripts_help", "HelpRegionTopScripts"); - initHelpBtn("restart_help", "HelpRegionRestart"); - - childSetAction("choose_avatar_btn", onClickChooseAvatar, this); - childSetAction("return_btn", onClickReturn, this); - childSetAction("top_colliders_btn", onClickTopColliders, this); - childSetAction("top_scripts_btn", onClickTopScripts, this); - childSetAction("restart_btn", onClickRestart, this); - childSetAction("cancel_restart_btn", onClickCancelRestart, this); - - return TRUE; -} - -// virtual -bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region) -{ - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - childDisable("apply_btn"); - childDisable("target_avatar_name"); - - childSetEnabled("choose_avatar_btn", allow_modify); - childSetEnabled("return_scripts", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("return_other_land", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("return_estate_wide", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("return_btn", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("top_colliders_btn", allow_modify); - childSetEnabled("top_scripts_btn", allow_modify); - childSetEnabled("restart_btn", allow_modify); - childSetEnabled("cancel_restart_btn", allow_modify); - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -// virtual -BOOL LLPanelRegionDebugInfo::sendUpdate() -{ - llinfos << "LLPanelRegionDebugInfo::sendUpdate" << llendl; - strings_t strings; - std::string buffer; - - buffer = llformat("%s", (childGetValue("disable_scripts_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - - buffer = llformat("%s", (childGetValue("disable_collisions_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - - buffer = llformat("%s", (childGetValue("disable_physics_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); - return TRUE; -} - -void LLPanelRegionDebugInfo::onClickChooseAvatar(void* data) -{ - LLFloaterAvatarPicker::show(callbackAvatarID, data, FALSE, TRUE); -} - -// static -void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector& names, const std::vector& ids, void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) data; - if (ids.empty() || names.empty()) return; - self->mTargetAvatar = ids[0]; - self->childSetValue("target_avatar_name", LLSD(names[0])); - self->refreshFromRegion( gAgent.getRegion() ); -} - -// static -void LLPanelRegionDebugInfo::onClickReturn(void* data) -{ - LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; - if (panelp->mTargetAvatar.isNull()) return; - - LLSD args; - args["USER_NAME"] = panelp->childGetValue("target_avatar_name").asString(); - LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - - U32 flags = SWD_ALWAYS_RETURN_OBJECTS; - - if (panelp->childGetValue("return_scripts").asBoolean()) - { - flags |= SWD_SCRIPTED_ONLY; - } - - if (panelp->childGetValue("return_other_land").asBoolean()) - { - flags |= SWD_OTHERS_LAND_ONLY; - } - payload["flags"] = int(flags); - payload["return_estate_wide"] = panelp->childGetValue("return_estate_wide").asBoolean(); - LLNotifications::instance().add("EstateObjectReturn", args, payload, - boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2)); -} - -bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID(); - if (!target_avatar.isNull()) - { - U32 flags = notification["payload"]["flags"].asInteger(); - bool return_estate_wide = notification["payload"]["return_estate_wide"]; - if (return_estate_wide) - { - // send as estate message - routed by spaceserver to all regions in estate - strings_t strings; - strings.push_back(llformat("%d", flags)); - strings.push_back(target_avatar.asString()); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); - } - else - { - // send to this simulator only - send_sim_wide_deletes(target_avatar, flags); - } - } - return false; -} - - -// static -void LLPanelRegionDebugInfo::onClickTopColliders(void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("1"); // one physics step - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); - self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); -} - -// static -void LLPanelRegionDebugInfo::onClickTopScripts(void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("6"); // top 5 scripts - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); - self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); -} - -// static -void LLPanelRegionDebugInfo::onClickRestart(void* data) -{ - LLNotifications::instance().add("ConfirmRestart", LLSD(), LLSD(), - boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2)); -} - -bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - strings_t strings; - strings.push_back("120"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); - return false; -} - -// static -void LLPanelRegionDebugInfo::onClickCancelRestart(void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("-1"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); -} - - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionTextureInfo -// -LLPanelRegionTextureInfo::LLPanelRegionTextureInfo() : LLPanelRegionInfo() -{ - // nothing. -} - -bool LLPanelRegionTextureInfo::refreshFromRegion(LLViewerRegion* region) -{ - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - childDisable("apply_btn"); - - if (region) - { - childSetValue("region_text", LLSD(region->getName())); - } - else - { - childSetValue("region_text", LLSD("")); - } - - if (!region) return LLPanelRegionInfo::refreshFromRegion(region); - - LLVLComposition* compp = region->getComposition(); - LLTextureCtrl* texture_ctrl; - std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); - if(texture_ctrl) - { - lldebugs << "Detail Texture " << i << ": " - << compp->getDetailTextureID(i) << llendl; - LLUUID tmp_id(compp->getDetailTextureID(i)); - texture_ctrl->setImageAssetID(tmp_id); - } - } - - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - childSetValue(buffer, LLSD(compp->getStartHeight(i))); - buffer = llformat("height_range_spin_%d", i); - childSetValue(buffer, LLSD(compp->getHeightRange(i))); - } - - // Call the parent for common book-keeping - return LLPanelRegionInfo::refreshFromRegion(region); -} - - -BOOL LLPanelRegionTextureInfo::postBuild() -{ - LLPanelRegionInfo::postBuild(); - std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - initCtrl(buffer); - } - - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - initCtrl(buffer); - buffer = llformat("height_range_spin_%d", i); - initCtrl(buffer); - } - -// LLButton* btn = new LLButton("dump", LLRect(0, 20, 100, 0), "", onClickDump, this); -// btn->setFollows(FOLLOWS_TOP|FOLLOWS_LEFT); -// addChild(btn); - - return LLPanelRegionInfo::postBuild(); -} - -BOOL LLPanelRegionTextureInfo::sendUpdate() -{ - llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl; - - // Make sure user hasn't chosen wacky textures. - if (!validateTextureSizes()) - { - return FALSE; - } - - LLTextureCtrl* texture_ctrl; - std::string buffer; - std::string id_str; - LLMessageSystem* msg = gMessageSystem; - strings_t strings; - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); - if(texture_ctrl) - { - LLUUID tmp_id(texture_ctrl->getImageAssetID()); - tmp_id.toString(id_str); - buffer = llformat("%d %s", i, id_str.c_str()); - strings.push_back(buffer); - } - } - sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); - strings.clear(); - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - std::string buffer2 = llformat("height_range_spin_%d", i); - std::string buffer3 = llformat("%d %f %f", i, (F32)childGetValue(buffer).asReal(), (F32)childGetValue(buffer2).asReal()); - strings.push_back(buffer3); - } - sendEstateOwnerMessage(msg, "textureheights", invoice, strings); - strings.clear(); - sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); - return TRUE; -} - -BOOL LLPanelRegionTextureInfo::validateTextureSizes() -{ - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - std::string buffer; - buffer = llformat("texture_detail_%d", i); - LLTextureCtrl* texture_ctrl = getChild(buffer); - if (!texture_ctrl) continue; - - LLUUID image_asset_id = texture_ctrl->getImageAssetID(); - LLViewerImage* img = gImageList.getImage(image_asset_id); - S32 components = img->getComponents(); - // Must ask for highest resolution version's width. JC - S32 width = img->getWidth(0); - S32 height = img->getHeight(0); - - //llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl; - - if (components != 3) - { - LLSD args; - args["TEXTURE_NUM"] = i+1; - args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); - LLNotifications::instance().add("InvalidTerrainBitDepth", args); - return FALSE; - } - - if (width > 512 || height > 512) - { - - LLSD args; - args["TEXTURE_NUM"] = i+1; - args["TEXTURE_SIZE_X"] = width; - args["TEXTURE_SIZE_Y"] = height; - LLNotifications::instance().add("InvalidTerrainSize", args); - return FALSE; - - } - } - - return TRUE; -} - - -// static -void LLPanelRegionTextureInfo::onClickDump(void* data) -{ - llinfos << "LLPanelRegionTextureInfo::onClickDump()" << llendl; -} - - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionTerrainInfo -///////////////////////////////////////////////////////////////////////////// -BOOL LLPanelRegionTerrainInfo::postBuild() -{ - LLPanelRegionInfo::postBuild(); - - initHelpBtn("water_height_help", "HelpRegionWaterHeight"); - initHelpBtn("terrain_raise_help", "HelpRegionTerrainRaise"); - initHelpBtn("terrain_lower_help", "HelpRegionTerrainLower"); - initHelpBtn("upload_raw_help", "HelpRegionUploadRaw"); - initHelpBtn("download_raw_help", "HelpRegionDownloadRaw"); - initHelpBtn("use_estate_sun_help", "HelpRegionUseEstateSun"); - initHelpBtn("fixed_sun_help", "HelpRegionFixedSun"); - initHelpBtn("bake_terrain_help", "HelpRegionBakeTerrain"); - - initCtrl("water_height_spin"); - initCtrl("terrain_raise_spin"); - initCtrl("terrain_lower_spin"); - - initCtrl("fixed_sun_check"); - childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); - childSetCommitCallback("use_estate_sun_check", onChangeUseEstateTime, this); - childSetCommitCallback("sun_hour_slider", onChangeSunHour, this); - - childSetAction("download_raw_btn", onClickDownloadRaw, this); - childSetAction("upload_raw_btn", onClickUploadRaw, this); - childSetAction("bake_terrain_btn", onClickBakeTerrain, this); - - return TRUE; -} - -// virtual -bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) -{ - llinfos << "LLPanelRegionTerrainInfo::refreshFromRegion" << llendl; - - BOOL owner_or_god = gAgent.isGodlike() - || (region && (region->getOwner() == gAgent.getID())); - BOOL owner_or_god_or_manager = owner_or_god - || (region && region->isEstateManager()); - setCtrlsEnabled(owner_or_god_or_manager); - childDisable("apply_btn"); - - childSetEnabled("download_raw_btn", owner_or_god); - childSetEnabled("upload_raw_btn", owner_or_god); - childSetEnabled("bake_terrain_btn", owner_or_god); - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -// virtual -BOOL LLPanelRegionTerrainInfo::sendUpdate() -{ - llinfos << "LLPanelRegionTerrainInfo::sendUpdate" << llendl; - std::string buffer; - strings_t strings; - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - buffer = llformat("%f", (F32)childGetValue("water_height_spin").asReal()); - strings.push_back(buffer); - buffer = llformat("%f", (F32)childGetValue("terrain_raise_spin").asReal()); - strings.push_back(buffer); - buffer = llformat("%f", (F32)childGetValue("terrain_lower_spin").asReal()); - strings.push_back(buffer); - buffer = llformat("%s", (childGetValue("use_estate_sun_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - buffer = llformat("%s", (childGetValue("fixed_sun_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - buffer = llformat("%f", (F32)childGetValue("sun_hour_slider").asReal() ); - strings.push_back(buffer); - - // Grab estate information in case the user decided to set the - // region back to estate time. JC - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return true; - - LLTabContainer* tab = floater->getChild("region_panels"); - if (!tab) return true; - - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); - if (!panel) return true; - - BOOL estate_global_time = panel->getGlobalTime(); - BOOL estate_fixed_sun = panel->getFixedSun(); - F32 estate_sun_hour; - if (estate_global_time) - { - estate_sun_hour = 0.f; - } - else - { - estate_sun_hour = panel->getSunHour(); - } - - buffer = llformat("%s", (estate_global_time ? "Y" : "N") ); - strings.push_back(buffer); - buffer = llformat("%s", (estate_fixed_sun ? "Y" : "N") ); - strings.push_back(buffer); - buffer = llformat("%f", estate_sun_hour); - strings.push_back(buffer); - - sendEstateOwnerMessage(gMessageSystem, "setregionterrain", invoice, strings); - return TRUE; -} - -// static -void LLPanelRegionTerrainInfo::onChangeUseEstateTime(LLUICtrl* ctrl, void* user_data) -{ - LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; - if (!panel) return; - BOOL use_estate_sun = panel->childGetValue("use_estate_sun_check").asBoolean(); - panel->childSetEnabled("fixed_sun_check", !use_estate_sun); - panel->childSetEnabled("sun_hour_slider", !use_estate_sun); - if (use_estate_sun) - { - panel->childSetValue("fixed_sun_check", LLSD(FALSE)); - panel->childSetValue("sun_hour_slider", LLSD(0.f)); - } - panel->childEnable("apply_btn"); -} - -// static -void LLPanelRegionTerrainInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) -{ - LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; - if (!panel) return; - // Just enable the apply button. We let the sun-hour slider be enabled - // for both fixed-sun and non-fixed-sun. JC - panel->childEnable("apply_btn"); -} - -// static -void LLPanelRegionTerrainInfo::onChangeSunHour(LLUICtrl* ctrl, void*) -{ - // can't use userdata to get panel, slider uses it internally - LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) ctrl->getParent(); - if (!panel) return; - panel->childEnable("apply_btn"); -} - -// static -void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data) -{ - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw")) - { - llwarns << "No file" << llendl; - return; - } - std::string filepath = picker.getFirstFile(); - gXferManager->expectFileForRequest(filepath); - - LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; - strings_t strings; - strings.push_back("download filename"); - strings.push_back(filepath); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); -} - -// static -void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data) -{ - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW)) - { - llwarns << "No file" << llendl; - return; - } - std::string filepath = picker.getFirstFile(); - gXferManager->expectFileForTransfer(filepath); - - LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; - strings_t strings; - strings.push_back("upload filename"); - strings.push_back(filepath); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); - - LLNotifications::instance().add("RawUploadStarted"); -} - -// static -void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data) -{ - LLNotifications::instance().add( - LLNotification::Params("ConfirmBakeTerrain") - .functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2))); -} - -bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - strings_t strings; - strings.push_back("bake"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); - return false; -} - -///////////////////////////////////////////////////////////////////////////// -// LLPanelEstateInfo -// - -LLPanelEstateInfo::LLPanelEstateInfo() -: LLPanelRegionInfo(), - mEstateID(0) // invalid -{ -} - -// static -void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) -{ - std::string name; - -// name.assign("setowner"); -// static LLDispatchSetEstateOwner set_owner; -// dispatch.addHandler(name, &set_owner); - - name.assign("estateupdateinfo"); - static LLDispatchEstateUpdateInfo estate_update_info; - dispatch.addHandler(name, &estate_update_info); - - name.assign("setaccess"); - static LLDispatchSetEstateAccess set_access; - dispatch.addHandler(name, &set_access); - - estate_dispatch_initialized = true; -} - -// static -// Disables the sun-hour slider and the use fixed time check if the use global time is check -void LLPanelEstateInfo::onChangeUseGlobalTime(LLUICtrl* ctrl, void* user_data) -{ - LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; - if (panel) - { - bool enabled = !panel->childGetValue("use_global_time_check").asBoolean(); - panel->childSetEnabled("sun_hour_slider", enabled); - panel->childSetEnabled("fixed_sun_check", enabled); - panel->childSetValue("fixed_sun_check", LLSD(FALSE)); - panel->enableButton("apply_btn"); - } -} - -// Enables the sun-hour slider if the fixed-sun checkbox is set -void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) -{ - LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; - if (panel) - { - bool enabled = !panel->childGetValue("fixed_sun_check").asBoolean(); - panel->childSetEnabled("use_global_time_check", enabled); - panel->childSetValue("use_global_time_check", LLSD(FALSE)); - panel->enableButton("apply_btn"); - } -} - - - - -//--------------------------------------------------------------------------- -// Add/Remove estate access button callbacks -//--------------------------------------------------------------------------- -void LLPanelEstateInfo::onClickEditSky(void* user_data) -{ - LLFloaterWindLight::show(); -} - -void LLPanelEstateInfo::onClickEditDayCycle(void* user_data) -{ - LLFloaterDayCycle::show(); -} - -// static -void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("allowed_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - //args - - LLSD args; - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAllowedAgentOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); -} - -// static -void LLPanelEstateInfo::onClickRemoveAllowedAgent(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("allowed_group_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAllowedGroupsOnRegion", args); - return; - } - - LLNotification::Params params("ChangeLindenAccess"); - params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2)); - if (isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } -} - -bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - LLFloaterGroupPicker* widget; - widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - if (widget) - { - widget->setSelectCallback(addAllowedGroup2, NULL); - if (parent_floater) - { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); - widget->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(widget); - } - } - - return false; -} - -// static -void LLPanelEstateInfo::onClickRemoveAllowedGroup(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddBannedAgent(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("banned_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxBannedAgentsOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); -} - -// static -void LLPanelEstateInfo::onClickRemoveBannedAgent(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddEstateManager(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("estate_manager_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_MANAGERS) - { // Tell user they can't add more managers - LLSD args; - args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS); - LLNotifications::instance().add("MaxManagersOnRegion", args); - } - else - { // Go pick managers to add - accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); - } -} - -// static -void LLPanelEstateInfo::onClickRemoveEstateManager(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); -} - -//--------------------------------------------------------------------------- -// Kick from estate methods -//--------------------------------------------------------------------------- -struct LLKickFromEstateInfo -{ - LLPanelEstateInfo *mEstatePanelp; - LLUUID mAgentID; -}; - -void LLPanelEstateInfo::onClickKickUser(void *user_data) -{ - LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data; - - // this depends on the grandparent view being a floater - // in order to set up floater dependency - LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - LLFloater* child_floater = LLFloaterAvatarPicker::show(LLPanelEstateInfo::onKickUserCommit, user_data, FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); -} - -void LLPanelEstateInfo::onKickUserCommit(const std::vector& names, const std::vector& ids, void* userdata) -{ - if (names.empty() || ids.empty()) return; - - //check to make sure there is one valid user and id - if( (ids[0].isNull()) || - (names[0].length() == 0) ) - { - return; - } - - LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata; - if(!self) return; - - //keep track of what user they want to kick and other misc info - LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo(); - kick_info->mEstatePanelp = self; - kick_info->mAgentID = ids[0]; - - //Bring up a confirmation dialog - LLSD args; - args["EVIL_USER"] = names[0]; - LLSD payload; - payload["agent_id"] = ids[0]; - LLNotifications::instance().add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2)); - -} - -bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - switch(option) - { - case 0: - { - //Kick User - strings_t strings; - strings.push_back(notification["payload"]["agent_id"].asString()); - - sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); - break; - } - default: - break; - } - return false; -} - -//--------------------------------------------------------------------------- -// Core Add/Remove estate access methods -// TODO: INTERNATIONAL: don't build message text here; -// instead, create multiple translatable messages and choose -// one based on the status. -//--------------------------------------------------------------------------- -std::string all_estates_text() -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return "(error)"; - - std::string owner = panel->getOwnerName(); - - LLViewerRegion* region = gAgent.getRegion(); - if (gAgent.isGodlike()) - { - return llformat("all estates\nowned by %s", owner.c_str()); - } - else if (region && region->getOwner() == gAgent.getID()) - { - return "all estates you own"; - } - else if (region && region->isEstateManager()) - { - return llformat("all estates that\nyou manage for %s", owner.c_str()); - } - else - { - return "(error)"; - } -} - -// static -bool LLPanelEstateInfo::isLindenEstate() -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return false; - - U32 estate_id = panel->getEstateID(); - return (estate_id <= ESTATE_LAST_LINDEN); -} - -typedef std::vector AgentOrGroupIDsVector; -struct LLEstateAccessChangeInfo -{ - LLEstateAccessChangeInfo(const LLSD& sd) - { - mDialogName = sd["dialog_name"].asString(); - mOperationFlag = (U32)sd["operation"].asInteger(); - LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray(); - for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray(); - id_it != end_it; - ++id_it) - { - mAgentOrGroupIDs.push_back(id_it->asUUID()); - } - } - - const LLSD asLLSD() const - { - LLSD sd; - sd["name"] = mDialogName; - sd["operation"] = (S32)mOperationFlag; - for (AgentOrGroupIDsVector::const_iterator it = mAgentOrGroupIDs.begin(); - it != mAgentOrGroupIDs.end(); - ++it) - { - sd["allowed_ids"].append(*it); - } - return sd; - } - - U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. - std::string mDialogName; - AgentOrGroupIDsVector mAgentOrGroupIDs; // List of agent IDs to apply to this change -}; - -// Special case callback for groups, since it has different callback format than names -// static -void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data) -{ - LLSD payload; - payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; - payload["dialog_name"] = "EstateAllowedGroupAdd"; - payload["allowed_ids"].append(id); - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params("EstateAllowedGroupAdd"); - params.payload(payload) - .substitutions(args) - .functor(accessCoreConfirm); - if (isLindenEstate()) - { - LLNotifications::instance().forceResponse(params, 0); - } - else - { - LLNotifications::instance().add(params); - } -} - -// static -void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name) -{ - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - // agent id filled in after avatar picker - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor(accessAddCore2); - - if (isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - // same as clicking "OK" - LLNotifications::instance().forceResponse(params, 0); - } -} - -// static -bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) - { - // abort change - return false; - } - - LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); - // avatar picker yes multi-select, yes close-on-select - LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE); - return false; -} - -// static -void LLPanelEstateInfo::accessAddCore3(const std::vector& names, const std::vector& ids, void* data) -{ - LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; - if (!change_info) return; - if (ids.empty()) - { - // User didn't select a name. - delete change_info; - change_info = NULL; - return; - } - // User did select a name. - change_info->mAgentOrGroupIDs = ids; - // Can't put estate owner on ban list - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return; - LLViewerRegion* region = gAgent.getRegion(); - if (!region) return; - - if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) - { - LLCtrlListInterface *list = panel->childGetListInterface("allowed_avatar_name_list"); - int currentCount = (list ? list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d",ids.size()); - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = "Allowed Residents"; - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - } - if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) - { - LLCtrlListInterface *list = panel->childGetListInterface("banned_avatar_name_list"); - int currentCount = (list ? list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d",ids.size()); - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = "Banned Residents"; - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - } - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params(change_info->mDialogName); - params.substitutions(args) - .payload(change_info->asLLSD()) - .functor(accessCoreConfirm); - - if (isLindenEstate()) - { - // just apply to this estate - LLNotifications::instance().forceResponse(params, 0); - } - else - { - // ask if this estate or all estates with this owner - LLNotifications::instance().add(params); - } -} - -// static -void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return; - LLNameListCtrl* name_list = panel->getChild(list_ctrl_name); - if (!name_list) return; - - std::vector list_vector = name_list->getAllSelected(); - if (list_vector.size() == 0) - return; - - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - - for (std::vector::const_iterator iter = list_vector.begin(); - iter != list_vector.end(); - iter++) - { - LLScrollListItem *item = (*iter); - payload["allowed_ids"].append(item->getUUID()); - } - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor(accessRemoveCore2); - - if (isLindenEstate()) - { - // warn on change linden estate - LLNotifications::instance().add(params); - } - else - { - // just proceed, as if clicking OK - LLNotifications::instance().forceResponse(params, 0); - } -} - -// static -bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) - { - // abort - return false; - } - - // If Linden estate, can only apply to "this" estate, not all estates - // owned by NULL. - if (isLindenEstate()) - { - accessCoreConfirm(notification, response); - } - else - { - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - LLNotifications::instance().add(notification["payload"]["dialog_name"], - args, - notification["payload"], - accessCoreConfirm); - } - return false; -} - -// Used for both access add and remove operations, depending on the mOperationFlag -// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.) -// static -bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); - - LLViewerRegion* region = gAgent.getRegion(); - - LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); - - for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); - iter != end_it; - iter++) - { - U32 flags = originalFlags; - if (iter + 1 != end_it) - flags |= ESTATE_ACCESS_NO_REPLY; - - const LLUUID id = iter->asUUID(); - if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) - && region && (region->getOwner() == id)) - { - LLNotifications::instance().add("OwnerCanNotBeDenied"); - break; - } - switch(option) - { - case 0: - // This estate - sendEstateAccessDelta(flags, id); - break; - case 1: - { - // All estates, either than I own or manage for this owner. - // This will be verified on simulator. JC - if (!region) break; - if (region->getOwner() == gAgent.getID() - || gAgent.isGodlike()) - { - flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; - sendEstateAccessDelta(flags, id); - } - else if (region->isEstateManager()) - { - flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; - sendEstateAccessDelta(flags, id); - } - break; - } - case 2: - default: - break; - } - } - return false; -} - -// key = "estateaccessdelta" -// str(estate_id) will be added to front of list by forward_EstateOwnerRequest_to_dataserver -// str[0] = str(agent_id) requesting the change -// str[1] = str(flags) (ESTATE_ACCESS_DELTA_*) -// str[2] = str(agent_id) to add or remove -// static -void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estateaccessdelta"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - std::string buf; - gAgent.getID().toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - buf = llformat("%u", flags); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - agent_or_group_id.toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - - if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | - ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) - { - - panel->clearAccessLists(); - } - - gAgent.sendReliableMessage(); -} - -void LLPanelEstateInfo::updateControls(LLViewerRegion* region) -{ - BOOL god = gAgent.isGodlike(); - BOOL owner = (region && (region->getOwner() == gAgent.getID())); - BOOL manager = (region && region->isEstateManager()); - setCtrlsEnabled(god || owner || manager); - - childDisable("apply_btn"); - childSetEnabled("add_allowed_avatar_btn", god || owner || manager); - childSetEnabled("remove_allowed_avatar_btn", god || owner || manager); - childSetEnabled("add_allowed_group_btn", god || owner || manager); - childSetEnabled("remove_allowed_group_btn", god || owner || manager); - childSetEnabled("add_banned_avatar_btn", god || owner || manager); - childSetEnabled("remove_banned_avatar_btn", god || owner || manager); - childSetEnabled("message_estate_btn", god || owner || manager); - childSetEnabled("kick_user_from_estate_btn", god || owner || manager); -#if ELAR_ENABLED - childSetEnabled("abuse_email_address", god || owner || manager); -#else - childSetEnabled("abuse_email_address", false); -#endif - - // estate managers can't add estate managers - childSetEnabled("add_estate_manager_btn", god || owner); - childSetEnabled("remove_estate_manager_btn", god || owner); - childSetEnabled("estate_manager_name_list", god || owner); -} - -bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) -{ - updateControls(region); - - // let the parent class handle the general data collection. - bool rv = LLPanelRegionInfo::refreshFromRegion(region); - - // We want estate info. To make sure it works across region - // boundaries and multiple packets, we add a serial number to the - // integers and track against that on update. - strings_t strings; - //integers_t integers; - //LLFloaterRegionInfo::incrementSerial(); - LLFloaterRegionInfo::nextInvoice(); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); - - - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - panel->clearAccessLists(); - - - sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); - - refresh(); - - return rv; -} - -void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) -{ - if (checkRemovalButton(child_ctrl->getName())) - { - // do nothing - } - else if (checkSunHourSlider(child_ctrl)) - { - // do nothing - } -} - -bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) -{ - llinfos << "LLPanelEstateInfo::estateUpdate()" << llendl; - return false; -} - - -BOOL LLPanelEstateInfo::postBuild() -{ - // set up the callbacks for the generic controls - initCtrl("externally_visible_check"); - initCtrl("use_global_time_check"); - initCtrl("fixed_sun_check"); - initCtrl("allow_direct_teleport"); - initCtrl("limit_payment"); - initCtrl("limit_age_verified"); - initCtrl("voice_chat_check"); - childSetCommitCallback("abuse_email_address", onChangeAnything, this); - childSetKeystrokeCallback("abuse_email_address", onChangeText, this); - - initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); - initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); - initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); - initHelpBtn("WLEditSkyHelp", "HelpEditSky"); - initHelpBtn("WLEditDayCycleHelp", "HelpEditDayCycle"); - - initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); - initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); - initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); - initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); - initHelpBtn("ban_resident_help", "HelpEstateBanResident"); - initHelpBtn("abuse_email_address_help", "HelpEstateAbuseEmailAddress"); - initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); - - // set up the use global time checkbox - childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this); - childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); - childSetCommitCallback("sun_hour_slider", onChangeChildCtrl, this); - - childSetCommitCallback("allowed_avatar_name_list", onChangeChildCtrl, this); - LLNameListCtrl *avatar_name_list = getChild("allowed_avatar_name_list"); - if (avatar_name_list) - { - avatar_name_list->setCommitOnSelectionChange(TRUE); - avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_allowed_avatar_btn", onClickAddAllowedAgent, this); - childSetAction("remove_allowed_avatar_btn", onClickRemoveAllowedAgent, this); - - childSetCommitCallback("allowed_group_name_list", onChangeChildCtrl, this); - LLNameListCtrl* group_name_list = getChild("allowed_group_name_list"); - if (group_name_list) - { - group_name_list->setCommitOnSelectionChange(TRUE); - group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_allowed_group_btn", onClickAddAllowedGroup, this); - childSetAction("remove_allowed_group_btn", onClickRemoveAllowedGroup, this); - - childSetCommitCallback("banned_avatar_name_list", onChangeChildCtrl, this); - LLNameListCtrl* banned_name_list = getChild("banned_avatar_name_list"); - if (banned_name_list) - { - banned_name_list->setCommitOnSelectionChange(TRUE); - banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_banned_avatar_btn", onClickAddBannedAgent, this); - childSetAction("remove_banned_avatar_btn", onClickRemoveBannedAgent, this); - - childSetCommitCallback("estate_manager_name_list", onChangeChildCtrl, this); - LLNameListCtrl* manager_name_list = getChild("estate_manager_name_list"); - if (manager_name_list) - { - manager_name_list->setCommitOnSelectionChange(TRUE); - manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue - } - - childSetAction("add_estate_manager_btn", onClickAddEstateManager, this); - childSetAction("remove_estate_manager_btn", onClickRemoveEstateManager, this); - childSetAction("message_estate_btn", onClickMessageEstate, this); - childSetAction("kick_user_from_estate_btn", onClickKickUser, this); - - childSetAction("WLEditSky", onClickEditSky, this); - childSetAction("WLEditDayCycle", onClickEditDayCycle, this); - - return LLPanelRegionInfo::postBuild(); -} - -void LLPanelEstateInfo::refresh() -{ - bool public_access = childGetValue("externally_visible_check").asBoolean(); - childSetEnabled("Only Allow", public_access); - childSetEnabled("limit_payment", public_access); - childSetEnabled("limit_age_verified", public_access); - // if this is set to false, then the limit fields are meaningless and should be turned off - if (public_access == false) - { - childSetValue("limit_payment", false); - childSetValue("limit_age_verified", false); - } -} - -BOOL LLPanelEstateInfo::sendUpdate() -{ - llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl; - - LLNotification::Params params("ChangeLindenEstate"); - params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2)); - - if (getEstateID() <= ESTATE_LAST_LINDEN) - { - // trying to change reserved estate, warn - LLNotifications::instance().add(params); - } - else - { - // for normal estates, just make the change - LLNotifications::instance().forceResponse(params, 0); - } - return TRUE; -} - -bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - switch(option) - { - case 0: - // send the update - if (!commitEstateInfoCaps()) - { - // the caps method failed, try the old way - LLFloaterRegionInfo::nextInvoice(); - commitEstateInfoDataserver(); - } - // we don't want to do this because we'll get it automatically from the sim - // after the spaceserver processes it -// else -// { -// // caps method does not automatically send this info -// LLFloaterRegionInfo::requestRegionInfo(); -// } - break; - case 1: - default: - // do nothing - break; - } - return false; -} - - -/* -// Request = "getowner" -// SParam[0] = "" (empty string) -// IParam[0] = serial -void LLPanelEstateInfo::getEstateOwner() -{ - // TODO -- disable the panel - // and call this function whenever we cross a region boundary - // re-enable when owner matches, and get new estate info - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_EstateOwnerRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - - msg->nextBlockFast(_PREHASH_RequestData); - msg->addStringFast(_PREHASH_Request, "getowner"); - - // we send an empty string so that the variable block is not empty - msg->nextBlockFast(_PREHASH_StringData); - msg->addStringFast(_PREHASH_SParam, ""); - - msg->nextBlockFast(_PREHASH_IntegerData); - msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial()); - - gAgent.sendMessage(); -} -*/ - -class LLEstateChangeInfoResponder : public LLHTTPClient::Responder -{ -public: - LLEstateChangeInfoResponder(void* userdata) : mpPanel((LLPanelEstateInfo*)userdata) {}; - - // if we get a normal response, handle it here - virtual void result(const LLSD& content) - { - // refresh the panel from the database - mpPanel->refresh(); - } - - // if we get an error response - virtual void error(U32 status, const std::string& reason) - { - llinfos << "LLEstateChangeInfoResponder::error " - << status << ": " << reason << llendl; - } -private: - LLPanelEstateInfo* mpPanel; -}; - -// tries to send estate info using a cap; returns true if it succeeded -bool LLPanelEstateInfo::commitEstateInfoCaps() -{ - std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo"); - - if (url.empty()) - { - // whoops, couldn't find the cap, so bail out - return false; - } - - LLSD body; - body["estate_name"] = getEstateName(); - - body["is_externally_visible"] = childGetValue("externally_visible_check").asBoolean(); - body["allow_direct_teleport"] = childGetValue("allow_direct_teleport").asBoolean(); - body["is_sun_fixed" ] = childGetValue("fixed_sun_check").asBoolean(); - body["deny_anonymous" ] = childGetValue("limit_payment").asBoolean(); - body["deny_age_unverified" ] = childGetValue("limit_age_verified").asBoolean(); - body["allow_voice_chat" ] = childGetValue("voice_chat_check").asBoolean(); - body["invoice" ] = LLFloaterRegionInfo::getLastInvoice(); - - // block fly is in estate database but not in estate UI, so we're not supporting it - //body["block_fly" ] = childGetValue("").asBoolean(); - - F32 sun_hour = getSunHour(); - if (childGetValue("use_global_time_check").asBoolean()) - { - sun_hour = 0.f; // 0 = global time - } - body["sun_hour"] = sun_hour; - - body["owner_abuse_email"] = childGetValue("abuse_email_address").asString(); - - // we use a responder so that we can re-get the data after committing to the database - LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder((void*)this)); - return true; -} - -/* This is the old way of doing things, is deprecated, and should be - deleted when the dataserver model can be removed */ -// key = "estatechangeinfo" -// strings[0] = str(estate_id) (added by simulator before relay - not here) -// strings[1] = estate_name -// strings[2] = str(estate_flags) -// strings[3] = str((S32)(sun_hour * 1024.f)) -void LLPanelEstateInfo::commitEstateInfoDataserver() -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estatechangeinfo"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - msg->nextBlock("ParamList"); - msg->addString("Parameter", getEstateName()); - - std::string buffer; - buffer = llformat("%u", computeEstateFlags()); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - - F32 sun_hour = getSunHour(); - if (childGetValue("use_global_time_check").asBoolean()) - { - sun_hour = 0.f; // 0 = global time - } - - buffer = llformat("%d", (S32)(sun_hour*1024.0f)); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - - gAgent.sendMessage(); -} - -void LLPanelEstateInfo::setEstateFlags(U32 flags) -{ - childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) ); - childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) ); - childSetValue( - "voice_chat_check", - LLSD(flags & REGION_FLAGS_ALLOW_VOICE ? TRUE : FALSE)); - childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); - childSetValue("limit_payment", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); - childSetValue("limit_age_verified", LLSD(flags & REGION_FLAGS_DENY_AGEUNVERIFIED ? TRUE : FALSE) ); - - refresh(); -} - -U32 LLPanelEstateInfo::computeEstateFlags() -{ - U32 flags = 0; - - if (childGetValue("externally_visible_check").asBoolean()) - { - flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; - } - - if ( childGetValue("voice_chat_check").asBoolean() ) - { - flags |= REGION_FLAGS_ALLOW_VOICE; - } - - if (childGetValue("allow_direct_teleport").asBoolean()) - { - flags |= REGION_FLAGS_ALLOW_DIRECT_TELEPORT; - } - - if (childGetValue("fixed_sun_check").asBoolean()) - { - flags |= REGION_FLAGS_SUN_FIXED; - } - - if (childGetValue("limit_payment").asBoolean()) - { - flags |= REGION_FLAGS_DENY_ANONYMOUS; - } - - if (childGetValue("limit_age_verified").asBoolean()) - { - flags |= REGION_FLAGS_DENY_AGEUNVERIFIED; - } - - - return flags; -} - -BOOL LLPanelEstateInfo::getGlobalTime() -{ - return childGetValue("use_global_time_check").asBoolean(); -} - -void LLPanelEstateInfo::setGlobalTime(bool b) -{ - childSetValue("use_global_time_check", LLSD(b)); - childSetEnabled("fixed_sun_check", LLSD(!b)); - childSetEnabled("sun_hour_slider", LLSD(!b)); - if (b) - { - childSetValue("sun_hour_slider", LLSD(0.f)); - } -} - - -BOOL LLPanelEstateInfo::getFixedSun() -{ - return childGetValue("fixed_sun_check").asBoolean(); -} - -void LLPanelEstateInfo::setSunHour(F32 sun_hour) -{ - if(sun_hour < 6.0f) - { - sun_hour = 24.0f + sun_hour; - } - childSetValue("sun_hour_slider", LLSD(sun_hour)); -} - -F32 LLPanelEstateInfo::getSunHour() -{ - if (childIsEnabled("sun_hour_slider")) - { - return (F32)childGetValue("sun_hour_slider").asReal(); - } - return 0.f; -} - -const std::string LLPanelEstateInfo::getEstateName() const -{ - return childGetValue("estate_name").asString(); -} - -void LLPanelEstateInfo::setEstateName(const std::string& name) -{ - childSetValue("estate_name", LLSD(name)); -} - -const std::string LLPanelEstateInfo::getOwnerName() const -{ - return childGetValue("estate_owner").asString(); -} - -void LLPanelEstateInfo::setOwnerName(const std::string& name) -{ - childSetValue("estate_owner", LLSD(name)); -} - -const std::string LLPanelEstateInfo::getAbuseEmailAddress() const -{ - return childGetValue("abuse_email_address").asString(); -} - -void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address) -{ - childSetValue("abuse_email_address", LLSD(address)); -} - -void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, - bool enable_group, - bool enable_ban) -{ - childSetEnabled("allow_resident_label", enable_agent); - childSetEnabled("allowed_avatar_name_list", enable_agent); - childSetVisible("allowed_avatar_name_list", enable_agent); - childSetEnabled("add_allowed_avatar_btn", enable_agent); - childSetEnabled("remove_allowed_avatar_btn", enable_agent); - - // Groups - childSetEnabled("allow_group_label", enable_group); - childSetEnabled("allowed_group_name_list", enable_group); - childSetVisible("allowed_group_name_list", enable_group); - childSetEnabled("add_allowed_group_btn", enable_group); - childSetEnabled("remove_allowed_group_btn", enable_group); - - // Ban - childSetEnabled("ban_resident_label", enable_ban); - childSetEnabled("banned_avatar_name_list", enable_ban); - childSetVisible("banned_avatar_name_list", enable_ban); - childSetEnabled("add_banned_avatar_btn", enable_ban); - childSetEnabled("remove_banned_avatar_btn", enable_ban); - - // Update removal buttons if needed - if (enable_agent) - { - checkRemovalButton("allowed_avatar_name_list"); - } - - if (enable_group) - { - checkRemovalButton("allowed_group_name_list"); - } - - if (enable_ban) - { - checkRemovalButton("banned_avatar_name_list"); - } -} - -// static -void LLPanelEstateInfo::callbackCacheName( - const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group, - void*) -{ - LLPanelEstateInfo* self = LLFloaterRegionInfo::getPanelEstate(); - if (!self) return; - - std::string name; - - if (id.isNull()) - { - name = "(none)"; - } - else - { - name = first + " " + last; - } - - self->setOwnerName(name); -} - -void LLPanelEstateInfo::clearAccessLists() -{ - LLNameListCtrl* name_list = getChild("allowed_avatar_name_list"); - if (name_list) - { - name_list->deleteAllItems(); - } - - name_list = getChild("banned_avatar_name_list"); - if (name_list) - { - name_list->deleteAllItems(); - } -} - -// enables/disables the "remove" button for the various allow/ban lists -BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) -{ - std::string btn_name = ""; - if (name == "allowed_avatar_name_list") - { - btn_name = "remove_allowed_avatar_btn"; - } - else if (name == "allowed_group_name_list") - { - btn_name = "remove_allowed_group_btn"; - } - else if (name == "banned_avatar_name_list") - { - btn_name = "remove_banned_avatar_btn"; - } - else if (name == "estate_manager_name_list") - { - //ONLY OWNER CAN ADD /DELET ESTATE MANAGER - LLViewerRegion* region = gAgent.getRegion(); - if (region && (region->getOwner() == gAgent.getID())) - { - btn_name = "remove_estate_manager_btn"; - } - } - - // enable the remove button if something is selected - LLNameListCtrl* name_list = getChild(name); - childSetEnabled(btn_name, name_list && name_list->getFirstSelected() ? TRUE : FALSE); - - return (btn_name != ""); -} - -BOOL LLPanelEstateInfo::checkSunHourSlider(LLUICtrl* child_ctrl) -{ - BOOL found_child_ctrl = FALSE; - if (child_ctrl->getName() == "sun_hour_slider") - { - enableButton("apply_btn"); - found_child_ctrl = TRUE; - } - return found_child_ctrl; -} - -// static -void LLPanelEstateInfo::onClickMessageEstate(void* userdata) -{ - llinfos << "LLPanelEstateInfo::onClickMessageEstate" << llendl; - LLNotifications::instance().add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2)); -} - -bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - std::string text = response["message"].asString(); - if(option != 0) return false; - if(text.empty()) return false; - llinfos << "Message to everyone: " << text << llendl; - strings_t strings; - //integers_t integers; - std::string name; - gAgent.buildFullname(name); - strings.push_back(strings_t::value_type(name)); - strings.push_back(strings_t::value_type(text)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); - return false; -} - -LLPanelEstateCovenant::LLPanelEstateCovenant() -: mCovenantID(LLUUID::null) -{ -} - -// virtual -bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) -{ - LLTextBox* region_name = getChild("region_name_text"); - if (region_name) - { - region_name->setText(region->getName()); - } - - LLTextBox* resellable_clause = getChild("resellable_clause"); - if (resellable_clause) - { - if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) - { - resellable_clause->setText(getString("can_not_resell")); - } - else - { - resellable_clause->setText(getString("can_resell")); - } - } - - LLTextBox* changeable_clause = getChild("changeable_clause"); - if (changeable_clause) - { - if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) - { - changeable_clause->setText(getString("can_change")); - } - else - { - changeable_clause->setText(getString("can_not_change")); - } - } - - LLTextBox* region_maturity = getChild("region_maturity_text"); - if (region_maturity) - { - region_maturity->setText(region->getSimAccessString()); - } - - LLTextBox* region_landtype = getChild("region_landtype_text"); - if (region_landtype) - { - region_landtype->setText(region->getSimProductName()); - } - - - // let the parent class handle the general data collection. - bool rv = LLPanelRegionInfo::refreshFromRegion(region); - LLMessageSystem *msg = gMessageSystem; - msg->newMessage("EstateCovenantRequest"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); - msg->sendReliable(region->getHost()); - return rv; -} - -// virtual -bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg) -{ - llinfos << "LLPanelEstateCovenant::estateUpdate()" << llendl; - return true; -} - -// virtual -BOOL LLPanelEstateCovenant::postBuild() -{ - initHelpBtn("covenant_help", "HelpEstateCovenant"); - mEstateNameText = getChild("estate_name_text"); - mEstateOwnerText = getChild("estate_owner_text"); - mLastModifiedText = getChild("covenant_timestamp_text"); - mEditor = getChild("covenant_editor"); - if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE); - LLButton* reset_button = getChild("reset_covenant"); - reset_button->setEnabled(gAgent.canManageEstate()); - reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); - - return LLPanelRegionInfo::postBuild(); -} - -// virtual -void LLPanelEstateCovenant::updateChild(LLUICtrl* child_ctrl) -{ -} - -// virtual -BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - LLInventoryItem* item = (LLInventoryItem*)cargo_data; - - if (!gAgent.canManageEstate()) - { - *accept = ACCEPT_NO; - return TRUE; - } - - switch(cargo_type) - { - case DAD_NOTECARD: - *accept = ACCEPT_YES_COPY_SINGLE; - if (item && drop) - { - LLSD payload; - payload["item_id"] = item->getUUID(); - LLNotifications::instance().add("EstateChangeCovenant", LLSD(), payload, - LLPanelEstateCovenant::confirmChangeCovenantCallback); - } - break; - default: - *accept = ACCEPT_NO; - break; - } - - return TRUE; -} - -// static -bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); - - if (!item || !self) return false; - - switch(option) - { - case 0: - self->loadInvItem(item); - break; - default: - break; - } - return false; -} - -// static -void LLPanelEstateCovenant::resetCovenantID(void* userdata) -{ - LLNotifications::instance().add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback); -} - -// static -bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response) -{ - LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); - if (!self) return false; - - S32 option = LLNotification::getSelectedOption(notification, response); - switch(option) - { - case 0: - self->loadInvItem(NULL); - break; - default: - break; - } - return false; -} - -void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp) -{ - const BOOL high_priority = TRUE; - if (itemp) - { - gAssetStorage->getInvItemAsset(gAgent.getRegionHost(), - gAgent.getID(), - gAgent.getSessionID(), - itemp->getPermissions().getOwner(), - LLUUID::null, - itemp->getUUID(), - itemp->getAssetUUID(), - itemp->getType(), - onLoadComplete, - (void*)this, - high_priority); - mAssetStatus = ASSET_LOADING; - } - else - { - mAssetStatus = ASSET_LOADED; - setCovenantTextEditor("There is no Covenant provided for this Estate."); - sendChangeCovenantID(LLUUID::null); - } -} - -// static -void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs, - const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) -{ - llinfos << "LLPanelEstateCovenant::onLoadComplete()" << llendl; - LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data; - if( panelp ) - { - if(0 == status) - { - LLVFile file(vfs, asset_uuid, type, LLVFile::READ); - - S32 file_length = file.getSize(); - - char* buffer = new char[file_length+1]; - if (buffer == NULL) - { - llerrs << "Memory Allocation Failed" << llendl; - return; - } - - file.read((U8*)buffer, file_length); /* Flawfinder: ignore */ - // put a EOS at the end - buffer[file_length] = 0; - - if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) - { - if( !panelp->mEditor->importBuffer( buffer, file_length+1 ) ) - { - llwarns << "Problem importing estate covenant." << llendl; - LLNotifications::instance().add("ProblemImportingEstateCovenant"); - } - else - { - panelp->sendChangeCovenantID(asset_uuid); - } - } - else - { - // Version 0 (just text, doesn't include version number) - panelp->sendChangeCovenantID(asset_uuid); - } - delete[] buffer; - } - else - { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || - LL_ERR_FILE_EMPTY == status) - { - LLNotifications::instance().add("MissingNotecardAssetID"); - } - else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) - { - LLNotifications::instance().add("NotAllowedToViewNotecard"); - } - else - { - LLNotifications::instance().add("UnableToLoadNotecardAsset"); - } - - llwarns << "Problem loading notecard: " << status << llendl; - } - panelp->mAssetStatus = ASSET_LOADED; - panelp->setCovenantID(asset_uuid); - } -} - -// key = "estatechangecovenantid" -// strings[0] = str(estate_id) (added by simulator before relay - not here) -// strings[1] = str(covenant_id) -void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id) -{ - if (asset_id != getCovenantID()) - { - setCovenantID(asset_id); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estatechangecovenantid"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - msg->nextBlock("ParamList"); - msg->addString("Parameter", getCovenantID().asString()); - gAgent.sendReliableMessage(); - } -} - -// virtual -BOOL LLPanelEstateCovenant::sendUpdate() -{ - return TRUE; -} - -const std::string& LLPanelEstateCovenant::getEstateName() const -{ - return mEstateNameText->getText(); -} - -void LLPanelEstateCovenant::setEstateName(const std::string& name) -{ - mEstateNameText->setText(name); -} - -// static -void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEditor->setText(string); - panelp->setCovenantID(asset_id); - } -} - -// static -void LLPanelEstateCovenant::updateEstateName(const std::string& name) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEstateNameText->setText(name); - } -} - -// static -void LLPanelEstateCovenant::updateLastModified(const std::string& text) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mLastModifiedText->setText(text); - } -} - -// static -void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEstateOwnerText->setText(name); - } -} - -const std::string& LLPanelEstateCovenant::getOwnerName() const -{ - return mEstateOwnerText->getText(); -} - -void LLPanelEstateCovenant::setOwnerName(const std::string& name) -{ - mEstateOwnerText->setText(name); -} - -void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text) -{ - mEditor->setText(text); -} - -// key = "estateupdateinfo" -// strings[0] = estate name -// strings[1] = str(owner_id) -// strings[2] = str(estate_id) -// strings[3] = str(estate_flags) -// strings[4] = str((S32)(sun_hour * 1024)) -// strings[5] = str(parent_estate_id) -// strings[6] = str(covenant_id) -// strings[7] = str(covenant_timestamp) -// strings[8] = str(send_to_agent_only) -// strings[9] = str(abuse_email_addr) -bool LLDispatchEstateUpdateInfo::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return true; - - // NOTE: LLDispatcher extracts strings with an extra \0 at the - // end. If we pass the std::string direct to the UI/renderer - // it draws with a weird character at the end of the string. - std::string estate_name = strings[0].c_str(); // preserve c_str() call! - panel->setEstateName(estate_name); - -#if ELAR_ENABLED - if (strings.size() > 9) - { - std::string abuse_email = strings[9].c_str(); // preserve c_str() call! - panel->setAbuseEmailAddress(abuse_email); - } - else -#endif - { - panel->setAbuseEmailAddress(panel->getString("email_unsupported")); - } - - LLViewerRegion* regionp = gAgent.getRegion(); - - LLUUID owner_id(strings[1]); - regionp->setOwner(owner_id); - // Update estate owner name in UI - const BOOL is_group = FALSE; - gCacheName->get(owner_id, is_group, LLPanelEstateInfo::callbackCacheName); - - U32 estate_id = strtoul(strings[2].c_str(), NULL, 10); - panel->setEstateID(estate_id); - - U32 flags = strtoul(strings[3].c_str(), NULL, 10); - panel->setEstateFlags(flags); - - F32 sun_hour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f; - if(sun_hour == 0 && (flags & REGION_FLAGS_SUN_FIXED ? FALSE : TRUE)) - { - panel->setGlobalTime(TRUE); - } - else - { - panel->setGlobalTime(FALSE); - panel->setSunHour(sun_hour); - } - - bool visible_from_mainland = (bool)(flags & REGION_FLAGS_EXTERNALLY_VISIBLE); - bool god = gAgent.isGodlike(); - bool linden_estate = (estate_id <= ESTATE_LAST_LINDEN); - - // If visible from mainland, disable the access allowed - // UI, as anyone can teleport there. - // However, gods need to be able to edit the access list for - // linden estates, regardless of visibility, to allow object - // and L$ transfers. - bool enable_agent = (!visible_from_mainland || (god && linden_estate)); - bool enable_group = enable_agent; - bool enable_ban = !linden_estate; - panel->setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); - - return true; -} - - -// key = "setaccess" -// strings[0] = str(estate_id) -// strings[1] = str(packed_access_lists) -// strings[2] = str(num allowed agent ids) -// strings[3] = str(num allowed group ids) -// strings[4] = str(num banned agent ids) -// strings[5] = str(num estate manager agent ids) -// strings[6] = bin(uuid) -// strings[7] = bin(uuid) -// strings[8] = bin(uuid) -// ... -bool LLDispatchSetEstateAccess::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return true; - - S32 index = 1; // skip estate_id - U32 access_flags = strtoul(strings[index++].c_str(), NULL,10); - S32 num_allowed_agents = strtol(strings[index++].c_str(), NULL, 10); - S32 num_allowed_groups = strtol(strings[index++].c_str(), NULL, 10); - S32 num_banned_agents = strtol(strings[index++].c_str(), NULL, 10); - S32 num_estate_managers = strtol(strings[index++].c_str(), NULL, 10); - - // sanity ckecks - if (num_allowed_agents > 0 - && !(access_flags & ESTATE_ACCESS_ALLOWED_AGENTS)) - { - llwarns << "non-zero count for allowed agents, but no corresponding flag" << llendl; - } - if (num_allowed_groups > 0 - && !(access_flags & ESTATE_ACCESS_ALLOWED_GROUPS)) - { - llwarns << "non-zero count for allowed groups, but no corresponding flag" << llendl; - } - if (num_banned_agents > 0 - && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) - { - llwarns << "non-zero count for banned agents, but no corresponding flag" << llendl; - } - if (num_estate_managers > 0 - && !(access_flags & ESTATE_ACCESS_MANAGERS)) - { - llwarns << "non-zero count for managers, but no corresponding flag" << llendl; - } - - // grab the UUID's out of the string fields - if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) - { - LLNameListCtrl* allowed_agent_name_list; - allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); - - int totalAllowedAgents = num_allowed_agents; - - if (allowed_agent_name_list) - { - totalAllowedAgents += allowed_agent_name_list->getItemCount(); - } - - std::string msg = llformat("Allowed residents: (%d, max %d)", - totalAllowedAgents, - ESTATE_MAX_ACCESS_IDS); - panel->childSetValue("allow_resident_label", LLSD(msg)); - - if (allowed_agent_name_list) - { - //allowed_agent_name_list->deleteAllItems(); - for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - allowed_agent_name_list->addNameItem(id); - } - panel->childSetEnabled("remove_allowed_avatar_btn", allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); - } - } - - if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) - { - LLNameListCtrl* allowed_group_name_list; - allowed_group_name_list = panel->getChild("allowed_group_name_list"); - - std::string msg = llformat("Allowed groups: (%d, max %d)", - num_allowed_groups, - (S32) ESTATE_MAX_GROUP_IDS); - panel->childSetValue("allow_group_label", LLSD(msg)); - - if (allowed_group_name_list) - { - allowed_group_name_list->deleteAllItems(); - for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - allowed_group_name_list->addGroupNameItem(id); - } - panel->childSetEnabled("remove_allowed_group_btn", allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); - } - } - - if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) - { - LLNameListCtrl* banned_agent_name_list; - banned_agent_name_list = panel->getChild("banned_avatar_name_list"); - - int totalBannedAgents = num_banned_agents; - - if (banned_agent_name_list) - { - totalBannedAgents += banned_agent_name_list->getItemCount(); - } - - - std::string msg = llformat("Banned residents: (%d, max %d)", - totalBannedAgents, - ESTATE_MAX_ACCESS_IDS); - panel->childSetValue("ban_resident_label", LLSD(msg)); - - if (banned_agent_name_list) - { - //banned_agent_name_list->deleteAllItems(); - for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - banned_agent_name_list->addNameItem(id); - } - panel->childSetEnabled("remove_banned_avatar_btn", banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); - } - } - - if (access_flags & ESTATE_ACCESS_MANAGERS) - { - std::string msg = llformat("Estate Managers: (%d, max %d)", - num_estate_managers, - ESTATE_MAX_MANAGERS); - panel->childSetValue("estate_manager_label", LLSD(msg)); - - LLNameListCtrl* estate_manager_name_list = - panel->getChild("estate_manager_name_list"); - if (estate_manager_name_list) - { - estate_manager_name_list->deleteAllItems(); // Clear existing entries - - // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't - // truncate the list unless it's really big. Go ahead and show the extras so the user doesn't get confused, - // and they can still remove them. - for (S32 i = 0; i < num_estate_managers && i < (ESTATE_MAX_MANAGERS * 4); i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - estate_manager_name_list->addNameItem(id); - } - panel->childSetEnabled("remove_estate_manager_btn", estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); - } - } - - return true; -} - -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) -void LLFloaterRegionInfo::open() -{ - // We'll allow access to the estate tools for estate managers (and for the sim owner) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - LLViewerRegion* pRegion = gAgent.getRegion(); - if (!pRegion) - return; - - // Should be able to call LLRegion::canManageEstate() but then we can fake god like - if ( (!pRegion->isEstateManager()) && (pRegion->getOwner() != gAgent.getID()) ) - return; - } - - LLFloater::open(); -} -// [/RLVa:KB] +/** + * @file llfloaterregioninfo.cpp + * @author Aaron Brashears + * @brief Implementation of the region info and controls floater and panels. + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterregioninfo.h" + +#include +#include + +#include "llcachename.h" +#include "lldir.h" +#include "lldispatcher.h" +#include "llglheaders.h" +#include "llregionflags.h" +#include "llstl.h" +#include "indra_constants.h" +#include "message.h" + +#include "llagent.h" +#include "llalertdialog.h" +#include "llappviewer.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfilepicker.h" +#include "llfloaterdaycycle.h" +#include "llfloatergodtools.h" // for send_sim_wide_deletes() +#include "llfloatertopobjects.h" // added to fix SL-32336 +#include "llfloatergroups.h" +#include "llfloatertelehub.h" +#include "llfloaterwindlight.h" +#include "llinventorymodel.h" +#include "lllineeditor.h" +#include "llalertdialog.h" +#include "llnamelistctrl.h" +#include "llsliderctrl.h" +#include "llspinctrl.h" +#include "lltabcontainer.h" +#include "lltextbox.h" +#include "llinventory.h" +#include "lltexturectrl.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "lluictrlfactory.h" +#include "llviewerimage.h" +#include "llviewerimagelist.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" +#include "llvlcomposition.h" +#include "hippoLimits.h" + +// [RLVa:KB] +#include "rlvhandler.h" +// [/RLVa:KB] + +#define ELAR_ENABLED 0 // Enable when server support is implemented + +const S32 TERRAIN_TEXTURE_COUNT = 4; +const S32 CORNER_COUNT = 4; + +///---------------------------------------------------------------------------- +/// Local class declaration +///---------------------------------------------------------------------------- + +class LLDispatchEstateUpdateInfo : public LLDispatchHandler +{ +public: + LLDispatchEstateUpdateInfo() {} + virtual ~LLDispatchEstateUpdateInfo() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); +}; + +class LLDispatchSetEstateAccess : public LLDispatchHandler +{ +public: + LLDispatchSetEstateAccess() {} + virtual ~LLDispatchSetEstateAccess() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); +}; + + +/* +void unpack_request_params( + LLMessageSystem* msg, + LLDispatcher::sparam_t& strings, + LLDispatcher::iparam_t& integers) +{ + char str_buf[MAX_STRING]; + S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData); + S32 i; + for (i = 0; i < str_count; ++i) + { + // we treat the SParam as binary data (since it might be an + // LLUUID in compressed form which may have embedded \0's,) + str_buf[0] = '\0'; + S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam); + if (data_size >= 0) + { + msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam, + str_buf, data_size, i, MAX_STRING - 1); + strings.push_back(std::string(str_buf, data_size)); + } + } + + U32 int_buf; + S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData); + for (i = 0; i < int_count; ++i) + { + msg->getU32("IntegerData", "IParam", int_buf, i); + integers.push_back(int_buf); + } +} +*/ + + + +bool estate_dispatch_initialized = false; + + +///---------------------------------------------------------------------------- +/// LLFloaterRegionInfo +///---------------------------------------------------------------------------- + +//S32 LLFloaterRegionInfo::sRequestSerial = 0; +LLUUID LLFloaterRegionInfo::sRequestInvoice; + +LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", NULL, FALSE); +} + +BOOL LLFloaterRegionInfo::postBuild() +{ + mTab = getChild("region_panels"); + + // contruct the panels + LLPanelRegionInfo* panel; + + panel = new LLPanelRegionGeneralInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml"); + mTab->addTabPanel(panel, panel->getLabel(), TRUE); + + panel = new LLPanelRegionOpenSettingsInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_open_region_settings.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelRegionDebugInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelRegionTextureInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_texture.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelRegionTerrainInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_terrain.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelEstateInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelEstateCovenant; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + gMessageSystem->setHandlerFunc( + "EstateOwnerMessage", + &processEstateOwnerRequest); + + return TRUE; +} + +LLFloaterRegionInfo::~LLFloaterRegionInfo() +{ +} + +void LLFloaterRegionInfo::onOpen() +{ + LLRect rect = gSavedSettings.getRect("FloaterRegionInfo"); + S32 left, top; + gFloaterView->getNewFloaterPosition(&left, &top); + rect.translate(left,top); + + refreshFromRegion(gAgent.getRegion()); + requestRegionInfo(); + LLFloater::onOpen(); +} + +// static +void LLFloaterRegionInfo::requestRegionInfo() +{ + LLTabContainer* tab = findInstance()->getChild("region_panels"); + + tab->getChild("General")->setCtrlsEnabled(FALSE); + tab->getChild("Debug")->setCtrlsEnabled(FALSE); + tab->getChild("Terrain")->setCtrlsEnabled(FALSE); + tab->getChild("Estate")->setCtrlsEnabled(FALSE); + tab->getChild("RegionSettings")->setCtrlsEnabled(FALSE); + + // Must allow anyone to request the RegionInfo data + // so non-owners/non-gods can see the values. + // Therefore can't use an EstateOwnerMessage JC + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("RequestRegionInfo"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + gAgent.sendReliableMessage(); +} + +// static +void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) +{ + static LLDispatcher dispatch; + if(!findInstance()) + { + return; + } + + if (!estate_dispatch_initialized) + { + LLPanelEstateInfo::initDispatch(dispatch); + } + + LLTabContainer* tab = findInstance()->getChild("region_panels"); + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); + + // unpack the message + std::string request; + LLUUID invoice; + LLDispatcher::sparam_t strings; + LLDispatcher::unpackMessage(msg, request, invoice, strings); + if(invoice != getLastInvoice()) + { + llwarns << "Mismatched Estate message: " << request << llendl; + return; + } + + //dispatch the message + dispatch.dispatch(request, invoice, strings); + + LLViewerRegion* region = gAgent.getRegion(); + panel->updateControls(region); +} + + +// static +void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) +{ + LLPanel* panel; + + llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; + if(!findInstance()) + { + return; + } + + LLTabContainer* tab = findInstance()->getChild("region_panels"); + + LLViewerRegion* region = gAgent.getRegion(); + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + + // extract message + std::string sim_name; + std::string sim_type = LLTrans::getString("land_type_unknown"); + U32 region_flags; + U8 agent_limit; + F32 object_bonus_factor; + U8 sim_access; + F32 water_height; + F32 terrain_raise_limit; + F32 terrain_lower_limit; + BOOL use_estate_sun; + F32 sun_hour; + msg->getString("RegionInfo", "SimName", sim_name); + msg->getU32("RegionInfo", "RegionFlags", region_flags); + msg->getU8("RegionInfo", "MaxAgents", agent_limit); + msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); + msg->getU8("RegionInfo", "SimAccess", sim_access); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); + msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun); + // actually the "last set" sun hour, not the current sun hour. JC + msg->getF32("RegionInfo", "SunHour", sun_hour); + // the only reasonable way to decide if we actually have any data is to + // check to see if any of these fields have nonzero sizes + if (msg->getSize("RegionInfo2", "ProductSKU") > 0 || + msg->getSize("RegionInfo2", "ProductName") > 0) + { + msg->getString("RegionInfo2", "ProductName", sim_type); + } + + // GENERAL PANEL + panel = tab->getChild("General"); + panel->childSetValue("region_text", LLSD(sim_name)); + panel->childSetValue("region_type", LLSD(sim_type)); + panel->childSetValue("version_channel_text", gLastVersionChannel); + + panel->childSetValue("block_terraform_check", (region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); + panel->childSetValue("block_fly_check", (region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); + panel->childSetValue("allow_damage_check", (region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); + panel->childSetValue("restrict_pushobject", (region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); + panel->childSetValue("allow_land_resell_check", (region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); + panel->childSetValue("allow_parcel_changes_check", (region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE ); + panel->childSetValue("block_parcel_search_check", (region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE ); + panel->childSetValue("agent_limit_spin", LLSD((F32)agent_limit) ); + panel->childSetValue("object_bonus_spin", LLSD(object_bonus_factor) ); + panel->childSetValue("access_combo", LLSD(sim_access) ); + + + // detect teen grid for maturity + + U32 parent_estate_id; + msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id); + BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that + panel->childSetEnabled("access_combo", gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid)); + panel->setCtrlsEnabled(allow_modify); + + // RegionSettings PANEL + panel = tab->getChild("RegionSettings"); + panel->setCtrlsEnabled(allow_modify); + + // DEBUG PANEL + panel = tab->getChild("Debug"); + + panel->childSetValue("region_text", LLSD(sim_name) ); + panel->childSetValue("disable_scripts_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) ); + panel->childSetValue("disable_collisions_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) ); + panel->childSetValue("disable_physics_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) ); + panel->setCtrlsEnabled(allow_modify); + + // TERRAIN PANEL + panel = tab->getChild("Terrain"); + + panel->childSetValue("region_text", LLSD(sim_name)); + panel->childSetValue("water_height_spin", LLSD(water_height)); + panel->childSetValue("terrain_raise_spin", LLSD(terrain_raise_limit)); + panel->childSetValue("terrain_lower_spin", LLSD(terrain_lower_limit)); + panel->childSetValue("use_estate_sun_check", LLSD(use_estate_sun)); + + panel->childSetValue("fixed_sun_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SUN_FIXED))); + panel->childSetEnabled("fixed_sun_check", allow_modify && !use_estate_sun); + panel->childSetValue("sun_hour_slider", LLSD(sun_hour)); + panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); + panel->setCtrlsEnabled(allow_modify); + + getInstance()->refreshFromRegion( gAgent.getRegion() ); +} + +// static +LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); + return panel; +} + +// static +LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild("Covenant"); + return panel; +} + +// static +LLPanelRegionOpenSettingsInfo* LLFloaterRegionInfo::getPanelOpenSettings() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelRegionOpenSettingsInfo* panel; + panel = (LLPanelRegionOpenSettingsInfo*)tab->getChild("RegionSettings"); + return panel; +} + +void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) +{ + // call refresh from region on all panels + std::for_each( + mInfoPanels.begin(), + mInfoPanels.end(), + llbind2nd( +#if LL_WINDOWS + std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion), +#else + std::mem_fun(&LLPanelRegionInfo::refreshFromRegion), +#endif + region)); +} + +// public +void LLFloaterRegionInfo::refresh() +{ + for(info_panels_t::iterator iter = mInfoPanels.begin(); + iter != mInfoPanels.end(); ++iter) + { + (*iter)->refresh(); + } +} + + +///---------------------------------------------------------------------------- +/// Local class implementation +///---------------------------------------------------------------------------- + +// +// LLPanelRegionInfo +// + +// static +void LLPanelRegionInfo::onBtnSet(void* user_data) +{ + LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; + if(!panel) return; + if (panel->sendUpdate()) + { + panel->disableButton("apply_btn"); + } +} + +//static +void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl, void* user_data) +{ + if (ctrl) + { + LLPanelRegionInfo* panel = (LLPanelRegionInfo*) ctrl->getParent(); + panel->updateChild(ctrl); + } +} + +// static +// Enables the "set" button if it is not already enabled +void LLPanelRegionInfo::onChangeAnything(LLUICtrl* ctrl, void* user_data) +{ + LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; + if(panel) + { + panel->enableButton("apply_btn"); + panel->refresh(); + } +} + +// static +// Enables set button on change to line editor +void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data) +{ + // reuse the previous method + onChangeAnything(0, user_data); +} + + +// virtual +BOOL LLPanelRegionInfo::postBuild() +{ + childSetAction("apply_btn", onBtnSet, this); + childDisable("apply_btn"); + refresh(); + return TRUE; +} + +// virtual +void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) +{ +} + +// virtual +bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region) +{ + if (region) mHost = region->getHost(); + return true; +} + +void LLPanelRegionInfo::sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const strings_t& strings) +{ + llinfos << "Sending estate request '" << request << "'" << llendl; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", request); + msg->addUUID("Invoice", invoice); + if(strings.empty()) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", NULL); + } + else + { + strings_t::const_iterator it = strings.begin(); + strings_t::const_iterator end = strings.end(); + for(; it != end; ++it) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", *it); + } + } + msg->sendReliable(mHost); +} + +void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable) +{ + childSetEnabled(btn_name, enable); +} + +void LLPanelRegionInfo::disableButton(const std::string& btn_name) +{ + childDisable(btn_name); +} + +void LLPanelRegionInfo::initCtrl(const std::string& name) +{ + childSetCommitCallback(name, onChangeAnything, this); +} + +void LLPanelRegionInfo::initHelpBtn(const std::string& name, const std::string& xml_alert) +{ + childSetAction(name, onClickHelp, new std::string(xml_alert)); +} + +// static +void LLPanelRegionInfo::onClickHelp(void* data) +{ + std::string* xml_alert = (std::string*)data; + LLNotifications::instance().add(*xml_alert); +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionGeneralInfo +// +bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + childDisable("apply_btn"); + childSetEnabled("access_text", allow_modify); + // childSetEnabled("access_combo", allow_modify); + // now set in processRegionInfo for teen grid detection + childSetEnabled("kick_btn", allow_modify); + childSetEnabled("kick_all_btn", allow_modify); + childSetEnabled("im_btn", allow_modify); + childSetEnabled("manage_telehub_btn", allow_modify); + + // Data gets filled in by processRegionInfo + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +BOOL LLPanelRegionGeneralInfo::postBuild() +{ + // Enable the "Apply" button if something is changed. JC + initCtrl("block_terraform_check"); + initCtrl("block_fly_check"); + initCtrl("allow_damage_check"); + initCtrl("allow_land_resell_check"); + initCtrl("allow_parcel_changes_check"); + initCtrl("agent_limit_spin"); + initCtrl("object_bonus_spin"); + initCtrl("access_combo"); + initCtrl("restrict_pushobject"); + initCtrl("block_parcel_search_check"); + initCtrl("minimum_agent_age"); + + initHelpBtn("terraform_help", "HelpRegionBlockTerraform"); + initHelpBtn("fly_help", "HelpRegionBlockFly"); + initHelpBtn("damage_help", "HelpRegionAllowDamage"); + initHelpBtn("agent_limit_help", "HelpRegionAgentLimit"); + initHelpBtn("object_bonus_help", "HelpRegionObjectBonus"); + initHelpBtn("access_help", "HelpRegionMaturity"); + initHelpBtn("restrict_pushobject_help", "HelpRegionRestrictPushObject"); + initHelpBtn("land_resell_help", "HelpRegionLandResell"); + initHelpBtn("parcel_changes_help", "HelpParcelChanges"); + initHelpBtn("parcel_search_help", "HelpRegionSearch"); + + childSetAction("kick_btn", onClickKick, this); + childSetAction("kick_all_btn", onClickKickAll, this); + childSetAction("im_btn", onClickMessage, this); + childSetAction("manage_telehub_btn", onClickManageTelehub, this); + + return LLPanelRegionInfo::postBuild(); +} + +// static +void LLPanelRegionGeneralInfo::onClickKick(void* userdata) +{ + llinfos << "LLPanelRegionGeneralInfo::onClickKick" << llendl; + LLPanelRegionGeneralInfo* panelp = (LLPanelRegionGeneralInfo*)userdata; + + // this depends on the grandparent view being a floater + // in order to set up floater dependency + LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); + LLFloater* child_floater = LLFloaterAvatarPicker::show(onKickCommit, userdata, FALSE, TRUE); + parent_floater->addDependentFloater(child_floater); +} + +// static +void LLPanelRegionGeneralInfo::onKickCommit(const std::vector& names, const std::vector& ids, void* userdata) +{ + if (names.empty() || ids.empty()) return; + if(ids[0].notNull()) + { + LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata; + if(!self) return; + strings_t strings; + // [0] = our agent id + // [1] = target agent id + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + + ids[0].toString(buffer); + strings.push_back(strings_t::value_type(buffer)); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); + } +} + +// static +void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata) +{ + llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl; + LLNotifications::instance().add("KickUsersFromRegion", + LLSD(), + LLSD(), + boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); +} + +bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option == 0) + { + strings_t strings; + // [0] = our agent id + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + // historical message name + sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); + } + return false; +} + +// static +void LLPanelRegionGeneralInfo::onClickMessage(void* userdata) +{ + llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl; + LLNotifications::instance().add("MessageRegion", + LLSD(), + LLSD(), + boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); +} + +// static +bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response) +{ + if(LLNotification::getSelectedOption(notification, response) != 0) return false; + + std::string text = response["message"].asString(); + if (text.empty()) return false; + + llinfos << "Message to everyone: " << text << llendl; + strings_t strings; + // [0] grid_x, unused here + // [1] grid_y, unused here + // [2] agent_id of sender + // [3] sender name + // [4] message + strings.push_back("-1"); + strings.push_back("-1"); + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + std::string name; + gAgent.buildFullname(name); + strings.push_back(strings_t::value_type(name)); + strings.push_back(strings_t::value_type(text)); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); + return false; +} + +// static +void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data) +{ + LLFloaterRegionInfo::getInstance()->close(); + + LLFloaterTelehub::show(); +} + +// setregioninfo +// strings[0] = 'Y' - block terraform, 'N' - not +// strings[1] = 'Y' - block fly, 'N' - not +// strings[2] = 'Y' - allow damage, 'N' - not +// strings[3] = 'Y' - allow land sale, 'N' - not +// strings[4] = agent limit +// strings[5] = object bonus +// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult) +// strings[7] = restrict pushobject +// strings[8] = 'Y' - allow parcel subdivide, 'N' - not +// strings[9] = 'Y' - block parcel search, 'N' - allow +BOOL LLPanelRegionGeneralInfo::sendUpdate() +{ + llinfos << "LLPanelRegionGeneralInfo::sendUpdate()" << llendl; + + // First try using a Cap. If that fails use the old method. + LLSD body; + std::string url = gAgent.getRegion()->getCapability("DispatchRegionInfo"); + if (!url.empty()) + { + body["block_terraform"] = childGetValue("block_terraform_check"); + body["block_fly"] = childGetValue("block_fly_check"); + body["allow_damage"] = childGetValue("allow_damage_check"); + body["allow_land_resell"] = childGetValue("allow_land_resell_check"); + body["agent_limit"] = childGetValue("agent_limit_spin"); + body["prim_bonus"] = childGetValue("object_bonus_spin"); + body["sim_access"] = childGetValue("access_combo"); + body["restrict_pushobject"] = childGetValue("restrict_pushobject"); + body["allow_parcel_changes"] = childGetValue("allow_parcel_changes_check"); + body["block_parcel_search"] = childGetValue("block_parcel_search_check"); + body["minimum_agent_age"] = childGetValue("minimum_agent_age"); + + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } + else + { + strings_t strings; + std::string buffer; + + buffer = llformat("%s", (childGetValue("block_terraform_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("block_fly_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("allow_damage_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("allow_land_resell_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + F32 value = (F32)childGetValue("agent_limit_spin").asReal(); + buffer = llformat("%f", value); + strings.push_back(strings_t::value_type(buffer)); + + value = (F32)childGetValue("object_bonus_spin").asReal(); + buffer = llformat("%f", value); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%d", childGetValue("access_combo").asInteger()); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("restrict_pushobject").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("allow_parcel_changes_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); + } + + // if we changed access levels, tell user about it + LLViewerRegion* region = gAgent.getRegion(); + if (region && (childGetValue("access_combo").asInteger() != region->getSimAccess()) ) + { + LLNotifications::instance().add("RegionMaturityChange"); + } + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionOpenSettingsInfo +// +bool LLPanelRegionOpenSettingsInfo::refreshFromRegion(LLViewerRegion* region) +{ + // Data gets filled in by hippo manager + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + + childSetValue("draw_distance", gAgent.mDrawDistance); + childSetValue("force_draw_distance", gAgent.mLockedDrawDistance); + childSetValue("allow_minimap", LLSD(gHippoLimits->mAllowMinimap)); + childSetValue("allow_physical_prims", (gHippoLimits->mAllowPhysicalPrims == 1 ? TRUE : FALSE)); + childSetValue("max_drag_distance", LLSD(gHippoLimits->mMaxDragDistance)); + childSetValue("min_hole_size", LLSD(gHippoLimits->mMinHoleSize)); + childSetValue("max_hollow_size", LLSD(gHippoLimits->mMaxHollow)); + childSetValue("max_inventory_items_transfer", LLSD(gHippoLimits->mMaxInventoryItemsTransfer)); + childSetValue("max_link_count", LLSD(gHippoLimits->mMaxLinkedPrims)); + childSetValue("max_link_count_phys", LLSD(gHippoLimits->mMaxPhysLinkedPrims)); + childSetValue("max_phys_prim_scale", LLSD(gHippoLimits->mMaxPrimScale));//Todo:Fix + childSetValue("max_prim_scale", LLSD(gHippoLimits->mMaxPrimScale)); + childSetValue("min_prim_scale", LLSD(gHippoLimits->mMinPrimScale)); + childSetValue("render_water", LLSD(gHippoLimits->mRenderWater)); + childSetValue("show_tags", LLSD(gHippoLimits->mRenderName)); + childSetValue("max_groups", LLSD(gHippoLimits->mMaxAgentGroups)); + childSetValue("allow_parcel_windlight", LLSD(gHippoLimits->mAllowParcelWindLight)); + childSetValue("enable_teen_mode", LLSD(gHippoLimits->mEnableTeenMode)); + childSetValue("enforce_max_build", LLSD(gHippoLimits->mEnforceMaxBuild)); + + setCtrlsEnabled(allow_modify); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +BOOL LLPanelRegionOpenSettingsInfo::postBuild() +{ + // Enable the "Apply" button if something is changed. JC + initCtrl("draw_distance"); + initCtrl("force_draw_distance"); + initCtrl("max_drag_distance"); + initCtrl("max_prim_scale"); + initCtrl("min_prim_scale"); + initCtrl("max_phys_prim_scale"); + initCtrl("max_hollow_size"); + initCtrl("min_hole_size"); + initCtrl("max_link_count"); + initCtrl("max_link_count_phys"); + initCtrl("max_inventory_items_transfer"); + initCtrl("max_groups"); + initCtrl("render_water"); + initCtrl("allow_minimap"); + initCtrl("allow_physical_prims"); + initCtrl("enable_teen_mode"); + initCtrl("show_tags"); + initCtrl("allow_parcel_windlight"); + + initHelpBtn("force_draw_distance_help", "HelpForceDrawDistance"); + initHelpBtn("max_inventory_items_transfer_help", "HelpMaxInventoryItemsTransfer"); + initHelpBtn("max_groups_help", "HelpMaxGroups"); + initHelpBtn("render_water_help", "HelpRenderWater"); + initHelpBtn("allow_minimap_help", "HelpAllowMinimap"); + initHelpBtn("allow_physical_prims_help", "HelpAllowPhysicalPrims"); + initHelpBtn("enable_teen_mode_help", "HelpEnableTeenMode"); + initHelpBtn("show_tags_help", "HelpShowTags"); + initHelpBtn("allow_parcel_windlight_help", "HelpAllowParcelWindLight"); + + childSetAction("apply_ors_btn", sendUpdate, this); + + refreshFromRegion(gAgent.getRegion()); + + return LLPanelRegionInfo::postBuild(); +} + +// setregioninfo +// strings[0] = 'Y' - block terraform, 'N' - not +// strings[1] = 'Y' - block fly, 'N' - not +// strings[2] = 'Y' - allow damage, 'N' - not +// strings[3] = 'Y' - allow land sale, 'N' - not +// strings[4] = agent limit +// strings[5] = object bonus +// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult) +// strings[7] = restrict pushobject +// strings[8] = 'Y' - allow parcel subdivide, 'N' - not +// strings[9] = 'Y' - block parcel search, 'N' - allow +void LLPanelRegionOpenSettingsInfo::sendUpdate(void* userdata) +{ + LLPanelRegionOpenSettingsInfo* self; + self = (LLPanelRegionOpenSettingsInfo*)userdata; + + llinfos << "LLPanelRegionOpenSettingsInfo::sendUpdate()" << llendl; + + LLSD body; + std::string url = gAgent.getRegion()->getCapability("DispatchOpenRegionSettings"); + if (!url.empty()) + { + body["draw_distance"] = self->childGetValue("draw_distance"); + body["force_draw_distance"] = self->childGetValue("force_draw_distance"); + body["allow_minimap"] = self->childGetValue("allow_minimap"); + body["allow_physical_prims"] = self->childGetValue("allow_physical_prims"); + body["max_drag_distance"] = self->childGetValue("max_drag_distance"); + body["min_hole_size"] = self->childGetValue("min_hole_size"); + body["max_hollow_size"] = self->childGetValue("max_hollow_size"); + body["max_inventory_items_transfer"] = self->childGetValue("max_inventory_items_transfer"); + body["max_link_count"] = self->childGetValue("max_link_count"); + body["max_link_count_phys"] = self->childGetValue("max_link_count_phys"); + body["max_phys_prim_scale"] = self->childGetValue("max_phys_prim_scale"); + body["max_prim_scale"] = self->childGetValue("max_prim_scale"); + body["min_prim_scale"] = self->childGetValue("min_prim_scale"); + body["render_water"] = self->childGetValue("render_water"); + body["show_tags"] = self->childGetValue("show_tags"); + body["max_groups"] = self->childGetValue("max_groups"); + body["allow_parcel_windlight"] = self->childGetValue("allow_parcel_windlight"); + body["enable_teen_mode"] = self->childGetValue("enable_teen_mode"); + body["enforce_max_build"] = self->childGetValue("enforce_max_build"); + + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionDebugInfo +///////////////////////////////////////////////////////////////////////////// +BOOL LLPanelRegionDebugInfo::postBuild() +{ + LLPanelRegionInfo::postBuild(); + initCtrl("disable_scripts_check"); + initCtrl("disable_collisions_check"); + initCtrl("disable_physics_check"); + + initHelpBtn("disable_scripts_help", "HelpRegionDisableScripts"); + initHelpBtn("disable_collisions_help", "HelpRegionDisableCollisions"); + initHelpBtn("disable_physics_help", "HelpRegionDisablePhysics"); + initHelpBtn("top_colliders_help", "HelpRegionTopColliders"); + initHelpBtn("top_scripts_help", "HelpRegionTopScripts"); + initHelpBtn("restart_help", "HelpRegionRestart"); + initHelpBtn("minimum_agent_age_help", "HelpRegionMinimumAge"); + + + childSetAction("choose_avatar_btn", onClickChooseAvatar, this); + childSetAction("return_btn", onClickReturn, this); + childSetAction("top_colliders_btn", onClickTopColliders, this); + childSetAction("top_scripts_btn", onClickTopScripts, this); + childSetAction("restart_btn", onClickRestart, this); + childSetAction("cancel_restart_btn", onClickCancelRestart, this); + + return TRUE; +} + +// virtual +bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + childDisable("apply_btn"); + childDisable("target_avatar_name"); + + childSetEnabled("choose_avatar_btn", allow_modify); + childSetEnabled("return_scripts", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("return_other_land", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("return_estate_wide", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("return_btn", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("top_colliders_btn", allow_modify); + childSetEnabled("top_scripts_btn", allow_modify); + childSetEnabled("restart_btn", allow_modify); + childSetEnabled("cancel_restart_btn", allow_modify); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +// virtual +BOOL LLPanelRegionDebugInfo::sendUpdate() +{ + llinfos << "LLPanelRegionDebugInfo::sendUpdate" << llendl; + strings_t strings; + std::string buffer; + + buffer = llformat("%s", (childGetValue("disable_scripts_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + + buffer = llformat("%s", (childGetValue("disable_collisions_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + + buffer = llformat("%s", (childGetValue("disable_physics_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); + return TRUE; +} + +void LLPanelRegionDebugInfo::onClickChooseAvatar(void* data) +{ + LLFloaterAvatarPicker::show(callbackAvatarID, data, FALSE, TRUE); +} + +// static +void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector& names, const std::vector& ids, void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) data; + if (ids.empty() || names.empty()) return; + self->mTargetAvatar = ids[0]; + self->childSetValue("target_avatar_name", LLSD(names[0])); + self->refreshFromRegion( gAgent.getRegion() ); +} + +// static +void LLPanelRegionDebugInfo::onClickReturn(void* data) +{ + LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; + if (panelp->mTargetAvatar.isNull()) return; + + LLSD args; + args["USER_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + LLSD payload; + payload["avatar_id"] = panelp->mTargetAvatar; + + U32 flags = SWD_ALWAYS_RETURN_OBJECTS; + + if (panelp->childGetValue("return_scripts").asBoolean()) + { + flags |= SWD_SCRIPTED_ONLY; + } + + if (panelp->childGetValue("return_other_land").asBoolean()) + { + flags |= SWD_OTHERS_LAND_ONLY; + } + payload["flags"] = int(flags); + payload["return_estate_wide"] = panelp->childGetValue("return_estate_wide").asBoolean(); + LLNotifications::instance().add("EstateObjectReturn", args, payload, + boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2)); +} + +bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID(); + if (!target_avatar.isNull()) + { + U32 flags = notification["payload"]["flags"].asInteger(); + bool return_estate_wide = notification["payload"]["return_estate_wide"]; + if (return_estate_wide) + { + // send as estate message - routed by spaceserver to all regions in estate + strings_t strings; + strings.push_back(llformat("%d", flags)); + strings.push_back(target_avatar.asString()); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); + } + else + { + // send to this simulator only + send_sim_wide_deletes(target_avatar, flags); + } + } + return false; +} + + +// static +void LLPanelRegionDebugInfo::onClickTopColliders(void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("1"); // one physics step + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LLFloaterTopObjects::show(); + LLFloaterTopObjects::clearList(); + self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); +} + +// static +void LLPanelRegionDebugInfo::onClickTopScripts(void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("6"); // top 5 scripts + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LLFloaterTopObjects::show(); + LLFloaterTopObjects::clearList(); + self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); +} + +// static +void LLPanelRegionDebugInfo::onClickRestart(void* data) +{ + LLNotifications::instance().add("ConfirmRestart", LLSD(), LLSD(), + boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2)); +} + +bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + strings_t strings; + strings.push_back("120"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); + return false; +} + +// static +void LLPanelRegionDebugInfo::onClickCancelRestart(void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("-1"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); +} + + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionTextureInfo +// +LLPanelRegionTextureInfo::LLPanelRegionTextureInfo() : LLPanelRegionInfo() +{ + // nothing. +} + +bool LLPanelRegionTextureInfo::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + childDisable("apply_btn"); + + if (region) + { + childSetValue("region_text", LLSD(region->getName())); + } + else + { + childSetValue("region_text", LLSD("")); + } + + if (!region) return LLPanelRegionInfo::refreshFromRegion(region); + + LLVLComposition* compp = region->getComposition(); + LLTextureCtrl* texture_ctrl; + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + texture_ctrl = getChild(buffer); + if(texture_ctrl) + { + lldebugs << "Detail Texture " << i << ": " + << compp->getDetailTextureID(i) << llendl; + LLUUID tmp_id(compp->getDetailTextureID(i)); + texture_ctrl->setImageAssetID(tmp_id); + } + } + + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + childSetValue(buffer, LLSD(compp->getStartHeight(i))); + buffer = llformat("height_range_spin_%d", i); + childSetValue(buffer, LLSD(compp->getHeightRange(i))); + } + + // Call the parent for common book-keeping + return LLPanelRegionInfo::refreshFromRegion(region); +} + + +BOOL LLPanelRegionTextureInfo::postBuild() +{ + LLPanelRegionInfo::postBuild(); + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + initCtrl(buffer); + } + + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + initCtrl(buffer); + buffer = llformat("height_range_spin_%d", i); + initCtrl(buffer); + } + +// LLButton* btn = new LLButton("dump", LLRect(0, 20, 100, 0), "", onClickDump, this); +// btn->setFollows(FOLLOWS_TOP|FOLLOWS_LEFT); +// addChild(btn); + + return LLPanelRegionInfo::postBuild(); +} + +BOOL LLPanelRegionTextureInfo::sendUpdate() +{ + llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl; + + // Make sure user hasn't chosen wacky textures. + if (!validateTextureSizes()) + { + return FALSE; + } + + LLTextureCtrl* texture_ctrl; + std::string buffer; + std::string id_str; + LLMessageSystem* msg = gMessageSystem; + strings_t strings; + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + texture_ctrl = getChild(buffer); + if(texture_ctrl) + { + LLUUID tmp_id(texture_ctrl->getImageAssetID()); + tmp_id.toString(id_str); + buffer = llformat("%d %s", i, id_str.c_str()); + strings.push_back(buffer); + } + } + sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); + strings.clear(); + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + std::string buffer2 = llformat("height_range_spin_%d", i); + std::string buffer3 = llformat("%d %f %f", i, (F32)childGetValue(buffer).asReal(), (F32)childGetValue(buffer2).asReal()); + strings.push_back(buffer3); + } + sendEstateOwnerMessage(msg, "textureheights", invoice, strings); + strings.clear(); + sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); + return TRUE; +} + +BOOL LLPanelRegionTextureInfo::validateTextureSizes() +{ + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + std::string buffer; + buffer = llformat("texture_detail_%d", i); + LLTextureCtrl* texture_ctrl = getChild(buffer); + if (!texture_ctrl) continue; + + LLUUID image_asset_id = texture_ctrl->getImageAssetID(); + LLViewerImage* img = gImageList.getImage(image_asset_id); + S32 components = img->getComponents(); + // Must ask for highest resolution version's width. JC + S32 width = img->getWidth(0); + S32 height = img->getHeight(0); + + //llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl; + + if (components != 3) + { + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); + LLNotifications::instance().add("InvalidTerrainBitDepth", args); + return FALSE; + } + + if (width > 512 || height > 512) + { + + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_SIZE_X"] = width; + args["TEXTURE_SIZE_Y"] = height; + LLNotifications::instance().add("InvalidTerrainSize", args); + return FALSE; + + } + } + + return TRUE; +} + + +// static +void LLPanelRegionTextureInfo::onClickDump(void* data) +{ + llinfos << "LLPanelRegionTextureInfo::onClickDump()" << llendl; +} + + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionTerrainInfo +///////////////////////////////////////////////////////////////////////////// +BOOL LLPanelRegionTerrainInfo::postBuild() +{ + LLPanelRegionInfo::postBuild(); + + initHelpBtn("water_height_help", "HelpRegionWaterHeight"); + initHelpBtn("terrain_raise_help", "HelpRegionTerrainRaise"); + initHelpBtn("terrain_lower_help", "HelpRegionTerrainLower"); + initHelpBtn("upload_raw_help", "HelpRegionUploadRaw"); + initHelpBtn("download_raw_help", "HelpRegionDownloadRaw"); + initHelpBtn("use_estate_sun_help", "HelpRegionUseEstateSun"); + initHelpBtn("fixed_sun_help", "HelpRegionFixedSun"); + initHelpBtn("bake_terrain_help", "HelpRegionBakeTerrain"); + + initCtrl("water_height_spin"); + initCtrl("terrain_raise_spin"); + initCtrl("terrain_lower_spin"); + + initCtrl("fixed_sun_check"); + childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); + childSetCommitCallback("use_estate_sun_check", onChangeUseEstateTime, this); + childSetCommitCallback("sun_hour_slider", onChangeSunHour, this); + + childSetAction("download_raw_btn", onClickDownloadRaw, this); + childSetAction("upload_raw_btn", onClickUploadRaw, this); + childSetAction("bake_terrain_btn", onClickBakeTerrain, this); + + return TRUE; +} + +// virtual +bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) +{ + llinfos << "LLPanelRegionTerrainInfo::refreshFromRegion" << llendl; + + BOOL owner_or_god = gAgent.isGodlike() + || (region && (region->getOwner() == gAgent.getID())); + BOOL owner_or_god_or_manager = owner_or_god + || (region && region->isEstateManager()); + setCtrlsEnabled(owner_or_god_or_manager); + childDisable("apply_btn"); + + childSetEnabled("download_raw_btn", owner_or_god); + childSetEnabled("upload_raw_btn", owner_or_god); + childSetEnabled("bake_terrain_btn", owner_or_god); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +// virtual +BOOL LLPanelRegionTerrainInfo::sendUpdate() +{ + llinfos << "LLPanelRegionTerrainInfo::sendUpdate" << llendl; + std::string buffer; + strings_t strings; + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + buffer = llformat("%f", (F32)childGetValue("water_height_spin").asReal()); + strings.push_back(buffer); + buffer = llformat("%f", (F32)childGetValue("terrain_raise_spin").asReal()); + strings.push_back(buffer); + buffer = llformat("%f", (F32)childGetValue("terrain_lower_spin").asReal()); + strings.push_back(buffer); + buffer = llformat("%s", (childGetValue("use_estate_sun_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + buffer = llformat("%s", (childGetValue("fixed_sun_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + buffer = llformat("%f", (F32)childGetValue("sun_hour_slider").asReal() ); + strings.push_back(buffer); + + // Grab estate information in case the user decided to set the + // region back to estate time. JC + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return true; + + LLTabContainer* tab = floater->getChild("region_panels"); + if (!tab) return true; + + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); + if (!panel) return true; + + BOOL estate_global_time = panel->getGlobalTime(); + BOOL estate_fixed_sun = panel->getFixedSun(); + F32 estate_sun_hour; + if (estate_global_time) + { + estate_sun_hour = 0.f; + } + else + { + estate_sun_hour = panel->getSunHour(); + } + + buffer = llformat("%s", (estate_global_time ? "Y" : "N") ); + strings.push_back(buffer); + buffer = llformat("%s", (estate_fixed_sun ? "Y" : "N") ); + strings.push_back(buffer); + buffer = llformat("%f", estate_sun_hour); + strings.push_back(buffer); + + sendEstateOwnerMessage(gMessageSystem, "setregionterrain", invoice, strings); + return TRUE; +} + +// static +void LLPanelRegionTerrainInfo::onChangeUseEstateTime(LLUICtrl* ctrl, void* user_data) +{ + LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; + if (!panel) return; + BOOL use_estate_sun = panel->childGetValue("use_estate_sun_check").asBoolean(); + panel->childSetEnabled("fixed_sun_check", !use_estate_sun); + panel->childSetEnabled("sun_hour_slider", !use_estate_sun); + if (use_estate_sun) + { + panel->childSetValue("fixed_sun_check", LLSD(FALSE)); + panel->childSetValue("sun_hour_slider", LLSD(0.f)); + } + panel->childEnable("apply_btn"); +} + +// static +void LLPanelRegionTerrainInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) +{ + LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; + if (!panel) return; + // Just enable the apply button. We let the sun-hour slider be enabled + // for both fixed-sun and non-fixed-sun. JC + panel->childEnable("apply_btn"); +} + +// static +void LLPanelRegionTerrainInfo::onChangeSunHour(LLUICtrl* ctrl, void*) +{ + // can't use userdata to get panel, slider uses it internally + LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) ctrl->getParent(); + if (!panel) return; + panel->childEnable("apply_btn"); +} + +// static +void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw")) + { + llwarns << "No file" << llendl; + return; + } + std::string filepath = picker.getFirstFile(); + gXferManager->expectFileForRequest(filepath); + + LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; + strings_t strings; + strings.push_back("download filename"); + strings.push_back(filepath); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); +} + +// static +void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW)) + { + llwarns << "No file" << llendl; + return; + } + std::string filepath = picker.getFirstFile(); + gXferManager->expectFileForTransfer(filepath); + + LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; + strings_t strings; + strings.push_back("upload filename"); + strings.push_back(filepath); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + + LLNotifications::instance().add("RawUploadStarted"); +} + +// static +void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data) +{ + LLNotifications::instance().add( + LLNotification::Params("ConfirmBakeTerrain") + .functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2))); +} + +bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + strings_t strings; + strings.push_back("bake"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + return false; +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelEstateInfo +// + +LLPanelEstateInfo::LLPanelEstateInfo() +: LLPanelRegionInfo(), + mEstateID(0) // invalid +{ +} + +// static +void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) +{ + std::string name; + +// name.assign("setowner"); +// static LLDispatchSetEstateOwner set_owner; +// dispatch.addHandler(name, &set_owner); + + name.assign("estateupdateinfo"); + static LLDispatchEstateUpdateInfo estate_update_info; + dispatch.addHandler(name, &estate_update_info); + + name.assign("setaccess"); + static LLDispatchSetEstateAccess set_access; + dispatch.addHandler(name, &set_access); + + estate_dispatch_initialized = true; +} + +// static +// Disables the sun-hour slider and the use fixed time check if the use global time is check +void LLPanelEstateInfo::onChangeUseGlobalTime(LLUICtrl* ctrl, void* user_data) +{ + LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; + if (panel) + { + bool enabled = !panel->childGetValue("use_global_time_check").asBoolean(); + panel->childSetEnabled("sun_hour_slider", enabled); + panel->childSetEnabled("fixed_sun_check", enabled); + panel->childSetValue("fixed_sun_check", LLSD(FALSE)); + panel->enableButton("apply_btn"); + } +} + +// Enables the sun-hour slider if the fixed-sun checkbox is set +void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) +{ + LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; + if (panel) + { + bool enabled = !panel->childGetValue("fixed_sun_check").asBoolean(); + panel->childSetEnabled("use_global_time_check", enabled); + panel->childSetValue("use_global_time_check", LLSD(FALSE)); + panel->enableButton("apply_btn"); + } +} + + + + +//--------------------------------------------------------------------------- +// Add/Remove estate access button callbacks +//--------------------------------------------------------------------------- +void LLPanelEstateInfo::onClickEditSky(void* user_data) +{ + LLFloaterWindLight::show(); +} + +void LLPanelEstateInfo::onClickEditDayCycle(void* user_data) +{ + LLFloaterDayCycle::show(); +} + +// static +void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("allowed_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + //args + + LLSD args; + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAllowedAgentOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); +} + +// static +void LLPanelEstateInfo::onClickRemoveAllowedAgent(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); +} + +// static +void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("allowed_group_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAllowedGroupsOnRegion", args); + return; + } + + LLNotification::Params params("ChangeLindenAccess"); + params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2)); + if (isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } +} + +bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + + LLFloaterGroupPicker* widget; + widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); + if (widget) + { + widget->setSelectCallback(addAllowedGroup2, NULL); + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); + widget->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(widget); + } + } + + return false; +} + +// static +void LLPanelEstateInfo::onClickRemoveAllowedGroup(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); +} + +// static +void LLPanelEstateInfo::onClickAddBannedAgent(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("banned_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxBannedAgentsOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); +} + +// static +void LLPanelEstateInfo::onClickRemoveBannedAgent(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); +} + +// static +void LLPanelEstateInfo::onClickAddEstateManager(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("estate_manager_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_MANAGERS) + { // Tell user they can't add more managers + LLSD args; + args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS); + LLNotifications::instance().add("MaxManagersOnRegion", args); + } + else + { // Go pick managers to add + accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); + } +} + +// static +void LLPanelEstateInfo::onClickRemoveEstateManager(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); +} + +//--------------------------------------------------------------------------- +// Kick from estate methods +//--------------------------------------------------------------------------- +struct LLKickFromEstateInfo +{ + LLPanelEstateInfo *mEstatePanelp; + LLUUID mAgentID; +}; + +void LLPanelEstateInfo::onClickKickUser(void *user_data) +{ + LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data; + + // this depends on the grandparent view being a floater + // in order to set up floater dependency + LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); + LLFloater* child_floater = LLFloaterAvatarPicker::show(LLPanelEstateInfo::onKickUserCommit, user_data, FALSE, TRUE); + parent_floater->addDependentFloater(child_floater); +} + +void LLPanelEstateInfo::onKickUserCommit(const std::vector& names, const std::vector& ids, void* userdata) +{ + if (names.empty() || ids.empty()) return; + + //check to make sure there is one valid user and id + if( (ids[0].isNull()) || + (names[0].length() == 0) ) + { + return; + } + + LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata; + if(!self) return; + + //keep track of what user they want to kick and other misc info + LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo(); + kick_info->mEstatePanelp = self; + kick_info->mAgentID = ids[0]; + + //Bring up a confirmation dialog + LLSD args; + args["EVIL_USER"] = names[0]; + LLSD payload; + payload["agent_id"] = ids[0]; + LLNotifications::instance().add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2)); + +} + +bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + switch(option) + { + case 0: + { + //Kick User + strings_t strings; + strings.push_back(notification["payload"]["agent_id"].asString()); + + sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); + break; + } + default: + break; + } + return false; +} + +//--------------------------------------------------------------------------- +// Core Add/Remove estate access methods +// TODO: INTERNATIONAL: don't build message text here; +// instead, create multiple translatable messages and choose +// one based on the status. +//--------------------------------------------------------------------------- +std::string all_estates_text() +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return "(error)"; + + std::string owner = panel->getOwnerName(); + + LLViewerRegion* region = gAgent.getRegion(); + if (gAgent.isGodlike()) + { + return llformat("all estates\nowned by %s", owner.c_str()); + } + else if (region && region->getOwner() == gAgent.getID()) + { + return "all estates you own"; + } + else if (region && region->isEstateManager()) + { + return llformat("all estates that\nyou manage for %s", owner.c_str()); + } + else + { + return "(error)"; + } +} + +// static +bool LLPanelEstateInfo::isLindenEstate() +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return false; + + U32 estate_id = panel->getEstateID(); + return (estate_id <= ESTATE_LAST_LINDEN); +} + +typedef std::vector AgentOrGroupIDsVector; +struct LLEstateAccessChangeInfo +{ + LLEstateAccessChangeInfo(const LLSD& sd) + { + mDialogName = sd["dialog_name"].asString(); + mOperationFlag = (U32)sd["operation"].asInteger(); + LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray(); + for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray(); + id_it != end_it; + ++id_it) + { + mAgentOrGroupIDs.push_back(id_it->asUUID()); + } + } + + const LLSD asLLSD() const + { + LLSD sd; + sd["name"] = mDialogName; + sd["operation"] = (S32)mOperationFlag; + for (AgentOrGroupIDsVector::const_iterator it = mAgentOrGroupIDs.begin(); + it != mAgentOrGroupIDs.end(); + ++it) + { + sd["allowed_ids"].append(*it); + } + return sd; + } + + U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. + std::string mDialogName; + AgentOrGroupIDsVector mAgentOrGroupIDs; // List of agent IDs to apply to this change +}; + +// Special case callback for groups, since it has different callback format than names +// static +void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data) +{ + LLSD payload; + payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; + payload["dialog_name"] = "EstateAllowedGroupAdd"; + payload["allowed_ids"].append(id); + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params("EstateAllowedGroupAdd"); + params.payload(payload) + .substitutions(args) + .functor(accessCoreConfirm); + if (isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name) +{ + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + // agent id filled in after avatar picker + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor(accessAddCore2); + + if (isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + // same as clicking "OK" + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) + { + // abort change + return false; + } + + LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); + // avatar picker yes multi-select, yes close-on-select + LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE); + return false; +} + +// static +void LLPanelEstateInfo::accessAddCore3(const std::vector& names, const std::vector& ids, void* data) +{ + LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; + if (!change_info) return; + if (ids.empty()) + { + // User didn't select a name. + delete change_info; + change_info = NULL; + return; + } + // User did select a name. + change_info->mAgentOrGroupIDs = ids; + // Can't put estate owner on ban list + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return; + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) + { + LLCtrlListInterface *list = panel->childGetListInterface("allowed_avatar_name_list"); + int currentCount = (list ? list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d",ids.size()); + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = "Allowed Residents"; + args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + } + if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) + { + LLCtrlListInterface *list = panel->childGetListInterface("banned_avatar_name_list"); + int currentCount = (list ? list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d",ids.size()); + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = "Banned Residents"; + args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + } + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params(change_info->mDialogName); + params.substitutions(args) + .payload(change_info->asLLSD()) + .functor(accessCoreConfirm); + + if (isLindenEstate()) + { + // just apply to this estate + LLNotifications::instance().forceResponse(params, 0); + } + else + { + // ask if this estate or all estates with this owner + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild(list_ctrl_name); + if (!name_list) return; + + std::vector list_vector = name_list->getAllSelected(); + if (list_vector.size() == 0) + return; + + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + + for (std::vector::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + payload["allowed_ids"].append(item->getUUID()); + } + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor(accessRemoveCore2); + + if (isLindenEstate()) + { + // warn on change linden estate + LLNotifications::instance().add(params); + } + else + { + // just proceed, as if clicking OK + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) + { + // abort + return false; + } + + // If Linden estate, can only apply to "this" estate, not all estates + // owned by NULL. + if (isLindenEstate()) + { + accessCoreConfirm(notification, response); + } + else + { + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotifications::instance().add(notification["payload"]["dialog_name"], + args, + notification["payload"], + accessCoreConfirm); + } + return false; +} + +// Used for both access add and remove operations, depending on the mOperationFlag +// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.) +// static +bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + + LLViewerRegion* region = gAgent.getRegion(); + + LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); + + for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); + iter != end_it; + iter++) + { + U32 flags = originalFlags; + if (iter + 1 != end_it) + flags |= ESTATE_ACCESS_NO_REPLY; + + const LLUUID id = iter->asUUID(); + if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) + && region && (region->getOwner() == id)) + { + LLNotifications::instance().add("OwnerCanNotBeDenied"); + break; + } + switch(option) + { + case 0: + // This estate + sendEstateAccessDelta(flags, id); + break; + case 1: + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) break; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + sendEstateAccessDelta(flags, id); + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + sendEstateAccessDelta(flags, id); + } + break; + } + case 2: + default: + break; + } + } + return false; +} + +// key = "estateaccessdelta" +// str(estate_id) will be added to front of list by forward_EstateOwnerRequest_to_dataserver +// str[0] = str(agent_id) requesting the change +// str[1] = str(flags) (ESTATE_ACCESS_DELTA_*) +// str[2] = str(agent_id) to add or remove +// static +void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estateaccessdelta"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + std::string buf; + gAgent.getID().toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + buf = llformat("%u", flags); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + agent_or_group_id.toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | + ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + + panel->clearAccessLists(); + } + + gAgent.sendReliableMessage(); +} + +void LLPanelEstateInfo::updateControls(LLViewerRegion* region) +{ + BOOL god = gAgent.isGodlike(); + BOOL owner = (region && (region->getOwner() == gAgent.getID())); + BOOL manager = (region && region->isEstateManager()); + setCtrlsEnabled(god || owner || manager); + + childDisable("apply_btn"); + childSetEnabled("add_allowed_avatar_btn", god || owner || manager); + childSetEnabled("remove_allowed_avatar_btn", god || owner || manager); + childSetEnabled("add_allowed_group_btn", god || owner || manager); + childSetEnabled("remove_allowed_group_btn", god || owner || manager); + childSetEnabled("add_banned_avatar_btn", god || owner || manager); + childSetEnabled("remove_banned_avatar_btn", god || owner || manager); + childSetEnabled("message_estate_btn", god || owner || manager); + childSetEnabled("kick_user_from_estate_btn", god || owner || manager); + childSetEnabled("abuse_email_address", god || owner || manager); + + // estate managers can't add estate managers + childSetEnabled("add_estate_manager_btn", god || owner); + childSetEnabled("remove_estate_manager_btn", god || owner); + childSetEnabled("estate_manager_name_list", god || owner); +} + +bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) +{ + updateControls(region); + + // let the parent class handle the general data collection. + bool rv = LLPanelRegionInfo::refreshFromRegion(region); + + // We want estate info. To make sure it works across region + // boundaries and multiple packets, we add a serial number to the + // integers and track against that on update. + strings_t strings; + //integers_t integers; + //LLFloaterRegionInfo::incrementSerial(); + LLFloaterRegionInfo::nextInvoice(); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); + + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + panel->clearAccessLists(); + + + sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); + + refresh(); + + return rv; +} + +void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) +{ + if (checkRemovalButton(child_ctrl->getName())) + { + // do nothing + } + else if (checkSunHourSlider(child_ctrl)) + { + // do nothing + } +} + +bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) +{ + llinfos << "LLPanelEstateInfo::estateUpdate()" << llendl; + return false; +} + + +BOOL LLPanelEstateInfo::postBuild() +{ + // set up the callbacks for the generic controls + initCtrl("externally_visible_check"); + initCtrl("use_global_time_check"); + initCtrl("fixed_sun_check"); + initCtrl("allow_direct_teleport"); + initCtrl("limit_payment"); + initCtrl("limit_age_verified"); + initCtrl("voice_chat_check"); + childSetCommitCallback("abuse_email_address", onChangeAnything, this); + childSetKeystrokeCallback("abuse_email_address", onChangeText, this); + + initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); + initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); + initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); + initHelpBtn("WLEditSkyHelp", "HelpEditSky"); + initHelpBtn("WLEditDayCycleHelp", "HelpEditDayCycle"); + + initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); + initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); + initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); + initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); + initHelpBtn("ban_resident_help", "HelpEstateBanResident"); + initHelpBtn("abuse_email_address_help", "HelpEstateAbuseEmailAddress"); + initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); + + // set up the use global time checkbox + childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this); + childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); + childSetCommitCallback("sun_hour_slider", onChangeChildCtrl, this); + + childSetCommitCallback("allowed_avatar_name_list", onChangeChildCtrl, this); + LLNameListCtrl *avatar_name_list = getChild("allowed_avatar_name_list"); + if (avatar_name_list) + { + avatar_name_list->setCommitOnSelectionChange(TRUE); + avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + childSetAction("add_allowed_avatar_btn", onClickAddAllowedAgent, this); + childSetAction("remove_allowed_avatar_btn", onClickRemoveAllowedAgent, this); + + childSetCommitCallback("allowed_group_name_list", onChangeChildCtrl, this); + LLNameListCtrl* group_name_list = getChild("allowed_group_name_list"); + if (group_name_list) + { + group_name_list->setCommitOnSelectionChange(TRUE); + group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + childSetAction("add_allowed_group_btn", onClickAddAllowedGroup, this); + childSetAction("remove_allowed_group_btn", onClickRemoveAllowedGroup, this); + + childSetCommitCallback("banned_avatar_name_list", onChangeChildCtrl, this); + LLNameListCtrl* banned_name_list = getChild("banned_avatar_name_list"); + if (banned_name_list) + { + banned_name_list->setCommitOnSelectionChange(TRUE); + banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + childSetAction("add_banned_avatar_btn", onClickAddBannedAgent, this); + childSetAction("remove_banned_avatar_btn", onClickRemoveBannedAgent, this); + + childSetCommitCallback("estate_manager_name_list", onChangeChildCtrl, this); + LLNameListCtrl* manager_name_list = getChild("estate_manager_name_list"); + if (manager_name_list) + { + manager_name_list->setCommitOnSelectionChange(TRUE); + manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue + } + + childSetAction("add_estate_manager_btn", onClickAddEstateManager, this); + childSetAction("remove_estate_manager_btn", onClickRemoveEstateManager, this); + childSetAction("message_estate_btn", onClickMessageEstate, this); + childSetAction("kick_user_from_estate_btn", onClickKickUser, this); + + childSetAction("WLEditSky", onClickEditSky, this); + childSetAction("WLEditDayCycle", onClickEditDayCycle, this); + + return LLPanelRegionInfo::postBuild(); +} + +void LLPanelEstateInfo::refresh() +{ + bool public_access = childGetValue("externally_visible_check").asBoolean(); + childSetEnabled("Only Allow", public_access); + childSetEnabled("limit_payment", public_access); + childSetEnabled("limit_age_verified", public_access); + // if this is set to false, then the limit fields are meaningless and should be turned off + if (public_access == false) + { + childSetValue("limit_payment", false); + childSetValue("limit_age_verified", false); + } +} + +BOOL LLPanelEstateInfo::sendUpdate() +{ + llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl; + + LLNotification::Params params("ChangeLindenEstate"); + params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2)); + + if (getEstateID() <= ESTATE_LAST_LINDEN) + { + // trying to change reserved estate, warn + LLNotifications::instance().add(params); + } + else + { + // for normal estates, just make the change + LLNotifications::instance().forceResponse(params, 0); + } + return TRUE; +} + +bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + switch(option) + { + case 0: + // send the update + if (!commitEstateInfoCaps()) + { + // the caps method failed, try the old way + LLFloaterRegionInfo::nextInvoice(); + commitEstateInfoDataserver(); + } + // we don't want to do this because we'll get it automatically from the sim + // after the spaceserver processes it +// else +// { +// // caps method does not automatically send this info +// LLFloaterRegionInfo::requestRegionInfo(); +// } + break; + case 1: + default: + // do nothing + break; + } + return false; +} + + +/* +// Request = "getowner" +// SParam[0] = "" (empty string) +// IParam[0] = serial +void LLPanelEstateInfo::getEstateOwner() +{ + // TODO -- disable the panel + // and call this function whenever we cross a region boundary + // re-enable when owner matches, and get new estate info + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_EstateOwnerRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + + msg->nextBlockFast(_PREHASH_RequestData); + msg->addStringFast(_PREHASH_Request, "getowner"); + + // we send an empty string so that the variable block is not empty + msg->nextBlockFast(_PREHASH_StringData); + msg->addStringFast(_PREHASH_SParam, ""); + + msg->nextBlockFast(_PREHASH_IntegerData); + msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial()); + + gAgent.sendMessage(); +} +*/ + +class LLEstateChangeInfoResponder : public LLHTTPClient::Responder +{ +public: + LLEstateChangeInfoResponder(void* userdata) : mpPanel((LLPanelEstateInfo*)userdata) {}; + + // if we get a normal response, handle it here + virtual void result(const LLSD& content) + { + // refresh the panel from the database + mpPanel->refresh(); + } + + // if we get an error response + virtual void error(U32 status, const std::string& reason) + { + llinfos << "LLEstateChangeInfoResponder::error " + << status << ": " << reason << llendl; + } +private: + LLPanelEstateInfo* mpPanel; +}; + +// tries to send estate info using a cap; returns true if it succeeded +bool LLPanelEstateInfo::commitEstateInfoCaps() +{ + std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo"); + + if (url.empty()) + { + // whoops, couldn't find the cap, so bail out + return false; + } + + LLSD body; + body["estate_name"] = getEstateName(); + + body["is_externally_visible"] = childGetValue("externally_visible_check").asBoolean(); + body["allow_direct_teleport"] = childGetValue("allow_direct_teleport").asBoolean(); + body["is_sun_fixed" ] = childGetValue("fixed_sun_check").asBoolean(); + body["deny_anonymous" ] = childGetValue("limit_payment").asBoolean(); + body["deny_age_unverified" ] = childGetValue("limit_age_verified").asBoolean(); + body["allow_voice_chat" ] = childGetValue("voice_chat_check").asBoolean(); + body["invoice" ] = LLFloaterRegionInfo::getLastInvoice(); + + // block fly is in estate database but not in estate UI, so we're not supporting it + //body["block_fly" ] = childGetValue("").asBoolean(); + + F32 sun_hour = getSunHour(); + if (childGetValue("use_global_time_check").asBoolean()) + { + sun_hour = 0.f; // 0 = global time + } + body["sun_hour"] = sun_hour; + + body["owner_abuse_email"] = childGetValue("abuse_email_address").asString(); + + // we use a responder so that we can re-get the data after committing to the database + LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder((void*)this)); + return true; +} + +/* This is the old way of doing things, is deprecated, and should be + deleted when the dataserver model can be removed */ +// key = "estatechangeinfo" +// strings[0] = str(estate_id) (added by simulator before relay - not here) +// strings[1] = estate_name +// strings[2] = str(estate_flags) +// strings[3] = str((S32)(sun_hour * 1024.f)) +void LLPanelEstateInfo::commitEstateInfoDataserver() +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estatechangeinfo"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + msg->nextBlock("ParamList"); + msg->addString("Parameter", getEstateName()); + + std::string buffer; + buffer = llformat("%u", computeEstateFlags()); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + + F32 sun_hour = getSunHour(); + if (childGetValue("use_global_time_check").asBoolean()) + { + sun_hour = 0.f; // 0 = global time + } + + buffer = llformat("%d", (S32)(sun_hour*1024.0f)); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + + gAgent.sendMessage(); +} + +void LLPanelEstateInfo::setEstateFlags(U32 flags) +{ + childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) ); + childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) ); + childSetValue( + "voice_chat_check", + LLSD(flags & REGION_FLAGS_ALLOW_VOICE ? TRUE : FALSE)); + childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); + childSetValue("limit_payment", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); + childSetValue("limit_age_verified", LLSD(flags & REGION_FLAGS_DENY_AGEUNVERIFIED ? TRUE : FALSE) ); + + refresh(); +} + +U32 LLPanelEstateInfo::computeEstateFlags() +{ + U32 flags = 0; + + if (childGetValue("externally_visible_check").asBoolean()) + { + flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; + } + + if ( childGetValue("voice_chat_check").asBoolean() ) + { + flags |= REGION_FLAGS_ALLOW_VOICE; + } + + if (childGetValue("allow_direct_teleport").asBoolean()) + { + flags |= REGION_FLAGS_ALLOW_DIRECT_TELEPORT; + } + + if (childGetValue("fixed_sun_check").asBoolean()) + { + flags |= REGION_FLAGS_SUN_FIXED; + } + + if (childGetValue("limit_payment").asBoolean()) + { + flags |= REGION_FLAGS_DENY_ANONYMOUS; + } + + if (childGetValue("limit_age_verified").asBoolean()) + { + flags |= REGION_FLAGS_DENY_AGEUNVERIFIED; + } + + + return flags; +} + +BOOL LLPanelEstateInfo::getGlobalTime() +{ + return childGetValue("use_global_time_check").asBoolean(); +} + +void LLPanelEstateInfo::setGlobalTime(bool b) +{ + childSetValue("use_global_time_check", LLSD(b)); + childSetEnabled("fixed_sun_check", LLSD(!b)); + childSetEnabled("sun_hour_slider", LLSD(!b)); + if (b) + { + childSetValue("sun_hour_slider", LLSD(0.f)); + } +} + + +BOOL LLPanelEstateInfo::getFixedSun() +{ + return childGetValue("fixed_sun_check").asBoolean(); +} + +void LLPanelEstateInfo::setSunHour(F32 sun_hour) +{ + if(sun_hour < 6.0f) + { + sun_hour = 24.0f + sun_hour; + } + childSetValue("sun_hour_slider", LLSD(sun_hour)); +} + +F32 LLPanelEstateInfo::getSunHour() +{ + if (childIsEnabled("sun_hour_slider")) + { + return (F32)childGetValue("sun_hour_slider").asReal(); + } + return 0.f; +} + +const std::string LLPanelEstateInfo::getEstateName() const +{ + return childGetValue("estate_name").asString(); +} + +void LLPanelEstateInfo::setEstateName(const std::string& name) +{ + childSetValue("estate_name", LLSD(name)); +} + +const std::string LLPanelEstateInfo::getOwnerName() const +{ + return childGetValue("estate_owner").asString(); +} + +void LLPanelEstateInfo::setOwnerName(const std::string& name) +{ + childSetValue("estate_owner", LLSD(name)); +} + +const std::string LLPanelEstateInfo::getAbuseEmailAddress() const +{ + return childGetValue("abuse_email_address").asString(); +} + +void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address) +{ + childSetValue("abuse_email_address", LLSD(address)); +} + +void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, + bool enable_group, + bool enable_ban) +{ + childSetEnabled("allow_resident_label", enable_agent); + childSetEnabled("allowed_avatar_name_list", enable_agent); + childSetVisible("allowed_avatar_name_list", enable_agent); + childSetEnabled("add_allowed_avatar_btn", enable_agent); + childSetEnabled("remove_allowed_avatar_btn", enable_agent); + + // Groups + childSetEnabled("allow_group_label", enable_group); + childSetEnabled("allowed_group_name_list", enable_group); + childSetVisible("allowed_group_name_list", enable_group); + childSetEnabled("add_allowed_group_btn", enable_group); + childSetEnabled("remove_allowed_group_btn", enable_group); + + // Ban + childSetEnabled("ban_resident_label", enable_ban); + childSetEnabled("banned_avatar_name_list", enable_ban); + childSetVisible("banned_avatar_name_list", enable_ban); + childSetEnabled("add_banned_avatar_btn", enable_ban); + childSetEnabled("remove_banned_avatar_btn", enable_ban); + + // Update removal buttons if needed + if (enable_agent) + { + checkRemovalButton("allowed_avatar_name_list"); + } + + if (enable_group) + { + checkRemovalButton("allowed_group_name_list"); + } + + if (enable_ban) + { + checkRemovalButton("banned_avatar_name_list"); + } +} + +// static +void LLPanelEstateInfo::callbackCacheName( + const LLUUID& id, + const std::string& first, + const std::string& last, + BOOL is_group, + void*) +{ + LLPanelEstateInfo* self = LLFloaterRegionInfo::getPanelEstate(); + if (!self) return; + + std::string name; + + if (id.isNull()) + { + name = "(none)"; + } + else + { + name = first + " " + last; + } + + self->setOwnerName(name); +} + +void LLPanelEstateInfo::clearAccessLists() +{ + LLNameListCtrl* name_list = getChild("allowed_avatar_name_list"); + if (name_list) + { + name_list->deleteAllItems(); + } + + name_list = getChild("banned_avatar_name_list"); + if (name_list) + { + name_list->deleteAllItems(); + } +} + +// enables/disables the "remove" button for the various allow/ban lists +BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) +{ + std::string btn_name = ""; + if (name == "allowed_avatar_name_list") + { + btn_name = "remove_allowed_avatar_btn"; + } + else if (name == "allowed_group_name_list") + { + btn_name = "remove_allowed_group_btn"; + } + else if (name == "banned_avatar_name_list") + { + btn_name = "remove_banned_avatar_btn"; + } + else if (name == "estate_manager_name_list") + { + //ONLY OWNER CAN ADD /DELET ESTATE MANAGER + LLViewerRegion* region = gAgent.getRegion(); + if (region && (region->getOwner() == gAgent.getID())) + { + btn_name = "remove_estate_manager_btn"; + } + } + + // enable the remove button if something is selected + LLNameListCtrl* name_list = getChild(name); + childSetEnabled(btn_name, name_list && name_list->getFirstSelected() ? TRUE : FALSE); + + return (btn_name != ""); +} + +BOOL LLPanelEstateInfo::checkSunHourSlider(LLUICtrl* child_ctrl) +{ + BOOL found_child_ctrl = FALSE; + if (child_ctrl->getName() == "sun_hour_slider") + { + enableButton("apply_btn"); + found_child_ctrl = TRUE; + } + return found_child_ctrl; +} + +// static +void LLPanelEstateInfo::onClickMessageEstate(void* userdata) +{ + llinfos << "LLPanelEstateInfo::onClickMessageEstate" << llendl; + LLNotifications::instance().add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2)); +} + +bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + std::string text = response["message"].asString(); + if(option != 0) return false; + if(text.empty()) return false; + llinfos << "Message to everyone: " << text << llendl; + strings_t strings; + //integers_t integers; + std::string name; + gAgent.buildFullname(name); + strings.push_back(strings_t::value_type(name)); + strings.push_back(strings_t::value_type(text)); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); + return false; +} + +LLPanelEstateCovenant::LLPanelEstateCovenant() +: mCovenantID(LLUUID::null) +{ +} + +// virtual +bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) +{ + LLTextBox* region_name = getChild("region_name_text"); + if (region_name) + { + region_name->setText(region->getName()); + } + + LLTextBox* resellable_clause = getChild("resellable_clause"); + if (resellable_clause) + { + if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + { + resellable_clause->setText(getString("can_not_resell")); + } + else + { + resellable_clause->setText(getString("can_resell")); + } + } + + LLTextBox* changeable_clause = getChild("changeable_clause"); + if (changeable_clause) + { + if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + { + changeable_clause->setText(getString("can_change")); + } + else + { + changeable_clause->setText(getString("can_not_change")); + } + } + + LLTextBox* region_maturity = getChild("region_maturity_text"); + if (region_maturity) + { + region_maturity->setText(region->getSimAccessString()); + } + + LLTextBox* region_landtype = getChild("region_landtype_text"); + if (region_landtype) + { + region_landtype->setText(region->getSimProductName()); + } + + + // let the parent class handle the general data collection. + bool rv = LLPanelRegionInfo::refreshFromRegion(region); + LLMessageSystem *msg = gMessageSystem; + msg->newMessage("EstateCovenantRequest"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->sendReliable(region->getHost()); + return rv; +} + +// virtual +bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg) +{ + llinfos << "LLPanelEstateCovenant::estateUpdate()" << llendl; + return true; +} + +// virtual +BOOL LLPanelEstateCovenant::postBuild() +{ + initHelpBtn("covenant_help", "HelpEstateCovenant"); + mEstateNameText = getChild("estate_name_text"); + mEstateOwnerText = getChild("estate_owner_text"); + mLastModifiedText = getChild("covenant_timestamp_text"); + mEditor = getChild("covenant_editor"); + if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE); + LLButton* reset_button = getChild("reset_covenant"); + reset_button->setEnabled(gAgent.canManageEstate()); + reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); + + return LLPanelRegionInfo::postBuild(); +} + +// virtual +void LLPanelEstateCovenant::updateChild(LLUICtrl* child_ctrl) +{ +} + +// virtual +BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + LLInventoryItem* item = (LLInventoryItem*)cargo_data; + + if (!gAgent.canManageEstate()) + { + *accept = ACCEPT_NO; + return TRUE; + } + + switch(cargo_type) + { + case DAD_NOTECARD: + *accept = ACCEPT_YES_COPY_SINGLE; + if (item && drop) + { + LLSD payload; + payload["item_id"] = item->getUUID(); + LLNotifications::instance().add("EstateChangeCovenant", LLSD(), payload, + LLPanelEstateCovenant::confirmChangeCovenantCallback); + } + break; + default: + *accept = ACCEPT_NO; + break; + } + + return TRUE; +} + +// static +bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); + LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); + + if (!item || !self) return false; + + switch(option) + { + case 0: + self->loadInvItem(item); + break; + default: + break; + } + return false; +} + +// static +void LLPanelEstateCovenant::resetCovenantID(void* userdata) +{ + LLNotifications::instance().add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback); +} + +// static +bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response) +{ + LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); + if (!self) return false; + + S32 option = LLNotification::getSelectedOption(notification, response); + switch(option) + { + case 0: + self->loadInvItem(NULL); + break; + default: + break; + } + return false; +} + +void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp) +{ + const BOOL high_priority = TRUE; + if (itemp) + { + gAssetStorage->getInvItemAsset(gAgent.getRegionHost(), + gAgent.getID(), + gAgent.getSessionID(), + itemp->getPermissions().getOwner(), + LLUUID::null, + itemp->getUUID(), + itemp->getAssetUUID(), + itemp->getType(), + onLoadComplete, + (void*)this, + high_priority); + mAssetStatus = ASSET_LOADING; + } + else + { + mAssetStatus = ASSET_LOADED; + setCovenantTextEditor("There is no Covenant provided for this Estate."); + sendChangeCovenantID(LLUUID::null); + } +} + +// static +void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs, + const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + llinfos << "LLPanelEstateCovenant::onLoadComplete()" << llendl; + LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data; + if( panelp ) + { + if(0 == status) + { + LLVFile file(vfs, asset_uuid, type, LLVFile::READ); + + S32 file_length = file.getSize(); + + char* buffer = new char[file_length+1]; + if (buffer == NULL) + { + llerrs << "Memory Allocation Failed" << llendl; + return; + } + + file.read((U8*)buffer, file_length); /* Flawfinder: ignore */ + // put a EOS at the end + buffer[file_length] = 0; + + if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) + { + if( !panelp->mEditor->importBuffer( buffer, file_length+1 ) ) + { + llwarns << "Problem importing estate covenant." << llendl; + LLNotifications::instance().add("ProblemImportingEstateCovenant"); + } + else + { + panelp->sendChangeCovenantID(asset_uuid); + } + } + else + { + // Version 0 (just text, doesn't include version number) + panelp->sendChangeCovenantID(asset_uuid); + } + delete[] buffer; + } + else + { + LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); + + if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + LLNotifications::instance().add("MissingNotecardAssetID"); + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + LLNotifications::instance().add("NotAllowedToViewNotecard"); + } + else + { + LLNotifications::instance().add("UnableToLoadNotecardAsset"); + } + + llwarns << "Problem loading notecard: " << status << llendl; + } + panelp->mAssetStatus = ASSET_LOADED; + panelp->setCovenantID(asset_uuid); + } +} + +// key = "estatechangecovenantid" +// strings[0] = str(estate_id) (added by simulator before relay - not here) +// strings[1] = str(covenant_id) +void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id) +{ + if (asset_id != getCovenantID()) + { + setCovenantID(asset_id); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estatechangecovenantid"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + msg->nextBlock("ParamList"); + msg->addString("Parameter", getCovenantID().asString()); + gAgent.sendReliableMessage(); + } +} + +// virtual +BOOL LLPanelEstateCovenant::sendUpdate() +{ + return TRUE; +} + +const std::string& LLPanelEstateCovenant::getEstateName() const +{ + return mEstateNameText->getText(); +} + +void LLPanelEstateCovenant::setEstateName(const std::string& name) +{ + mEstateNameText->setText(name); +} + +// static +void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEditor->setText(string); + panelp->setCovenantID(asset_id); + } +} + +// static +void LLPanelEstateCovenant::updateEstateName(const std::string& name) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEstateNameText->setText(name); + } +} + +// static +void LLPanelEstateCovenant::updateLastModified(const std::string& text) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mLastModifiedText->setText(text); + } +} + +// static +void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEstateOwnerText->setText(name); + } +} + +const std::string& LLPanelEstateCovenant::getOwnerName() const +{ + return mEstateOwnerText->getText(); +} + +void LLPanelEstateCovenant::setOwnerName(const std::string& name) +{ + mEstateOwnerText->setText(name); +} + +void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text) +{ + mEditor->setText(text); +} + +// key = "estateupdateinfo" +// strings[0] = estate name +// strings[1] = str(owner_id) +// strings[2] = str(estate_id) +// strings[3] = str(estate_flags) +// strings[4] = str((S32)(sun_hour * 1024)) +// strings[5] = str(parent_estate_id) +// strings[6] = str(covenant_id) +// strings[7] = str(covenant_timestamp) +// strings[8] = str(send_to_agent_only) +// strings[9] = str(abuse_email_addr) +bool LLDispatchEstateUpdateInfo::operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return true; + + // NOTE: LLDispatcher extracts strings with an extra \0 at the + // end. If we pass the std::string direct to the UI/renderer + // it draws with a weird character at the end of the string. + std::string estate_name = strings[0].c_str(); // preserve c_str() call! + panel->setEstateName(estate_name); + + if (strings.size() > 3) + { + std::string abuse_email = strings[9].c_str(); // preserve c_str() call! + panel->setAbuseEmailAddress(abuse_email); + } + else + { + panel->setAbuseEmailAddress(panel->getString("email_unsupported")); + } + + LLViewerRegion* regionp = gAgent.getRegion(); + + LLUUID owner_id(strings[1]); + regionp->setOwner(owner_id); + // Update estate owner name in UI + const BOOL is_group = FALSE; + gCacheName->get(owner_id, is_group, LLPanelEstateInfo::callbackCacheName); + + U32 estate_id = strtoul(strings[2].c_str(), NULL, 10); + panel->setEstateID(estate_id); + + U32 flags = strtoul(strings[3].c_str(), NULL, 10); + panel->setEstateFlags(flags); + + F32 sun_hour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f; + if(sun_hour == 0 && (flags & REGION_FLAGS_SUN_FIXED ? FALSE : TRUE)) + { + panel->setGlobalTime(TRUE); + } + else + { + panel->setGlobalTime(FALSE); + panel->setSunHour(sun_hour); + } + + bool visible_from_mainland = (bool)(flags & REGION_FLAGS_EXTERNALLY_VISIBLE); + bool god = gAgent.isGodlike(); + bool linden_estate = (estate_id <= ESTATE_LAST_LINDEN); + + // If visible from mainland, disable the access allowed + // UI, as anyone can teleport there. + // However, gods need to be able to edit the access list for + // linden estates, regardless of visibility, to allow object + // and L$ transfers. + bool enable_agent = (!visible_from_mainland || (god && linden_estate)); + bool enable_group = enable_agent; + bool enable_ban = !linden_estate; + panel->setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); + + return true; +} + + +// key = "setaccess" +// strings[0] = str(estate_id) +// strings[1] = str(packed_access_lists) +// strings[2] = str(num allowed agent ids) +// strings[3] = str(num allowed group ids) +// strings[4] = str(num banned agent ids) +// strings[5] = str(num estate manager agent ids) +// strings[6] = bin(uuid) +// strings[7] = bin(uuid) +// strings[8] = bin(uuid) +// ... +bool LLDispatchSetEstateAccess::operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return true; + + S32 index = 1; // skip estate_id + U32 access_flags = strtoul(strings[index++].c_str(), NULL,10); + S32 num_allowed_agents = strtol(strings[index++].c_str(), NULL, 10); + S32 num_allowed_groups = strtol(strings[index++].c_str(), NULL, 10); + S32 num_banned_agents = strtol(strings[index++].c_str(), NULL, 10); + S32 num_estate_managers = strtol(strings[index++].c_str(), NULL, 10); + + // sanity ckecks + if (num_allowed_agents > 0 + && !(access_flags & ESTATE_ACCESS_ALLOWED_AGENTS)) + { + llwarns << "non-zero count for allowed agents, but no corresponding flag" << llendl; + } + if (num_allowed_groups > 0 + && !(access_flags & ESTATE_ACCESS_ALLOWED_GROUPS)) + { + llwarns << "non-zero count for allowed groups, but no corresponding flag" << llendl; + } + if (num_banned_agents > 0 + && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) + { + llwarns << "non-zero count for banned agents, but no corresponding flag" << llendl; + } + if (num_estate_managers > 0 + && !(access_flags & ESTATE_ACCESS_MANAGERS)) + { + llwarns << "non-zero count for managers, but no corresponding flag" << llendl; + } + + // grab the UUID's out of the string fields + if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) + { + LLNameListCtrl* allowed_agent_name_list; + allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + + int totalAllowedAgents = num_allowed_agents; + + if (allowed_agent_name_list) + { + totalAllowedAgents += allowed_agent_name_list->getItemCount(); + } + + std::string msg = llformat("Allowed residents: (%d, max %d)", + totalAllowedAgents, + ESTATE_MAX_ACCESS_IDS); + panel->childSetValue("allow_resident_label", LLSD(msg)); + + if (allowed_agent_name_list) + { + //allowed_agent_name_list->deleteAllItems(); + for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + allowed_agent_name_list->addNameItem(id); + } + panel->childSetEnabled("remove_allowed_avatar_btn", allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); + allowed_agent_name_list->sortByColumnIndex(0, TRUE); + } + } + + if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) + { + LLNameListCtrl* allowed_group_name_list; + allowed_group_name_list = panel->getChild("allowed_group_name_list"); + + std::string msg = llformat("Allowed groups: (%d, max %d)", + num_allowed_groups, + (S32) ESTATE_MAX_GROUP_IDS); + panel->childSetValue("allow_group_label", LLSD(msg)); + + if (allowed_group_name_list) + { + allowed_group_name_list->deleteAllItems(); + for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + allowed_group_name_list->addGroupNameItem(id); + } + panel->childSetEnabled("remove_allowed_group_btn", allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); + allowed_group_name_list->sortByColumnIndex(0, TRUE); + } + } + + if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) + { + LLNameListCtrl* banned_agent_name_list; + banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + + int totalBannedAgents = num_banned_agents; + + if (banned_agent_name_list) + { + totalBannedAgents += banned_agent_name_list->getItemCount(); + } + + + std::string msg = llformat("Banned residents: (%d, max %d)", + totalBannedAgents, + ESTATE_MAX_ACCESS_IDS); + panel->childSetValue("ban_resident_label", LLSD(msg)); + + if (banned_agent_name_list) + { + //banned_agent_name_list->deleteAllItems(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + banned_agent_name_list->addNameItem(id); + } + panel->childSetEnabled("remove_banned_avatar_btn", banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); + banned_agent_name_list->sortByColumnIndex(0, TRUE); + } + } + + if (access_flags & ESTATE_ACCESS_MANAGERS) + { + std::string msg = llformat("Estate Managers: (%d, max %d)", + num_estate_managers, + ESTATE_MAX_MANAGERS); + panel->childSetValue("estate_manager_label", LLSD(msg)); + + LLNameListCtrl* estate_manager_name_list = + panel->getChild("estate_manager_name_list"); + if (estate_manager_name_list) + { + estate_manager_name_list->deleteAllItems(); // Clear existing entries + + // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't + // truncate the list unless it's really big. Go ahead and show the extras so the user doesn't get confused, + // and they can still remove them. + for (S32 i = 0; i < num_estate_managers && i < (ESTATE_MAX_MANAGERS * 4); i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + estate_manager_name_list->addNameItem(id); + } + panel->childSetEnabled("remove_estate_manager_btn", estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); + estate_manager_name_list->sortByColumnIndex(0, TRUE); + } + } + + return true; +} + +// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) +void LLFloaterRegionInfo::open() +{ + // We'll allow access to the estate tools for estate managers (and for the sim owner) + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) + { + LLViewerRegion* pRegion = gAgent.getRegion(); + if (!pRegion) + return; + + // Should be able to call LLRegion::canManageEstate() but then we can fake god like + if ( (!pRegion->isEstateManager()) && (pRegion->getOwner() != gAgent.getID()) ) + return; + } + + LLFloater::open(); +} +// [/RLVa:KB] diff --git a/linden/indra/newview/llfloaterregioninfo.h b/linden/indra/newview/llfloaterregioninfo.h index fd0d9ce..ee01c7c 100644 --- a/linden/indra/newview/llfloaterregioninfo.h +++ b/linden/indra/newview/llfloaterregioninfo.h @@ -53,6 +53,7 @@ class LLSpinCtrl; class LLTextBox; class LLPanelRegionGeneralInfo; +class LLPanelRegionOpenSettingsInfo; class LLPanelRegionDebugInfo; class LLPanelRegionTextureInfo; class LLPanelRegionTerrainInfo; @@ -83,6 +84,7 @@ public: static LLPanelEstateInfo* getPanelEstate(); static LLPanelEstateCovenant* getPanelCovenant(); + static LLPanelRegionOpenSettingsInfo* getPanelOpenSettings(); // from LLPanel virtual void refresh(); @@ -173,6 +175,24 @@ protected: ///////////////////////////////////////////////////////////////////////////// +class LLPanelRegionOpenSettingsInfo : public LLPanelRegionInfo +{ +public: + LLPanelRegionOpenSettingsInfo() + : LLPanelRegionInfo() {} + ~LLPanelRegionOpenSettingsInfo() {} + + virtual bool refreshFromRegion(LLViewerRegion* region); + + // LLPanel + virtual BOOL postBuild(); + +protected: + static void sendUpdate(void* userdata); +}; + +///////////////////////////////////////////////////////////////////////////// + class LLPanelRegionDebugInfo : public LLPanelRegionInfo { public: diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 6744faf..c092f5a 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -181,26 +181,23 @@ void* LLFloaterTools::createPanelLandInfo(void* data) void LLFloaterTools::updateToolsSizeLimits() { - if (gSavedSettings.getBOOL("DisableMaxBuildConstraints")) - { - getChild("Scale X")->setMaxValue(F32_MAX); - getChild("Scale Y")->setMaxValue(F32_MAX); - getChild("Scale Z")->setMaxValue(F32_MAX); + getChild("Scale X")->setMinValue(gHippoLimits->getMinPrimScale()); + getChild("Scale Y")->setMinValue(gHippoLimits->getMinPrimScale()); + getChild("Scale Z")->setMinValue(gHippoLimits->getMinPrimScale()); - getChild("Pos X")->setMaxValue(F32_MAX); - getChild("Pos Y")->setMaxValue(F32_MAX); - getChild("Pos Z")->setMaxValue(F32_MAX); - } - else - { - getChild("Scale X")->setMaxValue(gHippoLimits->getMaxPrimScale()); - getChild("Scale Y")->setMaxValue(gHippoLimits->getMaxPrimScale()); - getChild("Scale Z")->setMaxValue(gHippoLimits->getMaxPrimScale()); + getChild("Scale X")->setMaxValue(gHippoLimits->getMaxPrimScale()); + getChild("Scale Y")->setMaxValue(gHippoLimits->getMaxPrimScale()); + getChild("Scale Z")->setMaxValue(gHippoLimits->getMaxPrimScale()); - getChild("Scale X")->setMinValue(gHippoLimits->getMinPrimScale()); - getChild("Scale Y")->setMinValue(gHippoLimits->getMinPrimScale()); - getChild("Scale Z")->setMinValue(gHippoLimits->getMinPrimScale()); - } + getChild("Pos X")->setMinValue(gHippoLimits->getMinPrimXPos()); + getChild("Pos Y")->setMinValue(gHippoLimits->getMinPrimYPos()); + getChild("Pos Z")->setMinValue(gHippoLimits->getMinPrimZPos()); + + getChild("Pos X")->setMaxValue(gHippoLimits->getMaxPrimXPos()); + getChild("Pos Y")->setMaxValue(gHippoLimits->getMaxPrimYPos()); + getChild("Pos Z")->setMaxValue(gHippoLimits->getMinPrimZPos()); + + getChild("Physical Checkbox Ctrl")->setEnabled(gHippoLimits->mAllowPhysicalPrims); } void LLFloaterTools::updateToolsPrecision() @@ -1258,8 +1255,18 @@ void LLFloaterTools::onClickLink(void* data) return; } - S32 max_linked_prims = gHippoLimits->getMaxLinkedPrims(); - if (max_linked_prims > -1) + S32 max_linked_prims = 0; + if(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->usePhysics()) + { + //Physical - use phys prim limit + max_linked_prims = gHippoLimits->getMaxPhysLinkedPrims(); + } + else + { + //Non phys limit + max_linked_prims = gHippoLimits->getMaxLinkedPrims(); + } + if (max_linked_prims > -1) //-1 : no limits { S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); if (object_count > max_linked_prims + 1) @@ -1271,7 +1278,7 @@ void LLFloaterTools::onClickLink(void* data) return; } } - + if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) { LLNotifications::instance().add("CannotLinkIncompleteSet"); diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index 52d7b1f..2684e10 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -1,284 +1,310 @@ -/** - * @file llfloatertos.cpp - * @brief Terms of Service Agreement dialog - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloatertos.h" - -// viewer includes -#include "llagent.h" -#include "llappviewer.h" -#include "llstartup.h" -#include "llviewerstats.h" -#include "llviewertexteditor.h" -#include "llviewerwindow.h" - -// linden library includes -#include "llbutton.h" -#include "llhttpclient.h" -#include "llhttpstatuscodes.h" // for HTTP_FOUND -#include "llradiogroup.h" -#include "lltextbox.h" -#include "llui.h" -#include "lluictrlfactory.h" -#include "llvfile.h" -#include "message.h" - - -// static -LLFloaterTOS* LLFloaterTOS::sInstance = NULL; - -// static -LLFloaterTOS* LLFloaterTOS::show(ETOSType type, const std::string & message) -{ - if( !LLFloaterTOS::sInstance ) - { - LLFloaterTOS::sInstance = new LLFloaterTOS(type, message); - } - - if (type == TOS_TOS) - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml"); - } - else - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml"); - } - - return LLFloaterTOS::sInstance; -} - - -LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message) -: LLModalDialog( std::string(" "), 100, 100 ), - mType(type), - mMessage(message), - mWebBrowserWindowId( 0 ), - mLoadCompleteCount( 0 ) -{ -} - -// helper class that trys to download a URL from a web site and calls a method -// on parent class indicating if the web server is working or not -class LLIamHereTOS : public LLHTTPClient::Responder -{ - private: - LLIamHereTOS( LLFloaterTOS* parent ) : - mParent( parent ) - {} - - LLFloaterTOS* mParent; - - public: - - static boost::intrusive_ptr< LLIamHereTOS > build( LLFloaterTOS* parent ) - { - return boost::intrusive_ptr< LLIamHereTOS >( new LLIamHereTOS( parent ) ); - }; - - virtual void setParent( LLFloaterTOS* parentIn ) - { - mParent = parentIn; - }; - - virtual void result( const LLSD& content ) - { - if ( mParent ) - mParent->setSiteIsAlive( true ); - }; - - virtual void error( U32 status, const std::string& reason ) - { - if ( mParent ) - { - // *HACK: For purposes of this alive check, 302 Found - // (aka Moved Temporarily) is considered alive. The web site - // redirects this link to a "cache busting" temporary URL. JC - bool alive = (status == HTTP_FOUND); - mParent->setSiteIsAlive( alive ); - } - }; -}; - -// this is global and not a class member to keep crud out of the header file -namespace { - boost::intrusive_ptr< LLIamHereTOS > gResponsePtr = 0; -}; - -BOOL LLFloaterTOS::postBuild() -{ - childSetAction("Continue", onContinue, this); - childSetAction("Cancel", onCancel, this); - childSetCommitCallback("agree_chk", updateAgree, this); - - if ( mType != TOS_TOS ) - { - llinfos << "tos_type != TOS_TOS" << llendl; - // this displays the critical message - LLTextEditor *editor = getChild("tos_text"); - editor->setHandleEditKeysDirectly( TRUE ); - editor->setEnabled( FALSE ); - editor->setWordWrap(TRUE); - editor->setFocus(TRUE); - // editor->setValue(LLSD(mMessage)); - editor->setValue(mMessage); - - return TRUE; - } - - // disable Agree to TOS radio button until the page has fully loaded - LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); - tos_agreement->setEnabled( false ); - - // hide the SL text widget if we're displaying TOS with using a browser widget. - LLTextEditor *editor = getChild("tos_text"); - editor->setVisible(FALSE); - - LLWebBrowserCtrl* web_browser = getChild("tos_html"); - if ( web_browser ) - { - // start to observe it so we see navigate complete events - web_browser->addObserver( this ); - - gResponsePtr = LLIamHereTOS::build( this ); - LLHTTPClient::head( getString( "real_url" ), gResponsePtr ); - } - - return TRUE; -} - -void LLFloaterTOS::setSiteIsAlive( bool alive ) -{ - // only do this for TOS pages - if ( mType == TOS_TOS ) - { - LLWebBrowserCtrl* web_browser = getChild("tos_html"); - // if the contents of the site was retrieved - if ( alive ) - { - if ( web_browser ) - { - // navigate to the "real" page - web_browser->navigateTo( getString( "real_url" ) ); - }; - } - else - { - // normally this is set when navigation to TOS page navigation completes (so you can't accept before TOS loads) - // but if the page is unavailable, we need to do this now - LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); - tos_agreement->setEnabled( true ); - }; - }; -} - -LLFloaterTOS::~LLFloaterTOS() -{ - // stop obsaerving events - LLWebBrowserCtrl* web_browser = getChild("tos_html"); - if ( web_browser ) - { - web_browser->remObserver( this ); - }; - - // tell the responder we're not here anymore - if ( gResponsePtr ) - gResponsePtr->setParent( 0 ); - - LLFloaterTOS::sInstance = NULL; -} - -// virtual -void LLFloaterTOS::draw() -{ - // draw children - LLModalDialog::draw(); -} - -// static -void LLFloaterTOS::updateAgree(LLUICtrl*, void* userdata ) -{ - LLFloaterTOS* self = (LLFloaterTOS*) userdata; - bool agree = self->childGetValue("agree_chk").asBoolean(); - self->childSetEnabled("Continue", agree); -} - -// static -void LLFloaterTOS::onContinue( void* userdata ) -{ - LLFloaterTOS* self = (LLFloaterTOS*) userdata; - llinfos << "User agrees with TOS." << llendl; - if (self->mType == TOS_TOS) - { - gAcceptTOS = TRUE; - } - else - { - gAcceptCriticalMessage = TRUE; - } - - // Testing TOS dialog - #if ! LL_RELEASE_FOR_DOWNLOAD - if ( LLStartUp::getStartupState() == STATE_LOGIN_WAIT ) - { - LLStartUp::setStartupState( STATE_LOGIN_SHOW ); - } - else - #endif - - LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication - self->close(); // destroys this object -} - -// static -void LLFloaterTOS::onCancel( void* userdata ) -{ - LLFloaterTOS* self = (LLFloaterTOS*) userdata; - llinfos << "User disagrees with TOS." << llendl; - LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done); - LLStartUp::setStartupState( STATE_LOGIN_SHOW ); - self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS - self->close(); // destroys this object -} - -//virtual -void LLFloaterTOS::onNavigateComplete( const EventType& eventIn ) -{ - // skip past the loading screen navigate complete - if ( ++mLoadCompleteCount == 2 ) - { - llinfos << "NAVIGATE COMPLETE" << llendl; - // enable Agree to TOS radio button now that page has loaded - LLCheckBoxCtrl * tos_agreement = getChild("agree_chk"); - tos_agreement->setEnabled( true ); - }; -} +/** + * @file llfloatertos.cpp + * @brief Terms of Service Agreement dialog + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatertos.h" + +// viewer includes +#include "llagent.h" +#include "llappviewer.h" +#include "llstartup.h" +#include "llviewerstats.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" + +// linden library includes +#include "llbutton.h" +#include "llhttpclient.h" +#include "llhttpstatuscodes.h" // for HTTP_FOUND +#include "llradiogroup.h" +#include "lltextbox.h" +#include "llui.h" +#include "lluictrlfactory.h" +#include "llvfile.h" +#include "message.h" +#include "hippoGridManager.h" + + +// static +LLFloaterTOS* LLFloaterTOS::sInstance = NULL; + +// static +LLFloaterTOS* LLFloaterTOS::show(ETOSType type, const std::string & message) +{ + if( !LLFloaterTOS::sInstance ) + { + LLFloaterTOS::sInstance = new LLFloaterTOS(type, message); + } + + if (type == TOS_TOS) + { + LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml"); + } + else + { + LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml"); + } + + return LLFloaterTOS::sInstance; +} + + +LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message) +: LLModalDialog( std::string(" "), 100, 100 ), + mType(type), + mMessage(message), + mWebBrowserWindowId( 0 ), + mLoadCompleteCount( 0 ) +{ +} + +// helper class that trys to download a URL from a web site and calls a method +// on parent class indicating if the web server is working or not +class LLIamHereTOS : public LLHTTPClient::Responder +{ + private: + LLIamHereTOS( LLFloaterTOS* parent ) : + mParent( parent ) + {} + + LLFloaterTOS* mParent; + + public: + + static boost::intrusive_ptr< LLIamHereTOS > build( LLFloaterTOS* parent ) + { + return boost::intrusive_ptr< LLIamHereTOS >( new LLIamHereTOS( parent ) ); + }; + + virtual void setParent( LLFloaterTOS* parentIn ) + { + mParent = parentIn; + }; + + virtual void result( const LLSD& content ) + { + if ( mParent ) + mParent->setSiteIsAlive( true ); + }; + + virtual void error( U32 status, const std::string& reason ) + { + if ( mParent ) + { + // *HACK: For purposes of this alive check, 302 Found + // (aka Moved Temporarily) is considered alive. The web site + // redirects this link to a "cache busting" temporary URL. JC + bool alive = (status == HTTP_FOUND); + mParent->setSiteIsAlive( alive ); + } + }; +}; + +// this is global and not a class member to keep crud out of the header file +namespace { + boost::intrusive_ptr< LLIamHereTOS > gResponsePtr = 0; +}; + +BOOL LLFloaterTOS::postBuild() +{ + childSetAction("Continue", onContinue, this); + childSetAction("Cancel", onCancel, this); + childSetCommitCallback("agree_chk", updateAgree, this); + + LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); + tos_agreement->setEnabled( true ); + + //Always set this so that the TOS is displayed whether the web browser pops up or not. + LLTextEditor *editor = getChild("tos_text"); + editor->setHandleEditKeysDirectly( TRUE ); + editor->setEnabled( FALSE ); + editor->setWordWrap(TRUE); + editor->setFocus(TRUE); + editor->setValue(LLSD(mMessage)); + LLWebBrowserCtrl* web_browser = getChild("tos_html"); + if (web_browser) + { + //Disable for critical messages and text messages, it is reenabled later + web_browser->setVisible( FALSE ); + } + + if ( mType != TOS_TOS ) + { + // this displays the critical message only + return TRUE; + } + bool use_web_browser = false; + + //Check to see if the message is a link to display + std::string token = "http://"; + std::string::size_type iIndex = mMessage.rfind(token); + //IF it has http:// in it, we use the web browser + if(iIndex != std::string::npos && mMessage.length() >= 2) + { + // it exists + use_web_browser = true; + } + else if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + { + //Its SL, use the browser for it as thats what it should do + use_web_browser = true; + } + + if ( web_browser && use_web_browser) + { + // hide the SL text widget if we're displaying TOS with using a browser widget. + LLTextEditor *editor = getChild("tos_text"); + editor->setVisible( FALSE ); + + // disable Agree to TOS radio button until the page has fully loaded + tos_agreement->setEnabled( false ); + + // Reenable the web browser + web_browser->setVisible( TRUE ); + + // start to observe it so we see navigate complete events + web_browser->addObserver( this ); + + gResponsePtr = LLIamHereTOS::build( this ); + LLHTTPClient::head( getString( "real_url" ), gResponsePtr ); + } + + return TRUE; +} + +void LLFloaterTOS::setSiteIsAlive( bool alive ) +{ + // only do this for TOS pages + if ( mType == TOS_TOS ) + { + LLWebBrowserCtrl* web_browser = getChild("tos_html"); + // if the contents of the site was retrieved + if ( alive ) + { + if ( web_browser ) + { + // navigate to the "real" page + web_browser->navigateTo( getString( "real_url" ) ); + }; + } + else + { + // normally this is set when navigation to TOS page navigation completes (so you can't accept before TOS loads) + // but if the page is unavailable, we need to do this now + LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); + tos_agreement->setEnabled( true ); + }; + }; +} + +LLFloaterTOS::~LLFloaterTOS() +{ + // stop obsaerving events + LLWebBrowserCtrl* web_browser = getChild("tos_html"); + if ( web_browser ) + { + web_browser->remObserver( this ); + }; + + // tell the responder we're not here anymore + if ( gResponsePtr ) + gResponsePtr->setParent( 0 ); + + LLFloaterTOS::sInstance = NULL; +} + +// virtual +void LLFloaterTOS::draw() +{ + // draw children + LLModalDialog::draw(); +} + +// static +void LLFloaterTOS::updateAgree(LLUICtrl*, void* userdata ) +{ + LLFloaterTOS* self = (LLFloaterTOS*) userdata; + bool agree = self->childGetValue("agree_chk").asBoolean(); + self->childSetEnabled("Continue", agree); +} + +// static +void LLFloaterTOS::onContinue( void* userdata ) +{ + LLFloaterTOS* self = (LLFloaterTOS*) userdata; + llinfos << "User agrees with TOS." << llendl; + if (self->mType == TOS_TOS) + { + gAcceptTOS = TRUE; + } + else + { + gAcceptCriticalMessage = TRUE; + } + + // Testing TOS dialog + #if ! LL_RELEASE_FOR_DOWNLOAD + if ( LLStartUp::getStartupState() == STATE_LOGIN_WAIT ) + { + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); + } + else + #endif + + LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication + self->close(); // destroys this object +} + +// static +void LLFloaterTOS::onCancel( void* userdata ) +{ + LLFloaterTOS* self = (LLFloaterTOS*) userdata; + llinfos << "User disagrees with TOS." << llendl; + LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done); + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); + self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS + self->close(); // destroys this object +} + +//virtual +void LLFloaterTOS::onNavigateComplete( const EventType& eventIn ) +{ + // skip past the loading screen navigate complete + if ( ++mLoadCompleteCount == 2 ) + { + llinfos << "NAVIGATE COMPLETE" << llendl; + // enable Agree to TOS radio button now that page has loaded + LLCheckBoxCtrl * tos_agreement = getChild("agree_chk"); + tos_agreement->setEnabled( true ); + }; +} diff --git a/linden/indra/newview/llfloaterwater.cpp b/linden/indra/newview/llfloaterwater.cpp index c4b6d0d..782c56e 100644 --- a/linden/indra/newview/llfloaterwater.cpp +++ b/linden/indra/newview/llfloaterwater.cpp @@ -64,6 +64,8 @@ #include "llwaterparammanager.h" #include "llpostprocess.h" +#include "wlfloaterwindlightsend.h" + #undef max LLFloaterWater* LLFloaterWater::sWaterMenu = NULL; @@ -680,6 +682,12 @@ void LLFloaterWater::onSavePreset(LLUICtrl* ctrl, void* userData) } } + else if (ctrl->getValue().asString() == "send_to_server_item") + { + //Open the other box + WLFloaterWindLightSend::instance(); + WLFloaterWindLightSend::instance()->open(); + } else { LLWaterParamManager::instance()->mCurParams.mName = diff --git a/linden/indra/newview/llfloaterwindlight.cpp b/linden/indra/newview/llfloaterwindlight.cpp index be3c1fd..4937232 100644 --- a/linden/indra/newview/llfloaterwindlight.cpp +++ b/linden/indra/newview/llfloaterwindlight.cpp @@ -63,6 +63,9 @@ #include "llwlparamset.h" #include "llwlparammanager.h" #include "llpostprocess.h" +#include "wlfloaterwindlightsend.h" +#include "llworld.h" +#include "hippolimits.h" #undef max @@ -216,7 +219,9 @@ void LLFloaterWindLight::initCallbacks(void) { childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL); childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL); childSetCommitCallback("WLDistanceMult", onFloatControlMoved, ¶m_mgr->mDistanceMult); - childSetCommitCallback("DrawClassicClouds", LLSavedSettingsGlue::setBOOL, (void*)"SkyUseClassicClouds"); + childSetCommitCallback("DrawClassicClouds", onCloudDrawToggled, NULL); + childSetCommitCallback("WLCloudHeight", onCloudHeightMoved, NULL); + childSetCommitCallback("WLCloudRange", onCloudRangeMoved, NULL); // WL Top childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); @@ -425,7 +430,21 @@ void LLFloaterWindLight::syncMenu() bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); childSetValue("WLCloudLockX", lockX); childSetValue("WLCloudLockY", lockY); - childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds")); + childSetValue("DrawClassicClouds", gHippoLimits->skyUseClassicClouds); + + childSetValue("WLCloudHeight", gSavedSettings.getF32("ClassicCloudHeight")); + childSetValue("WLCloudRange", gSavedSettings.getF32("ClassicCloudRange")); + + if(!gHippoLimits->skyUseClassicClouds) + { + childDisable("WLCloudHeight"); + childDisable("WLCloudRange"); + } + else + { + childEnable("WLCloudHeight"); + childEnable("WLCloudRange"); + } // disable if locked, enable if not if(lockX) @@ -874,6 +893,12 @@ void LLFloaterWindLight::onSavePreset(LLUICtrl* ctrl, void* userData) } } + else if (ctrl->getValue().asString() == "send_to_server_item") + { + //Open the other box + WLFloaterWindLightSend::instance(); + WLFloaterWindLightSend::instance()->open(); + } else { // check to see if it's a default and shouldn't be overwritten @@ -1046,6 +1071,35 @@ void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData) // *HACK all cloud scrolling is off by an additive of 10. LLWLParamManager::instance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f); } +void LLFloaterWindLight::onCloudDrawToggled(LLUICtrl* ctrl, void* userData) +{ + LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); + + bool lock = cbCtrl->get(); + gHippoLimits->skyUseClassicClouds = lock; + + LLWorld::getInstance()->rebuildClouds(gAgent.getRegion()); +} + +void LLFloaterWindLight::onCloudHeightMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + + gSavedSettings.setF32("ClassicCloudHeight", sldrCtrl->getValueF32()); + + LLWorld::getInstance()->rebuildClouds(gAgent.getRegion()); +} + +void LLFloaterWindLight::onCloudRangeMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + + gSavedSettings.setF32("ClassicCloudRange", sldrCtrl->getValueF32()); +} void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) { diff --git a/linden/indra/newview/llfloaterwindlight.h b/linden/indra/newview/llfloaterwindlight.h index b9e5311..24b0e87 100644 --- a/linden/indra/newview/llfloaterwindlight.h +++ b/linden/indra/newview/llfloaterwindlight.h @@ -118,6 +118,10 @@ public: static void onCloudScrollXToggled(LLUICtrl* ctrl, void* userData); static void onCloudScrollYToggled(LLUICtrl* ctrl, void* userData); + static void onCloudDrawToggled(LLUICtrl* ctrl, void* userData); + static void onCloudHeightMoved(LLUICtrl* ctrl, void* userData); + static void onCloudRangeMoved(LLUICtrl* ctrl, void* userData); + //// menu management /// show off our menu diff --git a/linden/indra/newview/llhomelocationresponder.cpp b/linden/indra/newview/llhomelocationresponder.cpp index 3ef58e7..e609237 100644 --- a/linden/indra/newview/llhomelocationresponder.cpp +++ b/linden/indra/newview/llhomelocationresponder.cpp @@ -100,6 +100,8 @@ void LLHomeLocationResponder::result( const LLSD& content ) LLViewerRegion *viewer_region = gAgent.getRegion(); gAgent.setHomePosRegion( viewer_region->getHandle(), agent_pos ); + gAgent.takeHomeScreenshot(); + } } diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index 01fe6f8..aada658 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp @@ -533,7 +533,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) { F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance"); - if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) + if(max_drag_distance < gHippoLimits->getMaxDragDistance()) max_drag_distance = gHippoLimits->getMaxDragDistance(); //Take the more restrictive if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) { lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (too far)" << llendl; gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); diff --git a/linden/indra/newview/llprefschat.cpp b/linden/indra/newview/llprefschat.cpp index 6ebc880..8d704d5 100644 --- a/linden/indra/newview/llprefschat.cpp +++ b/linden/indra/newview/llprefschat.cpp @@ -72,6 +72,7 @@ private: BOOL mShowTimestamps; BOOL mPlayTypingAnim; BOOL mChatBubbles; + BOOL mLocalChatBubbles; BOOL mScriptErrorAsChat; BOOL mChatChannel; F32 mConsoleOpacity; @@ -106,6 +107,7 @@ LLPrefsChatImpl::LLPrefsChatImpl() childSetValue("script_errors_as_chat", gSavedSettings.getBOOL("ScriptErrorsAsChat")); childSetValue("bubble_text_chat", gSavedSettings.getBOOL("UseChatBubbles")); + childSetValue("local_bubble_text_chat", gSavedSettings.getBOOL("UseLocalChatWithBubbles")); childSetValue("chat_full_width_check", gSavedSettings.getBOOL("ChatFullWidth")); childSetValue("close_chat_on_return_check", gSavedSettings.getBOOL("CloseChatOnReturn")); childSetValue("play_typing_animation", gSavedSettings.getBOOL("PlayTypingAnim")); @@ -135,6 +137,7 @@ void LLPrefsChatImpl::refreshValues() mShowTimestamps = gSavedSettings.getBOOL("ChatShowTimestamps"); mScriptErrorAsChat = gSavedSettings.getBOOL("ScriptErrorsAsChat"); mChatBubbles = gSavedSettings.getBOOL("UseChatBubbles"); + mLocalChatBubbles = gSavedSettings.getBOOL("UseLocalChatWithBubbles"); mChatFullWidth = gSavedSettings.getBOOL("ChatFullWidth"); mCloseChatOnReturn = gSavedSettings.getBOOL("CloseChatOnReturn"); mPlayTypingAnim = gSavedSettings.getBOOL("PlayTypingAnim"); @@ -164,6 +167,7 @@ void LLPrefsChatImpl::cancel() gSavedSettings.setBOOL("ChatShowTimestamps", mShowTimestamps); gSavedSettings.setBOOL("ScriptErrorsAsChat", mScriptErrorAsChat); gSavedSettings.setBOOL("UseChatBubbles", mChatBubbles); + gSavedSettings.setBOOL("UseLocalChatWithBubbles", mLocalChatBubbles); gSavedSettings.setBOOL("ChatFullWidth", mChatFullWidth); gSavedSettings.setBOOL("CloseChatOnReturn", mCloseChatOnReturn); gSavedSettings.setBOOL("PlayTypingAnim", mPlayTypingAnim); @@ -196,6 +200,7 @@ void LLPrefsChatImpl::apply() gSavedSettings.setBOOL("ChatShowTimestamps", childGetValue("show_timestamps_check")); gSavedSettings.setBOOL("ScriptErrorsAsChat", childGetValue("script_errors_as_chat")); gSavedSettings.setBOOL("UseChatBubbles", childGetValue("bubble_text_chat")); + gSavedSettings.setBOOL("UseLocalChatWithBubbles", childGetValue("local_bubble_text_chat")); gSavedSettings.setBOOL("ChatFullWidth", childGetValue("chat_full_width_check")); gSavedSettings.setBOOL("CloseChatOnReturn", childGetValue("close_chat_on_return_check")); gSavedSettings.setBOOL("PlayTypingAnim", childGetValue("play_typing_animation")); diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index caaba05..d736fb0 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -59,6 +59,7 @@ #include "llglheaders.h" #include "lldrawpoolterrain.h" #include "lldrawable.h" +#include "hippolimits.h" extern LLPipeline gPipeline; @@ -295,7 +296,7 @@ void LLSurface::initTextures() // // Water texture // - if (gSavedSettings.getBOOL("RenderWater") ) + if (gSavedSettings.getBOOL("RenderWater") && gHippoLimits->mRenderWater) { createWaterTexture(); mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); @@ -306,6 +307,29 @@ void LLSurface::initTextures() } } +//static +void LLSurface::rebuildWater() +{ + //lldebugs << "Rebuilding Water..."; + if(!mWaterObjp.isNull()) + { + //lldebugs << "Removing Water"; + //Remove the old + gObjectList.killObject(mWaterObjp); + } + + if (gSavedSettings.getBOOL("RenderWater") && gHippoLimits->mRenderWater) + { + //lldebugs << "Building Water"; + createWaterTexture(); + mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); + gPipeline.createObject(mWaterObjp); + LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); + water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); + mWaterObjp->setPositionGlobal(water_pos_global); + } + //lldebugs << "Rebuilding Water Complete"; +} void LLSurface::setOriginGlobal(const LLVector3d &origin_global) { diff --git a/linden/indra/newview/llsurface.h b/linden/indra/newview/llsurface.h index 003b2f2..c217b19 100644 --- a/linden/indra/newview/llsurface.h +++ b/linden/indra/newview/llsurface.h @@ -91,6 +91,8 @@ public: void disconnectNeighbor(LLSurface *neighborp); void disconnectAllNeighbors(); + void rebuildWater(); //Destroys (if nesessary) and then rebuilds (if needed) + virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch); virtual void updatePatchVisibilities(LLAgent &agent); diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 2bc6e3e..4e133de 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp @@ -75,6 +75,7 @@ // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] +#include "hippoLimits.h" // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a @@ -1679,8 +1680,10 @@ void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent, LLNotifications::instance().add("IncompleteInventory"); return; } + count = items.count() + cats.count(); - if(count > MAX_ITEMS) + if(count > gHippoLimits->getMaxInventoryItemsTransfer() && + gHippoLimits->getMaxInventoryItemsTransfer() != -1) //MAX_ITEMS) { LLNotifications::instance().add("TooManyItems"); return; @@ -1776,8 +1779,9 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent, // MTUBYTES or 18 * count < 1200 => count < 1200/18 => // 66. I've cut it down a bit from there to give some pad. S32 count = items.count() + cats.count(); - if(count > MAX_ITEMS) - { + if(count > gHippoLimits->getMaxInventoryItemsTransfer() && + gHippoLimits->getMaxInventoryItemsTransfer() != -1) //MAX_ITEMS) + { LLNotifications::instance().add("TooManyItems"); return; } diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index 78940cc..4167464 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -82,6 +82,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" +#include "hippoLimits.h" // [RLVa:KB] #include "rlvhandler.h" @@ -181,6 +182,12 @@ void display_update_camera() { final_far *= 0.5f; } + if(gAgent.mLockedDrawDistance) + { + //Reset the draw distance and do not update with the new val + final_far = LLViewerCamera::getInstance()->getFar(); + gAgent.mDrawDistance = final_far; + } LLViewerCamera::getInstance()->setFar(final_far); gViewerWindow->setup3DRender(); @@ -305,13 +312,19 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // Update GL Texture statistics (used for discard logic?) // + LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); - LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); + S32 RenderName = gSavedSettings.getS32("RenderName"); + + if(RenderName > gHippoLimits->mRenderName)//The most restricted gets set here + RenderName = gHippoLimits->mRenderName; + + LLVOAvatar::sRenderName = RenderName; LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; @@ -835,6 +848,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) //} LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; + + //Check for RenderWater + if (!gSavedSettings.getBOOL("RenderWater") || !gHippoLimits->mRenderWater) + LLPipeline::sUnderWaterRender = FALSE; + LLPipeline::updateRenderDeferred(); stop_glerror(); diff --git a/linden/indra/newview/llviewerinventory.cpp b/linden/indra/newview/llviewerinventory.cpp index 33113f1..0e06353 100644 --- a/linden/indra/newview/llviewerinventory.cpp +++ b/linden/indra/newview/llviewerinventory.cpp @@ -268,7 +268,7 @@ void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const msg->addU32Fast(_PREHASH_Flags, mFlags); mSaleInfo.packMessage(msg); msg->addStringFast(_PREHASH_Name, mName); - msg->addStringFast(_PREHASH_Description, mDescription); + msg->addStringFast(_PREHASH_Description, mDescription); msg->addS32Fast(_PREHASH_CreationDate, mCreationDate); U32 crc = getCRC32(); msg->addU32Fast(_PREHASH_CRC, crc); diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index d3ca5f6..9e7b166 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -152,6 +152,7 @@ #include "hippoGridManager.h" #include "hippoLimits.h" +#include "wlsettingsmanager.h" #if LL_WINDOWS // For Windows specific error handler #include "llwindebug.h" // For the invalid message handler @@ -3116,8 +3117,17 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (!is_muted && !is_busy) { - static BOOL* sUseChatBubbles = rebind_llcontrol("UseChatBubbles", &gSavedSettings, true); - visible_in_chat_bubble = *sUseChatBubbles; + + BOOL sUseChatBubbles = gSavedSettings.getBOOL("UseChatBubbles"); + if(sUseChatBubbles) + { + BOOL localChat = gSavedSettings.getBOOL("UseLocalChatWithBubbles"); + if(localChat) + sUseChatBubbles = FALSE; //Act like they arn't enabled and show it anyway + } + //Update.. + visible_in_chat_bubble = sUseChatBubbles; + ((LLVOAvatar*)chatter)->addChat(chat); } } @@ -3569,6 +3579,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**) // Tell the LightShare handler that we have changed regions. WindlightMessage::resetRegion(); + WLSettingsManager::wlresetRegion(); } // stuff we have to do every time we get an AvatarInitComplete from a sim @@ -3835,6 +3846,7 @@ void process_crossed_region(LLMessageSystem* msg, void**) // Tell the LightShare handler that we have changed regions. WindlightMessage::resetRegion(); + WLSettingsManager::wlresetRegion(); } diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index 4fd3bfb..b63914c 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -452,6 +452,12 @@ void LLViewerRegion::setWaterHeight(F32 water_level) mLandp->setWaterHeight(water_level); } + +void LLViewerRegion::rebuildWater() +{ + mLandp->rebuildWater(); +} + F32 LLViewerRegion::getWaterHeight() const { return mLandp->getWaterHeight(); @@ -1416,7 +1422,9 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLSD capabilityNames = LLSD::emptyArray(); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("DispatchOpenRegionSettings"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("DispatchWindLightSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); capabilityNames.append("FetchInventory"); @@ -1434,6 +1442,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RequestTextureDownload"); + capabilityNames.append("RetrieveWindLightSettings"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); capabilityNames.append("SendPostcard"); diff --git a/linden/indra/newview/llviewerregion.h b/linden/indra/newview/llviewerregion.h index 09280a5..8cc80e3 100644 --- a/linden/indra/newview/llviewerregion.h +++ b/linden/indra/newview/llviewerregion.h @@ -132,6 +132,7 @@ public: void setWaterHeight(F32 water_level); F32 getWaterHeight() const; + void rebuildWater(); BOOL isVoiceEnabled() const; @@ -315,10 +316,11 @@ public: LLDynamicArray mMapAvatars; LLDynamicArray mMapAvatarIDs; -private: // The surfaces and other layers LLSurface* mLandp; +private: + // Region geometry data LLVector3d mOriginGlobal; // Location of southwest corner of region (meters) LLVector3d mCenterGlobal; // Location of center in world space (meters) diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 9937ed9..a20769e 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -94,7 +94,7 @@ #include "boost/lexical_cast.hpp" #endif #include "hippoLimits.h"// getMaxPrimScale - +#include "llstartup.h" // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] @@ -3666,7 +3666,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } // [/RLVa:KB] - BOOL need_comma = FALSE; static BOOL* sShowClientNameTag = rebind_llcontrol("ShowClientNameTag", &gSavedSettings, true); diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index 50ce53a..548818d 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -148,6 +148,7 @@ public: void clampAttachmentPositions(); S32 getAttachmentCount(); // Warning: order(N) not order(1) + // HUD functions BOOL hasHUDAttachment() const; LLBBox getHUDBBox() const; diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp index e01506e..0156622 100644 --- a/linden/indra/newview/llwaterparammanager.cpp +++ b/linden/indra/newview/llwaterparammanager.cpp @@ -75,6 +75,7 @@ #include "curl/curl.h" LLWaterParamManager * LLWaterParamManager::sInstance = NULL; +LLFrameTimer waterSmoothTransitionTimer; LLWaterParamManager::LLWaterParamManager() : mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"), @@ -454,9 +455,44 @@ void LLWaterParamManager::update(LLViewerCamera * cam) shaders_iter->mUniformsDirty = TRUE; } } + //Mix windlight settings if needed + if(sNeedsMix == TRUE) + { + if(sMixSet == NULL) + { + sNeedsMix = FALSE; + return; + } + if (waterSmoothTransitionTimer.getElapsedTimeF32() >= + (sMixTime / 100)) //100 steps inbetween + { + waterSmoothTransitionTimer.reset(); + mCurParams.mix(mCurParams, *sMixSet, sMixCount / 100);//.01 to 1.0 + } + sMixCount++; + if((sMixCount / 100) == 1) + { + //All done + sNeedsMix = FALSE; + std::string wlWaterPresetName = "(Region settings)"; + mCurParams.mName = wlWaterPresetName; + removeParamSet( wlWaterPresetName, true ); + addParamSet( wlWaterPresetName, mCurParams ); + savePreset( wlWaterPresetName ); + loadPreset( wlWaterPresetName, true ); + sMixSet = NULL; + } + } } } - +void LLWaterParamManager::SetMixTime(LLWaterParamSet *mixSet, F32 mixTime) +{ + waterSmoothTransitionTimer.reset(); + sNeedsMix = TRUE; + sMixSet = mixSet; + sMixTime = mixTime; + sMixCount = 1; +} // static void LLWaterParamManager::initClass(void) { diff --git a/linden/indra/newview/llwaterparammanager.h b/linden/indra/newview/llwaterparammanager.h index 588e436..96dd1aa 100644 --- a/linden/indra/newview/llwaterparammanager.h +++ b/linden/indra/newview/llwaterparammanager.h @@ -304,6 +304,8 @@ public: // singleton pattern implementation static LLWaterParamManager * instance(); + void SetMixTime(LLWaterParamSet* mixSet, F32 mixTime); + public: LLWaterParamSet mCurParams; @@ -334,6 +336,11 @@ private: LLVector4 mWaterPlane; F32 mWaterFogKS; + BOOL sNeedsMix; + LLWaterParamSet* sMixSet; + F32 sMixTime; + F32 sMixCount; + // our parameter manager singleton instance static LLWaterParamManager * sInstance; diff --git a/linden/indra/newview/llwaterparamset.cpp b/linden/indra/newview/llwaterparamset.cpp index a26cced..4b2e426 100644 --- a/linden/indra/newview/llwaterparamset.cpp +++ b/linden/indra/newview/llwaterparamset.cpp @@ -229,4 +229,96 @@ F32 LLWaterParamSet::getFloat(const std::string& paramName, bool& error) error = true; return 0; } +void LLWaterParamSet::mix(LLWaterParamSet& src, LLWaterParamSet& dest, F32 weight) +{ + // set up the iterators + LLSD::map_iterator cIt = mParamValues.beginMap(); + + LLSD srcVal; + LLSD destVal; + + // do the interpolation for all the ones saved as vectors + // skip the weird ones + for(; cIt != mParamValues.endMap(); cIt++) { + + // check params to make sure they're actually there + if(src.mParamValues.has(cIt->first)) + { + srcVal = src.mParamValues[cIt->first]; + } + else + { + continue; + } + + if(dest.mParamValues.has(cIt->first)) + { + destVal = dest.mParamValues[cIt->first]; + } + else + { + continue; + } + + // skip if not a vector + if(!cIt->second.isArray()) + { + continue; + } + + // only Real vectors allowed + if(!cIt->second[0].isReal()) + { + continue; + } + + // make sure all the same size + if( cIt->second.size() != srcVal.size() || + cIt->second.size() != destVal.size()) + { + continue; + } + + // more error checking might be necessary; + + for(int i=0; i < cIt->second.size(); ++i) + { + cIt->second[i] = (1.0f - weight) * (F32) srcVal[i].asReal() + + weight * (F32) destVal[i].asReal(); + } + } + mParamValues["waterFogColor"][0] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][0].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][0].asReal(); + mParamValues["waterFogColor"][1] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][1].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][1].asReal(); + mParamValues["waterFogColor"][2] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][2].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][2].asReal(); + mParamValues["waterFogColor"][3] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][3].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][3].asReal(); + + mParamValues["waterFogDensity"] = (1 - weight) * (F32) src.mParamValues["waterFogDensity"].asReal() + + weight * (F32) dest.mParamValues["waterFogDensity"].asReal(); + mParamValues["underWaterFogMod"] = (1 - weight) * (F32) src.mParamValues["underWaterFogMod"].asReal() + + weight * (F32) dest.mParamValues["underWaterFogMod"].asReal(); + mParamValues["fresnelScale"] = (1 - weight) * (F32) src.mParamValues["fresnelScale"].asReal() + + weight * (F32) dest.mParamValues["fresnelScale"].asReal(); + mParamValues["fresnelOffset"] = (1 - weight) * (F32) src.mParamValues["fresnelOffset"].asReal() + + weight * (F32) dest.mParamValues["fresnelOffset"].asReal(); + mParamValues["scaleAbove"] = (1 - weight) * (F32) src.mParamValues["scaleAbove"].asReal() + + weight * (F32) dest.mParamValues["scaleAbove"].asReal(); + mParamValues["scaleBelow"] = (1 - weight) * (F32) src.mParamValues["scaleBelow"].asReal() + + weight * (F32) dest.mParamValues["scaleBelow"].asReal(); + mParamValues["blurMultiplier"] = (1 - weight) * (F32) src.mParamValues["blurMultiplier"].asReal() + + weight * (F32) dest.mParamValues["blurMultiplier"].asReal(); + + mParamValues["wave2Dir"][0] = (1 - weight) * (F32) src.mParamValues["wave2Dir"][0].asReal() + + weight * (F32) dest.mParamValues["wave2Dir"][0].asReal(); + mParamValues["wave2Dir"][1] = (1 - weight) * (F32) src.mParamValues["wave2Dir"][1].asReal() + + weight * (F32) dest.mParamValues["wave2Dir"][1].asReal(); + + mParamValues["wave1Dir"][0] = (1 - weight) * (F32) src.mParamValues["wave1Dir"][0].asReal() + + weight * (F32) dest.mParamValues["wave1Dir"][0].asReal(); + mParamValues["wave1Dir"][1] = (1 - weight) * (F32) src.mParamValues["wave1Dir"][1].asReal() + + weight * (F32) dest.mParamValues["wave1Dir"][1].asReal(); +} diff --git a/linden/indra/newview/llwlparammanager.cpp b/linden/indra/newview/llwlparammanager.cpp index 31471d7..8007cce 100644 --- a/linden/indra/newview/llwlparammanager.cpp +++ b/linden/indra/newview/llwlparammanager.cpp @@ -71,11 +71,13 @@ #include "llviewerinventory.h" #include "llviewerregion.h" #include "llassetuploadresponders.h" +#include "llframetimer.h" #include "curl/curl.h" LLWLParamManager * LLWLParamManager::sInstance = NULL; std::vector LLWLParamManager::sObservers; +LLFrameTimer wlSmoothTransitionTimer; LLWLParamManager::LLWLParamManager() : @@ -562,6 +564,46 @@ void LLWLParamManager::update(LLViewerCamera * cam) } } } + + //Mix windlight settings if needed + if(sNeedsMix == TRUE) + { + if(sMixSet == NULL) + { + sNeedsMix = FALSE; + return; + } + if (wlSmoothTransitionTimer.getElapsedTimeF32() >= + (sMixTime / 100)) //100 steps inbetween + { + wlSmoothTransitionTimer.reset(); + mCurParams.mix(mCurParams, *sMixSet, sMixCount / 100);//.01 to 1.0 + } + sMixCount++; + if((sMixCount / 100) == 1) + { + //All done + sNeedsMix = FALSE; + std::string wlSkyPresetName = "(Region settings)"; + mCurParams.mName = wlSkyPresetName; + removeParamSet( wlSkyPresetName, true ); + addParamSet( wlSkyPresetName, mCurParams ); + savePreset( wlSkyPresetName ); + mAnimator.mIsRunning = false; + mAnimator.mUseLindenTime = false; + loadPreset( wlSkyPresetName, true ); + sMixSet = NULL; + } + } +} + +void LLWLParamManager::SetMixTime(LLWLParamSet *mixSet, F32 mixTime) +{ + wlSmoothTransitionTimer.reset(); + sNeedsMix = TRUE; + sMixSet = mixSet; + sMixTime = mixTime; + sMixCount = 1; } // static diff --git a/linden/indra/newview/llwlparammanager.h b/linden/indra/newview/llwlparammanager.h index 612a507..fc1127e 100644 --- a/linden/indra/newview/llwlparammanager.h +++ b/linden/indra/newview/llwlparammanager.h @@ -221,6 +221,8 @@ public: static void removeObserver(LLWLPresetsObserver* observer); static void notifyObservers(); + void SetMixTime(LLWLParamSet* mixSet, F32 mixTime); + public: // helper variables @@ -280,6 +282,11 @@ public: private: // our parameter manager singleton instance static LLWLParamManager * sInstance; + + BOOL sNeedsMix; + LLWLParamSet* sMixSet; + F32 sMixTime; + F32 sMixCount; static std::vector sObservers; diff --git a/linden/indra/newview/llwlparamset.cpp b/linden/indra/newview/llwlparamset.cpp index ea9c00a..19528eb 100644 --- a/linden/indra/newview/llwlparamset.cpp +++ b/linden/indra/newview/llwlparamset.cpp @@ -145,6 +145,11 @@ void LLWLParamSet::set(const std::string& paramName, float x) { mParamValues[paramName][0] = x; } + else + { + //Default this + mParamValues[paramName] = x; + } } void LLWLParamSet::set(const std::string& paramName, float x, float y) { diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index ca8ce2d..c484462 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp @@ -669,7 +669,8 @@ void LLWorld::updateClouds(const F32 dt) { static BOOL* sFreezeTime = rebind_llcontrol("FreezeTime", &gSavedSettings, true); if ((*sFreezeTime) || - !gSavedSettings.getBOOL("SkyUseClassicClouds")) + !gSavedSettings.getBOOL("SkyUseClassicClouds") || + !gHippoLimits->skyUseClassicClouds) { // don't move clouds in snapshot mode return; @@ -830,6 +831,14 @@ void LLWorld::setLandFarClip(const F32 far_clip) } } +void LLWorld::rebuildClouds(LLViewerRegion *regionp) +{ + regionp->mCloudLayer.destroy(); + regionp->mCloudLayer.create(regionp); + regionp->mCloudLayer.setWidth((F32)mWidth); + regionp->mCloudLayer.setWindPointer(®ionp->mWind); +} + // Some region that we're connected to, but not the one we're in, gave us // a (possibly) new water height. Update it in our local copy. void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height) diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index 2c5815c..964729d 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h @@ -150,6 +150,8 @@ public: void getInfo(LLSD& info); + void rebuildClouds(LLViewerRegion *regionp); + public: typedef std::list region_list_t; const region_list_t& getRegionList() const { return mActiveRegionList; } diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index cf766e0..2932865 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -101,6 +101,7 @@ #include "llwaterparammanager.h" #include "llspatialpartition.h" #include "llmutelist.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" @@ -5980,6 +5981,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) stop_glerror(); LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE; + + if (!gSavedSettings.getBOOL("RenderWater") || !gHippoLimits->mRenderWater) + LLPipeline::sUnderWaterRender = FALSE; if (LLPipeline::sUnderWaterRender) { diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml b/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml index 0e5a642..cd88c2e 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml @@ -58,7 +58,7 @@ font="SansSerif" mouse_opaque="true" name="Refresh" scale_image="TRUE" /> + min_val="5" max_val="512" increment="1" initial_val="20" decimal_digits="0" />