diff --git a/.hgtags b/.hgtags index b238c44b5e..4cc1302aac 100755 --- a/.hgtags +++ b/.hgtags @@ -587,3 +587,4 @@ ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release 21b7604680ef6b6ea67f8bebaaa588d6e263bdc1 6.0.1-release a3143db58a0f6b005232bf9018e7fef17ff9ec90 6.1.0-release 50f0ece62ddb5a244ecb6d00ef5a89d80ad50efa 6.1.1-release +82a89165e5929a6c3073d6cd60a543cb395f147b 6.2.0-release diff --git a/doc/contributions.txt b/doc/contributions.txt index 0c52d9e1ef..5b4a3db4da 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -223,6 +223,7 @@ Ansariel Hiller MAINT-8085 MAINT-8723 SL-10385 + SL-10891 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index a0c87b65cc..c13f39df9b 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -169,7 +169,7 @@ const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9; const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10; const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11; -const S32 ESTATE_MAX_MANAGERS = 10; +const S32 ESTATE_MAX_MANAGERS = 15; const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access, banned const S32 ESTATE_MAX_GROUP_IDS = (S32) ESTATE_ACCESS_MAX_ENTRIES_PER_PACKET; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 13065880ef..c45b0c6e41 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -520,6 +520,13 @@ void LLLineEditor::setCursorToEnd() deselect(); } +void LLLineEditor::resetScrollPosition() +{ + mScrollHPos = 0; + // make sure cursor says in visible range + setCursor(getCursor()); +} + BOOL LLLineEditor::canDeselect() const { return hasSelection(); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index c88f37484c..28c6bf88d9 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -219,6 +219,9 @@ public: void setCursor( S32 pos ); void setCursorToEnd(); + // set scroll to earliest position it can reasonable set + void resetScrollPosition(); + // Selects characters 'start' to 'end'. void setSelection(S32 start, S32 end); virtual void getSelectionRange(S32 *position, S32 *length) const; diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index c4b92e95c1..21b1ab4abc 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -327,6 +327,7 @@ void LLSpinCtrl::forceSetValue(const LLSD& value ) LLF32UICtrl::setValue(value); updateEditor(); + mEditor->resetScrollPosition(); } } @@ -392,7 +393,9 @@ void LLSpinCtrl::onEditorCommit( const LLSD& data ) if( success ) { - updateEditor(); + // We commited and clamped value + // try to display as much as possible + mEditor->resetScrollPosition(); } else { @@ -529,6 +532,7 @@ BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask) // text editors don't support revert normally (due to user confusion) // but not allowing revert on a spinner seems dangerous updateEditor(); + mEditor->resetScrollPosition(); mEditor->setFocus(FALSE); return TRUE; } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 75516842fe..d052056adb 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -264,13 +264,9 @@ void LLUI::dirtyRect(LLRect rect) void LLUI::setMousePositionScreen(S32 x, S32 y) { S32 screen_x, screen_y; -#if defined(LL_DARWIN) - screen_x = ll_round((F32)x); - screen_y = ll_round((F32)y); -#else screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); -#endif + LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert()); } diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index a18d3d4f98..fdb0a2cb16 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -353,6 +353,10 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) mouseDown:(NSEvent *)theEvent { + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; + // Apparently people still use this? if ([theEvent modifierFlags] & NSCommandKeyMask && !([theEvent modifierFlags] & NSControlKeyMask) && @@ -390,11 +394,17 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) rightMouseDown:(NSEvent *)theEvent { + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; callRightMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) rightMouseUp:(NSEvent *)theEvent { + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; callRightMouseUp(mMousePos, [theEvent modifierFlags]); } @@ -441,11 +451,17 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) otherMouseDown:(NSEvent *)theEvent { + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; callMiddleMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) otherMouseUp:(NSEvent *)theEvent { + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; callMiddleMouseUp(mMousePos, [theEvent modifierFlags]); } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index b8556fd749..58621b3a32 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -879,10 +879,11 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size) size->mX = sz.width; size->mY = sz.height; + err = noErr; } else { - LL_ERRS() << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << LL_ENDL; + LL_ERRS() << "LLWindowMacOSX::getSize(): no window and not fullscreen!" << LL_ENDL; } return (err == noErr); @@ -904,10 +905,13 @@ BOOL LLWindowMacOSX::getSize(LLCoordWindow *size) size->mX = sz.width; size->mY = sz.height; + err = noErr; + + } else { - LL_ERRS() << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << LL_ENDL; + LL_ERRS() << "LLWindowMacOSX::getSize(): no window and not fullscreen!" << LL_ENDL; } return (err == noErr); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 8410c2f2a5..1549cbc150 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4096,9 +4096,7 @@ void LLWindowWin32::setDPIAwareness() F32 LLWindowWin32::getSystemUISize() { - // Type fix - //float scale_value = 0; - F32 scale_value = 0.f; + F32 scale_value = 1.f; HWND hWnd = (HWND)getPlatformWindow(); HDC hdc = GetDC(hWnd); HMONITOR hMonitor; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3c90f74e8a..ca7befee1e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -159,7 +159,6 @@ set(viewer_SOURCE_FILES fsfloateraddtocontactset.cpp fsfloaterassetblacklist.cpp fsfloateravatarrendersettings.cpp - fsfloaterbantime.cpp fsfloaterblocklist.cpp fsfloatercontacts.cpp fsfloatercontactsetconfiguration.cpp @@ -330,6 +329,7 @@ set(viewer_SOURCE_FILES llfloateravatarpicker.cpp llfloateravatarrendersettings.cpp llfloateravatartextures.cpp + llfloaterbanduration.cpp llfloaterbeacons.cpp llfloaterbigpreview.cpp llfloaterbuildoptions.cpp @@ -913,7 +913,6 @@ set(viewer_HEADER_FILES fsfloateraddtocontactset.h fsfloaterassetblacklist.h fsfloateravatarrendersettings.h - fsfloaterbantime.h fsfloaterblocklist.h fsfloatercontacts.h fsfloatercontactsetconfiguration.h @@ -1087,6 +1086,7 @@ set(viewer_HEADER_FILES llfloateravatarpicker.h llfloateravatarrendersettings.h llfloateravatartextures.h + llfloaterbanduration.h llfloaterbeacons.h llfloaterbigpreview.h llfloaterbuildoptions.h diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 6abaeb2f90..024b066c0b 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.2.0 +6.2.1 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f447742221..96398df52f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -21500,6 +21500,19 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + ResetUIScaleOnFirstRun + + Comment + Resets the UI scale factor on first run due to changed display scaling behavior + Persist + 1 + Type + Boolean + Value + 1 + Backup + 0 + FSShowServerVersionChangeNotice Comment @@ -25159,7 +25172,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type Boolean Value - 0 + 0 FSLookAtTargetMaxDistance diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index f842c51971..6b68f8e158 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -815,6 +815,11 @@ bool cmd_line_chat(const std::string& revised_text, EChatType type, bool from_ge gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ") - 0.05f); return false; } + else if (command == "/zoffset_reset") + { + gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", 0.f); + return false; + } else if (command == sFSCmdLineOfferTp()) { LLUUID target_key; diff --git a/indra/newview/fsfloaterbantime.cpp b/indra/newview/fsfloaterbantime.cpp deleted file mode 100644 index 3927f63ec4..0000000000 --- a/indra/newview/fsfloaterbantime.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** -* @file fsfloaterbantime.cpp -* @brief Floater for ban time dialog -* -* $LicenseInfo:firstyear=2012&license=fsviewerlgpl$ -* Phoenix Firestorm Viewer Source Code -* Copyright (C) 2018, Liny Odell -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA -* http://www.firestormviewer.org -* $/LicenseInfo$ -*/ - -#include "llviewerprecompiledheaders.h" -#include "fsfloaterbantime.h" - -#include "llfloaterreg.h" -#include "llspinctrl.h" - -FSFloaterBanTime::FSFloaterBanTime(const LLSD& target) -: LLFloater(target) -{ -} - -BOOL FSFloaterBanTime::postBuild() -{ - childSetAction("BanConfirmButton", boost::bind(&FSFloaterBanTime::onClickBan, this)); - childSetAction("BanCancelButton", boost::bind(&FSFloaterBanTime::onClickCancel, this)); - - return TRUE; -} - -FSFloaterBanTime* FSFloaterBanTime::show(select_callback_t callback, const LLUUID& id) -{ - FSFloaterBanTime* floater = LLFloaterReg::showTypedInstance("fs_ban_time"); - if (!floater) - { - LL_WARNS() << "Cannot instantiate ban time floater" << LL_ENDL; - return NULL; - } - - floater->mSelectionCallback = callback; - floater->mAvatar_id = id; - - return floater; -} - -void FSFloaterBanTime::onClickCancel() -{ - closeFloater(); -} - -void FSFloaterBanTime::onClickBan() -{ - if (mSelectionCallback) - { - LLSpinCtrl* timectrl = findChild("ban_time"); - if (timectrl) - { - S32 time = timectrl->getValue().asInteger(); - if (time != 0) - { - LLDate now = LLDate::now(); - time = now.secondsSinceEpoch() + (time * 3600); - } - mSelectionCallback(mAvatar_id, time); - timectrl->set(0.f); - } - } - closeFloater(); -} diff --git a/indra/newview/fsfloaterbantime.h b/indra/newview/fsfloaterbantime.h deleted file mode 100644 index 1247cdf301..0000000000 --- a/indra/newview/fsfloaterbantime.h +++ /dev/null @@ -1,49 +0,0 @@ -/** -* @file fsfloaterbantime.cpp -* @brief Floater for ban time dialog -* -* $LicenseInfo:firstyear=2012&license=fsviewerlgpl$ -* Phoenix Firestorm Viewer Source Code -* Copyright (C) 2018, Liny Odell -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA -* http://www.firestormviewer.org -* $/LicenseInfo$ -*/ - -#ifndef FS_FLOATERBANTIME_H -#define FS_FLOATERBANTIME_H - -#include "llfloater.h" - -class FSFloaterBanTime : public LLFloater -{ -public: - FSFloaterBanTime(const LLSD& target); - BOOL postBuild(); - typedef boost::function select_callback_t; - static FSFloaterBanTime* show(select_callback_t callback, const LLUUID& id); - -private: - ~FSFloaterBanTime(){}; - void onClickBan(); - void onClickCancel(); - LLUUID mAvatar_id; - select_callback_t mSelectionCallback; -}; - -#endif // FS_FLOATERBANTIME_H diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 797c5a902e..126b269a67 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -2298,8 +2298,8 @@ bool LLAvatarActions::callbackEstateBan(const LLSD& notification, const LLSD& re } } - LLEstateInfoModel::instance().nextInvoice(); - LLPanelEstateInfo::sendEstateAccessDelta(flags, itAgent->asUUID()); + LLFloaterRegionInfo::nextInvoice(); + LLPanelEstateAccess::sendEstateAccessDelta(flags, itAgent->asUUID()); } } return false; diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp index e8da458168..4fdb860592 100644 --- a/indra/newview/llestateinfomodel.cpp +++ b/indra/newview/llestateinfomodel.cpp @@ -34,101 +34,15 @@ // viewer #include "llagent.h" +#include "llfloaterregioninfo.h" // for invoice id #include "llviewerregion.h" + #include "llcorehttputil.h" -//========================================================================= -namespace -{ - 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) - { - // 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) - - LL_DEBUGS("ESTATEINFOM") << "Received estate update" << LL_ENDL; - - // Update estate info model. - // This will call LLPanelEstateInfo::refreshFromEstate(). - // *TODO: Move estate message handling stuff to llestateinfomodel.cpp. - LLEstateInfoModel::instance().updateEstateInfo(strings); - - return true; - } - }; - - 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) - { - // 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) - // ... - - LLEstateInfoModel::instance().updateAccessInfo(strings); - - return true; - } - - }; - - class LLDispatchSetEstateExperience : public LLDispatchHandler - { - public: - virtual bool operator()(const LLDispatcher* dispatcher, const std::string& key, - const LLUUID& invoice, const sparam_t& strings) - { - // key = "setexperience" - // strings[0] = str(estate_id) - // strings[1] = str(send_to_agent_only) - // strings[2] = str(num blocked) - // strings[3] = str(num trusted) - // strings[4] = str(num allowed) - // strings[8] = bin(uuid) ... - // ... - - LLEstateInfoModel::instance().updateExperienceInfo(strings); - - return true; - } - - }; - -} - -//========================================================================= -LLEstateInfoModel::LLEstateInfoModel(): - mID(0), - mFlags(0), - mSunHour(0), - mRegion(nullptr) +LLEstateInfoModel::LLEstateInfoModel() +: mID(0) +, mFlags(0) +, mSunHour(0) { } @@ -137,52 +51,40 @@ boost::signals2::connection LLEstateInfoModel::setUpdateCallback(const update_si return mUpdateSignal.connect(cb); } -boost::signals2::connection LLEstateInfoModel::setUpdateAccessCallback(const update_flaged_signal_t::slot_type& cb) -{ - return mUpdateAccess.connect(cb); -} - -boost::signals2::connection LLEstateInfoModel::setUpdateExperienceCallback(const update_signal_t::slot_type& cb) -{ - return mUpdateExperience.connect(cb); -} - boost::signals2::connection LLEstateInfoModel::setCommitCallback(const update_signal_t::slot_type& cb) { return mCommitSignal.connect(cb); } -void LLEstateInfoModel::setRegion(LLViewerRegion* region) -{ - if (region != mRegion) - { - mRegion = region; - - if (mRegion) - { - nextInvoice(); - sendEstateOwnerMessage("getinfo", strings_t()); - } - } -} - - -void LLEstateInfoModel::clearRegion() -{ - mRegion = nullptr; -} - void LLEstateInfoModel::sendEstateInfo() { if (!commitEstateInfoCaps()) { // the caps method failed, try the old way - nextInvoice(); + LLFloaterRegionInfo::nextInvoice(); commitEstateInfoDataserver(); } } -void LLEstateInfoModel::updateEstateInfo(const strings_t& strings) +bool LLEstateInfoModel::getUseFixedSun() const { return getFlag(REGION_FLAGS_SUN_FIXED); } +bool LLEstateInfoModel::getIsExternallyVisible() const { return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE); } +bool LLEstateInfoModel::getAllowDirectTeleport() const { return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT); } +bool LLEstateInfoModel::getDenyAnonymous() const { return getFlag(REGION_FLAGS_DENY_ANONYMOUS); } +bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); } +bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); } +bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); } +bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); } + +void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); } +void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); } +void LLEstateInfoModel::setAllowDirectTeleport(bool val) { setFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, val); } +void LLEstateInfoModel::setDenyAnonymous(bool val) { setFlag(REGION_FLAGS_DENY_ANONYMOUS, val); } +void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED, val); } +void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); } +void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); } +void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); } + +void LLEstateInfoModel::update(const strings_t& strings) { // NOTE: LLDispatcher extracts strings with an extra \0 at the // end. If we pass the std::string direct to the UI/renderer @@ -193,10 +95,10 @@ void LLEstateInfoModel::updateEstateInfo(const strings_t& strings) mFlags = strtoul(strings[3].c_str(), NULL, 10); mSunHour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f; - LL_DEBUGS("ESTATEINFOM") << "Received estate info: " + LL_DEBUGS("WindlightSync") << "Received estate info: " << "is_sun_fixed = " << getUseFixedSun() << ", sun_hour = " << getSunHour() << LL_ENDL; - LL_DEBUGS("ESTATEINFOM") << getInfoDump() << LL_ENDL; + LL_DEBUGS() << getInfoDump() << LL_ENDL; // Update region owner. LLViewerRegion* regionp = gAgent.getRegion(); @@ -206,205 +108,20 @@ void LLEstateInfoModel::updateEstateInfo(const strings_t& strings) mUpdateSignal(); } -void LLEstateInfoModel::updateAccessInfo(const strings_t& strings) -{ - 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)) - { - LL_WARNS("ESTATEINFOM") << "non-zero count for allowed agents, but no corresponding flag" << LL_ENDL; - } - if (num_allowed_groups > 0 - && !(access_flags & ESTATE_ACCESS_ALLOWED_GROUPS)) - { - LL_WARNS("ESTATEINFOM") << "non-zero count for allowed groups, but no corresponding flag" << LL_ENDL; - } - if (num_banned_agents > 0 - && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) - { - LL_WARNS("ESTATEINFOM") << "non-zero count for banned agents, but no corresponding flag" << LL_ENDL; - } - if (num_estate_managers > 0 - && !(access_flags & ESTATE_ACCESS_MANAGERS)) - { - LL_WARNS("ESTATEINFOM") << "non-zero count for managers, but no corresponding flag" << LL_ENDL; - } - - // grab the UUID's out of the string fields - if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) - { - mAllowedAgents.clear(); - - 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 */ - mAllowedAgents.insert(id); - } - } - - if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) - { - mAllowedGroups.clear(); - - 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 */ - mAllowedGroups.insert(id); - } - } - - if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) - { - mBannedAgents.clear(); - - 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 */ - mBannedAgents.insert(id); - } - } - - if (access_flags & ESTATE_ACCESS_MANAGERS) - { - mEstateManagers.clear(); - - // 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 */ - mEstateManagers.insert(id); - } - } - - // Update the buttons which may change based on the list contents but also needs to account for general access features. - mUpdateAccess(access_flags); -} - -void LLEstateInfoModel::updateExperienceInfo(const strings_t& strings) -{ - strings_t::const_iterator it = strings.begin(); - ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10); - ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10); - - LLUUID id; - S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10); - S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10); - S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10); - - mExperienceAllowed.clear(); - mExperienceTrusted.clear(); - mExperienceBlocked.clear(); - - while (num_blocked-- > 0) - { - memcpy(id.mData, (*(it++)).data(), UUID_BYTES); - mExperienceBlocked.insert(id); - } - - while (num_trusted-- > 0) - { - memcpy(id.mData, (*(it++)).data(), UUID_BYTES); - mExperienceTrusted.insert(id); - } - - while (num_allowed-- > 0) - { - memcpy(id.mData, (*(it++)).data(), UUID_BYTES); - mExperienceAllowed.insert(id); - } - - mUpdateExperience(); -} - void LLEstateInfoModel::notifyCommit() { mCommitSignal(); } -void LLEstateInfoModel::initSingleton() -{ - gMessageSystem->setHandlerFunc("EstateOwnerMessage", &processEstateOwnerRequest); - - // name.assign("setowner"); - // static LLDispatchSetEstateOwner set_owner; - // dispatch.addHandler(name, &set_owner); - - static LLDispatchEstateUpdateInfo estate_update_info; - mDispatch.addHandler("estateupdateinfo", &estate_update_info); - - static LLDispatchSetEstateAccess set_access; - mDispatch.addHandler("setaccess", &set_access); - - static LLDispatchSetEstateExperience set_experience; - mDispatch.addHandler("setexperience", &set_experience); - -} - -void LLEstateInfoModel::sendEstateOwnerMessage(const std::string& request, const strings_t& strings) -{ - if (!mRegion) - { - LL_WARNS("ESTATEINFOM") << "No selected region." << LL_ENDL; - return; - } - LLMessageSystem* msg(gMessageSystem); - LLUUID invoice(LLEstateInfoModel::instance().getLastInvoice()); - - LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL; - 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(mRegion->getHost()); -} - //== PRIVATE STUFF ============================================================ // tries to send estate info using a cap; returns true if it succeeded bool LLEstateInfoModel::commitEstateInfoCaps() { - if (!mRegion) - { - LL_WARNS("ESTATEINFOM") << "Attempt to update estate caps with no anchor region! Don't do that!" << LL_ENDL; - return false; - } - std::string url = mRegion->getCapability("EstateChangeInfo"); + std::string url = gAgent.getRegionCapability("EstateChangeInfo"); if (url.empty()) { - LL_WARNS("ESTATEINFOM") << "No EstateChangeInfo cap from region." << LL_ENDL; // whoops, couldn't find the cap, so bail out return false; } @@ -433,14 +150,13 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) body["deny_age_unverified"] = getDenyAgeUnverified(); body["allow_voice_chat"] = getAllowVoiceChat(); body["override_public_access"] = getAllowAccessOverride(); - body["override_environment"] = getAllowEnvironmentOverride(); - body["invoice"] = getLastInvoice(); + body["invoice"] = LLFloaterRegionInfo::getLastInvoice(); - LL_DEBUGS("ESTATEINFOM") << "Sending estate caps: " + LL_DEBUGS("WindlightSync") << "Sending estate caps: " << "is_sun_fixed = " << getUseFixedSun() << ", sun_hour = " << getSunHour() << LL_ENDL; - LL_DEBUGS("ESTATEINFOM") << body << LL_ENDL; + LL_DEBUGS() << body << LL_ENDL; LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body); @@ -449,12 +165,12 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) if (status) { - LL_INFOS("ESTATEINFOM") << "Committed estate info" << LL_ENDL; + LL_INFOS() << "Committed estate info" << LL_ENDL; LLEstateInfoModel::instance().notifyCommit(); } else { - LL_WARNS("ESTATEINFOM") << "Failed to commit estate info " << LL_ENDL; + LL_WARNS() << "Failed to commit estate info " << LL_ENDL; } } @@ -467,15 +183,10 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) // strings[3] = str((S32)(sun_hour * 1024.f)) void LLEstateInfoModel::commitEstateInfoDataserver() { - if (!mRegion) - { - LL_WARNS("ESTATEINFOM") << "No selected region." << LL_ENDL; - return; - } - LL_DEBUGS("ESTATEINFOM") << "Sending estate info: " + LL_DEBUGS("WindlightSync") << "Sending estate info: " << "is_sun_fixed = " << getUseFixedSun() << ", sun_hour = " << getSunHour() << LL_ENDL; - LL_DEBUGS("ESTATEINFOM") << getInfoDump() << LL_ENDL; + LL_DEBUGS() << getInfoDump() << LL_ENDL; LLMessageSystem* msg = gMessageSystem; msg->newMessage("EstateOwnerMessage"); @@ -486,7 +197,7 @@ void LLEstateInfoModel::commitEstateInfoDataserver() msg->nextBlock("MethodData"); msg->addString("Method", "estatechangeinfo"); - msg->addUUID("Invoice", getLastInvoice()); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); msg->nextBlock("ParamList"); msg->addString("Parameter", getName()); @@ -497,7 +208,7 @@ void LLEstateInfoModel::commitEstateInfoDataserver() msg->nextBlock("ParamList"); msg->addString("Parameter", llformat("%d", (S32) (getSunHour() * 1024.0f))); - msg->sendReliable(mRegion->getHost()); + gAgent.sendMessage(); } std::string LLEstateInfoModel::getInfoDump() @@ -513,28 +224,9 @@ std::string LLEstateInfoModel::getInfoDump() dump["deny_age_unverified" ] = getDenyAgeUnverified(); dump["allow_voice_chat" ] = getAllowVoiceChat(); dump["override_public_access"] = getAllowAccessOverride(); - dump["override_environment"] = getAllowEnvironmentOverride(); + dump["override_environment"] = getAllowEnvironmentOverride(); std::stringstream dump_str; dump_str << dump; return dump_str.str(); } - -// static -void LLEstateInfoModel::processEstateOwnerRequest(LLMessageSystem* msg, void**) -{ - // unpack the message - std::string request; - LLUUID invoice; - LLDispatcher::sparam_t strings; - LLDispatcher::unpackMessage(msg, request, invoice, strings); - if (invoice != LLEstateInfoModel::instance().getLastInvoice()) - { - LL_WARNS("ESTATEINFOM") << "Mismatched Estate message: " << request << LL_ENDL; - return; - } - - //dispatch the message - LLEstateInfoModel::instance().mDispatch.dispatch(request, invoice, strings); -} - diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h index 2c89a85500..d6f00c573c 100644 --- a/indra/newview/llestateinfomodel.h +++ b/indra/newview/llestateinfomodel.h @@ -32,123 +32,78 @@ class LLMessageSystem; #include "llsingleton.h" #include "llcoros.h" #include "lleventcoro.h" -#include "lldispatcher.h" -#include "llregionflags.h" -class LLViewerRegion; /** * Contains estate info, notifies interested parties of its changes. */ class LLEstateInfoModel : public LLSingleton { - LLSINGLETON_C11(LLEstateInfoModel); + LLSINGLETON(LLEstateInfoModel); LOG_CLASS(LLEstateInfoModel); public: - typedef std::vector strings_t; - typedef boost::signals2::signal update_signal_t; - typedef boost::signals2::signal update_flaged_signal_t; - typedef boost::signals2::connection connection_t; + typedef boost::signals2::signal update_signal_t; + boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type& cb); /// the model has been externally updated + boost::signals2::connection setCommitCallback(const update_signal_t::slot_type& cb); /// our changes have been applied - connection_t setUpdateCallback(const update_signal_t::slot_type& cb); /// the model has been externally updated - connection_t setUpdateAccessCallback(const update_flaged_signal_t::slot_type& cb); - connection_t setUpdateExperienceCallback(const update_signal_t::slot_type& cb); - connection_t setCommitCallback(const update_signal_t::slot_type& cb); /// our changes have been applied - - void setRegion(LLViewerRegion* region); - void clearRegion(); - void sendEstateInfo(); /// send estate info to the simulator + void sendEstateInfo(); /// send estate info to the simulator // getters - bool getUseFixedSun() const { return getFlag(REGION_FLAGS_SUN_FIXED); } - bool getIsExternallyVisible() const { return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE); } - bool getAllowDirectTeleport() const { return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT); } - bool getDenyAnonymous() const { return getFlag(REGION_FLAGS_DENY_ANONYMOUS); } - bool getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); } - bool getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); } - bool getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); } - bool getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); } + bool getUseFixedSun() const; + bool getIsExternallyVisible() const; + bool getAllowDirectTeleport() const; + bool getDenyAnonymous() const; + bool getDenyAgeUnverified() const; + bool getAllowVoiceChat() const; + bool getAllowAccessOverride() const; + bool getAllowEnvironmentOverride() const; - const std::string& getName() const { return mName; } - const LLUUID& getOwnerID() const { return mOwnerID; } - U32 getID() const { return mID; } - F32 getSunHour() const { return getUseFixedSun() ? mSunHour : 0.f; } + const std::string& getName() const { return mName; } + const LLUUID& getOwnerID() const { return mOwnerID; } + U32 getID() const { return mID; } + F32 getSunHour() const { return getUseFixedSun() ? mSunHour : 0.f; } // setters - void setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); } - void setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); } - void setAllowDirectTeleport(bool val) { setFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, val); } - void setDenyAnonymous(bool val) { setFlag(REGION_FLAGS_DENY_ANONYMOUS, val); } - void setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED, val); } - void setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); } - void setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); } - void setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); } + void setUseFixedSun(bool val); + void setIsExternallyVisible(bool val); + void setAllowDirectTeleport(bool val); + void setDenyAnonymous(bool val); + void setDenyAgeUnverified(bool val); + void setAllowVoiceChat(bool val); + void setAllowAccessOverride(bool val); + void setAllowEnvironmentOverride(bool val); - void setSunHour(F32 sun_hour) { mSunHour = sun_hour; } - - const uuid_set_t & getAllowedAgents() const { return mAllowedAgents; } - const uuid_set_t & getAllowedGroups() const { return mAllowedGroups; } - const uuid_set_t & getBannedAgents() const { return mBannedAgents; } - const uuid_set_t & getEstateManagers() const { return mEstateManagers; } - - const uuid_set_t & getAllowedExperiences() const { return mExperienceAllowed; } - const uuid_set_t & getTrustedExperiences() const { return mExperienceTrusted; } - const uuid_set_t & getBlockedExperiences() const { return mExperienceBlocked; } - - void sendEstateOwnerMessage(const std::string& request, const strings_t& strings); - - //--------------------------------------------------------------------- - /// refresh model with data from the incoming server message - void updateEstateInfo(const strings_t& strings); - void updateAccessInfo(const strings_t& strings); - void updateExperienceInfo(const strings_t& strings); - - const LLUUID & getLastInvoice() { return mRequestInvoice; } - const LLUUID & nextInvoice() { mRequestInvoice.generate(); return mRequestInvoice; } + void setSunHour(F32 sun_hour) { mSunHour = sun_hour; } protected: + typedef std::vector strings_t; - void notifyCommit(); + friend class LLDispatchEstateUpdateInfo; - virtual void initSingleton() override; + /// refresh model with data from the incoming server message + void update(const strings_t& strings); + + void notifyCommit(); private: - bool commitEstateInfoCaps(); - void commitEstateInfoDataserver(); - inline bool getFlag(U64 flag) const; - inline void setFlag(U64 flag, bool val); - U64 getFlags() const { return mFlags; } - std::string getInfoDump(); + bool commitEstateInfoCaps(); + void commitEstateInfoDataserver(); + inline bool getFlag(U64 flag) const; + inline void setFlag(U64 flag, bool val); + U64 getFlags() const { return mFlags; } + std::string getInfoDump(); // estate info - std::string mName; /// estate name - LLUUID mOwnerID; /// estate owner id - U32 mID; /// estate id - U64 mFlags; /// estate flags - F32 mSunHour; /// estate sun hour + std::string mName; /// estate name + LLUUID mOwnerID; /// estate owner id + U32 mID; /// estate id + U64 mFlags; /// estate flags + F32 mSunHour; /// estate sun hour - uuid_set_t mAllowedAgents; - uuid_set_t mAllowedGroups; - uuid_set_t mBannedAgents; - uuid_set_t mEstateManagers; - - uuid_set_t mExperienceAllowed; - uuid_set_t mExperienceTrusted; - uuid_set_t mExperienceBlocked; - - update_signal_t mUpdateSignal; /// emitted when we receive update from sim - update_flaged_signal_t mUpdateAccess; - update_signal_t mUpdateExperience; - update_signal_t mCommitSignal; /// emitted when our update gets applied to sim - - LLDispatcher mDispatch; - LLUUID mRequestInvoice; - LLViewerRegion* mRegion; - - void commitEstateInfoCapsCoro(std::string url); - - static void processEstateOwnerRequest(LLMessageSystem* msg, void**); + update_signal_t mUpdateSignal; /// emitted when we receive update from sim + update_signal_t mCommitSignal; /// emitted when our update gets applied to sim + void commitEstateInfoCapsCoro(std::string url); }; inline bool LLEstateInfoModel::getFlag(U64 flag) const diff --git a/indra/newview/llfloaterbanduration.cpp b/indra/newview/llfloaterbanduration.cpp new file mode 100644 index 0000000000..6ba6c30cab --- /dev/null +++ b/indra/newview/llfloaterbanduration.cpp @@ -0,0 +1,92 @@ +/** +* @file llfloaterbanduration.cpp +* +* $LicenseInfo:firstyear=2004&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterbanduration.h" + +#include "llfloaterreg.h" +#include "llspinctrl.h" +#include "llradiogroup.h" + +LLFloaterBanDuration::LLFloaterBanDuration(const LLSD& target) + : LLFloater(target) +{ +} + +BOOL LLFloaterBanDuration::postBuild() +{ + childSetAction("ok_btn", boost::bind(&LLFloaterBanDuration::onClickBan, this)); + childSetAction("cancel_btn", boost::bind(&LLFloaterBanDuration::onClickCancel, this)); + + getChild("ban_duration_radio")->setCommitCallback(boost::bind(&LLFloaterBanDuration::onClickRadio, this)); + getChild("ban_duration_radio")->setSelectedIndex(0); + getChild("ban_hours")->setEnabled(FALSE); + + return TRUE; +} + +LLFloaterBanDuration* LLFloaterBanDuration::show(select_callback_t callback, uuid_vec_t ids) +{ + LLFloaterBanDuration* floater = LLFloaterReg::showTypedInstance("ban_duration"); + if (!floater) + { + LL_WARNS() << "Cannot instantiate ban duration floater" << LL_ENDL; + return NULL; + } + + floater->mSelectionCallback = callback; + floater->mAvatar_ids = ids; + + return floater; +} + +void LLFloaterBanDuration::onClickRadio() +{ + getChild("ban_hours")->setEnabled(getChild("ban_duration_radio")->getSelectedIndex() != 0); +} + +void LLFloaterBanDuration::onClickCancel() +{ + closeFloater(); +} + +void LLFloaterBanDuration::onClickBan() +{ + if (mSelectionCallback) + { + S32 time = 0; + if (getChild("ban_duration_radio")->getSelectedIndex() != 0) + { + LLSpinCtrl* hours_spin = getChild("ban_hours"); + if (hours_spin) + { + time = LLDate::now().secondsSinceEpoch() + (hours_spin->getValue().asInteger() * 3600); + } + } + mSelectionCallback(mAvatar_ids, time); + } + closeFloater(); +} + diff --git a/indra/newview/llfloaterbanduration.h b/indra/newview/llfloaterbanduration.h new file mode 100644 index 0000000000..e8ec7cc669 --- /dev/null +++ b/indra/newview/llfloaterbanduration.h @@ -0,0 +1,52 @@ +/** +* @file llfloaterbanduration.h +* +* $LicenseInfo:firstyear=2004&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + + +#ifndef LL_FLOATERBANDURATION_H +#define LL_FLOATERBANDURATION_H + +#include "llfloater.h" + +class LLFloaterBanDuration : public LLFloater +{ + typedef boost::function select_callback_t; + +public: + LLFloaterBanDuration(const LLSD& target); + BOOL postBuild(); + static LLFloaterBanDuration* show(select_callback_t callback, uuid_vec_t id); + +private: + ~LLFloaterBanDuration() {}; + void onClickBan(); + void onClickCancel(); + void onClickRadio(); + + uuid_vec_t mAvatar_ids; + select_callback_t mSelectionCallback; +}; + +#endif // LL_FLOATERBANDURATION_H + diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 75c931df07..41653423a7 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -46,6 +46,7 @@ #include "llfloaterreg.h" #include "llfloateravatarpicker.h" #include "llfloaterauction.h" +#include "llfloaterbanduration.h" #include "llfloatergroups.h" #include "llfloaterscriptlimits.h" #include "llavataractions.h" @@ -89,7 +90,6 @@ #include "llworld.h" // For FIRE-1292 #include "llsdutil.h" #include "llviewernetwork.h" -#include "fsfloaterbantime.h" #include "fsnamelistavatarmenu.h" #include "llfloaterauction.h" @@ -2759,33 +2759,49 @@ void LLPanelLandAccess::refresh() cit != parcel->mBanList.end(); ++cit) { const LLAccessEntry& entry = (*cit).second; - std::string prefix; + std::string duration; if (entry.mTime != 0) { LLStringUtil::format_map_t args; S32 now = time(NULL); - S32 seconds = entry.mTime - now; + S32 seconds = entry.mTime - now; if (seconds < 0) seconds = 0; - prefix.assign(" ("); - if (seconds >= 120) + + if (seconds >= 7200) { - args["[MINUTES]"] = llformat("%d", (seconds/60)); - std::string buf = parent_floater->getString ("Minutes", args); - prefix.append(buf); + args["[HOURS]"] = llformat("%d", (seconds / 3600)); + duration = parent_floater->getString("Hours", args); + } + else if (seconds >= 3600) + { + duration = "1 " + parent_floater->getString("Hour"); + } + else if (seconds >= 120) + { + args["[MINUTES]"] = llformat("%d", (seconds / 60)); + duration = parent_floater->getString("Minutes", args); } else if (seconds >= 60) { - prefix.append("1 " + parent_floater->getString("Minute")); + duration = "1 " + parent_floater->getString("Minute"); } else { args["[SECONDS]"] = llformat("%d", seconds); - std::string buf = parent_floater->getString ("Seconds", args); - prefix.append(buf); + duration = parent_floater->getString("Seconds", args); } - prefix.append(" " + parent_floater->getString("Remaining") + ") "); } - mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, "", prefix); + else + { + duration = parent_floater->getString("Always"); + } + LLSD item; + item["id"] = entry.mID; + LLSD& columns = item["columns"]; + columns[0]["column"] = "name"; // to be populated later + columns[1]["column"] = "duration"; + columns[1]["value"] = duration; + mListBanned->addElement(item); } mListBanned->sortByName(TRUE); } @@ -3158,7 +3174,7 @@ void LLPanelLandAccess::onClickAddBanned() LLView * button = findChild("add_banned"); LLFloater * root_floater = gFloaterView->getParentFloater(this); LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( - boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button); + boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), TRUE, FALSE, FALSE, root_floater->getName(), button); if (picker) { root_floater->addDependentFloater(picker); @@ -3168,52 +3184,42 @@ void LLPanelLandAccess::onClickAddBanned() // static void LLPanelLandAccess::callbackAvatarCBBanned(const uuid_vec_t& ids) { - if (!ids.empty()) + LLFloater * root_floater = gFloaterView->getParentFloater(this); + LLFloaterBanDuration* duration_floater = LLFloaterBanDuration::show( + boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned2, this, _1, _2), ids); + if (duration_floater) { - LLUUID id = ids[0]; - /* Add ability to do time based temp bans - LLParcel* parcel = mParcel->getParcel(); - if (parcel && parcel->addToBanList(id, 0)) + root_floater->addDependentFloater(duration_floater); + } +} + +void LLPanelLandAccess::callbackAvatarCBBanned2(const uuid_vec_t& ids, S32 duration) +{ + LLParcel* parcel = mParcel->getParcel(); + if (!parcel) return; + + U32 lists_to_update = 0; + + for (uuid_vec_t::const_iterator it = ids.begin(); it < ids.end(); it++) + { + LLUUID id = *it; + if (parcel->addToBanList(id, duration)) { - U32 lists_to_update = AL_BAN; + lists_to_update |= AL_BAN; // agent was successfully added to ban list // but we also need to check access list to ensure that agent will not be in two lists simultaneously if (parcel->removeFromAccessList(id)) { lists_to_update |= AL_ACCESS; } - LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(lists_to_update); - refresh(); } - */ - LLFloater * root_floater = gFloaterView->getParentFloater(this); - FSFloaterBanTime* timer = FSFloaterBanTime::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBannedTimed, this, _1, _2), id); - if (timer) - { - root_floater->addDependentFloater(timer); - } - // } -} -// Add ability to do time based temp bans -// static -void LLPanelLandAccess::callbackAvatarCBBannedTimed(const LLUUID& id, S32 time) -{ - LLParcel* parcel = mParcel->getParcel(); - if (parcel && parcel->addToBanList(id, time)) + if (lists_to_update > 0) { - U32 lists_to_update = AL_BAN; - // agent was successfully added to ban list - // but we also need to check access list to ensure that agent will not be in two lists simultaneously - if (parcel->removeFromAccessList(id)) - { - lists_to_update |= AL_ACCESS; - } LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(lists_to_update); refresh(); } } -// // static void LLPanelLandAccess::onClickRemoveBanned(void* data) diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 6fb294e18e..363468bbad 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -399,7 +399,7 @@ public: void onClickAddAccess(); void onClickAddBanned(); void callbackAvatarCBBanned(const uuid_vec_t& ids); - void callbackAvatarCBBannedTimed(const LLUUID& id, S32 time); // Add ability to do time based temp bans + void callbackAvatarCBBanned2(const uuid_vec_t& ids, S32 duration); void callbackAvatarCBAccess(const uuid_vec_t& ids); protected: diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index adfd3d64ce..0d4fa0435e 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -51,6 +51,7 @@ #include "llfloateravatarpicker.h" #include "llbutton.h" #include "llcheckboxctrl.h" +#include "llclipboard.h" #include "llcombobox.h" #include "llestateinfomodel.h" #include "llfilepicker.h" @@ -95,6 +96,7 @@ #include "llexperiencecache.h" #include "llpanelexperiences.h" #include "llcorehttputil.h" +#include "llavatarnamecache.h" #include "llenvironment.h" // Aurora Sim - Region Settings Console @@ -107,12 +109,51 @@ const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; +const U32 MAX_LISTED_NAMES = 100; + #define TMP_DISABLE_WLES // STORM-1180 ///---------------------------------------------------------------------------- /// 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); +}; + +class LLDispatchSetEstateExperience : public LLDispatchHandler +{ +public: + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); + + LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count ); +}; + + /* void unpack_request_params( LLMessageSystem* msg, @@ -189,6 +230,10 @@ bool estate_dispatch_initialized = false; /// LLFloaterRegionInfo ///---------------------------------------------------------------------------- +//S32 LLFloaterRegionInfo::sRequestSerial = 0; +LLUUID LLFloaterRegionInfo::sRequestInvoice; + + LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) : LLFloater(seed), mEnvironmentPanel(NULL), @@ -207,6 +252,11 @@ BOOL LLFloaterRegionInfo::postBuild() panel->buildFromFile("panel_region_estate.xml"); mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); + panel = new LLPanelEstateAccess; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_access.xml"); + mTab->addTabPanel(panel); + panel = new LLPanelEstateCovenant; mInfoPanels.push_back(panel); panel->buildFromFile("panel_region_covenant.xml"); @@ -257,6 +307,10 @@ BOOL LLFloaterRegionInfo::postBuild() panel->buildFromFile("panel_region_experiences.xml"); mTab->addTabPanel(panel); } + + gMessageSystem->setHandlerFunc( + "EstateOwnerMessage", + &processEstateOwnerRequest); // Request region info when agent region changes. mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this)); @@ -279,9 +333,22 @@ void LLFloaterRegionInfo::onOpen(const LLSD& key) disableTabCtrls(); return; } - LLEstateInfoModel::instance().clearRegion(); - requestRegionInfo(); // will cause refreshFromRegion() + refreshFromRegion(gAgent.getRegion()); + requestRegionInfo(); requestMeshRezInfo(); + + if (!mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterRegionInfo::onGodLevelChange, this, _1)); + } +} + +void LLFloaterRegionInfo::onClose(bool app_quitting) +{ + if (mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot.disconnect(); + } } void LLFloaterRegionInfo::onRegionChanged() @@ -292,6 +359,7 @@ void LLFloaterRegionInfo::onRegionChanged() } } +// static void LLFloaterRegionInfo::requestRegionInfo() { LLTabContainer* tab = findChild("region_panels"); @@ -301,6 +369,7 @@ void LLFloaterRegionInfo::requestRegionInfo() tab->getChild("Debug")->setCtrlsEnabled(FALSE); tab->getChild("Terrain")->setCtrlsEnabled(FALSE); tab->getChild("Estate")->setCtrlsEnabled(FALSE); + tab->getChild("Access")->setCtrlsEnabled(FALSE); } // Must allow anyone to request the RegionInfo data @@ -314,6 +383,56 @@ void LLFloaterRegionInfo::requestRegionInfo() gAgent.sendReliableMessage(); } +// static +void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) +{ + static LLDispatcher dispatch; + // FIRE-22573: Always refresh windlight even if floater not open + //LLFloaterRegionInfo* floater = LLFloaterReg::findTypedInstance("region_info"); + //if(!floater) + //{ + // return; + //} + // + + if (!estate_dispatch_initialized) + { + LLPanelEstateInfo::initDispatch(dispatch); + } + + // FIRE-22573: Always refresh windlight even if floater not open + //LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + + // unpack the message + std::string request; + LLUUID invoice; + LLDispatcher::sparam_t strings; + LLDispatcher::unpackMessage(msg, request, invoice, strings); + if(invoice != getLastInvoice()) + { + LL_WARNS() << "Mismatched Estate message: " << request << LL_ENDL; + return; + } + + //dispatch the message + dispatch.dispatch(request, invoice, strings); + + // FIRE-22573: Always refresh windlight even if floater not open + LLFloaterRegionInfo* floater = LLFloaterReg::findTypedInstance("region_info"); + if(!floater) + { + return; + } + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + // + if (panel) + { + panel->updateControls(gAgent.getRegion()); + } +} + + // static void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { @@ -471,6 +590,16 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() return panel; } +// static +LLPanelEstateAccess* LLFloaterRegionInfo::getPanelAccess() +{ + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateAccess* panel = (LLPanelEstateAccess*)tab->getChild("Access"); + return panel; +} + // static LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() { @@ -525,6 +654,7 @@ void LLFloaterRegionInfo::disableTabCtrls() tab->getChild("Terrain")->setCtrlsEnabled(FALSE); tab->getChild("panel_env_info")->setCtrlsEnabled(FALSE); tab->getChild("Estate")->setCtrlsEnabled(FALSE); + tab->getChild("Access")->setCtrlsEnabled(FALSE); } // Aurora Sim - Region Settings Console @@ -589,6 +719,15 @@ void LLFloaterRegionInfo::disableTopButtons() getChildView("top_scripts_btn")->setEnabled(false); } +void LLFloaterRegionInfo::onGodLevelChange(U8 god_level) +{ + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (floater && floater->getVisible()) + { + refreshFromRegion(gAgent.getRegion()); + } +} + ///---------------------------------------------------------------------------- /// Local class implementation ///---------------------------------------------------------------------------- @@ -657,10 +796,43 @@ void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) // virtual bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region) { - LLEstateInfoModel::instance().setRegion(region); + if (region) mHost = region->getHost(); return true; } +void LLPanelRegionInfo::sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const strings_t& strings) +{ + LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL; + 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) { LLView* button = findChildView(btn_name); @@ -794,7 +966,8 @@ void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids) ids[0].toString(buffer); strings.push_back(strings_t::value_type(buffer)); - LLEstateInfoModel::instance().sendEstateOwnerMessage("teleporthomeuser", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); } } @@ -819,8 +992,9 @@ bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const L gAgent.getID().toString(buffer); strings.push_back(buffer); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); // historical message name - LLEstateInfoModel::instance().sendEstateOwnerMessage("teleporthomeallusers", strings); + sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); } return false; } @@ -859,7 +1033,8 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L LLAgentUI::buildFullname(name); strings.push_back(strings_t::value_type(name)); strings.push_back(strings_t::value_type(text)); - LLEstateInfoModel::instance().sendEstateOwnerMessage("simulatormessage", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); return false; } @@ -952,7 +1127,8 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate() buffer = llformat("%s", (getChild("allow_parcel_changes_check")->getValue().asBoolean() ? "Y" : "N")); strings.push_back(strings_t::value_type(buffer)); - LLEstateInfoModel::instance().sendEstateOwnerMessage("setregioninfo", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); } // if we changed access levels, tell user about it @@ -1135,7 +1311,8 @@ BOOL LLPanelRegionDebugInfo::sendUpdate() buffer = llformat("%s", (getChild("disable_physics_check")->getValue().asBoolean() ? "Y" : "N")); strings.push_back(buffer); - LLEstateInfoModel::instance().sendEstateOwnerMessage("setregiondebug", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); return TRUE; } @@ -1205,7 +1382,9 @@ bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD strings.push_back(llformat("%d", flags)); strings.push_back(target_avatar.asString()); - LLEstateInfoModel::instance().sendEstateOwnerMessage("estateobjectreturn", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); } else { @@ -1223,6 +1402,7 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data) LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; strings_t strings; strings.push_back("1"); // one physics step + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); if(!instance) return; LLFloaterReg::showInstance("top_objects"); @@ -1232,7 +1412,7 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data) self->getChildView("top_colliders_btn")->setEnabled(false); self->getChildView("top_scripts_btn")->setEnabled(false); - LLEstateInfoModel::instance().sendEstateOwnerMessage("colliders", strings); + self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); } // static @@ -1241,6 +1421,7 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data) LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; strings_t strings; strings.push_back("6"); // top 5 scripts + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); if(!instance) return; LLFloaterReg::showInstance("top_objects"); @@ -1250,7 +1431,7 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data) self->getChildView("top_colliders_btn")->setEnabled(false); self->getChildView("top_scripts_btn")->setEnabled(false); - LLEstateInfoModel::instance().sendEstateOwnerMessage("scripts", strings); + self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); } // static @@ -1275,16 +1456,19 @@ bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLS strings_t strings; strings.push_back(seconds.asString()); - LLEstateInfoModel::instance().sendEstateOwnerMessage("restart", strings); + 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"); - LLEstateInfoModel::instance().sendEstateOwnerMessage("restart", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); } // static @@ -1452,6 +1636,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL; std::string buffer; strings_t strings; + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); // update the model LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); @@ -1460,7 +1645,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() region_info.mTerrainLowerLimit = (F32) getChild("terrain_lower_spin")->getValue().asReal(); // and sync the region with it - region_info.sendRegionTerrain(LLEstateInfoModel::instance().getLastInvoice()); + region_info.sendRegionTerrain(invoice); // ======================================= // Assemble and send texturedetail message @@ -1497,6 +1682,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() LLTextureCtrl* texture_ctrl; std::string id_str; + LLMessageSystem* msg = gMessageSystem; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { @@ -1510,7 +1696,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() strings.push_back(buffer); } } - LLEstateInfoModel::instance().sendEstateOwnerMessage("texturedetail", strings); + sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); strings.clear(); // ======================================== @@ -1523,13 +1709,13 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() std::string buffer3 = llformat("%d %f %f", i, (F32)getChild(buffer)->getValue().asReal(), (F32)getChild(buffer2)->getValue().asReal()); strings.push_back(buffer3); } - LLEstateInfoModel::instance().sendEstateOwnerMessage("textureheights", strings); + sendEstateOwnerMessage(msg, "textureheights", invoice, strings); strings.clear(); // ======================================== // Send texturecommit message - LLEstateInfoModel::instance().sendEstateOwnerMessage("texturecommit", strings); + sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); return TRUE; } @@ -1574,7 +1760,7 @@ bool LLPanelRegionTerrainInfo::callbackTextureHeights(const LLSD& notification, // strings_t strings; // strings.push_back("download filename"); // strings.push_back(filepath); -// LLEstateInfoModel::instance().sendEstateOwnerMessage("terrain", strings); +// self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); //} // //// static @@ -1593,7 +1779,8 @@ bool LLPanelRegionTerrainInfo::callbackTextureHeights(const LLSD& notification, // strings_t strings; // strings.push_back("upload filename"); // strings.push_back(filepath); -// LLEstateInfoModel::instance().sendEstateOwnerMessage("terrain", strings); +// LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); +// self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); // // LLNotificationsUtil::add("RawUploadStarted"); //} @@ -1612,7 +1799,8 @@ void LLPanelRegionTerrainInfo::onDownloadRawFilepickerCB(const std::vectorgetItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - //args - - LLSD args; - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); -} - -void LLPanelEstateInfo::onClickRemoveAllowedAgent() -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); -} - -void LLPanelEstateInfo::onClickAddAllowedGroup() -{ - LLCtrlListInterface *list = 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); - LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args); - return; - } - - LLNotification::Params params("ChangeLindenAccess"); - params.functor.function(boost::bind(&LLPanelEstateInfo::addAllowedGroup, this, _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 = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return false; - - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); - if (widget) - { - widget->removeNoneOption(); - widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1)); - 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; -} - -void LLPanelEstateInfo::onClickRemoveAllowedGroup() -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); -} - -void LLPanelEstateInfo::onClickAddBannedAgent() -{ - LLCtrlListInterface *list = 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); - LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); -} - -void LLPanelEstateInfo::onClickRemoveBannedAgent() -{ - accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); } // static -void LLPanelEstateInfo::onClickAddEstateManager() +void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) { - LLCtrlListInterface *list = 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); - LLNotificationsUtil::add("MaxManagersOnRegion", args); - } - else - { // Go pick managers to add - accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); - } -} + std::string name; + + name.assign("estateupdateinfo"); + static LLDispatchEstateUpdateInfo estate_update_info; + dispatch.addHandler(name, &estate_update_info); -// static -void LLPanelEstateInfo::onClickRemoveEstateManager() -{ - accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); + name.assign("setaccess"); + static LLDispatchSetEstateAccess set_access; + dispatch.addHandler(name, &set_access); + + name.assign("setexperience"); + static LLDispatchSetEstateExperience set_experience; + dispatch.addHandler(name, &set_experience); + + estate_dispatch_initialized = true; } //--------------------------------------------------------------------------- @@ -1830,7 +1919,7 @@ bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& re strings_t strings; strings.push_back(notification["payload"]["agent_id"].asString()); - LLEstateInfoModel::instance().sendEstateOwnerMessage("kickestate", strings); + sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); break; } default: @@ -1901,11 +1990,13 @@ struct LLEstateAccessChangeInfo LLSD sd; sd["name"] = mDialogName; sd["operation"] = (S32)mOperationFlag; - for (uuid_vec_t::const_iterator it = mAgentOrGroupIDs.begin(); - it != mAgentOrGroupIDs.end(); - ++it) + for (U32 i = 0; i < mAgentOrGroupIDs.size(); ++i) { - sd["allowed_ids"].append(*it); + sd["allowed_ids"].append(mAgentOrGroupIDs[i]); + if (mAgentNames.size() > i) + { + sd["allowed_names"].append(mAgentNames[i].asLLSD()); + } } return sd; } @@ -1913,348 +2004,9 @@ struct LLEstateAccessChangeInfo U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. std::string mDialogName; uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change + std::vector mAgentNames; // Optional list of the agent names for notifications }; -// Special case callback for groups, since it has different callback format than names -void LLPanelEstateInfo::addAllowedGroup2(LLUUID id) -{ - 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.function(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.function(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 = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - // abort change - return false; - } - - LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); - //Get parent floater name - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL; - const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : LLStringUtil::null; - - //Determine the button that triggered opening of the avatar picker - //(so that a shadow frustum from the button to the avatar picker can be created) - LLView * button = NULL; - switch(change_info->mOperationFlag) - { - case ESTATE_ACCESS_ALLOWED_AGENT_ADD: - button = panel->findChild("add_allowed_avatar_btn"); - break; - - case ESTATE_ACCESS_BANNED_AGENT_ADD: - button = panel->findChild("add_banned_avatar_btn"); - break; - - case ESTATE_ACCESS_MANAGER_ADD: - button = panel->findChild("add_estate_manager_btn"); - break; - } - - // avatar picker yes multi-select, yes close-on-select - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), - TRUE, TRUE, FALSE, parent_floater_name, button); - - //Allows the closed parent floater to close the child floater (avatar picker) - if (child_floater) - { - parent_floater->addDependentFloater(child_floater); - } - - return false; -} - -// static -void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& 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"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::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"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::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.function(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.function(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 = LLNotificationsUtil::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(); - LLNotificationsUtil::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 = LLNotificationsUtil::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)) - { - LLNotificationsUtil::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", LLEstateInfoModel::instance().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(); -} - // static void LLPanelEstateInfo::updateEstateOwnerName(const std::string& name) { @@ -2284,36 +2036,9 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) getChildView("apply_btn")->setEnabled(FALSE); - BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; - - getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager)); - getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager); - - getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) ); - getChildView("allowed_group_name_list")->setEnabled(god || owner || manager); - - // Can't ban people from mainland, orientation islands, etc. because this - // creates much network traffic and server load. - // Disable their accounts in CSR tool instead. - bool linden_estate = isLindenEstate(); - bool enable_ban = (god || owner || manager) && !linden_estate; - getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); - getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager); - getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); - // estate managers can't add estate managers - getChildView("add_estate_manager_btn")->setEnabled(god || owner); - getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); - getChildView("estate_manager_name_list")->setEnabled(god || owner); - refresh(); } @@ -2330,13 +2055,12 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) 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(); - - LLEstateInfoModel::instance().setRegion(region); + sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); refresh(); @@ -2366,49 +2090,6 @@ BOOL LLPanelEstateInfo::postBuild() initCtrl("voice_chat_check"); initCtrl("parcel_access_override"); - getChild("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - 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", boost::bind(&LLPanelEstateInfo::onClickAddAllowedAgent, this)); - childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveAllowedAgent, this)); - - getChild("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - 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); - } - - getChild("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onClickAddAllowedGroup, this)); - childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveAllowedGroup, this)); - - getChild("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - 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", boost::bind(&LLPanelEstateInfo::onClickAddBannedAgent, this)); - childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveBannedAgent, this)); - - getChild("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - 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", boost::bind(&LLPanelEstateInfo::onClickAddEstateManager, this)); - childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveEstateManager, this)); childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this)); childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this)); @@ -2456,147 +2137,6 @@ void LLPanelEstateInfo::refreshFromEstate() refresh(); } - -void LLPanelEstateInfo::refreshAccessFromEstate(U32 flags) -{ - const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); - - // grab the UUID's out of the string fields - if (flags & ESTATE_ACCESS_ALLOWED_AGENTS) - { - LLNameListCtrl *allowed_agent_name_list(getChild("allowed_avatar_name_list")); - - const uuid_set_t& allowed_agents(estate_info.getAllowedAgents()); - int totalAllowedAgents = allowed_agents.size(); - - if (allowed_agent_name_list) - { - totalAllowedAgents += allowed_agent_name_list->getItemCount(); - } - - LLStringUtil::format_map_t args; - args["[ALLOWEDAGENTS]"] = llformat("%d", totalAllowedAgents); - args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args); - getChild("allow_resident_label")->setValue(LLSD(msg)); - - if (allowed_agent_name_list) - { - // Don't sort these as we add them, sort them when we are done. - allowed_agent_name_list->clearSortOrder(); - allowed_agent_name_list->deleteAllItems(); - - for (const LLUUID &id : allowed_agents) - { - allowed_agent_name_list->addNameItem(id); - } - allowed_agent_name_list->sortByName(TRUE); - } - } - - if (flags & ESTATE_ACCESS_ALLOWED_GROUPS) - { - LLNameListCtrl* allowed_group_name_list(getChild("allowed_group_name_list")); - const uuid_set_t &allowed_groups(estate_info.getAllowedGroups()); - - LLStringUtil::format_map_t args; - args["[ALLOWEDGROUPS]"] = llformat("%d", allowed_groups.size()); - args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS); - std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args); - getChild("allow_group_label")->setValue(LLSD(msg)); - - if (allowed_group_name_list) - { - // Don't sort these as we add them, sort them when we are done. - allowed_group_name_list->clearSortOrder(); - allowed_group_name_list->deleteAllItems(); - - for (const LLUUID &id: allowed_groups) - { - allowed_group_name_list->addGroupNameItem(id); - } - allowed_group_name_list->sortByName(TRUE); - } - } - - if (flags & ESTATE_ACCESS_BANNED_AGENTS) - { - LLNameListCtrl* banned_agent_name_list(getChild("banned_avatar_name_list")); - const uuid_set_t &banned_agents(estate_info.getBannedAgents()); - int totalBannedAgents = banned_agents.size(); - - if (banned_agent_name_list) - { - totalBannedAgents += banned_agent_name_list->getItemCount(); - } - - - LLStringUtil::format_map_t args; - args["[BANNEDAGENTS]"] = llformat("%d", totalBannedAgents); - args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - std::string msg = LLTrans::getString("RegionInfoBannedResidents", args); - getChild("ban_resident_label")->setValue(LLSD(msg)); - - if (banned_agent_name_list) - { - // Don't sort these as we add them, sort them when we are done. - banned_agent_name_list->clearSortOrder(); - - for (const LLUUID &id: banned_agents) - { - banned_agent_name_list->addNameItem(id); - } - banned_agent_name_list->sortByName(TRUE); - } - } - - if (flags & ESTATE_ACCESS_MANAGERS) - { - LLNameListCtrl* estate_manager_name_list(getChild("estate_manager_name_list")); - const uuid_set_t &estate_mgrs(estate_info.getEstateManagers()); - - LLStringUtil::format_map_t args; - args["[ESTATEMANAGERS]"] = llformat("%d", estate_mgrs.size()); - args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS); - std::string msg = LLTrans::getString("RegionInfoEstateManagers", args); - getChild("estate_manager_label")->setValue(LLSD(msg)); - - if (estate_manager_name_list) - { - // Don't sort these as we add them, sort them when we are done. - estate_manager_name_list->clearSortOrder(); - 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 (const LLUUID &id : estate_mgrs) - { - estate_manager_name_list->addNameItem(id); - } - estate_manager_name_list->sortByName(TRUE); - } - } - - // Update the buttons which may change based on the list contents but also needs to account for general access features. - updateControls(gAgent.getRegion()); -} - - -namespace -{ - LLSD set_to_llsdarray(const uuid_set_t &values) - { - LLSD result(LLSD::emptyArray()); - - for (const LLUUID &id : values) - { - result.append(id); - } - return result; - } -} - BOOL LLPanelEstateInfo::sendUpdate() { LL_INFOS() << "LLPanelEsateInfo::sendUpdate()" << LL_ENDL; @@ -2634,6 +2174,8 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con estate_info.setDenyAgeUnverified(getChild("limit_age_verified")->getValue().asBoolean()); estate_info.setAllowVoiceChat(getChild("voice_chat_check")->getValue().asBoolean()); estate_info.setAllowAccessOverride(getChild("parcel_access_override")->getValue().asBoolean()); + // JIGGLYPUFF + //estate_info.setAllowAccessOverride(getChild("")->getValue().asBoolean()); // send the update to sim estate_info.sendEstateInfo(); } @@ -2693,22 +2235,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name) getChild("estate_owner")->setValue(LLSD(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(); - } - updateControls(gAgent.getRegion()); -} - // static void LLPanelEstateInfo::onClickMessageEstate(void* userdata) { @@ -2729,8 +2255,8 @@ bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& re LLAgentUI::buildFullname(name); strings.push_back(strings_t::value_type(name)); strings.push_back(strings_t::value_type(text)); - - LLEstateInfoModel::instance().sendEstateOwnerMessage("instantmessage", strings); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); return false; } @@ -3015,7 +2541,7 @@ void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id) msg->nextBlock("MethodData"); msg->addString("Method", "estatechangecovenantid"); - msg->addUUID("Invoice", LLEstateInfoModel::instance().getLastInvoice()); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); msg->nextBlock("ParamList"); msg->addString("Parameter", getCovenantID().asString()); @@ -3095,6 +2621,96 @@ 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) +{ + LL_DEBUGS() << "Received estate update" << LL_ENDL; + + // Update estate info model. + // This will call LLPanelEstateInfo::refreshFromEstate(). + // *TODO: Move estate message handling stuff to llestateinfomodel.cpp. + LLEstateInfoModel::instance().update(strings); + + return true; +} + +bool LLDispatchSetEstateAccess::operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel && panel->getPendingUpdate()) + { + panel->setPendingUpdate(false); + panel->updateLists(); + } + return true; +} + +LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count ) +{ + LLSD idList = LLSD::emptyArray(); + LLUUID id; + while(count--> 0) + { + memcpy(id.mData, (*(it++)).data(), UUID_BYTES); + idList.append(id); + } + return idList; +} + +// key = "setexperience" +// strings[0] = str(estate_id) +// strings[1] = str(send_to_agent_only) +// strings[2] = str(num blocked) +// strings[3] = str(num trusted) +// strings[4] = str(num allowed) +// strings[8] = bin(uuid) ... +// ... +bool LLDispatchSetEstateExperience::operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) +{ + LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); + if (!panel) return true; + + sparam_t::const_iterator it = strings.begin(); + ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10); + ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10); + + LLUUID id; + S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10); + S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10); + S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10); + + LLSD ids = LLSD::emptyMap() + .with("blocked", getIDs(it, strings.end(), num_blocked)) + .with("trusted", getIDs(it + (num_blocked), strings.end(), num_trusted)) + .with("allowed", getIDs(it + (num_blocked+num_trusted), strings.end(), num_allowed)); + + panel->processResponse(ids); + + return true; +} + BOOL LLPanelRegionExperiences::postBuild() { mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE); @@ -3107,8 +2723,6 @@ BOOL LLPanelRegionExperiences::postBuild() getChild("allowed_text_help")->setText(getString("allowed_estate_text")); getChild("blocked_text_help")->setText(getString("blocked_estate_text")); - LLEstateInfoModel::instance().setUpdateExperienceCallback(boost::bind(&LLPanelRegionExperiences::refreshExperiencesFromEstate, this)); - return LLPanelRegionInfo::postBuild(); } @@ -3152,18 +2766,6 @@ void LLPanelRegionExperiences::processResponse( const LLSD& content ) } -void LLPanelRegionExperiences::refreshExperiencesFromEstate() -{ - const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); - - LLSD ids = LLSDMap("blocked", set_to_llsdarray(estate_info.getBlockedExperiences())) - ("trusted", set_to_llsdarray(estate_info.getTrustedExperiences())) - ("allowed", set_to_llsdarray(estate_info.getAllowedExperiences())); - - processResponse(ids); -} - - // Used for both access add and remove operations, depending on the flag // passed in (ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE, etc.) // static @@ -3226,7 +2828,11 @@ void LLPanelRegionExperiences::sendEstateExperienceDelta(U32 flags, const LLUUID str[1] = llformat("%u", flags); experience_id.toString(str[2]); - LLEstateInfoModel::instance().sendEstateOwnerMessage("estateexperiencedelta", str); + LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); + if (panel) + { + panel->sendEstateOwnerMessage(gMessageSystem, "estateexperiencedelta", LLFloaterRegionInfo::getLastInvoice(), str); + } } @@ -3364,6 +2970,971 @@ void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id ) onChangeAnything(); } + +LLPanelEstateAccess::LLPanelEstateAccess() +: LLPanelRegionInfo(), mPendingUpdate(false) +{} + +BOOL LLPanelEstateAccess::postBuild() +{ + getChild("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + 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); + } + + getChild("allowed_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedSearchEdit, this, _2)); + childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddAllowedAgent, this)); + childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedAgent, this)); + childSetAction("copy_allowed_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedList, this)); + + getChild("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + 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); + } + + getChild("allowed_group_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedGroupsSearchEdit, this, _2)); + getChild("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onClickAddAllowedGroup, this)); + childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedGroup, this)); + childSetAction("copy_allowed_group_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedGroupList, this)); + + getChild("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + 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); + } + + getChild("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2)); + childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddBannedAgent, this)); + childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveBannedAgent, this)); + childSetAction("copy_banned_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyBannedList, this)); + + getChild("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + 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", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this)); + childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveEstateManager, this)); + + return TRUE; +} + +void LLPanelEstateAccess::updateControls(LLViewerRegion* region) +{ + BOOL god = gAgent.isGodlike(); + BOOL owner = (region && (region->getOwner() == gAgent.getID())); + BOOL manager = (region && region->isEstateManager()); + BOOL enable_cotrols = god || owner || manager; + setCtrlsEnabled(enable_cotrols); + + BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; + + getChildView("add_allowed_avatar_btn")->setEnabled(enable_cotrols); + getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && enable_cotrols); + getChildView("allowed_avatar_name_list")->setEnabled(enable_cotrols); + + getChildView("add_allowed_group_btn")->setEnabled(enable_cotrols); + getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && enable_cotrols); + getChildView("allowed_group_name_list")->setEnabled(enable_cotrols); + + // Can't ban people from mainland, orientation islands, etc. because this + // creates much network traffic and server load. + // Disable their accounts in CSR tool instead. + bool linden_estate = LLPanelEstateInfo::isLindenEstate(); + bool enable_ban = enable_cotrols && !linden_estate; + getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); + getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); + getChildView("banned_avatar_name_list")->setEnabled(enable_cotrols); + + // estate managers can't add estate managers + getChildView("add_estate_manager_btn")->setEnabled(god || owner); + getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); + getChildView("estate_manager_name_list")->setEnabled(god || owner); + + if (enable_cotrols != mCtrlsEnabled) + { + mCtrlsEnabled = enable_cotrols; + updateLists(); // update the lists on the agent's access level change + } +} + +//--------------------------------------------------------------------------- +// Add/Remove estate access button callbacks +//--------------------------------------------------------------------------- +void LLPanelEstateAccess::onClickAddAllowedAgent() +{ + LLCtrlListInterface *list = 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); + LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); +} + +void LLPanelEstateAccess::onClickRemoveAllowedAgent() +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); +} + +void LLPanelEstateAccess::onClickAddAllowedGroup() +{ + LLCtrlListInterface *list = 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); + LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args); + return; + } + + LLNotification::Params params("ChangeLindenAccess"); + params.functor.function(boost::bind(&LLPanelEstateAccess::addAllowedGroup, this, _1, _2)); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } +} + +bool LLPanelEstateAccess::addAllowedGroup(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return false; + + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + + LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); + if (widget) + { + widget->removeNoneOption(); + widget->setSelectGroupCallback(boost::bind(&LLPanelEstateAccess::addAllowedGroup2, this, _1)); + 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; +} + +void LLPanelEstateAccess::onClickRemoveAllowedGroup() +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); +} + +void LLPanelEstateAccess::onClickAddBannedAgent() +{ + LLCtrlListInterface *list = 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); + LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); +} + +void LLPanelEstateAccess::onClickRemoveBannedAgent() +{ + accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); +} + +void LLPanelEstateAccess::onClickCopyAllowedList() +{ + copyListToClipboard("allowed_avatar_name_list"); +} + +void LLPanelEstateAccess::onClickCopyAllowedGroupList() +{ + copyListToClipboard("allowed_group_name_list"); +} + +void LLPanelEstateAccess::onClickCopyBannedList() +{ + copyListToClipboard("banned_avatar_name_list"); +} + +// static +void LLPanelEstateAccess::onClickAddEstateManager() +{ + LLCtrlListInterface *list = 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); + LLNotificationsUtil::add("MaxManagersOnRegion", args); + } + else + { // Go pick managers to add + accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); + } +} + +// static +void LLPanelEstateAccess::onClickRemoveEstateManager() +{ + accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); +} + + +// Special case callback for groups, since it has different callback format than names +void LLPanelEstateAccess::addAllowedGroup2(LLUUID id) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel) + { + LLNameListCtrl* group_list = panel->getChild("allowed_group_name_list"); + LLScrollListItem* item = group_list->getNameItemByAgentId(id); + if (item) + { + LLSD args; + args["GROUP"] = item->getColumn(0)->getValue().asString(); + LLNotificationsUtil::add("GroupIsAlreadyInList", args); + return; + } + } + + 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.function(accessCoreConfirm); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateAccess::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.function(accessAddCore2); + + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + // same as clicking "OK" + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateAccess::accessAddCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // abort change + return false; + } + + LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); + //Get parent floater name + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL; + const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : ""; + + //Determine the button that triggered opening of the avatar picker + //(so that a shadow frustum from the button to the avatar picker can be created) + LLView * button = NULL; + switch (change_info->mOperationFlag) + { + case ESTATE_ACCESS_ALLOWED_AGENT_ADD: + button = panel->findChild("add_allowed_avatar_btn"); + break; + + case ESTATE_ACCESS_BANNED_AGENT_ADD: + button = panel->findChild("add_banned_avatar_btn"); + break; + + case ESTATE_ACCESS_MANAGER_ADD: + button = panel->findChild("add_estate_manager_btn"); + break; + } + + // avatar picker yes multi-select, yes close-on-select + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateAccess::accessAddCore3, _1, _2, (void*)change_info), + TRUE, TRUE, FALSE, parent_floater_name, button); + + //Allows the closed parent floater to close the child floater (avatar picker) + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } + + return false; +} + +// static +void LLPanelEstateAccess::accessAddCore3(const uuid_vec_t& ids, std::vector names, 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 + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) + { + LLNameListCtrl* name_list = panel->getChild("allowed_avatar_name_list"); + int currentCount = (name_list ? name_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"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + + uuid_vec_t ids_allowed; + std::vector names_allowed; + std::string already_allowed; + bool single = true; + for (U32 i = 0; i < ids.size(); ++i) + { + LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); + if (item) + { + if (!already_allowed.empty()) + { + already_allowed += ", "; + single = false; + } + already_allowed += item->getColumn(0)->getValue().asString(); + } + else + { + ids_allowed.push_back(ids[i]); + names_allowed.push_back(names[i]); + } + } + if (!already_allowed.empty()) + { + LLSD args; + args["AGENT"] = already_allowed; + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + change_info->mAgentOrGroupIDs = ids_allowed; + change_info->mAgentNames = names_allowed; + } + if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) + { + LLNameListCtrl* name_list = panel->getChild("banned_avatar_name_list"); + LLNameListCtrl* em_list = panel->getChild("estate_manager_name_list"); + int currentCount = (name_list ? name_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"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + + uuid_vec_t ids_allowed; + std::vector names_allowed; + std::string already_banned; + std::string em_ban; + bool single = true; + for (U32 i = 0; i < ids.size(); ++i) + { + bool is_allowed = true; + LLScrollListItem* em_item = em_list->getNameItemByAgentId(ids[i]); + if (em_item) + { + if (!em_ban.empty()) + { + em_ban += ", "; + } + em_ban += em_item->getColumn(0)->getValue().asString(); + is_allowed = false; + } + + LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); + if (item) + { + if (!already_banned.empty()) + { + already_banned += ", "; + single = false; + } + already_banned += item->getColumn(0)->getValue().asString(); + is_allowed = false; + } + + if (is_allowed) + { + ids_allowed.push_back(ids[i]); + names_allowed.push_back(names[i]); + } + } + if (!em_ban.empty()) + { + LLSD args; + args["AGENT"] = em_ban; + LLNotificationsUtil::add("ProblemBanningEstateManager", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + if (!already_banned.empty()) + { + LLSD args; + args["AGENT"] = already_banned; + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + change_info->mAgentOrGroupIDs = ids_allowed; + change_info->mAgentNames = names_allowed; + } + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotification::Params params(change_info->mDialogName); + params.substitutions(args) + .payload(change_info->asLLSD()) + .functor.function(accessCoreConfirm); + + if (LLPanelEstateInfo::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 LLPanelEstateAccess::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + 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.function(accessRemoveCore2); + + if (LLPanelEstateInfo::isLindenEstate()) + { + // warn on change linden estate + LLNotifications::instance().add(params); + } + else + { + // just proceed, as if clicking OK + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateAccess::accessRemoveCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::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 (LLPanelEstateInfo::isLindenEstate()) + { + accessCoreConfirm(notification, response); + } + else + { + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotificationsUtil::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 LLPanelEstateAccess::accessCoreConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + U32 flags = originalFlags; + + LLViewerRegion* region = gAgent.getRegion(); + + if (option == 2) // cancel + { + return false; + } + else if (option == 1) + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) return false; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + } + } + + std::string names; + U32 listed_names = 0; + for (U32 i = 0; i < notification["payload"]["allowed_ids"].size(); ++i) + { + if (i + 1 != notification["payload"]["allowed_ids"].size()) + { + flags |= ESTATE_ACCESS_NO_REPLY; + } + else + { + flags &= ~ESTATE_ACCESS_NO_REPLY; + } + + const LLUUID id = notification["payload"]["allowed_ids"][i].asUUID(); + if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) + && region && (region->getOwner() == id)) + { + LLNotificationsUtil::add("OwnerCanNotBeDenied"); + break; + } + + sendEstateAccessDelta(flags, id); + + if ((flags & (ESTATE_ACCESS_ALLOWED_GROUP_ADD | ESTATE_ACCESS_ALLOWED_GROUP_REMOVE)) == 0) + { + // fill the name list for confirmation + if (listed_names < MAX_LISTED_NAMES) + { + if (!names.empty()) + { + names += ", "; + } + if (!notification["payload"]["allowed_names"][i]["display_name"].asString().empty()) + { + names += notification["payload"]["allowed_names"][i]["display_name"].asString(); + } + else + { //try to get an agent name from cache + LLAvatarName av_name; + if (LLAvatarNameCache::get(id, &av_name)) + { + names += av_name.getCompleteName(); + } + } + + } + listed_names++; + } + } + if (listed_names > MAX_LISTED_NAMES) + { + LLSD args; + args["EXTRA_COUNT"] = llformat("%d", listed_names - MAX_LISTED_NAMES); + names += " " + LLTrans::getString("AndNMore", args); + } + + if (!names.empty()) // show the conirmation + { + LLSD args; + args["AGENT"] = names; + + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE)) + { + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + } + else if (flags & (ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + } + + if (flags & ESTATE_ACCESS_APPLY_TO_ALL_ESTATES) + { + args["ESTATE"] = LLTrans::getString("RegionInfoAllEstates"); + } + else if (flags & ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES) + { + args["ESTATE"] = LLTrans::getString("RegionInfoManagedEstates"); + } + else + { + args["ESTATE"] = LLTrans::getString("RegionInfoThisEstate"); + } + + bool single = (listed_names == 1); + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_ADD)) + { + LLNotificationsUtil::add(single ? "AgentWasAddedToList" : "AgentsWereAddedToList", args); + } + else if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + LLNotificationsUtil::add(single ? "AgentWasRemovedFromList" : "AgentsWereRemovedFromList", args); + } + } + + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel) + { + panel->setPendingUpdate(true); + } + + 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 LLPanelEstateAccess::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); + + gAgent.sendReliableMessage(); +} + +void LLPanelEstateAccess::updateChild(LLUICtrl* child_ctrl) +{ + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); +} + +void LLPanelEstateAccess::updateLists() +{ + std::string cap_url = gAgent.getRegionCapability("EstateAccess"); + if (!cap_url.empty()) + { + LLCoros::instance().launch("LLFloaterRegionInfo::requestEstateGetAccessCoro", boost::bind(LLPanelEstateAccess::requestEstateGetAccessCoro, cap_url)); + } +} + +void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestEstateGetAccessoCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + if (allowed_agent_name_list && result.has("AllowedAgents")) + { + LLStringUtil::format_map_t args; + args["[ALLOWEDAGENTS]"] = llformat("%d", result["AllowedAgents"].size()); + args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args); + panel->getChild("allow_resident_label")->setValue(LLSD(msg)); + + allowed_agent_name_list->clearSortOrder(); + allowed_agent_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["AllowedAgents"].beginArray(); it != result["AllowedAgents"].endArray(); ++it) + { + LLUUID id = (*it)["id"].asUUID(); + allowed_agent_name_list->addNameItem(id); + } + allowed_agent_name_list->sortByName(TRUE); + } + + LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + if (banned_agent_name_list && result.has("BannedAgents")) + { + LLStringUtil::format_map_t args; + args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size()); + args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + std::string msg = LLTrans::getString("RegionInfoBannedResidents", args); + panel->getChild("ban_resident_label")->setValue(LLSD(msg)); + + banned_agent_name_list->clearSortOrder(); + banned_agent_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["BannedAgents"].beginArray(); it != result["BannedAgents"].endArray(); ++it) + { + LLSD item; + item["id"] = (*it)["id"].asUUID(); + LLSD& columns = item["columns"]; + + columns[0]["column"] = "name"; // to be populated later + + columns[1]["column"] = "last_login_date"; + columns[1]["value"] = (*it)["last_login_date"].asString().substr(0, 16); // cut the seconds + + std::string ban_date = (*it)["ban_date"].asString(); + columns[2]["column"] = "ban_date"; + columns[2]["value"] = ban_date[0] != '0' ? ban_date.substr(0, 16) : LLTrans::getString("na"); // server returns the "0000-00-00 00:00:00" date in case it doesn't know it + + columns[3]["column"] = "bannedby"; + LLUUID banning_id = (*it)["banning_id"].asUUID(); + LLAvatarName av_name; + if (banning_id.isNull()) + { + columns[3]["value"] = LLTrans::getString("na"); + } + else if (LLAvatarNameCache::get(banning_id, &av_name)) + { + columns[3]["value"] = av_name.getCompleteName(); //TODO: fetch the name if it wasn't cached + } + + banned_agent_name_list->addElement(item); + } + banned_agent_name_list->sortByName(TRUE); + } + + LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); + if (allowed_group_name_list && result.has("AllowedGroups")) + { + LLStringUtil::format_map_t args; + args["[ALLOWEDGROUPS]"] = llformat("%d", result["AllowedGroups"].size()); + args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS); + std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args); + panel->getChild("allow_group_label")->setValue(LLSD(msg)); + + allowed_group_name_list->clearSortOrder(); + allowed_group_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["AllowedGroups"].beginArray(); it != result["AllowedGroups"].endArray(); ++it) + { + LLUUID id = (*it)["id"].asUUID(); + allowed_group_name_list->addGroupNameItem(id); + } + allowed_group_name_list->sortByName(TRUE); + } + + LLNameListCtrl* estate_manager_name_list = panel->getChild("estate_manager_name_list"); + if (estate_manager_name_list && result.has("Managers")) + { + LLStringUtil::format_map_t args; + args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size()); + args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS); + std::string msg = LLTrans::getString("RegionInfoEstateManagers", args); + panel->getChild("estate_manager_label")->setValue(LLSD(msg)); + + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["Managers"].beginArray(); it != result["Managers"].endArray(); ++it) + { + LLUUID id = (*it)["agent_id"].asUUID(); + estate_manager_name_list->addNameItem(id); + } + estate_manager_name_list->sortByName(TRUE); + } + + + panel->updateControls(gAgent.getRegion()); +} + +//--------------------------------------------------------------------------- +// Access lists search +//--------------------------------------------------------------------------- +void LLPanelEstateAccess::onAllowedSearchEdit(const std::string& search_string) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + searchAgent(allowed_agent_name_list, search_string); +} + +void LLPanelEstateAccess::onAllowedGroupsSearchEdit(const std::string& search_string) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); + searchAgent(allowed_group_name_list, search_string); +} + +void LLPanelEstateAccess::onBannedSearchEdit(const std::string& search_string) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + searchAgent(banned_agent_name_list, search_string); +} + +void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string) +{ + if (!listCtrl) return; + + if (!search_string.empty()) + { + listCtrl->setSearchColumn(0); // name column + listCtrl->selectItemByPrefix(search_string, FALSE); + } + else + { + listCtrl->deselectAllItems(TRUE); + } +} + +void LLPanelEstateAccess::copyListToClipboard(std::string list_name) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild(list_name); + if (!name_list) return; + + std::vector list_vector = name_list->getAllData(); + if (list_vector.size() == 0) return; + + LLSD::String list_to_copy; + for (std::vector::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + if (item) + { + list_to_copy += item->getColumn(0)->getValue().asString(); + } + if (std::next(iter) != list_vector.end()) + { + list_to_copy += "\n"; + } + } + + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(list_to_copy), 0, list_to_copy.length()); +} + +bool LLPanelEstateAccess::refreshFromRegion(LLViewerRegion* region) +{ + updateLists(); + return LLPanelRegionInfo::refreshFromRegion(region); +} + //========================================================================= const U32 LLPanelRegionEnvironment::DIRTY_FLAG_OVERRIDE(0x01 << 4); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index be9c892edc..53515a6ce2 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -29,6 +29,7 @@ #define LL_LLFLOATERREGIONINFO_H #include +#include "llagent.h" #include "llassettype.h" #include "llfloater.h" #include "llhost.h" @@ -67,6 +68,7 @@ class LLPanelEstateCovenant; class LLPanelExperienceListEditor; class LLPanelExperiences; class LLPanelRegionExperiences; +class LLPanelEstateAccess; class LLPanelRegionEnvironment; class LLEventTimer; @@ -78,15 +80,21 @@ public: /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); /*virtual*/ BOOL postBuild(); + static void processEstateOwnerRequest(LLMessageSystem* msg, void**); + // get and process region info if necessary. static void processRegionInfo(LLMessageSystem* msg); + static const LLUUID& getLastInvoice() { return sRequestInvoice; } + static void nextInvoice() { sRequestInvoice.generate(); } //static S32 getSerial() { return sRequestSerial; } //static void incrementSerial() { sRequestSerial++; } static LLPanelEstateInfo* getPanelEstate(); + static LLPanelEstateAccess* getPanelAccess(); static LLPanelEstateCovenant* getPanelCovenant(); static LLPanelRegionTerrainInfo* getPanelRegionTerrain(); static LLPanelRegionExperiences* getPanelExperiences(); @@ -109,20 +117,22 @@ private: LLFloaterRegionInfo(const LLSD& seed); ~LLFloaterRegionInfo(); - - protected: void onTabSelected(const LLSD& param); void disableTabCtrls(); void refreshFromRegion(LLViewerRegion* region); + void onGodLevelChange(U8 god_level); // member data LLTabContainer* mTab; typedef std::vector info_panels_t; info_panels_t mInfoPanels; LLPanelRegionEnvironment *mEnvironmentPanel; + //static S32 sRequestSerial; // serial # of last EstateOwnerRequest + static LLUUID sRequestInvoice; private: + LLAgent::god_level_change_slot_t mGodLevelChangeSlot; boost::signals2::connection mRegionChangedCallback; }; @@ -158,6 +168,15 @@ protected: typedef std::vector strings_t; //typedef std::vector integers_t; + void sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const strings_t& strings); + + + // member data + LLHost mHost; }; ///////////////////////////////////////////////////////////////////////////// @@ -283,9 +302,12 @@ private: }; ///////////////////////////////////////////////////////////////////////////// + class LLPanelEstateInfo : public LLPanelRegionInfo { public: + static void initDispatch(LLDispatcher& dispatch); + void onChangeFixedSun(); void onChangeUseGlobalTime(); void onChangeAccessOverride(); @@ -295,35 +317,11 @@ public: void onClickEditDayCycle(); void onClickEditDayCycleHelp(); - void onClickAddAllowedAgent(); - void onClickRemoveAllowedAgent(); - void onClickAddAllowedGroup(); - void onClickRemoveAllowedGroup(); - void onClickAddBannedAgent(); - void onClickRemoveBannedAgent(); - void onClickAddEstateManager(); - void onClickRemoveEstateManager(); void onClickKickUser(); - // Group picker callback is different, can't use core methods below - bool addAllowedGroup(const LLSD& notification, const LLSD& response); - void addAllowedGroup2(LLUUID id); - // Core methods for all above add/remove button clicks - static void accessAddCore(U32 operation_flag, const std::string& dialog_name); - static bool accessAddCore2(const LLSD& notification, const LLSD& response); - static void accessAddCore3(const uuid_vec_t& ids, void* data); - - static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); - static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); - - // used for both add and remove operations - static bool accessCoreConfirm(const LLSD& notification, const LLSD& response); bool kickUserConfirm(const LLSD& notification, const LLSD& response); - // Send the actual EstateOwnerRequest "estateaccessdelta" message - static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); - void onKickUserCommit(const uuid_vec_t& ids); static void onClickMessageEstate(void* data); bool onMessageCommit(const LLSD& notification, const LLSD& response); @@ -345,7 +343,6 @@ public: virtual void refresh(); void refreshFromEstate(); - void refreshAccessFromEstate(U32 flags); static bool isLindenEstate(); @@ -360,7 +357,6 @@ protected: void commitEstateAccess(); void commitEstateManagers(); - void clearAccessLists(); BOOL checkSunHourSlider(LLUICtrl* child_ctrl); U32 mEstateID; @@ -448,7 +444,7 @@ public: void sendPurchaseRequest()const; void processResponse( const LLSD& content ); private: - void refreshExperiencesFromEstate(); + void refreshRegionExperiences(); static std::string regionCapabilityQuery(LLViewerRegion* region, const std::string &cap); @@ -463,4 +459,70 @@ private: LLUUID mDefaultExperience; }; + +class LLPanelEstateAccess : public LLPanelRegionInfo +{ + LOG_CLASS(LLPanelEnvironmentInfo); + +public: + LLPanelEstateAccess(); + + virtual BOOL postBuild(); + virtual void updateChild(LLUICtrl* child_ctrl); + + void updateControls(LLViewerRegion* region); + void updateLists(); + + void setPendingUpdate(bool pending) { mPendingUpdate = pending; } + bool getPendingUpdate() { return mPendingUpdate; } + + virtual bool refreshFromRegion(LLViewerRegion* region); + + // Moved to public + static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); + +private: + void onClickAddAllowedAgent(); + void onClickRemoveAllowedAgent(); + void onClickCopyAllowedList(); + void onClickAddAllowedGroup(); + void onClickRemoveAllowedGroup(); + void onClickCopyAllowedGroupList(); + void onClickAddBannedAgent(); + void onClickRemoveBannedAgent(); + void onClickCopyBannedList(); + void onClickAddEstateManager(); + void onClickRemoveEstateManager(); + void onAllowedSearchEdit(const std::string& search_string); + void onAllowedGroupsSearchEdit(const std::string& search_string); + void onBannedSearchEdit(const std::string& search_string); + + // Group picker callback is different, can't use core methods below + bool addAllowedGroup(const LLSD& notification, const LLSD& response); + void addAllowedGroup2(LLUUID id); + + // Core methods for all above add/remove button clicks + static void accessAddCore(U32 operation_flag, const std::string& dialog_name); + static bool accessAddCore2(const LLSD& notification, const LLSD& response); + static void accessAddCore3(const uuid_vec_t& ids, std::vector names, void* data); + + static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); + static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); + + // used for both add and remove operations + static bool accessCoreConfirm(const LLSD& notification, const LLSD& response); + + // Send the actual EstateOwnerRequest "estateaccessdelta" message + // Moved to public + //static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); + + static void requestEstateGetAccessCoro(std::string url); + + void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string); + void copyListToClipboard(std::string list_name); + + bool mPendingUpdate; + BOOL mCtrlsEnabled; +}; + #endif diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 2a6e978712..3df57761d8 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -32,6 +32,7 @@ #include "llavatarnamecache.h" #include "llcachename.h" +#include "llfloater.h" #include "llfloaterreg.h" #include "llinventory.h" #include "llscrolllistitem.h" @@ -221,7 +222,10 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) BOOL handled = FALSE; S32 column_index = getColumnIndexFromOffset(x); LLNameListItem* hit_item = dynamic_cast(hitItem(x, y)); - if (hit_item + LLFloater* floater = gFloaterView->getParentFloater(this); + if (floater + && floater->isFrontmost() + && hit_item && column_index == mNameColumnIndex) { // ...this is the column with the avatar name @@ -328,8 +332,19 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( switch(name_item.target) { case GROUP: - gCacheName->getGroupName(id, fullname); - // fullname will be "nobody" if group not found + if (!gCacheName->getGroupName(id, fullname)) + { + avatar_name_cache_connection_map_t::iterator it = mGroupNameCacheConnections.find(id); + if (it != mGroupNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mGroupNameCacheConnections.erase(it); + } + mGroupNameCacheConnections[id] = gCacheName->getGroup(id, boost::bind(&LLNameListCtrl::onGroupNameCache, this, _1, _2, item->getHandle())); + } break; case SPECIAL: // just use supplied name @@ -433,6 +448,20 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) } } +// public +LLScrollListItem* LLNameListCtrl::getNameItemByAgentId(const LLUUID& agent_id) +{ + for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++) + { + LLScrollListItem* item = *it; + if (item && item->getUUID() == agent_id) + { + return item; + } + } + return NULL; +} + void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, @@ -499,6 +528,31 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, dirtyColumns(); } +void LLNameListCtrl::onGroupNameCache(const LLUUID& group_id, const std::string name, LLHandle item) +{ + avatar_name_cache_connection_map_t::iterator it = mGroupNameCacheConnections.find(group_id); + if (it != mGroupNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mGroupNameCacheConnections.erase(it); + } + + LLNameListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == group_id) + { + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) + { + cell->setValue(name); + setNeedsSort(); + } + } + + dirtyColumns(); +} void LLNameListCtrl::updateColumns(bool force_update) { diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index b6685f02a7..e7c11a343b 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -166,6 +166,8 @@ public: void removeNameItem(const LLUUID& agent_id); + LLScrollListItem* getNameItemByAgentId(const LLUUID& agent_id); + // LLView interface /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, @@ -183,6 +185,7 @@ public: private: void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle item); + void onGroupNameCache(const LLUUID& group_id, const std::string name, LLHandle item); private: S32 mNameColumnIndex; @@ -191,6 +194,7 @@ private: bool mShortNames; // display name only, no SLID typedef std::map avatar_name_cache_connection_map_t; avatar_name_cache_connection_map_t mAvatarNameCacheConnections; + avatar_name_cache_connection_map_t mGroupNameCacheConnections; // Fix Baker's NameListCtrl un-fix // S32 mPendingLookupsRemaining; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index a112b6eae7..0ccd89080b 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -40,6 +40,7 @@ #include "llfloateravatarpicker.h" //#include "llfloateravatarrendersettings.h" // [FS Persisted Avatar Render Settings] #include "llfloateravatartextures.h" +#include "llfloaterbanduration.h" #include "llfloaterbigpreview.h" #include "llfloaterbeacons.h" #include "llfloaterbuildoptions.h" @@ -175,7 +176,6 @@ #include "fsfloateraddtocontactset.h" #include "fsfloaterassetblacklist.h" #include "fsfloateravatarrendersettings.h" -#include "fsfloaterbantime.h" #include "fsfloatercontacts.h" #include "fsfloatercontactsetconfiguration.h" #include "fsfloaterexport.h" @@ -247,6 +247,7 @@ void LLViewerFloaterReg::registerFloaters() //LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("ban_duration", "floater_ban_duration.xml", &LLFloaterReg::build); LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("bulk_perms", "floater_bulk_perms.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("buy_currency", "floater_buy_currency.xml", &LLFloaterBuyCurrency::buildFloater); @@ -464,7 +465,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("floater_profile", "floater_profile_view.xml",&LLFloaterReg::build); LLFloaterReg::add("fs_asset_blacklist", "floater_fs_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("fs_ban_time", "floater_fs_ban_duration.xml", &LLFloaterReg::build); LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_add_contact", "floater_fs_contact_add.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_contact_set_config", "floater_fs_contact_set_configuration.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7fd3e82c4e..f51ad4957c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3080,6 +3080,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("DirectDelivery"); capabilityNames.append("EnvironmentSettings"); + capabilityNames.append("EstateAccess"); // Aurora Sim capabilityNames.append("DispatchOpenRegionSettings"); // Aurora Sim diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d52c87732e..547fc434ab 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1857,9 +1857,19 @@ LLViewerWindow::LLViewerWindow(const Params& p) LLCoordScreen scr; mWindow->getSize(&scr); + // Reset UI scale factor on first run if OS's display scaling is not 100% + if (gSavedSettings.getBOOL("ResetUIScaleOnFirstRun")) + { + if (mWindow->getSystemUISize() != 1.f) + { + gSavedSettings.setF32("UIScaleFactor", 1.f); + } + gSavedSettings.setBOOL("ResetUIScaleOnFirstRun", FALSE); + } + // Get the real window rect the window was created with (since there are various OS-dependent reasons why // the size of a window or fullscreen context may have been adjusted slightly...) - F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getSystemUISize(); + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); mDisplayScale *= ui_scale_factor; @@ -6588,7 +6598,7 @@ F32 LLViewerWindow::getWorldViewAspectRatio() const void LLViewerWindow::calcDisplayScale() { - F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getSystemUISize(); + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); LLVector2 display_scale; display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); display_scale *= ui_scale_factor; diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index 74ca8c3b74..e764b89fd6 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -9,6 +9,12 @@ "Parcel_R_Dark" + + [HOURS] Std. + + + Std. + [MINUTES] Min. @@ -21,6 +27,9 @@ Restzeit + + Permanent + @@ -486,9 +495,12 @@ Nur große Parzellen können in der Suche aufgeführt werden. - Immer verbannt ([COUNT]/[MAX]) + Verbannt ([COUNT]/[MAX]) - + + + + + + diff --git a/indra/newview/skins/default/xui/en/floater_fs_ban_duration.xml b/indra/newview/skins/default/xui/en/floater_fs_ban_duration.xml deleted file mode 100644 index d776463891..0000000000 --- a/indra/newview/skins/default/xui/en/floater_fs_ban_duration.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - Ban duration: - - - - hours. - - - 0 means forever. - - - - diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 7c5929c7f2..dd170179f4 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3924,6 +3924,62 @@ Cannot add estate owner to estate 'Banned resident' list. type="alertmodal"> Unable to add banned resident to estate manager list. + + +Unable to add estate manager [AGENT] to banned list. + + + +<nolink>[GROUP]</nolink> is already in the Allowed Groups list. + + + +[AGENT] is already in your [LIST_TYPE] list. + + + +[AGENT] are already in your [LIST_TYPE] list. + + + +[AGENT] was added to [LIST_TYPE] list of [ESTATE]. + + + +[AGENT] were added to [LIST_TYPE] list of [ESTATE]. + + + +[AGENT] was removed from [LIST_TYPE] list of [ESTATE]. + + + +[AGENT] were removed from [LIST_TYPE] list of [ESTATE]. + + type="alertmodal"> + Remove from allowed list for this estate only or for [ALL_ESTATES]? confirm + type="alertmodal"> + Remove from group allowed list for this estate only or [ALL_ESTATES]? group confirm @@ -4888,8 +4946,9 @@ Deny access for this estate only or for [ALL_ESTATES]? icon="alert.tga" label="Select estate" name="EstateBannedAgentRemove" - type="alert"> -Remove this resident from the ban list for access for this estate only or for [ALL_ESTATES]? + type="alertmodal"> + +Remove this Resident from the ban list for access for this estate only or for [ALL_ESTATES]? confirm + type="alertmodal"> + Remove estate manager for this estate only or for [ALL_ESTATES]? confirm + + + + + + + + + Estate Managers: + + + + + + + +